1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-06 00:13:28 +00:00

[PM-16984] Improve decryption code clarity (#12681)

* Improve decrypt failure logging

* Rename decryptcontext to decrypttrace

* Improve docs
This commit is contained in:
Bernd Schoolmann
2025-02-18 16:59:53 +01:00
committed by GitHub
parent 2622422cf7
commit 7a7be6088a
3 changed files with 38 additions and 65 deletions

View File

@@ -65,7 +65,6 @@ export default class Domain {
key: SymmetricCryptoKey = null, key: SymmetricCryptoKey = null,
objectContext: string = "No Domain Context", objectContext: string = "No Domain Context",
): Promise<T> { ): Promise<T> {
const promises = [];
const self: any = this; const self: any = this;
for (const prop in map) { for (const prop in map) {
@@ -74,27 +73,15 @@ export default class Domain {
continue; continue;
} }
(function (theProp) { const mapProp = map[prop] || prop;
const p = Promise.resolve() if (self[mapProp]) {
.then(() => { (viewModel as any)[prop] = await self[mapProp].decrypt(
const mapProp = map[theProp] || theProp; orgId,
if (self[mapProp]) { key,
return self[mapProp].decrypt( `Property: ${prop}; ObjectContext: ${objectContext}`,
orgId, );
key, }
`Property: ${prop}; ObjectContext: ${objectContext}`,
);
}
return null;
})
.then((val: any) => {
(viewModel as any)[theProp] = val;
});
promises.push(p);
})(prop);
} }
await Promise.all(promises);
return viewModel; return viewModel;
} }
@@ -121,22 +108,20 @@ export default class Domain {
_: Constructor<TThis> = this.constructor as Constructor<TThis>, _: Constructor<TThis> = this.constructor as Constructor<TThis>,
objectContext: string = "No Domain Context", objectContext: string = "No Domain Context",
): Promise<DecryptedObject<TThis, TEncryptedKeys>> { ): Promise<DecryptedObject<TThis, TEncryptedKeys>> {
const promises = []; const decryptedObjects = [];
for (const prop of encryptedProperties) { for (const prop of encryptedProperties) {
const value = (this as any)[prop] as EncString; const value = (this as any)[prop] as EncString;
promises.push( const decrypted = await this.decryptProperty(
this.decryptProperty( prop,
prop, value,
value, key,
key, encryptService,
encryptService, `Property: ${prop.toString()}; ObjectContext: ${objectContext}`,
`Property: ${prop.toString()}; ObjectContext: ${objectContext}`,
),
); );
decryptedObjects.push(decrypted);
} }
const decryptedObjects = await Promise.all(promises);
const decryptedObject = decryptedObjects.reduce( const decryptedObject = decryptedObjects.reduce(
(acc, obj) => { (acc, obj) => {
return { ...acc, ...obj }; return { ...acc, ...obj };

View File

@@ -12,7 +12,10 @@ import { CipherRepromptType } from "../../enums/cipher-reprompt-type";
import { CipherType } from "../../enums/cipher-type"; import { CipherType } from "../../enums/cipher-type";
import { CipherData } from "../data/cipher.data"; import { CipherData } from "../data/cipher.data";
import { LocalData } from "../data/local.data"; import { LocalData } from "../data/local.data";
import { AttachmentView } from "../view/attachment.view";
import { CipherView } from "../view/cipher.view"; import { CipherView } from "../view/cipher.view";
import { FieldView } from "../view/field.view";
import { PasswordHistoryView } from "../view/password-history.view";
import { Attachment } from "./attachment"; import { Attachment } from "./attachment";
import { Card } from "./card"; import { Card } from "./card";
@@ -136,6 +139,7 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
if (this.key != null) { if (this.key != null) {
const encryptService = Utils.getContainerService().getEncryptService(); const encryptService = Utils.getContainerService().getEncryptService();
const keyBytes = await encryptService.decryptToBytes( const keyBytes = await encryptService.decryptToBytes(
this.key, this.key,
encKey, encKey,
@@ -198,44 +202,28 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
} }
if (this.attachments != null && this.attachments.length > 0) { if (this.attachments != null && this.attachments.length > 0) {
const attachments: any[] = []; const attachments: AttachmentView[] = [];
await this.attachments.reduce((promise, attachment) => { for (const attachment of this.attachments) {
return promise attachments.push(
.then(() => { await attachment.decrypt(this.organizationId, `Cipher Id: ${this.id}`, encKey),
return attachment.decrypt(this.organizationId, `Cipher Id: ${this.id}`, encKey); );
}) }
.then((decAttachment) => {
attachments.push(decAttachment);
});
}, Promise.resolve());
model.attachments = attachments; model.attachments = attachments;
} }
if (this.fields != null && this.fields.length > 0) { if (this.fields != null && this.fields.length > 0) {
const fields: any[] = []; const fields: FieldView[] = [];
await this.fields.reduce((promise, field) => { for (const field of this.fields) {
return promise fields.push(await field.decrypt(this.organizationId, encKey));
.then(() => { }
return field.decrypt(this.organizationId, encKey);
})
.then((decField) => {
fields.push(decField);
});
}, Promise.resolve());
model.fields = fields; model.fields = fields;
} }
if (this.passwordHistory != null && this.passwordHistory.length > 0) { if (this.passwordHistory != null && this.passwordHistory.length > 0) {
const passwordHistory: any[] = []; const passwordHistory: PasswordHistoryView[] = [];
await this.passwordHistory.reduce((promise, ph) => { for (const ph of this.passwordHistory) {
return promise passwordHistory.push(await ph.decrypt(this.organizationId, encKey));
.then(() => { }
return ph.decrypt(this.organizationId, encKey);
})
.then((decPh) => {
passwordHistory.push(decPh);
});
}, Promise.resolve());
model.passwordHistory = passwordHistory; model.passwordHistory = passwordHistory;
} }

View File

@@ -368,20 +368,20 @@ export class DefaultKeyService implements KeyServiceAbstraction {
await this.stateProvider.getUser(userId, USER_ENCRYPTED_ORGANIZATION_KEYS).update(() => { await this.stateProvider.getUser(userId, USER_ENCRYPTED_ORGANIZATION_KEYS).update(() => {
const encOrgKeyData: { [orgId: string]: EncryptedOrganizationKeyData } = {}; const encOrgKeyData: { [orgId: string]: EncryptedOrganizationKeyData } = {};
orgs.forEach((org) => { for (const org of orgs) {
encOrgKeyData[org.id] = { encOrgKeyData[org.id] = {
type: "organization", type: "organization",
key: org.key, key: org.key,
}; };
}); }
providerOrgs.forEach((org) => { for (const org of providerOrgs) {
encOrgKeyData[org.id] = { encOrgKeyData[org.id] = {
type: "provider", type: "provider",
providerId: org.providerId, providerId: org.providerId,
key: org.key, key: org.key,
}; };
}); }
return encOrgKeyData; return encOrgKeyData;
}); });
} }