From 063bb010db093877c05bd6fc81db00b08a0fd1f3 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 1 Mar 2018 23:44:29 -0500 Subject: [PATCH] refactor for login uris and response model changes --- src/enums/index.ts | 1 + src/enums/uriMatchType.ts | 8 ++++ src/models/api/cardApi.ts | 17 ++++++++ src/models/api/fieldApi.ts | 13 ++++++ src/models/api/identityApi.ts | 41 ++++++++++++++++++ src/models/api/loginApi.ts | 21 +++++++++ src/models/api/loginUriApi.ts | 11 +++++ src/models/api/secureNoteApi.ts | 9 ++++ src/models/data/cardData.ts | 16 ++++--- src/models/data/cipherData.ts | 17 ++++---- src/models/data/fieldData.ts | 10 +++-- src/models/data/identityData.ts | 40 +++++++++--------- src/models/data/index.ts | 1 + src/models/data/loginData.ts | 23 +++++++--- src/models/data/loginUriData.ts | 13 ++++++ src/models/data/secureNoteData.ts | 6 ++- src/models/domain/field.ts | 2 +- src/models/domain/index.ts | 1 + src/models/domain/login.ts | 28 +++++++++--- src/models/domain/loginUri.ts | 31 ++++++++++++++ src/models/request/cipherRequest.ts | 35 +++++++++++---- src/models/response/cipherResponse.ts | 40 +++++++++++++++++- src/models/view/cipherView.ts | 4 -- src/models/view/index.ts | 1 + src/models/view/loginUriView.ts | 61 +++++++++++++++++++++++++++ src/models/view/loginView.ts | 43 ++++--------------- src/services/cipher.service.ts | 14 +++++- 27 files changed, 405 insertions(+), 102 deletions(-) create mode 100644 src/enums/uriMatchType.ts create mode 100644 src/models/api/cardApi.ts create mode 100644 src/models/api/fieldApi.ts create mode 100644 src/models/api/identityApi.ts create mode 100644 src/models/api/loginApi.ts create mode 100644 src/models/api/loginUriApi.ts create mode 100644 src/models/api/secureNoteApi.ts create mode 100644 src/models/data/loginUriData.ts create mode 100644 src/models/domain/loginUri.ts create mode 100644 src/models/view/loginUriView.ts diff --git a/src/enums/index.ts b/src/enums/index.ts index e0eac44ae0..740efbf9a9 100644 --- a/src/enums/index.ts +++ b/src/enums/index.ts @@ -5,3 +5,4 @@ export { FieldType } from './fieldType'; export { LogLevelType } from './logLevelType'; export { SecureNoteType } from './secureNoteType'; export { TwoFactorProviderType } from './twoFactorProviderType'; +export { UriMatchType } from './uriMatchType'; diff --git a/src/enums/uriMatchType.ts b/src/enums/uriMatchType.ts new file mode 100644 index 0000000000..ed6b6ab54f --- /dev/null +++ b/src/enums/uriMatchType.ts @@ -0,0 +1,8 @@ +export enum UriMatchType { + BaseDomain = 0, + FullHostname = 1, + StartsWith = 2, + Exact = 3, + RegularExpression = 4, + Never = 5, +} diff --git a/src/models/api/cardApi.ts b/src/models/api/cardApi.ts new file mode 100644 index 0000000000..f91c44ef16 --- /dev/null +++ b/src/models/api/cardApi.ts @@ -0,0 +1,17 @@ +export class CardApi { + cardholderName: string; + brand: string; + number: string; + expMonth: string; + expYear: string; + code: string; + + constructor(data: any) { + this.cardholderName = data.CardholderName; + this.brand = data.Brand; + this.number = data.Number; + this.expMonth = data.ExpMonth; + this.expYear = data.ExpYear; + this.code = data.Code; + } +} diff --git a/src/models/api/fieldApi.ts b/src/models/api/fieldApi.ts new file mode 100644 index 0000000000..59a8a06aaa --- /dev/null +++ b/src/models/api/fieldApi.ts @@ -0,0 +1,13 @@ +import { FieldType } from '../../enums/fieldType'; + +export class FieldApi { + name: string; + value: string; + type: FieldType; + + constructor(response: any) { + this.type = response.Type; + this.name = response.Name; + this.value = response.Value; + } +} diff --git a/src/models/api/identityApi.ts b/src/models/api/identityApi.ts new file mode 100644 index 0000000000..e498eb71fe --- /dev/null +++ b/src/models/api/identityApi.ts @@ -0,0 +1,41 @@ +export class IdentityApi { + title: string; + firstName: string; + middleName: string; + lastName: string; + address1: string; + address2: string; + address3: string; + city: string; + state: string; + postalCode: string; + country: string; + company: string; + email: string; + phone: string; + ssn: string; + username: string; + passportNumber: string; + licenseNumber: string; + + constructor(data: any) { + this.title = data.Title; + this.firstName = data.FirstName; + this.middleName = data.MiddleName; + this.lastName = data.LastName; + this.address1 = data.Address1; + this.address2 = data.Address2; + this.address3 = data.Address3; + this.city = data.City; + this.state = data.State; + this.postalCode = data.PostalCode; + this.country = data.Country; + this.company = data.Company; + this.email = data.Email; + this.phone = data.Phone; + this.ssn = data.SSN; + this.username = data.Username; + this.passportNumber = data.PassportNumber; + this.licenseNumber = data.LicenseNumber; + } +} diff --git a/src/models/api/loginApi.ts b/src/models/api/loginApi.ts new file mode 100644 index 0000000000..ba9a9da11d --- /dev/null +++ b/src/models/api/loginApi.ts @@ -0,0 +1,21 @@ +import { LoginUriApi } from './loginUriApi'; + +export class LoginApi { + uris: LoginUriApi[]; + username: string; + password: string; + totp: string; + + constructor(data: any) { + this.username = data.Username; + this.password = data.Password; + this.totp = data.Totp; + + if (data.Uris) { + this.uris = []; + data.Uris.forEach((u: any) => { + this.uris.push(new LoginUriApi(u)); + }); + } + } +} diff --git a/src/models/api/loginUriApi.ts b/src/models/api/loginUriApi.ts new file mode 100644 index 0000000000..cdaa651e80 --- /dev/null +++ b/src/models/api/loginUriApi.ts @@ -0,0 +1,11 @@ +import { UriMatchType } from '../../enums/uriMatchType'; + +export class LoginUriApi { + uri: string; + match: UriMatchType = null; + + constructor(data: any) { + this.uri = data.Uri; + this.match = data.Match ? data.Match : null; + } +} diff --git a/src/models/api/secureNoteApi.ts b/src/models/api/secureNoteApi.ts new file mode 100644 index 0000000000..4a31aa27b2 --- /dev/null +++ b/src/models/api/secureNoteApi.ts @@ -0,0 +1,9 @@ +import { SecureNoteType } from '../../enums/secureNoteType'; + +export class SecureNoteApi { + type: SecureNoteType; + + constructor(data: any) { + this.type = data.Type; + } +} diff --git a/src/models/data/cardData.ts b/src/models/data/cardData.ts index 238621c72a..1a4edea4ea 100644 --- a/src/models/data/cardData.ts +++ b/src/models/data/cardData.ts @@ -1,3 +1,5 @@ +import { CardApi } from '../api/cardApi'; + export class CardData { cardholderName: string; brand: string; @@ -6,12 +8,12 @@ export class CardData { expYear: string; code: string; - constructor(data: any) { - this.cardholderName = data.CardholderName; - this.brand = data.Brand; - this.number = data.Number; - this.expMonth = data.ExpMonth; - this.expYear = data.ExpYear; - this.code = data.Code; + constructor(data: CardApi) { + this.cardholderName = data.cardholderName; + this.brand = data.brand; + this.number = data.number; + this.expMonth = data.expMonth; + this.expYear = data.expYear; + this.code = data.code; } } diff --git a/src/models/data/cipherData.ts b/src/models/data/cipherData.ts index 0a4f83c520..1a76ed5c79 100644 --- a/src/models/data/cipherData.ts +++ b/src/models/data/cipherData.ts @@ -40,6 +40,8 @@ export class CipherData { this.favorite = response.favorite; this.revisionDate = response.revisionDate; this.type = response.type; + this.name = response.name; + this.notes = response.notes; if (collectionIds != null) { this.collectionIds = collectionIds; @@ -47,29 +49,26 @@ export class CipherData { this.collectionIds = response.collectionIds; } - this.name = response.data.Name; - this.notes = response.data.Notes; - switch (this.type) { case CipherType.Login: - this.login = new LoginData(response.data); + this.login = new LoginData(response.login); break; case CipherType.SecureNote: - this.secureNote = new SecureNoteData(response.data); + this.secureNote = new SecureNoteData(response.secureNote); break; case CipherType.Card: - this.card = new CardData(response.data); + this.card = new CardData(response.card); break; case CipherType.Identity: - this.identity = new IdentityData(response.data); + this.identity = new IdentityData(response.identity); break; default: break; } - if (response.data.Fields != null) { + if (response.fields != null) { this.fields = []; - response.data.Fields.forEach((field: any) => { + response.fields.forEach((field) => { this.fields.push(new FieldData(field)); }); } diff --git a/src/models/data/fieldData.ts b/src/models/data/fieldData.ts index cd0fb2c42b..0632d7349d 100644 --- a/src/models/data/fieldData.ts +++ b/src/models/data/fieldData.ts @@ -1,13 +1,15 @@ import { FieldType } from '../../enums/fieldType'; +import { FieldApi } from '../api/fieldApi'; + export class FieldData { type: FieldType; name: string; value: string; - constructor(response: any) { - this.type = response.Type; - this.name = response.Name; - this.value = response.Value; + constructor(response: FieldApi) { + this.type = response.type; + this.name = response.name; + this.value = response.value; } } diff --git a/src/models/data/identityData.ts b/src/models/data/identityData.ts index 34f2099595..d1ac84a7b2 100644 --- a/src/models/data/identityData.ts +++ b/src/models/data/identityData.ts @@ -1,3 +1,5 @@ +import { IdentityApi } from '../api/identityApi'; + export class IdentityData { title: string; firstName: string; @@ -18,24 +20,24 @@ export class IdentityData { passportNumber: string; licenseNumber: string; - constructor(data: any) { - this.title = data.Title; - this.firstName = data.FirstName; - this.middleName = data.MiddleName; - this.lastName = data.LastName; - this.address1 = data.Address1; - this.address2 = data.Address2; - this.address3 = data.Address3; - this.city = data.City; - this.state = data.State; - this.postalCode = data.PostalCode; - this.country = data.Country; - this.company = data.Company; - this.email = data.Email; - this.phone = data.Phone; - this.ssn = data.SSN; - this.username = data.Username; - this.passportNumber = data.PassportNumber; - this.licenseNumber = data.LicenseNumber; + constructor(data: IdentityApi) { + this.title = data.title; + this.firstName = data.firstName; + this.middleName = data.middleName; + this.lastName = data.lastName; + this.address1 = data.address1; + this.address2 = data.address2; + this.address3 = data.address3; + this.city = data.city; + this.state = data.state; + this.postalCode = data.postalCode; + this.country = data.country; + this.company = data.company; + this.email = data.email; + this.phone = data.phone; + this.ssn = data.ssn; + this.username = data.username; + this.passportNumber = data.passportNumber; + this.licenseNumber = data.licenseNumber; } } diff --git a/src/models/data/index.ts b/src/models/data/index.ts index 7a5a86df2e..97732b6d76 100644 --- a/src/models/data/index.ts +++ b/src/models/data/index.ts @@ -6,4 +6,5 @@ export { FieldData } from './fieldData'; export { FolderData } from './folderData'; export { IdentityData } from './identityData'; export { LoginData } from './loginData'; +export { LoginUriData } from './loginUriData'; export { SecureNoteData } from './secureNoteData'; diff --git a/src/models/data/loginData.ts b/src/models/data/loginData.ts index 2052a7a889..f81e8e0897 100644 --- a/src/models/data/loginData.ts +++ b/src/models/data/loginData.ts @@ -1,13 +1,24 @@ +import { LoginApi } from '../api/loginApi'; +import { LoginUriApi } from '../api/loginUriApi'; + +import { LoginUriData } from './loginUriData'; + export class LoginData { - uri: string; + uris: LoginUriData[]; username: string; password: string; totp: string; - constructor(data: any) { - this.uri = data.Uri; - this.username = data.Username; - this.password = data.Password; - this.totp = data.Totp; + constructor(data: LoginApi) { + this.username = data.username; + this.password = data.password; + this.totp = data.totp; + + if (data.uris) { + this.uris = []; + data.uris.forEach((u) => { + this.uris.push(new LoginUriData(u)); + }); + } } } diff --git a/src/models/data/loginUriData.ts b/src/models/data/loginUriData.ts new file mode 100644 index 0000000000..71ad8079c1 --- /dev/null +++ b/src/models/data/loginUriData.ts @@ -0,0 +1,13 @@ +import { UriMatchType } from '../../enums/uriMatchType'; + +import { LoginUriApi } from '../api/loginUriApi'; + +export class LoginUriData { + uri: string; + match: UriMatchType = null; + + constructor(data: LoginUriApi) { + this.uri = data.uri; + this.match = data.match; + } +} diff --git a/src/models/data/secureNoteData.ts b/src/models/data/secureNoteData.ts index 4b27125a13..a508c1b31d 100644 --- a/src/models/data/secureNoteData.ts +++ b/src/models/data/secureNoteData.ts @@ -1,9 +1,11 @@ import { SecureNoteType } from '../../enums/secureNoteType'; +import { SecureNoteApi } from '../api/secureNoteApi'; + export class SecureNoteData { type: SecureNoteType; - constructor(data: any) { - this.type = data.Type; + constructor(data: SecureNoteApi) { + this.type = data.type; } } diff --git a/src/models/domain/field.ts b/src/models/domain/field.ts index 023fefe5a9..599dabff1c 100644 --- a/src/models/domain/field.ts +++ b/src/models/domain/field.ts @@ -9,7 +9,7 @@ import { FieldView } from '../view/fieldView'; export class Field extends Domain { name: CipherString; - vault: CipherString; + value: CipherString; type: FieldType; constructor(obj?: FieldData, alreadyEncrypted: boolean = false) { diff --git a/src/models/domain/index.ts b/src/models/domain/index.ts index 7597a746d3..99846ea2f2 100644 --- a/src/models/domain/index.ts +++ b/src/models/domain/index.ts @@ -10,6 +10,7 @@ export { Field } from './field'; export { Folder } from './folder'; export { Identity } from './identity'; export { Login } from './login'; +export { LoginUri } from './loginUri'; export { PasswordHistory } from './passwordHistory'; export { SecureNote } from './secureNote'; export { SymmetricCryptoKey } from './symmetricCryptoKey'; diff --git a/src/models/domain/login.ts b/src/models/domain/login.ts index 1c98dc7031..211a371069 100644 --- a/src/models/domain/login.ts +++ b/src/models/domain/login.ts @@ -1,12 +1,15 @@ +import { LoginUri } from './loginUri'; + import { LoginData } from '../data/loginData'; +import { LoginUriView } from '../view/loginUriView'; import { LoginView } from '../view/loginView'; import { CipherString } from './cipherString'; import Domain from './domain'; export class Login extends Domain { - uri: CipherString; + uris: LoginUri[]; username: CipherString; password: CipherString; totp: CipherString; @@ -18,19 +21,34 @@ export class Login extends Domain { } this.buildDomainModel(this, obj, { - uri: null, username: null, password: null, totp: null, }, alreadyEncrypted, []); + + if (obj.uris) { + this.uris = []; + obj.uris.forEach((u) => { + this.uris.push(new LoginUri(u, alreadyEncrypted)); + }); + } } - decrypt(orgId: string): Promise { - return this.decryptObj(new LoginView(this), { - uri: null, + async decrypt(orgId: string): Promise { + const view = await this.decryptObj(new LoginView(this), { username: null, password: null, totp: null, }, orgId); + + if (this.uris != null) { + view.uris = []; + for (let i = 0; i < this.uris.length; i++) { + const uri = await this.uris[i].decrypt(orgId); + view.uris.push(uri); + } + } + + return view; } } diff --git a/src/models/domain/loginUri.ts b/src/models/domain/loginUri.ts new file mode 100644 index 0000000000..0cb6b19a7f --- /dev/null +++ b/src/models/domain/loginUri.ts @@ -0,0 +1,31 @@ +import { UriMatchType } from '../../enums/uriMatchType'; + +import { LoginUriData } from '../data/loginUriData'; + +import { LoginUriView } from '../view/loginUriView'; + +import { CipherString } from './cipherString'; +import Domain from './domain'; + +export class LoginUri extends Domain { + uri: CipherString; + match: UriMatchType; + + constructor(obj?: LoginUriData, alreadyEncrypted: boolean = false) { + super(); + if (obj == null) { + return; + } + + this.match = obj.match; + this.buildDomainModel(this, obj, { + uri: null, + }, alreadyEncrypted, []); + } + + decrypt(orgId: string): Promise { + return this.decryptObj(new LoginUriView(this), { + uri: null, + }, orgId); + } +} diff --git a/src/models/request/cipherRequest.ts b/src/models/request/cipherRequest.ts index 232883f323..68b5c3170a 100644 --- a/src/models/request/cipherRequest.ts +++ b/src/models/request/cipherRequest.ts @@ -1,5 +1,14 @@ import { CipherType } from '../../enums/cipherType'; +import { Cipher } from '../domain/cipher'; +import { Field } from '../domain/field'; + +import { CardApi } from '../api/cardApi'; +import { FieldApi } from '../api/fieldApi'; +import { IdentityApi } from '../api/identityApi'; +import { LoginApi } from '../api/loginApi'; +import { SecureNoteApi } from '../api/secureNoteApi'; + export class CipherRequest { type: CipherType; folderId: string; @@ -7,13 +16,13 @@ export class CipherRequest { name: string; notes: string; favorite: boolean; - login: any; - secureNote: any; - card: any; - identity: any; - fields: any[]; + login: LoginApi; + secureNote: SecureNoteApi; + card: CardApi; + identity: IdentityApi; + fields: FieldApi[]; - constructor(cipher: any) { + constructor(cipher: Cipher) { this.type = cipher.type; this.folderId = cipher.folderId; this.organizationId = cipher.organizationId; @@ -24,11 +33,21 @@ export class CipherRequest { switch (this.type) { case CipherType.Login: this.login = { - uri: cipher.login.uri ? cipher.login.uri.encryptedString : null, + uris: null, username: cipher.login.username ? cipher.login.username.encryptedString : null, password: cipher.login.password ? cipher.login.password.encryptedString : null, totp: cipher.login.totp ? cipher.login.totp.encryptedString : null, }; + + if (cipher.login.uris) { + this.login.uris = []; + cipher.login.uris.forEach((u) => { + this.login.uris.push({ + uri: u.uri ? u.uri.encryptedString : null, + match: u.match ? u.match : null, + }); + }); + } break; case CipherType.SecureNote: this.secureNote = { @@ -74,7 +93,7 @@ export class CipherRequest { if (cipher.fields) { this.fields = []; - cipher.fields.forEach((field: any) => { + cipher.fields.forEach((field) => { this.fields.push({ type: field.type, name: field.name ? field.name.encryptedString : null, diff --git a/src/models/response/cipherResponse.ts b/src/models/response/cipherResponse.ts index 241b8530a0..c8ed70ffd0 100644 --- a/src/models/response/cipherResponse.ts +++ b/src/models/response/cipherResponse.ts @@ -1,14 +1,26 @@ import { AttachmentResponse } from './attachmentResponse'; +import { CardApi } from '../api/cardApi'; +import { FieldApi } from '../api/fieldApi'; +import { IdentityApi } from '../api/identityApi'; +import { LoginApi } from '../api/loginApi'; +import { SecureNoteApi } from '../api/secureNoteApi'; + export class CipherResponse { id: string; organizationId: string; folderId: string; type: number; + name: string; + notes: string; + fields: FieldApi[]; + login: LoginApi; + card: CardApi; + identity: IdentityApi; + secureNote: SecureNoteApi; favorite: boolean; edit: boolean; organizationUseTotp: boolean; - data: any; revisionDate: string; attachments: AttachmentResponse[]; collectionIds: string[]; @@ -18,12 +30,36 @@ export class CipherResponse { this.organizationId = response.OrganizationId; this.folderId = response.FolderId; this.type = response.Type; + this.name = response.Name; + this.notes = response.Notes; this.favorite = response.Favorite; this.edit = response.Edit; this.organizationUseTotp = response.OrganizationUseTotp; - this.data = response.Data; this.revisionDate = response.RevisionDate; + if (response.Login != null) { + this.login = new LoginApi(response.Login); + } + + if (response.Card != null) { + this.card = new CardApi(response.Card); + } + + if (response.Identity != null) { + this.identity = new IdentityApi(response.Identity); + } + + if (response.SecureNote != null) { + this.secureNote = new SecureNoteApi(response.SecureNote); + } + + if (response.Fields != null) { + this.fields = []; + response.Fields.forEach((field: any) => { + this.fields.push(new FieldApi(field)); + }); + } + if (response.Attachments != null) { this.attachments = []; response.Attachments.forEach((attachment: any) => { diff --git a/src/models/view/cipherView.ts b/src/models/view/cipherView.ts index 6f00464841..9566c7d285 100644 --- a/src/models/view/cipherView.ts +++ b/src/models/view/cipherView.ts @@ -69,8 +69,4 @@ export class CipherView implements View { get login_username(): string { return this.login != null ? this.login.username : null; } - - get login_uri(): string { - return this.login != null ? this.login.uri : null; - } } diff --git a/src/models/view/index.ts b/src/models/view/index.ts index 0e07c256be..1bc3f9d6cb 100644 --- a/src/models/view/index.ts +++ b/src/models/view/index.ts @@ -3,6 +3,7 @@ export { CardView } from './cardView'; export { CipherView } from './cipherView'; export { FieldView } from './fieldView'; export { IdentityView } from './identityView'; +export { LoginUriView } from './loginUriView'; export { LoginView } from './loginView'; export { SecureNoteView } from './secureNoteView'; export { View } from './view'; diff --git a/src/models/view/loginUriView.ts b/src/models/view/loginUriView.ts new file mode 100644 index 0000000000..6222fef96e --- /dev/null +++ b/src/models/view/loginUriView.ts @@ -0,0 +1,61 @@ +import { UriMatchType } from '../../enums/uriMatchType'; + +import { View } from './view'; + +import { LoginUri } from '../domain/loginUri'; + +import { PlatformUtilsService } from '../../abstractions/platformUtils.service'; + +export class LoginUriView implements View { + match: UriMatchType = null; + + // tslint:disable + private _uri: string; + private _domain: string; + // tslint:enable + + constructor(u?: LoginUri) { + if (!u) { + return; + } + + this.match = u.match; + } + + get uri(): string { + return this._uri; + } + set uri(value: string) { + this._uri = value; + this._domain = null; + } + + get domain(): string { + if (this._domain == null && this.uri != null) { + const containerService = (window as any).bitwardenContainerService; + if (containerService) { + const platformUtilsService: PlatformUtilsService = containerService.getPlatformUtilsService(); + this._domain = platformUtilsService.getDomain(this.uri); + if (this._domain === '') { + this._domain = null; + } + } else { + throw new Error('window.bitwardenContainerService not initialized.'); + } + } + + return this._domain; + } + + get domainOrUri(): string { + return this.domain != null ? this.domain : this.uri; + } + + get isWebsite(): boolean { + return this.uri != null && (this.uri.indexOf('http://') === 0 || this.uri.indexOf('https://') === 0); + } + + get canLaunch(): boolean { + return this.uri != null && this.uri.indexOf('://') > -1; + } +} diff --git a/src/models/view/loginView.ts b/src/models/view/loginView.ts index c3554c9c38..4f73b3a739 100644 --- a/src/models/view/loginView.ts +++ b/src/models/view/loginView.ts @@ -1,3 +1,4 @@ +import { LoginUriView } from './loginUriView'; import { View } from './view'; import { Login } from '../domain/login'; @@ -7,12 +8,11 @@ import { PlatformUtilsService } from '../../abstractions/platformUtils.service'; export class LoginView implements View { username: string; totp: string; + uris: LoginUriView[]; // tslint:disable - private _uri: string; private _username: string; private _password: string; - private _domain: string; private _maskedPassword: string; // tslint:enable @@ -20,14 +20,6 @@ export class LoginView implements View { // ctor } - get uri(): string { - return this._uri; - } - set uri(value: string) { - this._uri = value; - this._domain = null; - } - get password(): string { return this._password; } @@ -36,21 +28,8 @@ export class LoginView implements View { this._maskedPassword = null; } - get domain(): string { - if (this._domain == null && this.uri != null) { - const containerService = (window as any).bitwardenContainerService; - if (containerService) { - const platformUtilsService: PlatformUtilsService = containerService.getPlatformUtilsService(); - this._domain = platformUtilsService.getDomain(this.uri); - if (this._domain === '') { - this._domain = null; - } - } else { - throw new Error('window.bitwardenContainerService not initialized.'); - } - } - - return this._domain; + get uri(): string { + return this.hasUris ? this.uris[0].uri : null; } get maskedPassword(): string { @@ -68,15 +47,11 @@ export class LoginView implements View { return this.username; } - get domainOrUri(): string { - return this.domain != null ? this.domain : this.uri; - } - - get isWebsite(): boolean { - return this.uri != null && (this.uri.indexOf('http://') === 0 || this.uri.indexOf('https://') === 0); - } - get canLaunch(): boolean { - return this.uri != null && this.uri.indexOf('://') > -1; + return this.hasUris && this.uris[0].canLaunch; + } + + get hasUris(): boolean { + return this.uris != null && this.uris.length > 0; } } diff --git a/src/services/cipher.service.ts b/src/services/cipher.service.ts index fb8e532d62..5d3c60a64f 100644 --- a/src/services/cipher.service.ts +++ b/src/services/cipher.service.ts @@ -9,6 +9,7 @@ import Domain from '../models/domain/domain'; import { Field } from '../models/domain/field'; import { Identity } from '../models/domain/identity'; import { Login } from '../models/domain/login'; +import { LoginUri } from '../models/domain/loginUri'; import { SecureNote } from '../models/domain/secureNote'; import { SymmetricCryptoKey } from '../models/domain/symmetricCryptoKey'; @@ -487,11 +488,22 @@ export class CipherService implements CipherServiceAbstraction { case CipherType.Login: cipher.login = new Login(); await this.encryptObjProperty(model.login, cipher.login, { - uri: null, username: null, password: null, totp: null, }, key); + + if (model.login.uris != null) { + cipher.login.uris = []; + for (let i = 0; i < model.login.uris.length; i++) { + const loginUri = new LoginUri(); + loginUri.match = model.login.uris[i].match; + await this.encryptObjProperty(model.login.uris[i], loginUri, { + uri: null, + }, key); + cipher.login.uris.push(loginUri); + } + } return; case CipherType.SecureNote: cipher.secureNote = new SecureNote();