diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index c166273e35..dc151a7e5d 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -1198,6 +1198,9 @@ "typeIdentity": { "message": "Identity" }, + "typePasskey": { + "message": "Passkey" + }, "passwordHistory": { "message": "Password history" }, diff --git a/apps/browser/src/popup/vault/vault-filter.component.html b/apps/browser/src/popup/vault/vault-filter.component.html index 26689a5055..8ddc6c01dc 100644 --- a/apps/browser/src/popup/vault/vault-filter.component.html +++ b/apps/browser/src/popup/vault/vault-filter.component.html @@ -112,6 +112,19 @@ <span class="row-sub-label">{{ typeCounts.get(cipherType.SecureNote) || 0 }}</span> <span><i class="bwi bwi-angle-right bwi-lg row-sub-icon"></i></span> </button> + <button + type="button" + class="box-content-row" + appStopClick + (click)="selectType(cipherType.Fido2Key)" + > + <div class="row-main"> + <div class="icon"><i class="bwi bwi-fw bwi-lg bwi-key"></i></div> + <span class="text">{{ "typePasskey" | i18n }}</span> + </div> + <span class="row-sub-label">{{ typeCounts.get(cipherType.Fido2Key) || 0 }}</span> + <span><i class="bwi bwi-angle-right bwi-lg row-sub-icon"></i></span> + </button> </div> </div> <div class="box list" *ngIf="nestedFolders?.length"> diff --git a/apps/browser/src/popup/vault/view.component.html b/apps/browser/src/popup/vault/view.component.html index 73d75b662b..db8acc79c3 100644 --- a/apps/browser/src/popup/vault/view.component.html +++ b/apps/browser/src/popup/vault/view.component.html @@ -555,7 +555,12 @@ class="box-content-row" appStopClick (click)="fillCipher()" - *ngIf="cipher.type !== cipherType.SecureNote && !cipher.isDeleted && !inPopout" + *ngIf=" + cipher.type !== cipherType.SecureNote && + !cipher.isDeleted && + !inPopout && + cipher.type != cipherType.Fido2Key + " > <div class="row-main text-primary"> <div class="icon text-primary" aria-hidden="true"> @@ -569,7 +574,12 @@ class="box-content-row" appStopClick (click)="fillCipherAndSave()" - *ngIf="cipher.type === cipherType.Login && !cipher.isDeleted && !inPopout" + *ngIf=" + cipher.type === cipherType.Login && + !cipher.isDeleted && + !inPopout && + cipher.type != cipherType.Fido2Key + " > <div class="row-main text-primary"> <div class="icon text-primary" aria-hidden="true"> @@ -583,7 +593,7 @@ class="box-content-row" appStopClick (click)="clone()" - *ngIf="!cipher.organizationId && !cipher.isDeleted" + *ngIf="!cipher.organizationId && !cipher.isDeleted && cipher.type != cipherType.Fido2Key" > <div class="row-main text-primary"> <div class="icon text-primary" aria-hidden="true"> diff --git a/libs/angular/src/components/icon.component.ts b/libs/angular/src/components/icon.component.ts index 1c9b5a8b55..562986d471 100644 --- a/libs/angular/src/components/icon.component.ts +++ b/libs/angular/src/components/icon.component.ts @@ -65,6 +65,9 @@ export class IconComponent implements OnChanges { case CipherType.Identity: this.icon = "bwi-id-card"; break; + case CipherType.Fido2Key: + this.icon = "bwi-key"; // TODO: Verify if this icon should be classified as "Bitwarden Object" + break; default: break; } diff --git a/libs/common/src/models/view/cipher.view.ts b/libs/common/src/models/view/cipher.view.ts index c7968e9722..fb452ad5b8 100644 --- a/libs/common/src/models/view/cipher.view.ts +++ b/libs/common/src/models/view/cipher.view.ts @@ -78,6 +78,8 @@ export class CipherView implements View, InitializerMetadata { return this.card; case CipherType.Identity: return this.identity; + case CipherType.Fido2Key: + return this.fido2Key; default: break; } diff --git a/libs/common/src/models/view/fido2-key.view.ts b/libs/common/src/models/view/fido2-key.view.ts index 964a893fd1..aa7b4309dc 100644 --- a/libs/common/src/models/view/fido2-key.view.ts +++ b/libs/common/src/models/view/fido2-key.view.ts @@ -1,6 +1,12 @@ -export class Fido2KeyView { +import { ItemView } from "./item.view"; + +export class Fido2KeyView extends ItemView { key: string; rpId: string; origin: string; userHandle: string; + + get subTitle(): string { + return null; + } } diff --git a/libs/common/src/services/fido2/fido2.service.ts b/libs/common/src/services/fido2/fido2.service.ts index fa3a441304..098b5659e4 100644 --- a/libs/common/src/services/fido2/fido2.service.ts +++ b/libs/common/src/services/fido2/fido2.service.ts @@ -172,6 +172,10 @@ export class Fido2Service implements Fido2ServiceAbstraction { for (const allowedCredential of allowedCredentialIds) { cipher = await this.cipherService.get(allowedCredential); + if (cipher.deletedDate != undefined) { + cipher = undefined; + } + if (cipher != undefined) { break; } @@ -211,7 +215,7 @@ export class Fido2Service implements Fido2ServiceAbstraction { private async getCredentialByRp(rpId: string): Promise<BitCredential | undefined> { const allCipherViews = await this.cipherService.getAllDecrypted(); const cipherView = allCipherViews.find( - (cv) => cv.type === CipherType.Fido2Key && cv.fido2Key?.rpId === rpId + (cv) => !cv.isDeleted && cv.type === CipherType.Fido2Key && cv.fido2Key?.rpId === rpId ); if (cipherView == undefined) {