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:
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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> = {}) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user