From 80c94bf9b7fd59b3e568bed7bf32436505dec135 Mon Sep 17 00:00:00 2001 From: Todd Martin <106564991+trmartin4@users.noreply.github.com> Date: Wed, 11 Oct 2023 17:38:53 -0400 Subject: [PATCH] Updated fido2Credentials to initialize as null instead of empty array (#6548) * Updated fido2Credentials to be null instead of empty string * Updated cipher tests. * Fixed tests. * Updated view and clone logic. * Updated templates to handle null value. * Further null checks. --- .../src/vault/popup/components/fido2/fido2.component.ts | 2 +- .../vault/popup/components/vault/add-edit.component.html | 2 +- .../src/vault/popup/components/vault/view.component.html | 2 +- apps/desktop/src/vault/app/vault/add-edit.component.html | 2 +- apps/desktop/src/vault/app/vault/view.component.html | 2 +- .../app/vault/individual-vault/add-edit.component.html | 2 +- .../src/app/vault/individual-vault/vault.component.ts | 2 +- libs/angular/src/vault/components/add-edit.component.ts | 4 ++-- libs/angular/src/vault/components/view.component.ts | 2 +- libs/common/src/vault/models/domain/cipher.spec.ts | 2 -- libs/common/src/vault/models/domain/login.spec.ts | 5 +---- libs/common/src/vault/models/domain/login.ts | 9 +++++++-- libs/common/src/vault/models/view/login.view.ts | 9 ++++++--- .../vault/services/fido2/fido2-authenticator.service.ts | 6 +++--- 14 files changed, 27 insertions(+), 24 deletions(-) diff --git a/apps/browser/src/vault/popup/components/fido2/fido2.component.ts b/apps/browser/src/vault/popup/components/fido2/fido2.component.ts index 7ee9e959f0e5..91fb2d29aa9d 100644 --- a/apps/browser/src/vault/popup/components/fido2/fido2.component.ts +++ b/apps/browser/src/vault/popup/components/fido2/fido2.component.ts @@ -235,7 +235,7 @@ export class Fido2Component implements OnInit, OnDestroy { } else if (data?.type === "ConfirmNewCredentialRequest") { let userVerified = false; - if (this.cipher.login.fido2Credentials.length > 0) { + if (this.cipher.login.hasFido2Credentials) { const confirmed = await this.dialogService.openSimpleDialog({ title: { key: "overwritePasskey" }, content: { key: "overwritePasskeyAlert" }, diff --git a/apps/browser/src/vault/popup/components/vault/add-edit.component.html b/apps/browser/src/vault/popup/components/vault/add-edit.component.html index 600633f01491..b2a42776e18a 100644 --- a/apps/browser/src/vault/popup/components/vault/add-edit.component.html +++ b/apps/browser/src/vault/popup/components/vault/add-edit.component.html @@ -131,7 +131,7 @@

-
+
{{ "typePasskey" | i18n }} diff --git a/apps/browser/src/vault/popup/components/vault/view.component.html b/apps/browser/src/vault/popup/components/vault/view.component.html index 9f487b58d7eb..a4b2ae200c85 100644 --- a/apps/browser/src/vault/popup/components/vault/view.component.html +++ b/apps/browser/src/vault/popup/components/vault/view.component.html @@ -144,7 +144,7 @@

-
+
{{ "typePasskey" | i18n }} diff --git a/apps/desktop/src/vault/app/vault/add-edit.component.html b/apps/desktop/src/vault/app/vault/add-edit.component.html index 4529d8fb3f7c..1580932257b7 100644 --- a/apps/desktop/src/vault/app/vault/add-edit.component.html +++ b/apps/desktop/src/vault/app/vault/add-edit.component.html @@ -117,7 +117,7 @@

{{ "typePasskey" | i18n }} diff --git a/apps/desktop/src/vault/app/vault/view.component.html b/apps/desktop/src/vault/app/vault/view.component.html index 6996271ebc55..87438d9a2dd0 100644 --- a/apps/desktop/src/vault/app/vault/view.component.html +++ b/apps/desktop/src/vault/app/vault/view.component.html @@ -119,7 +119,7 @@

-
+
{{ "typePasskey" | i18n }} {{ "dateCreated" | i18n }} {{ cipher.login.fido2Credentials[0].creationDate | date : "short" }} diff --git a/apps/web/src/app/vault/individual-vault/add-edit.component.html b/apps/web/src/app/vault/individual-vault/add-edit.component.html index d5eb15e84587..91fff843d96b 100644 --- a/apps/web/src/app/vault/individual-vault/add-edit.component.html +++ b/apps/web/src/app/vault/individual-vault/add-edit.component.html @@ -191,7 +191,7 @@

{{ title }}

- +
diff --git a/apps/web/src/app/vault/individual-vault/vault.component.ts b/apps/web/src/app/vault/individual-vault/vault.component.ts index da8873351657..aae45d27e25e 100644 --- a/apps/web/src/app/vault/individual-vault/vault.component.ts +++ b/apps/web/src/app/vault/individual-vault/vault.component.ts @@ -721,7 +721,7 @@ export class VaultComponent implements OnInit, OnDestroy { } async cloneCipher(cipher: CipherView) { - if (cipher.login?.fido2Credentials.length > 0) { + if (cipher.login?.hasFido2Credentials) { const confirmed = await this.dialogService.openSimpleDialog({ title: { key: "passkeyNotCopied" }, content: { key: "passkeyNotCopiedAlert" }, diff --git a/libs/angular/src/vault/components/add-edit.component.ts b/libs/angular/src/vault/components/add-edit.component.ts index 40f16d336697..2f71985b8fdf 100644 --- a/libs/angular/src/vault/components/add-edit.component.ts +++ b/libs/angular/src/vault/components/add-edit.component.ts @@ -328,8 +328,8 @@ export class AddEditComponent implements OnInit, OnDestroy { if (this.cloneMode) { this.cipher.id = null; - if (this.cipher.type === CipherType.Login && this.cipher.login.fido2Credentials.length > 0) { - this.cipher.login.fido2Credentials = []; + if (this.cipher.type === CipherType.Login && this.cipher.login.hasFido2Credentials) { + this.cipher.login.fido2Credentials = null; } } diff --git a/libs/angular/src/vault/components/view.component.ts b/libs/angular/src/vault/components/view.component.ts index f9a12dc810bd..90032617b46d 100644 --- a/libs/angular/src/vault/components/view.component.ts +++ b/libs/angular/src/vault/components/view.component.ts @@ -157,7 +157,7 @@ export class ViewComponent implements OnDestroy, OnInit { } async clone() { - if (this.cipher.login?.fido2Credentials.length > 0) { + if (this.cipher.login?.hasFido2Credentials) { const confirmed = await this.dialogService.openSimpleDialog({ title: { key: "passkeyNotCopied" }, content: { key: "passkeyNotCopiedAlert" }, diff --git a/libs/common/src/vault/models/domain/cipher.spec.ts b/libs/common/src/vault/models/domain/cipher.spec.ts index 33c9cec56b44..6234fe7029b2 100644 --- a/libs/common/src/vault/models/domain/cipher.spec.ts +++ b/libs/common/src/vault/models/domain/cipher.spec.ts @@ -82,7 +82,6 @@ describe("Cipher DTO", () => { passwordRevisionDate: "2022-01-31T12:00:00.000Z", totp: "EncryptedString", autofillOnPageLoad: false, - fido2Credentials: [], }, passwordHistory: [ { password: "EncryptedString", lastUsedDate: "2022-01-31T12:00:00.000Z" }, @@ -151,7 +150,6 @@ describe("Cipher DTO", () => { password: { encryptedString: "EncryptedString", encryptionType: 0 }, totp: { encryptedString: "EncryptedString", encryptionType: 0 }, uris: [{ match: 0, uri: { encryptedString: "EncryptedString", encryptionType: 0 } }], - fido2Credentials: [], }, attachments: [ { diff --git a/libs/common/src/vault/models/domain/login.spec.ts b/libs/common/src/vault/models/domain/login.spec.ts index 69b4aa7cabfc..99c31d332ac5 100644 --- a/libs/common/src/vault/models/domain/login.spec.ts +++ b/libs/common/src/vault/models/domain/login.spec.ts @@ -25,7 +25,6 @@ describe("Login DTO", () => { username: null, password: null, totp: null, - fido2Credentials: [], }); }); @@ -56,9 +55,7 @@ describe("Login DTO", () => { it("Initialize without LoginData", () => { const login = new Login(); - expect(login).toEqual({ - fido2Credentials: [], - }); + expect(login).toEqual({}); }); it("Decrypts correctly", async () => { diff --git a/libs/common/src/vault/models/domain/login.ts b/libs/common/src/vault/models/domain/login.ts index ab4827ae4665..43886adb7019 100644 --- a/libs/common/src/vault/models/domain/login.ts +++ b/libs/common/src/vault/models/domain/login.ts @@ -16,7 +16,7 @@ export class Login extends Domain { passwordRevisionDate?: Date; totp: EncString; autofillOnPageLoad: boolean; - fido2Credentials: Fido2Credential[] = []; + fido2Credentials: Fido2Credential[]; constructor(obj?: LoginData) { super(); @@ -46,6 +46,7 @@ export class Login extends Domain { } if (obj.fido2Credentials) { + this.fido2Credentials = []; this.fido2Credentials = obj.fido2Credentials.map((key) => new Fido2Credential(key)); } } @@ -71,6 +72,7 @@ export class Login extends Domain { } if (this.fido2Credentials != null) { + view.fido2Credentials = []; view.fido2Credentials = await Promise.all( this.fido2Credentials.map((key) => key.decrypt(orgId, encKey)) ); @@ -97,7 +99,10 @@ export class Login extends Domain { }); } - l.fido2Credentials = this.fido2Credentials.map((key) => key.toFido2CredentialData()); + if (this.fido2Credentials != null && this.fido2Credentials.length > 0) { + l.fido2Credentials = []; + l.fido2Credentials = this.fido2Credentials.map((key) => key.toFido2CredentialData()); + } return l; } diff --git a/libs/common/src/vault/models/view/login.view.ts b/libs/common/src/vault/models/view/login.view.ts index a55943dda045..fa05189ba0c0 100644 --- a/libs/common/src/vault/models/view/login.view.ts +++ b/libs/common/src/vault/models/view/login.view.ts @@ -19,7 +19,7 @@ export class LoginView extends ItemView { totp: string = null; uris: LoginUriView[] = null; autofillOnPageLoad: boolean = null; - fido2Credentials: Fido2CredentialView[] = []; + fido2Credentials: Fido2CredentialView[] = null; constructor(l?: Login) { super(); @@ -65,6 +65,10 @@ export class LoginView extends ItemView { return this.uris != null && this.uris.length > 0; } + get hasFido2Credentials(): boolean { + return this.fido2Credentials != null && this.fido2Credentials.length > 0; + } + matchesUri( targetUri: string, equivalentDomains: Set, @@ -81,8 +85,7 @@ export class LoginView extends ItemView { const passwordRevisionDate = obj.passwordRevisionDate == null ? null : new Date(obj.passwordRevisionDate); const uris = obj.uris?.map((uri: any) => LoginUriView.fromJSON(uri)); - const fido2Credentials = - obj.fido2Credentials?.map((key) => Fido2CredentialView.fromJSON(key)) ?? []; + const fido2Credentials = obj.fido2Credentials?.map((key) => Fido2CredentialView.fromJSON(key)); return Object.assign(new LoginView(), obj, { passwordRevisionDate, diff --git a/libs/common/src/vault/services/fido2/fido2-authenticator.service.ts b/libs/common/src/vault/services/fido2/fido2-authenticator.service.ts index b3ab710db7e2..02f078dee0b7 100644 --- a/libs/common/src/vault/services/fido2/fido2-authenticator.service.ts +++ b/libs/common/src/vault/services/fido2/fido2-authenticator.service.ts @@ -312,7 +312,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr !cipher.isDeleted && cipher.organizationId == undefined && cipher.type === CipherType.Login && - cipher.login.fido2Credentials.length > 0 && + cipher.login.hasFido2Credentials && ids.includes(cipher.login.fido2Credentials[0].credentialId) ) .map((cipher) => cipher.id); @@ -340,7 +340,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr (cipher) => !cipher.isDeleted && cipher.type === CipherType.Login && - cipher.login.fido2Credentials.length > 0 && + cipher.login.hasFido2Credentials && cipher.login.fido2Credentials[0].rpId === rpId && ids.includes(cipher.login.fido2Credentials[0].credentialId) ); @@ -352,7 +352,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr (cipher) => !cipher.isDeleted && cipher.type === CipherType.Login && - cipher.login.fido2Credentials.length > 0 && + cipher.login.hasFido2Credentials && cipher.login.fido2Credentials[0].rpId === rpId && cipher.login.fido2Credentials[0].discoverable );