mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-16 10:45:20 +01:00
[EC-598] feat: add fido2Key to cipher
This commit is contained in:
parent
0225093c11
commit
cb07b2121e
@ -3,4 +3,5 @@ export enum CipherType {
|
||||
SecureNote = 2,
|
||||
Card = 3,
|
||||
Identity = 4,
|
||||
Fido2Key = 5,
|
||||
}
|
||||
|
20
libs/common/src/models/api/fido2-key.api.ts
Normal file
20
libs/common/src/models/api/fido2-key.api.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { BaseResponse } from "../response/base.response";
|
||||
|
||||
export class Fido2KeyApi extends BaseResponse {
|
||||
key: string;
|
||||
rpId: string;
|
||||
origin: string;
|
||||
userHandle: string;
|
||||
|
||||
constructor(data: any = null) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.key = this.getResponseProperty("Key");
|
||||
this.rpId = this.getResponseProperty("RpId");
|
||||
this.origin = this.getResponseProperty("Origin");
|
||||
this.userHandle = this.getResponseProperty("UserHandle");
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import { CipherResponse } from "../response/cipher.response";
|
||||
|
||||
import { AttachmentData } from "./attachment.data";
|
||||
import { CardData } from "./card.data";
|
||||
import { Fido2KeyData } from "./fido2-key.data";
|
||||
import { FieldData } from "./field.data";
|
||||
import { IdentityData } from "./identity.data";
|
||||
import { LoginData } from "./login.data";
|
||||
@ -26,6 +27,7 @@ export class CipherData {
|
||||
secureNote?: SecureNoteData;
|
||||
card?: CardData;
|
||||
identity?: IdentityData;
|
||||
fido2Key?: Fido2KeyData;
|
||||
fields?: FieldData[];
|
||||
attachments?: AttachmentData[];
|
||||
passwordHistory?: PasswordHistoryData[];
|
||||
@ -68,6 +70,9 @@ export class CipherData {
|
||||
case CipherType.Identity:
|
||||
this.identity = new IdentityData(response.identity);
|
||||
break;
|
||||
case CipherType.Fido2Key:
|
||||
this.fido2Key = new Fido2KeyData(response.fido2Key);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
19
libs/common/src/models/data/fido2-key.data.ts
Normal file
19
libs/common/src/models/data/fido2-key.data.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { Fido2KeyApi } from "../api/fido2-key.api";
|
||||
|
||||
export class Fido2KeyData {
|
||||
key: string;
|
||||
rpId: string;
|
||||
origin: string;
|
||||
userHandle: string;
|
||||
|
||||
constructor(data?: Fido2KeyApi) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.key = data.key;
|
||||
this.rpId = data.rpId;
|
||||
this.origin = data.origin;
|
||||
this.userHandle = data.userHandle;
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ import { Attachment } from "./attachment";
|
||||
import { Card } from "./card";
|
||||
import Domain from "./domain-base";
|
||||
import { EncString } from "./enc-string";
|
||||
import { Fido2Key } from "./fido2-key";
|
||||
import { Field } from "./field";
|
||||
import { Identity } from "./identity";
|
||||
import { Login } from "./login";
|
||||
@ -38,6 +39,7 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
|
||||
identity: Identity;
|
||||
card: Card;
|
||||
secureNote: SecureNote;
|
||||
fido2Key: Fido2Key;
|
||||
attachments: Attachment[];
|
||||
fields: Field[];
|
||||
passwordHistory: Password[];
|
||||
@ -94,6 +96,9 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
|
||||
case CipherType.Identity:
|
||||
this.identity = new Identity(obj.identity);
|
||||
break;
|
||||
case CipherType.Fido2Key:
|
||||
this.fido2Key = new Fido2Key(obj.fido2Key);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -143,6 +148,9 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
|
||||
case CipherType.Identity:
|
||||
model.identity = await this.identity.decrypt(this.organizationId, encKey);
|
||||
break;
|
||||
case CipherType.Fido2Key:
|
||||
model.fido2Key = await this.fido2Key.decrypt(this.organizationId, encKey);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -228,6 +236,9 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
|
||||
case CipherType.Identity:
|
||||
c.identity = this.identity.toIdentityData();
|
||||
break;
|
||||
case CipherType.Fido2Key:
|
||||
c.fido2Key = this.fido2Key.toFido2KeyData();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -281,6 +292,9 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
|
||||
case CipherType.SecureNote:
|
||||
domain.secureNote = SecureNote.fromJSON(obj.secureNote);
|
||||
break;
|
||||
case CipherType.Fido2Key:
|
||||
domain.fido2Key = Fido2Key.fromJSON(obj.fido2Key);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
78
libs/common/src/models/domain/fido2-key.ts
Normal file
78
libs/common/src/models/domain/fido2-key.ts
Normal file
@ -0,0 +1,78 @@
|
||||
import { Jsonify } from "type-fest";
|
||||
|
||||
import { Fido2KeyData } from "../data/fido2-key.data";
|
||||
import { Fido2KeyView } from "../view/fido2-key.view";
|
||||
|
||||
import Domain from "./domain-base";
|
||||
import { EncString } from "./enc-string";
|
||||
import { SymmetricCryptoKey } from "./symmetric-crypto-key";
|
||||
|
||||
export class Fido2Key extends Domain {
|
||||
key: EncString; // PCKS#8
|
||||
rpId: EncString;
|
||||
origin: EncString;
|
||||
userHandle: EncString;
|
||||
// extensions: Record<string, unknown>;
|
||||
|
||||
constructor(obj?: Fido2KeyData) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(
|
||||
this,
|
||||
obj,
|
||||
{
|
||||
key: null,
|
||||
rpId: null,
|
||||
origin: null,
|
||||
userHandle: null,
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<Fido2KeyView> {
|
||||
return this.decryptObj(
|
||||
new Fido2KeyView(),
|
||||
{
|
||||
key: null,
|
||||
rpId: null,
|
||||
origin: null,
|
||||
userHandle: null,
|
||||
},
|
||||
orgId,
|
||||
encKey
|
||||
);
|
||||
}
|
||||
|
||||
toFido2KeyData(): Fido2KeyData {
|
||||
const i = new Fido2KeyData();
|
||||
this.buildDataModel(this, i, {
|
||||
key: null,
|
||||
rpId: null,
|
||||
origin: null,
|
||||
userHandle: null,
|
||||
});
|
||||
return i;
|
||||
}
|
||||
|
||||
static fromJSON(obj: Jsonify<Fido2Key>): Fido2Key {
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const key = EncString.fromJSON(obj.key);
|
||||
const rpId = EncString.fromJSON(obj.rpId);
|
||||
const origin = EncString.fromJSON(obj.origin);
|
||||
const userHandle = EncString.fromJSON(obj.userHandle);
|
||||
|
||||
return Object.assign(new Fido2Key(), obj, {
|
||||
key,
|
||||
rpId,
|
||||
origin,
|
||||
userHandle,
|
||||
});
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import { CipherRepromptType } from "../../enums/cipherRepromptType";
|
||||
import { CardApi } from "../api/card.api";
|
||||
import { Fido2KeyApi } from "../api/fido2-key.api";
|
||||
import { FieldApi } from "../api/field.api";
|
||||
import { IdentityApi } from "../api/identity.api";
|
||||
import { LoginApi } from "../api/login.api";
|
||||
@ -21,6 +22,7 @@ export class CipherResponse extends BaseResponse {
|
||||
card: CardApi;
|
||||
identity: IdentityApi;
|
||||
secureNote: SecureNoteApi;
|
||||
fido2Key: Fido2KeyApi;
|
||||
favorite: boolean;
|
||||
edit: boolean;
|
||||
viewPassword: boolean;
|
||||
@ -74,6 +76,11 @@ export class CipherResponse extends BaseResponse {
|
||||
this.secureNote = new SecureNoteApi(secureNote);
|
||||
}
|
||||
|
||||
const fido2Key = this.getResponseProperty("Fido2Key");
|
||||
if (fido2Key != null) {
|
||||
this.fido2Key = new Fido2KeyApi(fido2Key);
|
||||
}
|
||||
|
||||
const fields = this.getResponseProperty("Fields");
|
||||
if (fields != null) {
|
||||
this.fields = fields.map((f: any) => new FieldApi(f));
|
||||
|
@ -10,6 +10,7 @@ import { Cipher } from "../domain/cipher";
|
||||
|
||||
import { AttachmentView } from "./attachment.view";
|
||||
import { CardView } from "./card.view";
|
||||
import { Fido2KeyView } from "./fido2-key.view";
|
||||
import { FieldView } from "./field.view";
|
||||
import { IdentityView } from "./identity.view";
|
||||
import { LoginView } from "./login.view";
|
||||
@ -35,6 +36,7 @@ export class CipherView implements View, InitializerMetadata {
|
||||
identity = new IdentityView();
|
||||
card = new CardView();
|
||||
secureNote = new SecureNoteView();
|
||||
fido2Key = new Fido2KeyView();
|
||||
attachments: AttachmentView[] = null;
|
||||
fields: FieldView[] = null;
|
||||
passwordHistory: PasswordHistoryView[] = null;
|
||||
|
7
libs/common/src/models/view/fido2-key.view.ts
Normal file
7
libs/common/src/models/view/fido2-key.view.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export class Fido2KeyView {
|
||||
id: string;
|
||||
key: string;
|
||||
rpId: string;
|
||||
origin: string;
|
||||
userHandle: string;
|
||||
}
|
@ -84,7 +84,7 @@ export class Fido2Service implements Fido2ServiceAbstraction {
|
||||
})
|
||||
);
|
||||
|
||||
this.credentials.set(credentialId.encoded, {
|
||||
await this.saveCredential({
|
||||
credentialId,
|
||||
keyPair,
|
||||
origin: params.origin,
|
||||
@ -170,6 +170,10 @@ export class Fido2Service implements Fido2ServiceAbstraction {
|
||||
return credential;
|
||||
}
|
||||
|
||||
private async saveCredential(credential: BitCredential): Promise<void> {
|
||||
this.credentials.set(credential.credentialId.encoded, credential);
|
||||
}
|
||||
|
||||
private getCredentialByRp(rpId: string): BitCredential | undefined {
|
||||
for (const credential of this.credentials.values()) {
|
||||
if (credential.rpId === rpId) {
|
||||
|
Loading…
Reference in New Issue
Block a user