mirror of
https://github.com/bitwarden/browser
synced 2026-02-04 10:43:47 +00:00
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.
This commit is contained in:
@@ -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" },
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
</div>
|
||||
|
||||
<!--Passkey-->
|
||||
<div class="box" *ngIf="cipher.login.fido2Credentials[0] && !cloneMode">
|
||||
<div class="box" *ngIf="cipher.login.hasFido2Credentials && !cloneMode">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row text-muted">
|
||||
<span class="row-label">{{ "typePasskey" | i18n }}</span>
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
</div>
|
||||
|
||||
<!--Passkey-->
|
||||
<div class="box" *ngIf="cipher.login.fido2Credentials[0]">
|
||||
<div class="box" *ngIf="cipher.login.hasFido2Credentials">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row text-muted">
|
||||
<span class="row-label">{{ "typePasskey" | i18n }}</span>
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
<!--Passkey-->
|
||||
<div
|
||||
class="box-content-row text-muted"
|
||||
*ngIf="cipher.login.fido2Credentials[0] && !cloneMode"
|
||||
*ngIf="cipher.login.hasFido2Credentials && !cloneMode"
|
||||
appBoxRow
|
||||
>
|
||||
<span class="row-label">{{ "typePasskey" | i18n }}</span>
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!--Passkey-->
|
||||
<div class="box-content-row text-muted" *ngIf="cipher.login.fido2Credentials[0]">
|
||||
<div class="box-content-row text-muted" *ngIf="cipher.login.hasFido2Credentials">
|
||||
<span class="row-label">{{ "typePasskey" | i18n }}</span>
|
||||
{{ "dateCreated" | i18n }}
|
||||
{{ cipher.login.fido2Credentials[0].creationDate | date : "short" }}
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<ng-container *ngIf="cipher.login.fido2Credentials[0]">
|
||||
<ng-container *ngIf="cipher.login.hasFido2Credentials">
|
||||
<div class="row">
|
||||
<div class="col-6 form-group">
|
||||
<label for="loginFido2credential">{{ "typePasskey" | i18n }}</label>
|
||||
|
||||
@@ -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" },
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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" },
|
||||
|
||||
@@ -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: [
|
||||
{
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<string>,
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user