1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-31 08:43:54 +00:00

Remove decrypt from encstring

This commit is contained in:
Bernd Schoolmann
2025-12-08 19:13:33 +01:00
parent 39cef3b640
commit ed35d899e3
4 changed files with 11 additions and 104 deletions

View File

@@ -33,7 +33,6 @@ export function BuildTestObject<T, K extends keyof T = keyof T>(
export function mockEnc(s: string): MockProxy<EncString> {
const mocked = mock<EncString>();
mocked.decryptedValue = s;
mocked.decrypt.mockResolvedValue(s);
return mocked;
}

View File

@@ -1,4 +1,4 @@
import { mock, MockProxy } from "jest-mock-extended";
import { mock } from "jest-mock-extended";
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
// eslint-disable-next-line no-restricted-imports
@@ -8,7 +8,7 @@ import { makeStaticByteArray } from "../../../../spec";
import { EncryptionType } from "../../../platform/enums";
import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key";
import { ContainerService } from "../../../platform/services/container.service";
import { UserKey, OrgKey } from "../../../types/key";
import { UserKey } from "../../../types/key";
import { EncryptService } from "../abstractions/encrypt.service";
import { EncString } from "./enc-string";
@@ -249,66 +249,6 @@ describe("EncString", () => {
});
});
describe("decrypt", () => {
let keyService: MockProxy<KeyService>;
let encryptService: MockProxy<EncryptService>;
let encString: EncString;
beforeEach(() => {
keyService = mock<KeyService>();
encryptService = mock<EncryptService>();
encString = new EncString(null);
(window as any).bitwardenContainerService = new ContainerService(keyService, encryptService);
});
it("handles value it can't decrypt", async () => {
encryptService.decryptString.mockRejectedValue("error");
(window as any).bitwardenContainerService = new ContainerService(keyService, encryptService);
const decrypted = await encString.decrypt(null);
expect(decrypted).toBe("[error: cannot decrypt]");
expect(encString).toEqual({
decryptedValue: "[error: cannot decrypt]",
encryptedString: null,
});
});
it("uses provided key without depending on KeyService", async () => {
const key = mock<SymmetricCryptoKey>();
await encString.decrypt(null, key);
expect(keyService.getUserKey).not.toHaveBeenCalled();
expect(encryptService.decryptString).toHaveBeenCalledWith(encString, key);
});
it("gets an organization key if required", async () => {
const orgKey = mock<OrgKey>();
keyService.getOrgKey.calledWith("orgId").mockResolvedValue(orgKey);
await encString.decrypt("orgId", null);
expect(keyService.getOrgKey).toHaveBeenCalledWith("orgId");
expect(encryptService.decryptString).toHaveBeenCalledWith(encString, orgKey);
});
it("gets the user's decryption key if required", async () => {
const userKey = mock<UserKey>();
keyService.getUserKey.mockResolvedValue(userKey);
await encString.decrypt(null, null);
expect(keyService.getUserKey).toHaveBeenCalledWith();
expect(encryptService.decryptString).toHaveBeenCalledWith(encString, userKey);
});
});
describe("toJSON", () => {
it("Should be represented by the encrypted string", () => {
const encString = new EncString(EncryptionType.AesCbc256_B64, "data", "iv");

View File

@@ -6,7 +6,6 @@ import { EncString as SdkEncString } from "@bitwarden/sdk-internal";
import { EncryptionType, EXPECTED_NUM_PARTS_BY_ENCRYPTION_TYPE } from "../../../platform/enums";
import { Utils } from "../../../platform/misc/utils";
import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key";
export const DECRYPT_ERROR = "[error: cannot decrypt]";
@@ -156,46 +155,6 @@ export class EncString {
return EXPECTED_NUM_PARTS_BY_ENCRYPTION_TYPE[encType] === encPieces.length;
}
/**
* @deprecated - This function is deprecated. Use EncryptService.decryptString instead.
* @returns - The decrypted string, or `[error: cannot decrypt]` if decryption fails.
*/
async decrypt(
orgId: string | null,
key: SymmetricCryptoKey | null = null,
context?: string,
): Promise<string> {
if (this.decryptedValue != null) {
return this.decryptedValue;
}
try {
if (key == null) {
key = await this.getKeyForDecryption(orgId);
}
if (key == null) {
throw new Error("No key to decrypt EncString with orgId " + orgId);
}
const encryptService = Utils.getContainerService().getEncryptService();
this.decryptedValue = await encryptService.decryptString(this, key);
} catch (e) {
// eslint-disable-next-line no-console
console.error(
"[EncString Generic Decrypt] failed to decrypt encstring. Context: " +
(context ?? "No context"),
e,
);
this.decryptedValue = DECRYPT_ERROR;
}
return this.decryptedValue;
}
private async getKeyForDecryption(orgId: string) {
const keyService = Utils.getContainerService().getKeyService();
return orgId != null ? await keyService.getOrgKey(orgId) : await keyService.getUserKey();
}
}
/**

View File

@@ -124,6 +124,15 @@ describe("Send", () => {
encryptService.decryptBytes
.calledWith(send.key, userKey)
.mockResolvedValue(makeStaticByteArray(32));
encryptService.decryptString.mockImplementation((encString: any) => {
if (encString === send.name) {
return Promise.resolve("name");
}
if (encString === send.notes) {
return Promise.resolve("notes");
}
return Promise.resolve(null);
});
keyService.makeSendKey.mockResolvedValue("cryptoKey" as any);
keyService.userKey$.calledWith(userId).mockReturnValue(of(userKey));