1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-15 15:53:27 +00:00

[PM-18243] Improve type safety in decryption (#12885)

* Improve decrypt failure logging

* Rename decryptcontext to decrypttrace

* Improve docs

* PM-16984: Improving type safety of decryption

* Improving type safety of decryption

---------

Co-authored-by: Bernd Schoolmann <mail@quexten.com>
This commit is contained in:
Maciej Zieniuk
2025-03-11 14:06:44 +01:00
committed by GitHub
parent 7e6f2fa798
commit 5cd47ac907
18 changed files with 111 additions and 154 deletions

View File

@@ -43,11 +43,10 @@ export class Attachment extends Domain {
context = "No Cipher Context",
encKey?: SymmetricCryptoKey,
): Promise<AttachmentView> {
const view = await this.decryptObj(
const view = await this.decryptObj<Attachment, AttachmentView>(
this,
new AttachmentView(this),
{
fileName: null,
},
["fileName"],
orgId,
encKey,
"DomainType: Attachment; " + context,

View File

@@ -42,16 +42,10 @@ export class Card extends Domain {
context = "No Cipher Context",
encKey?: SymmetricCryptoKey,
): Promise<CardView> {
return this.decryptObj(
return this.decryptObj<Card, CardView>(
this,
new CardView(),
{
cardholderName: null,
brand: null,
number: null,
expMonth: null,
expYear: null,
code: null,
},
["cardholderName", "brand", "number", "expMonth", "expYear", "code"],
orgId,
encKey,
"DomainType: Card; " + context,

View File

@@ -154,12 +154,10 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
bypassValidation = false;
}
await this.decryptObj(
await this.decryptObj<Cipher, CipherView>(
this,
model,
{
name: null,
notes: null,
},
["name", "notes"],
this.organizationId,
encKey,
);

View File

@@ -52,41 +52,38 @@ export class Fido2Credential extends Domain {
}
async decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<Fido2CredentialView> {
const view = await this.decryptObj(
const view = await this.decryptObj<Fido2Credential, Fido2CredentialView>(
this,
new Fido2CredentialView(),
{
credentialId: null,
keyType: null,
keyAlgorithm: null,
keyCurve: null,
keyValue: null,
rpId: null,
userHandle: null,
userName: null,
rpName: null,
userDisplayName: null,
discoverable: null,
},
[
"credentialId",
"keyType",
"keyAlgorithm",
"keyCurve",
"keyValue",
"rpId",
"userHandle",
"userName",
"rpName",
"userDisplayName",
],
orgId,
encKey,
);
const { counter } = await this.decryptObj(
{ counter: "" },
const { counter } = await this.decryptObj<
Fido2Credential,
{
counter: null,
},
orgId,
encKey,
);
counter: string;
}
>(this, { counter: "" }, ["counter"], orgId, encKey);
// Counter will end up as NaN if this fails
view.counter = parseInt(counter);
const { discoverable } = await this.decryptObj(
const { discoverable } = await this.decryptObj<Fido2Credential, { discoverable: string }>(
this,
{ discoverable: "" },
{
discoverable: null,
},
["discoverable"],
orgId,
encKey,
);

View File

@@ -35,12 +35,10 @@ export class Field extends Domain {
}
decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<FieldView> {
return this.decryptObj(
return this.decryptObj<Field, FieldView>(
this,
new FieldView(this),
{
name: null,
value: null,
},
["name", "value"],
orgId,
encKey,
);

View File

@@ -40,13 +40,7 @@ export class Folder extends Domain {
}
decrypt(): Promise<FolderView> {
return this.decryptObj(
new FolderView(this),
{
name: null,
},
null,
);
return this.decryptObj<Folder, FolderView>(this, new FolderView(this), ["name"], null);
}
async decryptWithKey(

View File

@@ -66,28 +66,29 @@ export class Identity extends Domain {
context: string = "No Cipher Context",
encKey?: SymmetricCryptoKey,
): Promise<IdentityView> {
return this.decryptObj(
return this.decryptObj<Identity, IdentityView>(
this,
new IdentityView(),
{
title: null,
firstName: null,
middleName: null,
lastName: null,
address1: null,
address2: null,
address3: null,
city: null,
state: null,
postalCode: null,
country: null,
company: null,
email: null,
phone: null,
ssn: null,
username: null,
passportNumber: null,
licenseNumber: null,
},
[
"title",
"firstName",
"middleName",
"lastName",
"address1",
"address2",
"address3",
"city",
"state",
"postalCode",
"country",
"company",
"email",
"phone",
"ssn",
"username",
"passportNumber",
"licenseNumber",
],
orgId,
encKey,
"DomainType: Identity; " + context,

View File

@@ -38,11 +38,10 @@ export class LoginUri extends Domain {
context: string = "No Cipher Context",
encKey?: SymmetricCryptoKey,
): Promise<LoginUriView> {
return this.decryptObj(
return this.decryptObj<LoginUri, LoginUriView>(
this,
new LoginUriView(this),
{
uri: null,
},
["uri"],
orgId,
encKey,
context,

View File

@@ -58,13 +58,10 @@ export class Login extends Domain {
context: string = "No Cipher Context",
encKey?: SymmetricCryptoKey,
): Promise<LoginView> {
const view = await this.decryptObj(
const view = await this.decryptObj<Login, LoginView>(
this,
new LoginView(this),
{
username: null,
password: null,
totp: null,
},
["username", "password", "totp"],
orgId,
encKey,
`DomainType: Login; ${context}`,

View File

@@ -25,11 +25,10 @@ export class Password extends Domain {
}
decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<PasswordHistoryView> {
return this.decryptObj(
return this.decryptObj<Password, PasswordHistoryView>(
this,
new PasswordHistoryView(this),
{
password: null,
},
["password"],
orgId,
encKey,
"DomainType: PasswordHistory",

View File

@@ -36,13 +36,10 @@ export class SshKey extends Domain {
context = "No Cipher Context",
encKey?: SymmetricCryptoKey,
): Promise<SshKeyView> {
return this.decryptObj(
return this.decryptObj<SshKey, SshKeyView>(
this,
new SshKeyView(),
{
privateKey: null,
publicKey: null,
keyFingerprint: null,
},
["privateKey", "publicKey", "keyFingerprint"],
orgId,
encKey,
"DomainType: SshKey; " + context,