1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-15 07:54:55 +00:00

Merge branch 'km/encstring-remove-decrypt-vault' into km/decrypt-obj

This commit is contained in:
Bernd Schoolmann
2025-10-29 18:47:19 +01:00
16 changed files with 85 additions and 64 deletions

View File

@@ -2,7 +2,10 @@
// @ts-strict-ignore
import { mock, MockProxy } from "jest-mock-extended";
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string";
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
import { KeyService } from "@bitwarden/key-management";
import { EncryptionType } from "../src/platform/enums";
import { Utils } from "../src/platform/misc/utils";
@@ -29,7 +32,7 @@ export function BuildTestObject<T, K extends keyof T = keyof T>(
export function mockEnc(s: string): MockProxy<EncString> {
const mocked = mock<EncString>();
mocked.decrypt.mockResolvedValue(s);
mocked.decryptedValue = s;
return mocked;
}
@@ -77,4 +80,14 @@ export const mockFromSdk = (stub: any) => {
return `${stub}_fromSdk`;
};
export const mockContainerService = () => {
const keyService = mock<KeyService>();
const encryptService = mock<EncryptService>();
encryptService.decryptString.mockImplementation(async (encStr, _key) => {
return encStr.decryptedValue;
});
(window as any).bitwardenContainerService = new ContainerService(keyService, encryptService);
return (window as any).bitwardenContainerService;
};
export { trackEmissions, awaitAsync } from "@bitwarden/core-test-utils";

View File

@@ -130,12 +130,7 @@ describe("Send", () => {
const view = await send.decrypt(userId);
expect(text.decrypt).toHaveBeenNthCalledWith(1, "cryptoKey");
expect(send.name.decrypt).toHaveBeenNthCalledWith(
1,
null,
"cryptoKey",
"Property: name; ObjectContext: No Domain Context",
);
expect(encryptService.decryptString).toHaveBeenNthCalledWith(1, send.name, "cryptoKey");
expect(view).toMatchObject({
id: "id",

View File

@@ -4,12 +4,10 @@ import { mock, MockProxy } from "jest-mock-extended";
// eslint-disable-next-line no-restricted-imports
import { KeyService } from "@bitwarden/key-management";
import { makeStaticByteArray, mockEnc, mockFromJson } from "../../../../spec";
import { makeStaticByteArray, mockContainerService, mockEnc, mockFromJson } from "../../../../spec";
import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service";
import { EncryptedString, EncString } from "../../../key-management/crypto/models/enc-string";
import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key";
import { ContainerService } from "../../../platform/services/container.service";
import { UserKey } from "../../../types/key";
import { AttachmentData } from "../../models/data/attachment.data";
import { Attachment } from "../../models/domain/attachment";
@@ -64,10 +62,9 @@ describe("Attachment", () => {
let encryptService: MockProxy<EncryptService>;
beforeEach(() => {
keyService = mock<KeyService>();
encryptService = mock<EncryptService>();
(window as any).bitwardenContainerService = new ContainerService(keyService, encryptService);
const containerService = mockContainerService();
keyService = containerService.keyService as MockProxy<KeyService>;
encryptService = containerService.encryptService as MockProxy<EncryptService>;
});
it("expected output", async () => {
@@ -79,14 +76,13 @@ describe("Attachment", () => {
attachment.key = mockEnc("key");
attachment.fileName = mockEnc("fileName");
const userKey = new SymmetricCryptoKey(makeStaticByteArray(64));
keyService.getUserKey.mockResolvedValue(userKey as UserKey);
encryptService.decryptFileData.mockResolvedValue(makeStaticByteArray(32));
encryptService.unwrapSymmetricKey.mockResolvedValue(
new SymmetricCryptoKey(makeStaticByteArray(64)),
);
const view = await attachment.decrypt(null);
const userKey = new SymmetricCryptoKey(makeStaticByteArray(64));
const view = await attachment.decrypt(userKey);
expect(view).toEqual({
id: "id",

View File

@@ -1,4 +1,9 @@
import { mockEnc, mockFromJson } from "../../../../spec";
import {
makeSymmetricCryptoKey,
mockContainerService,
mockEnc,
mockFromJson,
} from "../../../../spec";
import { EncryptedString, EncString } from "../../../key-management/crypto/models/enc-string";
import { CardData } from "../../../vault/models/data/card.data";
import { Card } from "../../models/domain/card";
@@ -58,7 +63,10 @@ describe("Card", () => {
card.expYear = mockEnc("expYear");
card.code = mockEnc("code");
const view = await card.decrypt(null);
const userKey = makeSymmetricCryptoKey(64);
mockContainerService();
const view = await card.decrypt(userKey);
expect(view).toEqual({
_brand: "brand",

View File

@@ -2,9 +2,7 @@ import { mock } from "jest-mock-extended";
import { Jsonify } from "type-fest";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
// 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
import { KeyService } from "@bitwarden/key-management";
import { MockProxy } from "@bitwarden/common/platform/spec/mock-deep";
import {
CipherType as SdkCipherType,
UriMatchType,
@@ -14,11 +12,15 @@ import {
EncString as SdkEncString,
} from "@bitwarden/sdk-internal";
import { makeStaticByteArray, mockEnc, mockFromJson } from "../../../../spec/utils";
import {
makeStaticByteArray,
mockContainerService,
mockEnc,
mockFromJson,
} from "../../../../spec/utils";
import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service";
import { EncString } from "../../../key-management/crypto/models/enc-string";
import { UriMatchStrategy } from "../../../models/domain/domain-service";
import { ContainerService } from "../../../platform/services/container.service";
import { InitializerKey } from "../../../platform/services/cryptography/initializer-key";
import { UserId } from "../../../types/guid";
import { CipherService } from "../../abstractions/cipher.service";
@@ -42,6 +44,13 @@ import { CipherPermissionsApi } from "../api/cipher-permissions.api";
const mockSymmetricKey = new SymmetricCryptoKey(makeStaticByteArray(64));
describe("Cipher DTO", () => {
let encryptService: MockProxy<EncryptService>;
beforeEach(() => {
const containerService = mockContainerService();
encryptService = containerService.encryptService;
});
it("Convert from empty CipherData", () => {
const data = new CipherData();
const cipher = new Cipher(data);
@@ -97,8 +106,6 @@ describe("Cipher DTO", () => {
login.decrypt.mockResolvedValue(loginView);
cipher.login = login;
const keyService = mock<KeyService>();
const encryptService = mock<EncryptService>();
const cipherService = mock<CipherService>();
encryptService.unwrapSymmetricKey.mockRejectedValue(new Error("Failed to unwrap key"));
@@ -106,8 +113,6 @@ describe("Cipher DTO", () => {
new SymmetricCryptoKey(makeStaticByteArray(64)),
);
(window as any).bitwardenContainerService = new ContainerService(keyService, encryptService);
const cipherView = await cipher.decrypt(
await cipherService.getKeyForCipherKeyDecryption(cipher, mockUserId),
);
@@ -322,15 +327,10 @@ describe("Cipher DTO", () => {
login.decrypt.mockResolvedValue(loginView);
cipher.login = login;
const keyService = mock<KeyService>();
const encryptService = mock<EncryptService>();
encryptService.unwrapSymmetricKey.mockResolvedValue(
new SymmetricCryptoKey(makeStaticByteArray(64)),
);
(window as any).bitwardenContainerService = new ContainerService(keyService, encryptService);
const cipherView = await cipher.decrypt(mockSymmetricKey);
expect(cipherView).toMatchObject({
@@ -447,15 +447,10 @@ describe("Cipher DTO", () => {
cipher.permissions = new CipherPermissionsApi();
cipher.archivedDate = undefined;
const keyService = mock<KeyService>();
const encryptService = mock<EncryptService>();
encryptService.unwrapSymmetricKey.mockResolvedValue(
new SymmetricCryptoKey(makeStaticByteArray(64)),
);
(window as any).bitwardenContainerService = new ContainerService(keyService, encryptService);
const cipherView = await cipher.decrypt(mockSymmetricKey);
expect(cipherView).toMatchObject({
@@ -590,15 +585,10 @@ describe("Cipher DTO", () => {
card.decrypt.mockResolvedValue(cardView);
cipher.card = card;
const keyService = mock<KeyService>();
const encryptService = mock<EncryptService>();
encryptService.unwrapSymmetricKey.mockResolvedValue(
new SymmetricCryptoKey(makeStaticByteArray(64)),
);
(window as any).bitwardenContainerService = new ContainerService(keyService, encryptService);
const cipherView = await cipher.decrypt(mockSymmetricKey);
expect(cipherView).toMatchObject({
@@ -757,15 +747,10 @@ describe("Cipher DTO", () => {
identity.decrypt.mockResolvedValue(identityView);
cipher.identity = identity;
const keyService = mock<KeyService>();
const encryptService = mock<EncryptService>();
encryptService.unwrapSymmetricKey.mockResolvedValue(
new SymmetricCryptoKey(makeStaticByteArray(64)),
);
(window as any).bitwardenContainerService = new ContainerService(keyService, encryptService);
const cipherView = await cipher.decrypt(mockSymmetricKey);
expect(cipherView).toMatchObject({

View File

@@ -1,4 +1,4 @@
import { mockEnc } from "../../../../spec";
import { makeSymmetricCryptoKey, mockContainerService, mockEnc } from "../../../../spec";
import { EncString } from "../../../key-management/crypto/models/enc-string";
import { EncryptionType } from "../../../platform/enums";
import { Fido2CredentialData } from "../data/fido2-credential.data";
@@ -103,7 +103,10 @@ describe("Fido2Credential", () => {
credential.discoverable = mockEnc("true");
credential.creationDate = mockDate;
const credentialView = await credential.decrypt(null);
mockContainerService();
const cipherKey = makeSymmetricCryptoKey(64);
const credentialView = await credential.decrypt(cipherKey);
expect(credentialView).toEqual({
credentialId: "credentialId",

View File

@@ -6,7 +6,7 @@ import {
IdentityLinkedIdType,
} from "@bitwarden/sdk-internal";
import { mockEnc, mockFromJson } from "../../../../spec";
import { mockContainerService, mockEnc, mockFromJson } from "../../../../spec";
import { EncryptedString, EncString } from "../../../key-management/crypto/models/enc-string";
import { CardLinkedId, IdentityLinkedId, LoginLinkedId } from "../../enums";
import { FieldData } from "../../models/data/field.data";
@@ -22,6 +22,7 @@ describe("Field", () => {
value: "encValue",
linkedId: null,
};
mockContainerService();
});
it("Convert from empty", () => {

View File

@@ -1,6 +1,12 @@
import { mock, MockProxy } from "jest-mock-extended";
import { makeEncString, makeSymmetricCryptoKey, mockEnc, mockFromJson } from "../../../../spec";
import {
makeEncString,
makeSymmetricCryptoKey,
mockContainerService,
mockEnc,
mockFromJson,
} from "../../../../spec";
import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service";
import { EncryptedString, EncString } from "../../../key-management/crypto/models/enc-string";
import { FolderData } from "../../models/data/folder.data";
@@ -15,6 +21,7 @@ describe("Folder", () => {
name: "encName",
revisionDate: "2022-01-31T12:00:00.000Z",
};
mockContainerService();
});
it("Convert", () => {

View File

@@ -1,4 +1,4 @@
import { mockEnc, mockFromJson } from "../../../../spec";
import { mockContainerService, mockEnc, mockFromJson } from "../../../../spec";
import { EncryptedString, EncString } from "../../../key-management/crypto/models/enc-string";
import { IdentityData } from "../../models/data/identity.data";
import { Identity } from "../../models/domain/identity";
@@ -27,6 +27,8 @@ describe("Identity", () => {
passportNumber: "encpassportNumber",
licenseNumber: "enclicenseNumber",
};
mockContainerService();
});
it("Convert from empty", () => {

View File

@@ -3,7 +3,7 @@ import { Jsonify } from "type-fest";
import { UriMatchType } from "@bitwarden/sdk-internal";
import { mockEnc, mockFromJson } from "../../../../spec";
import { mockContainerService, mockEnc, mockFromJson } from "../../../../spec";
import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service";
import { EncString } from "../../../key-management/crypto/models/enc-string";
import { UriMatchStrategy } from "../../../models/domain/domain-service";
@@ -20,6 +20,8 @@ describe("LoginUri", () => {
uriChecksum: "encUriChecksum",
match: UriMatchStrategy.Domain,
};
mockContainerService();
});
it("Convert from empty", () => {

View File

@@ -46,10 +46,10 @@ export class LoginUri extends Domain {
return false;
}
const keyService = Utils.getContainerService().getEncryptService();
const localChecksum = await keyService.hash(clearTextUri, "sha256");
const encryptService = Utils.getContainerService().getEncryptService();
const localChecksum = await encryptService.hash(clearTextUri, "sha256");
const remoteChecksum = await this.uriChecksum.decrypt(null, encKey);
const remoteChecksum = await encryptService.decryptString(this.uriChecksum, encKey);
return remoteChecksum === localChecksum;
}

View File

@@ -1,6 +1,6 @@
import { MockProxy, mock } from "jest-mock-extended";
import { mockEnc, mockFromJson } from "../../../../spec";
import { mockContainerService, mockEnc, mockFromJson } from "../../../../spec";
import { EncryptedString, EncString } from "../../../key-management/crypto/models/enc-string";
import { UriMatchStrategy } from "../../../models/domain/domain-service";
import { LoginData } from "../../models/data/login.data";
@@ -14,6 +14,10 @@ import { Fido2CredentialView } from "../view/fido2-credential.view";
import { Fido2Credential } from "./fido2-credential";
describe("Login DTO", () => {
beforeEach(() => {
mockContainerService();
});
it("Convert from empty LoginData", () => {
const data = new LoginData();
const login = new Login(data);

View File

@@ -1,4 +1,4 @@
import { mockEnc, mockFromJson } from "../../../../spec";
import { mockContainerService, mockEnc, mockFromJson } from "../../../../spec";
import { EncryptedString, EncString } from "../../../key-management/crypto/models/enc-string";
import { PasswordHistoryData } from "../../models/data/password-history.data";
import { Password } from "../../models/domain/password";
@@ -11,6 +11,7 @@ describe("Password", () => {
password: "encPassword",
lastUsedDate: "2022-01-31T12:00:00.000Z",
};
mockContainerService();
});
it("Convert from empty", () => {

View File

@@ -1,3 +1,4 @@
import { mockContainerService } from "../../../../spec";
import { SecureNoteType } from "../../enums";
import { SecureNoteData } from "../data/secure-note.data";
@@ -10,6 +11,8 @@ describe("SecureNote", () => {
data = {
type: SecureNoteType.Generic,
};
mockContainerService();
});
it("Convert from empty", () => {

View File

@@ -1,6 +1,6 @@
import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string";
import { mockEnc } from "../../../../spec";
import { mockContainerService, mockEnc } from "../../../../spec";
import { SshKeyApi } from "../api/ssh-key.api";
import { SshKeyData } from "../data/ssh-key.data";
@@ -17,6 +17,8 @@ describe("Sshkey", () => {
KeyFingerprint: "keyFingerprint",
}),
);
mockContainerService();
});
it("Convert", () => {

View File

@@ -55,7 +55,7 @@ const ENCRYPTED_BYTES = mock<EncArrayBuffer>();
const cipherData: CipherData = {
id: "id",
organizationId: "orgId",
organizationId: "4ff8c0b2-1d3e-4f8c-9b2d-1d3e4f8c0b2" as OrganizationId,
folderId: "folderId",
edit: true,
viewPassword: true,
@@ -119,6 +119,8 @@ describe("Cipher Service", () => {
beforeEach(() => {
encryptService.encryptFileData.mockReturnValue(Promise.resolve(ENCRYPTED_BYTES));
encryptService.encryptString.mockReturnValue(Promise.resolve(new EncString(ENCRYPTED_TEXT)));
keyService.orgKeys$.mockReturnValue(of({ [orgId]: makeSymmetricCryptoKey(32) as OrgKey }));
keyService.userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64) as UserKey));
// Mock i18nService collator
i18nService.collator = {
@@ -181,9 +183,6 @@ describe("Cipher Service", () => {
const testCipher = new Cipher(cipherData);
const expectedRevisionDate = "2022-01-31T12:00:00.000Z";
keyService.getOrgKey.mockReturnValue(
Promise.resolve<any>(new SymmetricCryptoKey(new Uint8Array(32)) as OrgKey),
);
keyService.makeDataEncKey.mockReturnValue(
Promise.resolve([
new SymmetricCryptoKey(new Uint8Array(32)),