mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
[PM-12423] Migrate Cipher Decryption to Use SDK (#14206)
* Created mappings for client domain object to SDK * Add abstract decrypt observable * Added todo for future consideration * Added implementation to cipher service * Added adapter and unit tests * Created cipher encryption abstraction and service * Register cipher encryption service * Added tests for the cipher encryption service * changed signature * Updated feature flag name * added new function to be used for decrypting ciphers * Added new encryptedKey field * added new function to be used for decrypting ciphers * Manually set fields * Added encrypted key in attachment view * Fixed test * Updated references to use decrypt with feature flag * Added dependency * updated package.json * lint fix * fixed tests * Fixed small mapping issues * Fixed test * Added function to decrypt fido2 key value * Added function to decrypt fido2 key value and updated test * updated to use sdk function without prociding the key * updated localdata sdk type change * decrypt attachment content using sdk * Fixed dependency issues * updated package.json * Refactored service to handle getting decrypted buffer using the legacy and sdk implementations * updated services and component to use refactored version * Updated decryptCiphersWithSdk to use decryptManyLegacy for batch decryption, ensuring the SDK is only called once per batch * Fixed merge conflicts * Fixed merge conflicts * Fixed merge conflicts * Fixed lint issues * Moved getDecryptedAttachmentBuffer to cipher service * Moved getDecryptedAttachmentBuffer to cipher service * ensure CipherView properties are null instead of undefined * Fixed test * ensure AttachmentView properties are null instead of undefined * Linked ticket in comment * removed unused orgKey
This commit is contained in:
@@ -10,7 +10,7 @@ import { EncryptService } from "@bitwarden/common/key-management/crypto/abstract
|
||||
import { CipherWithIdExport } from "@bitwarden/common/models/export/cipher-with-ids.export";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { EncryptedString, EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { CipherId, UserId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
@@ -172,6 +172,8 @@ describe("VaultExportService", () => {
|
||||
let apiService: MockProxy<ApiService>;
|
||||
let fetchMock: jest.Mock;
|
||||
|
||||
const userId = "" as UserId;
|
||||
|
||||
beforeEach(() => {
|
||||
cryptoFunctionService = mock<CryptoFunctionService>();
|
||||
cipherService = mock<CipherService>();
|
||||
@@ -185,7 +187,6 @@ describe("VaultExportService", () => {
|
||||
|
||||
keyService.userKey$.mockReturnValue(new BehaviorSubject("mockOriginalUserKey" as any));
|
||||
|
||||
const userId = "" as UserId;
|
||||
const accountInfo: AccountInfo = {
|
||||
email: "",
|
||||
emailVerified: true,
|
||||
@@ -338,7 +339,9 @@ describe("VaultExportService", () => {
|
||||
|
||||
cipherService.getAllDecrypted.mockResolvedValue([cipherView]);
|
||||
folderService.getAllDecryptedFromState.mockResolvedValue([]);
|
||||
encryptService.decryptFileData.mockResolvedValue(new Uint8Array(255));
|
||||
cipherService.getDecryptedAttachmentBuffer.mockRejectedValue(
|
||||
new Error("Error decrypting attachment"),
|
||||
);
|
||||
|
||||
global.fetch = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
@@ -356,13 +359,17 @@ describe("VaultExportService", () => {
|
||||
it("contains attachments with folders", async () => {
|
||||
const cipherData = new CipherData();
|
||||
cipherData.id = "mock-id";
|
||||
const cipherRecord: Record<CipherId, CipherData> = {
|
||||
["mock-id" as CipherId]: cipherData,
|
||||
};
|
||||
const cipherView = new CipherView(new Cipher(cipherData));
|
||||
const attachmentView = new AttachmentView(new Attachment(new AttachmentData()));
|
||||
attachmentView.fileName = "mock-file-name";
|
||||
cipherView.attachments = [attachmentView];
|
||||
cipherService.ciphers$.mockReturnValue(of(cipherRecord));
|
||||
cipherService.getAllDecrypted.mockResolvedValue([cipherView]);
|
||||
folderService.getAllDecryptedFromState.mockResolvedValue([]);
|
||||
encryptService.decryptFileData.mockResolvedValue(new Uint8Array(255));
|
||||
cipherService.getDecryptedAttachmentBuffer.mockResolvedValue(new Uint8Array(255));
|
||||
global.fetch = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
status: 200,
|
||||
|
||||
@@ -12,14 +12,12 @@ import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/a
|
||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||
import { CipherWithIdExport, FolderWithIdExport } from "@bitwarden/common/models/export";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { CipherId, UserId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
|
||||
import { Folder } from "@bitwarden/common/vault/models/domain/folder";
|
||||
import { AttachmentView } from "@bitwarden/common/vault/models/view/attachment.view";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
|
||||
import { KdfConfigService, KeyService } from "@bitwarden/key-management";
|
||||
@@ -118,8 +116,19 @@ export class IndividualVaultExportService
|
||||
const cipherFolder = attachmentsFolder.folder(cipher.id);
|
||||
for (const attachment of cipher.attachments) {
|
||||
const response = await this.downloadAttachment(cipher.id, attachment.id);
|
||||
const decBuf = await this.decryptAttachment(cipher, attachment, response);
|
||||
cipherFolder.file(attachment.fileName, decBuf);
|
||||
|
||||
try {
|
||||
const decBuf = await this.cipherService.getDecryptedAttachmentBuffer(
|
||||
cipher.id as CipherId,
|
||||
attachment,
|
||||
response,
|
||||
activeUserId,
|
||||
);
|
||||
|
||||
cipherFolder.file(attachment.fileName, decBuf);
|
||||
} catch {
|
||||
throw new Error("Error decrypting attachment");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,23 +155,6 @@ export class IndividualVaultExportService
|
||||
return response;
|
||||
}
|
||||
|
||||
private async decryptAttachment(
|
||||
cipher: CipherView,
|
||||
attachment: AttachmentView,
|
||||
response: Response,
|
||||
) {
|
||||
try {
|
||||
const encBuf = await EncArrayBuffer.fromResponse(response);
|
||||
const key =
|
||||
attachment.key != null
|
||||
? attachment.key
|
||||
: await this.keyService.getOrgKey(cipher.organizationId);
|
||||
return await this.encryptService.decryptFileData(encBuf, key);
|
||||
} catch {
|
||||
throw new Error("Error decrypting attachment");
|
||||
}
|
||||
}
|
||||
|
||||
private async getDecryptedExport(
|
||||
activeUserId: UserId,
|
||||
format: "json" | "csv",
|
||||
|
||||
@@ -155,12 +155,9 @@ export class OrganizationVaultExportService
|
||||
.forEach(async (c) => {
|
||||
const cipher = new Cipher(new CipherData(c));
|
||||
exportPromises.push(
|
||||
this.cipherService
|
||||
.getKeyForCipherKeyDecryption(cipher, activeUserId)
|
||||
.then((key) => cipher.decrypt(key))
|
||||
.then((decCipher) => {
|
||||
decCiphers.push(decCipher);
|
||||
}),
|
||||
this.cipherService.decrypt(cipher, activeUserId).then((decCipher) => {
|
||||
decCiphers.push(decCipher);
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user