From bdd40d87556ea2bdd8b98c2114b12d6afc84e829 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Sat, 4 Nov 2017 22:43:07 -0400 Subject: [PATCH] move domain models to ts --- src/background.html | 1 - src/background.js | 7 + src/enums/secureNoteType.enum.ts | 3 + src/models/domain/attachment.ts | 43 ++++ src/models/domain/card.ts | 43 ++++ src/models/domain/cipher.ts | 181 ++++++++++++++++ src/models/domain/domain.ts | 2 +- src/models/domain/field.ts | 39 ++++ src/models/domain/folder.ts | 4 +- src/models/domain/identity.ts | 79 +++++++ src/models/domain/login.ts | 37 ++++ src/models/domain/secureNote.ts | 27 +++ src/models/domainModels.js | 360 ------------------------------- src/popup/app/app.js | 9 +- src/services/utils.service.ts | 152 ++++++------- 15 files changed, 545 insertions(+), 442 deletions(-) create mode 100644 src/enums/secureNoteType.enum.ts create mode 100644 src/models/domain/attachment.ts create mode 100644 src/models/domain/card.ts create mode 100644 src/models/domain/cipher.ts create mode 100644 src/models/domain/field.ts create mode 100644 src/models/domain/identity.ts create mode 100644 src/models/domain/login.ts create mode 100644 src/models/domain/secureNote.ts delete mode 100644 src/models/domainModels.js diff --git a/src/background.html b/src/background.html index d353afbb..ecce90d7 100644 --- a/src/background.html +++ b/src/background.html @@ -4,7 +4,6 @@ - diff --git a/src/background.js b/src/background.js index 04f720c4..40c89dc4 100644 --- a/src/background.js +++ b/src/background.js @@ -15,7 +15,14 @@ import UserService from './services/user.service'; import UtilsService from './services/utils.service'; // Model imports +import { Attachment } from './models/domain/attachment'; +import { Card } from './models/domain/card'; +import { Cipher } from './models/domain/cipher'; +import { Field } from './models/domain/field'; import { Folder } from './models/domain/folder'; +import { Identity } from './models/domain/identity'; +import { Login } from './models/domain/login'; +import { SecureNote } from './models/domain/secureNote'; import { AttachmentData } from './models/data/attachmentData'; import { CardData } from './models/data/cardData'; diff --git a/src/enums/secureNoteType.enum.ts b/src/enums/secureNoteType.enum.ts new file mode 100644 index 00000000..c7f3e44a --- /dev/null +++ b/src/enums/secureNoteType.enum.ts @@ -0,0 +1,3 @@ +export enum SecureNoteType { + Generic = 0, +} diff --git a/src/models/domain/attachment.ts b/src/models/domain/attachment.ts new file mode 100644 index 00000000..c73e841a --- /dev/null +++ b/src/models/domain/attachment.ts @@ -0,0 +1,43 @@ +import { AttachmentData } from '../data/attachmentData'; + +import { CipherString } from './cipherString'; +import Domain from './domain'; + +class Attachment extends Domain { + id: string; + url: string; + size: number; + sizeName: string; + fileName: CipherString; + + constructor(obj?: AttachmentData, alreadyEncrypted: boolean = false) { + super(); + if (obj == null) { + return; + } + + this.size = obj.size; + this.buildDomainModel(this, obj, { + id: null, + url: null, + sizeName: null, + fileName: null, + }, alreadyEncrypted, ['id', 'url', 'sizeName']); + } + + decrypt(orgId: string): Promise { + const model = { + id: this.id, + size: this.size, + sizeName: this.sizeName, + url: this.url, + }; + + return this.decryptObj(model, this, { + fileName: null, + }, orgId); + } +} + +export { Attachment }; +(window as any).Attachment = Attachment; diff --git a/src/models/domain/card.ts b/src/models/domain/card.ts new file mode 100644 index 00000000..b30ad053 --- /dev/null +++ b/src/models/domain/card.ts @@ -0,0 +1,43 @@ +import { CardData } from '../data/cardData'; + +import { CipherString } from './cipherString'; +import Domain from './domain'; + +class Card extends Domain { + cardholderName: CipherString; + brand: CipherString; + number: CipherString; + expMonth: CipherString; + expYear: CipherString; + code: CipherString; + + constructor(obj?: CardData, alreadyEncrypted: boolean = false) { + super(); + if (obj == null) { + return; + } + + this.buildDomainModel(this, obj, { + cardholderName: null, + brand: null, + number: null, + expMonth: null, + expYear: null, + code: null, + }, alreadyEncrypted, []); + } + + decrypt(orgId: string): Promise { + return this.decryptObj({}, this, { + cardholderName: null, + brand: null, + number: null, + expMonth: null, + expYear: null, + code: null, + }, orgId); + } +} + +export { Card }; +(window as any).Card = Card; diff --git a/src/models/domain/cipher.ts b/src/models/domain/cipher.ts new file mode 100644 index 00000000..de4d915e --- /dev/null +++ b/src/models/domain/cipher.ts @@ -0,0 +1,181 @@ +import { CipherType } from '../../enums/cipherType.enum'; + +import { CipherData } from '../data/cipherData'; + +import { Attachment } from './attachment'; +import { Card } from './card'; +import { CipherString } from './cipherString'; +import Domain from './domain'; +import { Field } from './field'; +import { Identity } from './identity'; +import { Login } from './login'; +import { SecureNote } from './secureNote'; + +import UtilsService from '../../services/utils.service'; + +class Cipher extends Domain { + id: string; + organizationId: string; + folderId: string; + name: CipherString; + notes: CipherString; + type: CipherType; + favorite: boolean; + organizationUseTotp: boolean; + edit: boolean; + localData: any; + login: Login; + identity: Identity; + card: Card; + secureNote: SecureNote; + attachments: Attachment[]; + fields: Field[]; + + constructor(obj?: CipherData, alreadyEncrypted: boolean = false, localData: any = null) { + super(); + if (obj == null) { + return; + } + + this.buildDomainModel(this, obj, { + id: null, + organizationId: null, + folderId: null, + name: null, + notes: null, + }, alreadyEncrypted, ['id', 'organizationId', 'folderId']); + + this.type = obj.type; + this.favorite = obj.favorite; + this.organizationUseTotp = obj.organizationUseTotp; + this.edit = obj.edit; + + switch (this.type) { + case CipherType.Login: + this.login = new Login(obj.login, alreadyEncrypted); + break; + case CipherType.SecureNote: + this.secureNote = new SecureNote(obj.secureNote, alreadyEncrypted); + break; + case CipherType.Card: + this.card = new Card(obj.card, alreadyEncrypted); + break; + case CipherType.Identity: + this.identity = new Identity(obj.identity, alreadyEncrypted); + break; + default: + break; + } + + if (obj.attachments != null) { + this.attachments = []; + for (const attachment of obj.attachments) { + this.attachments.push(new Attachment(attachment, alreadyEncrypted)); + } + } else { + this.attachments = null; + } + + if (obj.fields != null) { + this.fields = []; + for (const field of obj.fields) { + this.fields.push(new Field(field, alreadyEncrypted)); + } + } else { + this.fields = null; + } + } + + async decrypt(): Promise { + const model = { + id: this.id, + organizationId: this.organizationId, + folderId: this.folderId, + favorite: this.favorite, + type: this.type, + localData: this.localData, + login: null as any, + card: null as any, + identity: null as any, + secureNote: null as any, + subTitle: null as string, + attachments: null as any[], + fields: null as any[], + }; + + await this.decryptObj(model, this, { + name: null, + notes: null, + }, this.organizationId); + + switch (this.type) { + case CipherType.Login: + model.login = await this.login.decrypt(this.organizationId); + model.subTitle = model.login.username; + if (model.login.uri) { + model.login.domain = UtilsService.getDomain(model.login.uri); + } + break; + case CipherType.SecureNote: + model.secureNote = await this.secureNote.decrypt(this.organizationId); + model.subTitle = null; + break; + case CipherType.Card: + model.card = await this.card.decrypt(this.organizationId); + model.subTitle = model.card.brand; + if (model.card.number && model.card.number.length >= 4) { + if (model.subTitle !== '') { + model.subTitle += ', '; + } + model.subTitle += ('*' + model.card.number.substr(model.card.number.length - 4)); + } + break; + case CipherType.Identity: + model.identity = await this.identity.decrypt(this.organizationId); + model.subTitle = ''; + if (model.identity.firstName) { + model.subTitle = model.identity.firstName; + } + if (model.identity.lastName) { + if (model.subTitle !== '') { + model.subTitle += ' '; + } + model.subTitle += model.identity.lastName; + } + break; + default: + break; + } + + const orgId = this.organizationId; + + if (this.attachments != null) { + const attachments: any[] = []; + await this.attachments.reduce((promise, attachment) => { + return promise.then(() => { + return attachment.decrypt(orgId); + }).then((decAttachment) => { + attachments.push(decAttachment); + }); + }, Promise.resolve()); + model.attachments = attachments; + } + + if (this.fields != null) { + const fields: any[] = []; + await this.fields.reduce((promise, field) => { + return promise.then(() => { + return field.decrypt(orgId); + }).then((decField) => { + fields.push(decField); + }); + }, Promise.resolve()); + model.fields = fields; + } + + return model; + } +} + +export { Cipher }; +(window as any).Attachment = Cipher; diff --git a/src/models/domain/domain.ts b/src/models/domain/domain.ts index fcf3341d..e8818a7d 100644 --- a/src/models/domain/domain.ts +++ b/src/models/domain/domain.ts @@ -1,7 +1,7 @@ import { CipherString } from '../domain/cipherString'; export default abstract class Domain { - protected buildDomainModel(model: any, obj: any, map: any, alreadyEncrypted: boolean, notEncList: any = []) { + protected buildDomainModel(model: any, obj: any, map: any, alreadyEncrypted: boolean, notEncList: any[] = []) { for (const prop in map) { if (!map.hasOwnProperty(prop)) { continue; diff --git a/src/models/domain/field.ts b/src/models/domain/field.ts new file mode 100644 index 00000000..5bc3b85f --- /dev/null +++ b/src/models/domain/field.ts @@ -0,0 +1,39 @@ +import { FieldType } from '../../enums/fieldType.enum'; + +import { FieldData } from '../data/fieldData'; + +import { CipherString } from './cipherString'; +import Domain from './domain'; + +class Field extends Domain { + name: CipherString; + vault: CipherString; + type: FieldType; + + constructor(obj?: FieldData, alreadyEncrypted: boolean = false) { + super(); + if (obj == null) { + return; + } + + this.type = obj.type; + this.buildDomainModel(this, obj, { + name: null, + value: null, + }, alreadyEncrypted, []); + } + + decrypt(orgId: string): Promise { + const model = { + type: this.type, + }; + + return this.decryptObj(model, this, { + name: null, + value: null, + }, orgId); + } +} + +export { Field }; +(window as any).Field = Field; diff --git a/src/models/domain/folder.ts b/src/models/domain/folder.ts index 63f4c222..238f8cb8 100644 --- a/src/models/domain/folder.ts +++ b/src/models/domain/folder.ts @@ -19,12 +19,12 @@ class Folder extends Domain { }, alreadyEncrypted, ['id']); } - async decrypt(): Promise { + decrypt(): Promise { const model = { id: this.id, }; - return await this.decryptObj(model, this, { + return this.decryptObj(model, this, { name: null, }, null); } diff --git a/src/models/domain/identity.ts b/src/models/domain/identity.ts new file mode 100644 index 00000000..2a1c47d2 --- /dev/null +++ b/src/models/domain/identity.ts @@ -0,0 +1,79 @@ +import { IdentityData } from '../data/identityData'; + +import { CipherString } from './cipherString'; +import Domain from './domain'; + +class Identity extends Domain { + title: CipherString; + firstName: CipherString; + middleName: CipherString; + lastName: CipherString; + address1: CipherString; + address2: CipherString; + address3: CipherString; + city: CipherString; + state: CipherString; + postalCode: CipherString; + country: CipherString; + company: CipherString; + email: CipherString; + phone: CipherString; + ssn: CipherString; + username: CipherString; + passportNumber: CipherString; + licenseNumber: CipherString; + + constructor(obj?: IdentityData, alreadyEncrypted: boolean = false) { + super(); + if (obj == null) { + return; + } + + this.buildDomainModel(this, obj, { + title: null, + firstName: null, + middleName: null, + lastName: null, + address1: null, + address2: null, + address3: null, + city: null, + state: null, + postalCode: null, + country: null, + company: null, + email: null, + phone: null, + ssn: null, + username: null, + passportNumber: null, + licenseNumber: null, + }, alreadyEncrypted, []); + } + + decrypt(orgId: string): Promise { + return this.decryptObj({}, this, { + title: null, + firstName: null, + middleName: null, + lastName: null, + address1: null, + address2: null, + address3: null, + city: null, + state: null, + postalCode: null, + country: null, + company: null, + email: null, + phone: null, + ssn: null, + username: null, + passportNumber: null, + licenseNumber: null, + }, orgId); + } +} + +export { Identity }; +(window as any).Identity = Identity; diff --git a/src/models/domain/login.ts b/src/models/domain/login.ts new file mode 100644 index 00000000..b6e0b0aa --- /dev/null +++ b/src/models/domain/login.ts @@ -0,0 +1,37 @@ +import { LoginData } from '../data/loginData'; + +import { CipherString } from './cipherString'; +import Domain from './domain'; + +class Login extends Domain { + uri: CipherString; + username: CipherString; + password: CipherString; + totp: CipherString; + + constructor(obj?: LoginData, alreadyEncrypted: boolean = false) { + super(); + if (obj == null) { + return; + } + + this.buildDomainModel(this, obj, { + uri: null, + username: null, + password: null, + totp: null, + }, alreadyEncrypted, []); + } + + decrypt(orgId: string): Promise { + return this.decryptObj({}, this, { + uri: null, + username: null, + password: null, + totp: null, + }, orgId); + } +} + +export { Login }; +(window as any).Login = Login; diff --git a/src/models/domain/secureNote.ts b/src/models/domain/secureNote.ts new file mode 100644 index 00000000..2c742f8e --- /dev/null +++ b/src/models/domain/secureNote.ts @@ -0,0 +1,27 @@ +import { SecureNoteType } from '../../enums/secureNoteType.enum'; + +import { SecureNoteData } from '../data/secureNoteData'; + +import Domain from './domain'; + +class SecureNote extends Domain { + type: SecureNoteType; + + constructor(obj?: SecureNoteData, alreadyEncrypted: boolean = false) { + super(); + if (obj == null) { + return; + } + + this.type = obj.type; + } + + decrypt(orgId: string): any { + return { + type: this.type, + }; + } +} + +export { SecureNote }; +(window as any).SecureNote = SecureNote; diff --git a/src/models/domainModels.js b/src/models/domainModels.js deleted file mode 100644 index 4e50ee2a..00000000 --- a/src/models/domainModels.js +++ /dev/null @@ -1,360 +0,0 @@ -var Cipher = window.Cipher = function (obj, alreadyEncrypted, localData) { - this.constantsService = chrome.extension.getBackgroundPage().bg_constantsService; - this.utilsService = chrome.extension.getBackgroundPage().bg_utilsService; - - buildDomainModel(this, obj, { - id: null, - organizationId: null, - folderId: null, - name: null, - notes: null - }, alreadyEncrypted, ['id', 'organizationId', 'folderId']); - - this.type = obj.type; - this.favorite = obj.favorite ? true : false; - this.organizationUseTotp = obj.organizationUseTotp ? true : false; - this.edit = obj.edit ? true : false; - this.localData = localData; - - switch (this.type) { - case this.constantsService.cipherType.login: - this.login = new Login2(obj.login, alreadyEncrypted); - break; - case this.constantsService.cipherType.secureNote: - this.secureNote = new SecureNote(obj.secureNote, alreadyEncrypted); - break; - case this.constantsService.cipherType.card: - this.card = new Card(obj.card, alreadyEncrypted); - break; - case this.constantsService.cipherType.identity: - this.identity = new Identity(obj.identity, alreadyEncrypted); - break; - default: - break; - } - - var i; - if (obj.attachments) { - this.attachments = []; - for (i = 0; i < obj.attachments.length; i++) { - this.attachments.push(new Attachment(obj.attachments[i], alreadyEncrypted)); - } - } - else { - this.attachments = null; - } - - if (obj.fields) { - this.fields = []; - for (i = 0; i < obj.fields.length; i++) { - this.fields.push(new Field(obj.fields[i], alreadyEncrypted)); - } - } - else { - this.fields = null; - } -}; - -var Login2 = window.Login2 = function (obj, alreadyEncrypted) { - buildDomainModel(this, obj, { - uri: null, - username: null, - password: null, - totp: null - }, alreadyEncrypted, []); -}; - -var Identity = window.Identity = function (obj, alreadyEncrypted) { - buildDomainModel(this, obj, { - title: null, - firstName: null, - middleName: null, - lastName: null, - address1: null, - address2: null, - address3: null, - city: null, - state: null, - postalCode: null, - country: null, - company: null, - email: null, - phone: null, - ssn: null, - username: null, - passportNumber: null, - licenseNumber: null - }, alreadyEncrypted, []); -}; - -var Card = window.Card = function (obj, alreadyEncrypted) { - buildDomainModel(this, obj, { - cardholderName: null, - brand: null, - number: null, - expMonth: null, - expYear: null, - code: null - }, alreadyEncrypted, []); -}; - -var SecureNote = window.SecureNote = function (obj, alreadyEncrypted) { - this.type = obj.type; -}; - -var Field = window.Field = function (obj, alreadyEncrypted) { - this.type = obj.type; - buildDomainModel(this, obj, { - name: null, - value: null - }, alreadyEncrypted, []); -}; - -var Attachment = window.Attachment = function (obj, alreadyEncrypted) { - this.size = obj.size; - buildDomainModel(this, obj, { - id: null, - url: null, - sizeName: null, - fileName: null - }, alreadyEncrypted, ['id', 'url', 'sizeName']); -}; - -var Folder = window.Folder = function (obj, alreadyEncrypted) { - buildDomainModel(this, obj, { - id: null, - name: null - }, alreadyEncrypted, ['id']); -}; - -function buildDomainModel(model, obj, map, alreadyEncrypted, notEncList) { - notEncList = notEncList || []; - for (var prop in map) { - if (map.hasOwnProperty(prop)) { - var objProp = obj[(map[prop] || prop)]; - if (alreadyEncrypted === true || notEncList.indexOf(prop) > -1) { - model[prop] = objProp ? objProp : null; - } - else { - model[prop] = objProp ? new CipherString(objProp) : null; - } - } - } -} - -(function () { - Cipher.prototype.decrypt = function () { - var self = this; - - var model = { - id: self.id, - organizationId: self.organizationId, - folderId: self.folderId, - favorite: self.favorite, - type: self.type, - localData: self.localData - }; - - var attachments = []; - var fields = []; - - return decryptObj(model, this, { - name: null, - notes: null - }, self.organizationId).then(function () { - switch (self.type) { - case self.constantsService.cipherType.login: - return self.login.decrypt(self.organizationId); - case self.constantsService.cipherType.secureNote: - return self.secureNote.decrypt(self.organizationId); - case self.constantsService.cipherType.card: - return self.card.decrypt(self.organizationId); - case self.constantsService.cipherType.identity: - return self.identity.decrypt(self.organizationId); - default: - return; - } - }).then(function (decObj) { - switch (self.type) { - case self.constantsService.cipherType.login: - model.login = decObj; - model.subTitle = model.login.username; - if (model.login.uri) { - model.login.domain = self.utilsService.getDomain(model.login.uri); - } - break; - case self.constantsService.cipherType.secureNote: - model.secureNote = decObj; - model.subTitle = null; - break; - case self.constantsService.cipherType.card: - model.card = decObj; - model.subTitle = model.card.brand; - if (model.card.number && model.card.number.length >= 4) { - if (model.subTitle !== '') { - model.subTitle += ', '; - } - model.subTitle += ('*' + model.card.number.substr(model.card.number.length - 4)); - } - break; - case self.constantsService.cipherType.identity: - model.identity = decObj; - model.subTitle = ''; - if (model.identity.firstName) { - model.subTitle = model.identity.firstName; - } - if (model.identity.lastName) { - if (model.subTitle !== '') { - model.subTitle += ' '; - } - model.subTitle += model.identity.lastName; - } - break; - default: - break; - } - return; - }).then(function () { - if (self.attachments) { - return self.attachments.reduce(function (promise, attachment) { - return promise.then(function () { - return attachment.decrypt(self.organizationId); - }).then(function (decAttachment) { - attachments.push(decAttachment); - }); - }, Q()); - } - return; - }).then(function () { - model.attachments = attachments.length ? attachments : null; - - if (self.fields) { - return self.fields.reduce(function (promise, field) { - return promise.then(function () { - return field.decrypt(self.organizationId); - }).then(function (decField) { - fields.push(decField); - }); - }, Q()); - } - return; - }).then(function () { - model.fields = fields.length ? fields : null; - return model; - }, function (e) { - console.log(e); - }); - }; - - Login2.prototype.decrypt = function (orgId) { - return decryptObj({}, this, { - uri: null, - username: null, - password: null, - totp: null - }, orgId); - }; - - Card.prototype.decrypt = function (orgId) { - return decryptObj({}, this, { - cardholderName: null, - brand: null, - number: null, - expMonth: null, - expYear: null, - code: null - }, orgId); - }; - - SecureNote.prototype.decrypt = function (orgId) { - return { - type: this.type - }; - }; - - Identity.prototype.decrypt = function (orgId) { - return decryptObj({}, this, { - title: null, - firstName: null, - middleName: null, - lastName: null, - address1: null, - address2: null, - address3: null, - city: null, - state: null, - postalCode: null, - country: null, - company: null, - email: null, - phone: null, - ssn: null, - username: null, - passportNumber: null, - licenseNumber: null - }, orgId); - }; - - Field.prototype.decrypt = function (orgId) { - var model = { - type: this.type - }; - - return decryptObj(model, this, { - name: null, - value: null - }, orgId); - }; - - Attachment.prototype.decrypt = function (orgId) { - var model = { - id: this.id, - size: this.size, - sizeName: this.sizeName, - url: this.url - }; - - return decryptObj(model, this, { - fileName: null - }, orgId); - }; - - Folder.prototype.decrypt = function () { - var self = this; - var model = { - id: self.id - }; - - return decryptObj(model, this, { - name: null - }, null); - }; - - function decryptObj(model, self, map, orgId) { - var promises = []; - for (var prop in map) { - if (map.hasOwnProperty(prop)) { - /* jshint ignore:start */ - (function (theProp) { - var promise = Q().then(function () { - var mapProp = map[theProp] || theProp; - if (self[mapProp]) { - return self[mapProp].decrypt(orgId); - } - return null; - }).then(function (val) { - model[theProp] = val; - return; - }); - - promises.push(promise); - })(prop); - /* jshint ignore:end */ - } - } - - return Q.all(promises).then(function () { - return model; - }); - } -})(); diff --git a/src/popup/app/app.js b/src/popup/app/app.js index 9141bfd4..19401ab9 100644 --- a/src/popup/app/app.js +++ b/src/popup/app/app.js @@ -21,8 +21,6 @@ require('../../scripts/analytics.js'); require('../../scripts/duo.js'); require('../../scripts/u2f.js'); -require('../../models/domainModels.js'); - require('../less/libs.less'); require('../less/popup.less'); @@ -32,7 +30,14 @@ import ServicesModule from './services/services.module'; import LockModule from './lock/lock.module'; // Model imports +import { Attachment } from '../../models/domain/attachment'; +import { Card } from '../../models/domain/card'; +import { Cipher } from '../../models/domain/cipher'; +import { Field } from '../../models/domain/field'; import { Folder } from '../../models/domain/folder'; +import { Identity } from '../../models/domain/identity'; +import { Login } from '../../models/domain/login'; +import { SecureNote } from '../../models/domain/secureNote'; import { AttachmentData } from '../../models/data/attachmentData'; import { CardData } from '../../models/data/cardData'; diff --git a/src/services/utils.service.ts b/src/services/utils.service.ts index 74f26284..b6ac27a1 100644 --- a/src/services/utils.service.ts +++ b/src/services/utils.service.ts @@ -147,6 +147,76 @@ export default class UtilsService { }); } + static getDomain(uriString: string): string { + if (uriString == null) { + return null; + } + + uriString = uriString.trim(); + if (uriString === '') { + return null; + } + + if (uriString.startsWith('http://') || uriString.startsWith('https://')) { + try { + const url = new URL(uriString); + if (!url || !url.hostname) { + return null; + } + + if (url.hostname === 'localhost' || UtilsService.validIpAddress(url.hostname)) { + return url.hostname; + } + + if ((window as any).tldjs) { + const domain = (window as any).tldjs.getDomain(uriString); + if (domain) { + return domain; + } + } + + return url.hostname; + } catch (e) { } + } else if ((window as any).tldjs) { + const domain: string = (window as any).tldjs.getDomain(uriString); + if (domain != null) { + return domain; + } + } + + return null; + } + + static validIpAddress(ipString: string): boolean { + // tslint:disable-next-line + const ipRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; + return ipRegex.test(ipString); + } + + static getHostname(uriString: string): string { + if (uriString == null) { + return null; + } + + uriString = uriString.trim(); + if (uriString === '') { + return null; + } + + if (uriString.startsWith('http://') || uriString.startsWith('https://')) { + try { + const url = new URL(uriString); + if (!url || !url.hostname) { + return null; + } + + return url.hostname; + } catch (e) { } + } + + return null; + } + private browserCache: BrowserType = null; private analyticsIdCache: string = null; @@ -195,7 +265,6 @@ export default class UtilsService { } this.analyticsIdCache = AnalyticsIds[this.getBrowser()]; - return this.analyticsIdCache; } @@ -238,85 +307,22 @@ export default class UtilsService { } }); - doc.on( - 'focus', - '.list-section-item input, .list-section-item select, .list-section-item textarea', + doc.on('focus', '.list-section-item input, .list-section-item select, .list-section-item textarea', function(e: Event) { $(this).parent().addClass('active'); }); - doc.on( - 'blur', '.list-section-item input, .list-section-item select, .list-section-item textarea', + doc.on('blur', '.list-section-item input, .list-section-item select, .list-section-item textarea', function(e: Event) { $(this).parent().removeClass('active'); }); } - getDomain(uriString: string) { - if (!uriString) { - return null; - } - - uriString = uriString.trim(); - if (uriString === '') { - return null; - } - - if (uriString.startsWith('http://') || uriString.startsWith('https://')) { - try { - const url = new URL(uriString); - if (!url || !url.hostname) { - return null; - } - - if (url.hostname === 'localhost' || this.validIpAddress(url.hostname)) { - return url.hostname; - } - - if ((window as any).tldjs) { - const domain = (window as any).tldjs.getDomain(uriString); - if (domain) { - return domain; - } - } - - return url.hostname; - } catch (e) { - return null; - } - } else if ((window as any).tldjs) { - const domain2 = (window as any).tldjs.getDomain(uriString); - if (domain2) { - return domain2; - } - } - - return null; + getDomain(uriString: string): string { + return UtilsService.getDomain(uriString); } - getHostname(uriString: string) { - if (!uriString) { - return null; - } - - uriString = uriString.trim(); - if (uriString === '') { - return null; - } - - if (uriString.startsWith('http://') || uriString.startsWith('https://')) { - try { - const url = new URL(uriString); - if (!url || !url.hostname) { - return null; - } - - return url.hostname; - } catch (e) { - return null; - } - } - - return null; + getHostname(uriString: string): string { + return UtilsService.getHostname(uriString); } copyToClipboard(text: string, doc: Document) { @@ -375,10 +381,4 @@ export default class UtilsService { getObjFromStorage(key: string) { return UtilsService.getObjFromStorage(key); } - - private validIpAddress(ipString: string) { - // tslint:disable-next-line - const ipRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; - return ipRegex.test(ipString); - } }