1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-28 10:33:31 +00:00

[PM-3810] Unify Passkeys view (#6335)

* Removed standalone fido2key view, update login view to show created date when a fido2key is present, reverted icon component to previous state without fido2key type, removed filters to handle standalone fido2key as login type

* Allow duplication

* Removed launchable behaviours from fido2 key view

* Reworked desktop views from standalone fido2keys to unified fido2keys in the login

* Reworked web views from standalone fido2keys to unified fido2keys in the login

* Fixed test case to not create standalone fido2keys

* Updated views to use fido2key creation date

* removed unused locale

* moved logic from template to class

* Removed fido2key ciphertype

* Removed fido2key ciphertype references
This commit is contained in:
SmithThe4th
2023-09-26 16:13:33 -04:00
committed by GitHub
parent 6fbc0c29f9
commit 9778cd73df
30 changed files with 64 additions and 516 deletions

View File

@@ -1,3 +1,4 @@
import { DatePipe } from "@angular/common";
import { Component } from "@angular/core";
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
@@ -47,7 +48,8 @@ export class EmergencyAddEditComponent extends BaseAddEditComponent {
organizationService: OrganizationService,
logService: LogService,
sendApiService: SendApiService,
dialogService: DialogService
dialogService: DialogService,
datePipe: DatePipe
) {
super(
cipherService,
@@ -66,7 +68,8 @@ export class EmergencyAddEditComponent extends BaseAddEditComponent {
logService,
passwordRepromptService,
sendApiService,
dialogService
dialogService,
datePipe
);
}

View File

@@ -99,19 +99,6 @@
{{ "launch" | i18n }}
</a>
</ng-container>
<!-- Fido2Key -->
<ng-container *ngIf="cipher.type === CipherType.Fido2Key && !cipher.isDeleted">
<a
bitMenuItem
*ngIf="cipher.fido2Key.canLaunch"
type="button"
[href]="cipher.fido2Key.launchUri"
target="_blank"
>
<i class="bwi bwi-fw bwi-share-square" aria-hidden="true"></i>
{{ "launch" | i18n }}
</a>
</ng-container>
<button bitMenuItem type="button" (click)="attachments()">
<i class="bwi bwi-fw bwi-paperclip" aria-hidden="true"></i>

View File

@@ -166,9 +166,8 @@ export class VaultItemsComponent {
protected canClone(vaultItem: VaultItem) {
return (
((vaultItem.cipher.organizationId && this.cloneableOrganizationCiphers) ||
vaultItem.cipher.organizationId == null) &&
!vaultItem.cipher.fido2Key?.rpId
(vaultItem.cipher.organizationId && this.cloneableOrganizationCiphers) ||
vaultItem.cipher.organizationId == null
);
}

View File

@@ -201,7 +201,7 @@
class="form-control"
type="text"
name="Login.Fido2key"
[value]="'passkeyTwoStepLogin' | i18n"
[value]="fido2KeyCreationDateValue"
appInputVerbatim
disabled
readonly
@@ -832,89 +832,6 @@
</div>
</div>
</ng-container>
<!-- Fido2Key -->
<ng-container *ngIf="cipher.type === cipherType.Fido2Key">
<div class="row">
<div class="col-6 form-group">
<label for="fido2KeyUserDisplayName">{{ "username" | i18n }}</label>
<div class="input-group">
<input
id="fido2KeyUserDisplayName"
class="form-control"
type="text"
name="Fido2key.UserDisplayName"
[(ngModel)]="cipher.fido2Key.userDisplayName"
appInputVerbatim
[disabled]="cipher.isDeleted || viewOnly"
[readonly]="!cipher.edit && editMode"
/>
<div class="input-group-append" *ngIf="!cipher.isDeleted">
<button
type="button"
class="btn btn-outline-secondary"
appA11yTitle="{{ 'copyUsername' | i18n }}"
(click)="copy(cipher.fido2Key.userDisplayName, 'username', 'Username')"
>
<i class="bwi bwi-lg bwi-clone" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
<div class="col-6 form-group">
<label for="fido2keyCreationDate">{{ "typePasskey" | i18n }}</label>
<div class="input-group">
<input
id="fido2keyCreationDate"
class="form-control"
type="text"
name="Fido2key.CreationDate"
[value]="('dateCreated' | i18n) + ' ' + (cipher.creationDate | date : 'short')"
appInputVerbatim
disabled
readonly
/>
</div>
</div>
</div>
<div class="row">
<div class="col-12 form-group">
<label for="fido2keyApplication">{{ "application" | i18n }}</label>
<div class="input-group">
<input
class="form-control"
id="fido2keyApplication"
type="text"
name="Fido2key.Application"
[value]="cipher.fido2Key.rpId"
disabled
readonly
appInputVerbatim
/>
<div class="input-group-append">
<button
type="button"
class="btn btn-outline-secondary"
appA11yTitle="{{ 'launch' | i18n }}"
(click)="launch(cipher.fido2Key)"
>
<i class="bwi bwi-lg bwi-share-square" aria-hidden="true"></i>
</button>
<button
type="button"
class="btn btn-outline-secondary"
appA11yTitle="{{ 'copyUri' | i18n }}"
(click)="copy(cipher.fido2Key.launchUri, 'uri', 'URI')"
>
<i class="bwi bwi-lg bwi-clone" aria-hidden="true"></i>
</button>
</div>
</div>
<small class="form-text text-muted">{{ "passkeyEditInformation" | i18n }}</small>
</div>
</div>
</ng-container>
<div class="form-group">
<label for="notes">{{ "notes" | i18n }}</label>
<textarea

View File

@@ -1,3 +1,4 @@
import { DatePipe } from "@angular/common";
import { Component, OnDestroy, OnInit } from "@angular/core";
import { AddEditComponent as BaseAddEditComponent } from "@bitwarden/angular/vault/components/add-edit.component";
@@ -42,6 +43,15 @@ export class AddEditComponent extends BaseAddEditComponent implements OnInit, On
protected totpInterval: number;
protected override componentName = "app-vault-add-edit";
get fido2KeyCreationDateValue(): string {
const dateCreated = this.i18nService.t("dateCreated");
const creationDate = this.datePipe.transform(
this.cipher?.login?.fido2Keys?.[0]?.creationDate,
"short"
);
return `${dateCreated} ${creationDate}`;
}
constructor(
cipherService: CipherService,
folderService: FolderService,
@@ -59,7 +69,8 @@ export class AddEditComponent extends BaseAddEditComponent implements OnInit, On
logService: LogService,
passwordRepromptService: PasswordRepromptService,
sendApiService: SendApiService,
dialogService: DialogService
dialogService: DialogService,
private datePipe: DatePipe
) {
super(
cipherService,

View File

@@ -211,17 +211,6 @@ describe("createFilter", () => {
expect(result).toBe(true);
});
});
describe("given a cipher with Fido2Key type", () => {
it("should return true when filter is login", () => {
const cipher = createCipher({ type: CipherType.Fido2Key });
const filterFunction = createFilterFunction({ type: "login" });
const result = filterFunction(cipher);
expect(result).toBe(true);
});
});
});
function createCipher(options: Partial<CipherView> = {}) {

View File

@@ -16,12 +16,7 @@ export function createFilterFunction(filter: RoutedVaultFilterModel): FilterFunc
if (filter.type === "identity" && cipher.type !== CipherType.Identity) {
return false;
}
// Login and Fido2Key are both login types
if (
filter.type === "login" &&
cipher.type !== CipherType.Login &&
cipher.type !== CipherType.Fido2Key
) {
if (filter.type === "login" && cipher.type !== CipherType.Login) {
return false;
}
if (filter.type === "note" && cipher.type !== CipherType.SecureNote) {

View File

@@ -42,15 +42,6 @@ describe("VaultFilter", () => {
},
null
);
const loginCiphersFilter = new TreeNode<CipherTypeFilter>(
{
id: "login",
name: "login",
type: CipherType.Login,
icon: "bwi-globe",
},
null
);
const trashFilter = new TreeNode<CipherTypeFilter>(
{
id: "trash",
@@ -288,19 +279,6 @@ describe("VaultFilter", () => {
expect(result).toBe(true);
});
});
describe("given a cipher with Fido2Key type", () => {
it("should return true when filter is login", () => {
const cipher = createCipher({ type: CipherType.Fido2Key });
const filterFunction = createFilterFunction({
selectedCipherTypeNode: loginCiphersFilter,
});
const result = filterFunction(cipher);
expect(result).toBe(true);
});
});
});
});

