From c23ee3b98aefac9d1cf593bfa75bb1b1c18d41c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Sun, 30 Jun 2024 00:48:56 +0200 Subject: [PATCH] PM-4661: Add passkey.username as item.username (#9756) * Add incoming passkey.username as item.username * Driveby fix, was sending wrong username * added username to new-cipher too * Guarded the if-block * Update apps/browser/src/vault/popup/components/vault/add-edit.component.ts Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> * Fixed broken test * fixed username on existing ciphers --------- Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> --- .../vault/popup/components/fido2/fido2.component.ts | 11 +++++++---- .../popup/components/vault/add-edit.component.ts | 8 ++++++++ .../fido2/fido2-authenticator.service.spec.ts | 2 +- .../services/fido2/fido2-authenticator.service.ts | 6 +++++- 4 files changed, 21 insertions(+), 6 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 049dc30ef61..752a9100721 100644 --- a/apps/browser/src/vault/popup/components/fido2/fido2.component.ts +++ b/apps/browser/src/vault/popup/components/fido2/fido2.component.ts @@ -256,7 +256,7 @@ export class Fido2Component implements OnInit, OnDestroy { const name = data.credentialName || data.rpId; // TODO: Revert to check for user verification once user verification for passkeys is approved for production. // PM-4577 - https://github.com/bitwarden/clients/pull/8746 - await this.createNewCipher(name); + await this.createNewCipher(name, data.userName); // We are bypassing user verification pending approval. this.send({ @@ -310,6 +310,7 @@ export class Fido2Component implements OnInit, OnDestroy { name: data.credentialName || data.rpId, uri: this.url, uilocation: "popout", + username: data.userName, senderTabId: this.senderTabId, sessionId: this.sessionId, userVerification: data.userVerification, @@ -357,11 +358,13 @@ export class Fido2Component implements OnInit, OnDestroy { this.destroy$.complete(); } - private buildCipher(name: string) { + private buildCipher(name: string, username: string) { this.cipher = new CipherView(); this.cipher.name = name; + this.cipher.type = CipherType.Login; this.cipher.login = new LoginView(); + this.cipher.login.username = username; this.cipher.login.uris = [new LoginUriView()]; this.cipher.login.uris[0].uri = this.url; this.cipher.card = new CardView(); @@ -371,8 +374,8 @@ export class Fido2Component implements OnInit, OnDestroy { this.cipher.reprompt = CipherRepromptType.None; } - private async createNewCipher(name: string) { - this.buildCipher(name); + private async createNewCipher(name: string, username: string) { + this.buildCipher(name, username); const cipher = await this.cipherService.encrypt(this.cipher); try { await this.cipherService.createWithServer(cipher); diff --git a/apps/browser/src/vault/popup/components/vault/add-edit.component.ts b/apps/browser/src/vault/popup/components/vault/add-edit.component.ts index bf7a6b07a5c..e72077fa82d 100644 --- a/apps/browser/src/vault/popup/components/vault/add-edit.component.ts +++ b/apps/browser/src/vault/popup/components/vault/add-edit.component.ts @@ -128,6 +128,14 @@ export class AddEditComponent extends BaseAddEditComponent { await this.load(); if (!this.editMode || this.cloneMode) { + // Only allow setting username if there's no existing value + if ( + params.username && + (this.cipher.login.username == null || this.cipher.login.username === "") + ) { + this.cipher.login.username = params.username; + } + if (params.name && (this.cipher.name == null || this.cipher.name === "")) { this.cipher.name = params.name; } diff --git a/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts b/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts index a8690da9e2b..5da67f807b7 100644 --- a/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts +++ b/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts @@ -214,7 +214,7 @@ describe("FidoAuthenticatorService", () => { expect(userInterfaceSession.confirmNewCredential).toHaveBeenCalledWith({ credentialName: params.rpEntity.name, - userName: params.userEntity.displayName, + userName: params.userEntity.name, userVerification, rpId: params.rpEntity.id, } as NewCredentialParams); diff --git a/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts b/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts index 6a22f03cf73..47d76897a3b 100644 --- a/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts +++ b/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts @@ -111,7 +111,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr let pubKeyDer: ArrayBuffer; const response = await userInterfaceSession.confirmNewCredential({ credentialName: params.rpEntity.name, - userName: params.userEntity.displayName, + userName: params.userEntity.name, userVerification: params.requireUserVerification, rpId: params.rpEntity.id, }); @@ -145,6 +145,10 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr fido2Credential = await createKeyView(params, keyPair.privateKey); cipher.login.fido2Credentials = [fido2Credential]; + // update username if username is missing + if (Utils.isNullOrEmpty(cipher.login.username)) { + cipher.login.username = fido2Credential.userName; + } const reencrypted = await this.cipherService.encrypt(cipher); await this.cipherService.updateWithServer(reencrypted); credentialId = fido2Credential.credentialId;