View File

@@ -120,13 +120,7 @@ export class VaultFilter {
cipherPassesFilter = cipher.isDeleted;
}
if (this.cipherType && cipherPassesFilter) {
//Fido2Key's should also be included in the Login type
if (this.cipherType === CipherType.Login) {
cipherPassesFilter =
cipher.type === this.cipherType || cipher.type === CipherType.Fido2Key;
} else {
cipherPassesFilter = cipher.type === this.cipherType;
}
cipherPassesFilter = cipher.type === this.cipherType;
}
if (this.selectedFolderNode) {
// No folder

View File

@@ -1,3 +1,4 @@
import { DatePipe } from "@angular/common";
import { Component } from "@angular/core";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
@@ -49,7 +50,8 @@ export class AddEditComponent extends BaseAddEditComponent {
passwordRepromptService: PasswordRepromptService,
organizationService: OrganizationService,
sendApiService: SendApiService,
dialogService: DialogService
dialogService: DialogService,
datePipe: DatePipe
) {
super(
cipherService,
@@ -68,7 +70,8 @@ export class AddEditComponent extends BaseAddEditComponent {
logService,
passwordRepromptService,
sendApiService,
dialogService
dialogService,
datePipe
);
}

View File

@@ -7178,15 +7178,9 @@
"application": {
"message": "Application"
},
"passkeyEditInformation": {
"message": "You cannot edit passkey application because it would invalidate the passkey."
},
"duplicatePasskey": {
"message": "A passkey with this ID already exists in this organization."
},
"passkeyTwoStepLogin": {
"message": "Available for two-step login"
},
"passkeyNotCopied": {
"message": "Passkey will not be copied"
},