diff --git a/apps/web/src/app/auth/emergency-access/services/emergency-access.service.spec.ts b/apps/web/src/app/auth/emergency-access/services/emergency-access.service.spec.ts index 05d6094745c..3c60e671991 100644 --- a/apps/web/src/app/auth/emergency-access/services/emergency-access.service.spec.ts +++ b/apps/web/src/app/auth/emergency-access/services/emergency-access.service.spec.ts @@ -203,8 +203,8 @@ describe("EmergencyAccessService", () => { { id: "cipher1", decrypted: true }, { id: "cipher2", decrypted: true }, ]); - expect(mockEncryptedCipher1.decrypt).toHaveBeenCalledWith(mockGrantorUserKey); - expect(mockEncryptedCipher2.decrypt).toHaveBeenCalledWith(mockGrantorUserKey); + expect(mockEncryptedCipher1.decrypt).toHaveBeenCalledWith(mockGrantorUserKey, params.activeUserId); + expect(mockEncryptedCipher2.decrypt).toHaveBeenCalledWith(mockGrantorUserKey, params.activeUserId); expect(emergencyAccessApiService.postEmergencyAccessView).toHaveBeenCalledWith(params.id); expect(keyService.userPrivateKey$).toHaveBeenCalledWith(params.activeUserId); expect(encryptService.decapsulateKeyUnsigned).toHaveBeenCalledWith( diff --git a/libs/common/spec/utils.ts b/libs/common/spec/utils.ts index a0588b10016..901f045c1e5 100644 --- a/libs/common/spec/utils.ts +++ b/libs/common/spec/utils.ts @@ -1,9 +1,13 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { mock, MockProxy } from "jest-mock-extended"; +import { of } from "rxjs"; -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 { EncryptService } from "../src/key-management/crypto/abstractions/encrypt.service"; +import { EncString } from "../src/key-management/crypto/models/enc-string"; import { EncryptionType } from "../src/platform/enums"; import { Utils } from "../src/platform/misc/utils"; import { SymmetricCryptoKey } from "../src/platform/models/domain/symmetric-crypto-key"; @@ -30,6 +34,7 @@ export function BuildTestObject( /** @deprecated */ export function mockEnc(s: string): MockProxy { const mocked = mock(); + mocked.data = s; return mocked; } @@ -76,4 +81,12 @@ export const mockFromSdk = (stub: any) => { return `${stub}_fromSdk`; }; +export const mockContainerService = () => { + // Mock the container service for decryption + const keyService = mock(); + const encryptService = mock(); + (window as any).bitwardenContainerService = new ContainerService(keyService, encryptService); + return (window as any).bitwardenContainerService; +} + export { trackEmissions, awaitAsync } from "@bitwarden/core-test-utils"; diff --git a/libs/common/src/key-management/crypto/models/enc-string.ts b/libs/common/src/key-management/crypto/models/enc-string.ts index f895e807abf..ba5b9ea36ac 100644 --- a/libs/common/src/key-management/crypto/models/enc-string.ts +++ b/libs/common/src/key-management/crypto/models/enc-string.ts @@ -9,12 +9,21 @@ import { EncryptionType, EXPECTED_NUM_PARTS_BY_ENCRYPTION_TYPE } from "../../../ export const DECRYPT_ERROR = "[error: cannot decrypt]"; +/** + * A legacy TS wrapper around the SDK EncString type. Use SdkEncString directly where possible. + * This type will be deprecated in the future. + */ export class EncString { encryptedString?: SdkEncString; + /** @deprecated */ encryptionType?: EncryptionType; + /** @deprecated */ decryptedValue?: string; + /** @deprecated */ data?: string; + /** @deprecated */ iv?: string; + /** @deprecated */ mac?: string; constructor( @@ -30,14 +39,17 @@ export class EncString { } } + /** @deprecated */ get ivBytes(): Uint8Array { return this.iv == null ? null : Utils.fromB64ToArray(this.iv); } + /** @deprecated */ get macBytes(): Uint8Array { return this.mac == null ? null : Utils.fromB64ToArray(this.mac); } + /** @deprecated */ get dataBytes(): Uint8Array { return this.data == null ? null : Utils.fromB64ToArray(this.data); } @@ -58,6 +70,7 @@ export class EncString { return new EncString(obj); } + /** @deprecated */ private initFromData(encType: EncryptionType, data: string, iv: string, mac: string) { if (iv != null) { this.encryptedString = (encType + "." + iv + "|" + data) as SdkEncString; @@ -76,6 +89,7 @@ export class EncString { this.mac = mac; } + /** @deprecated */ private initFromEncryptedString(encryptedString: string) { this.encryptedString = encryptedString as SdkEncString; if (!this.encryptedString) { @@ -114,6 +128,7 @@ export class EncString { } } + /** @deprecated */ private static parseEncryptedString(encryptedString: string): { encType: EncryptionType; encPieces: string[]; diff --git a/libs/common/src/platform/models/domain/domain-base.ts b/libs/common/src/platform/models/domain/domain-base.ts index e20ef42bf75..578d3bd55b0 100644 --- a/libs/common/src/platform/models/domain/domain-base.ts +++ b/libs/common/src/platform/models/domain/domain-base.ts @@ -10,28 +10,35 @@ import { Utils } from "../../misc/utils"; import { SymmetricCryptoKey } from "./symmetric-crypto-key"; -// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type + +/** @deprecated */ type EncStringKeys = ConditionalKeys, EncString>; +/** @deprecated */ export type DecryptedObject< TEncryptedObject, TDecryptedKeys extends EncStringKeys, > = Record & Omit; // extracts shared keys from the domain and view types +/** @deprecated */ type EncryptableKeys = (keyof D & ConditionalKeys) & (keyof V & ConditionalKeys); +/** @deprecated */ type DomainEncryptableKeys = { [key in ConditionalKeys]?: EncString | null | undefined; }; +/** @deprecated */ type ViewEncryptableKeys = { [key in ConditionalKeys]?: string | null | undefined; }; // https://contributing.bitwarden.com/architecture/clients/data-model#domain +/** @deprecated encryption and decryption of domain objects should be moved to the SDK */ export default class Domain { + /** @deprecated */ protected buildDomainModel( domain: D, dataObj: any, @@ -53,6 +60,7 @@ export default class Domain { } } + /** @deprecated */ protected buildDataModel( domain: D, dataObj: any, diff --git a/libs/common/src/tools/send/models/domain/send-access.spec.ts b/libs/common/src/tools/send/models/domain/send-access.spec.ts index 9fc04b88b8d..5b36c86161a 100644 --- a/libs/common/src/tools/send/models/domain/send-access.spec.ts +++ b/libs/common/src/tools/send/models/domain/send-access.spec.ts @@ -1,6 +1,7 @@ import { mock } from "jest-mock-extended"; +import { of } from "rxjs"; -import { mockEnc } from "../../../../../spec"; +import { makeSymmetricCryptoKey, mockContainerService, mockEnc } from "../../../../../spec"; import { SendType } from "../../enums/send-type"; import { SendAccessResponse } from "../response/send-access.response"; @@ -55,6 +56,10 @@ describe("SendAccess", () => { }); it("Decrypt", async () => { + const containerService = mockContainerService(); + containerService.getKeyService().userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64))); + containerService.getEncryptService().decryptString.mockResolvedValue("name"); + const sendAccess = new SendAccess(); sendAccess.id = "id"; sendAccess.type = SendType.Text; diff --git a/libs/common/src/tools/send/models/domain/send-file.spec.ts b/libs/common/src/tools/send/models/domain/send-file.spec.ts index bd9e397c61b..eb0a0490b0a 100644 --- a/libs/common/src/tools/send/models/domain/send-file.spec.ts +++ b/libs/common/src/tools/send/models/domain/send-file.spec.ts @@ -1,4 +1,12 @@ -import { mockEnc } from "../../../../../spec"; +import { of } from "rxjs"; + +import mock from "@bitwarden/common/platform/spec/mock-deep"; +// eslint-disable-next-line no-restricted-imports +import { KeyService } from "@bitwarden/key-management"; + +import { makeSymmetricCryptoKey, mockContainerService, mockEnc } from "../../../../../spec"; +import { EncryptService } from "../../../../key-management/crypto/abstractions/encrypt.service"; +import { ContainerService } from "../../../../platform/services/container.service"; import { SendFileData } from "../data/send-file.data"; import { SendFile } from "./send-file"; @@ -39,6 +47,11 @@ describe("SendFile", () => { }); it("Decrypt", async () => { + const containerService = mockContainerService(); + containerService.getKeyService().userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64))); + containerService.getEncryptService() + .decryptString.mockResolvedValue("fileName"); + const sendFile = new SendFile(); sendFile.id = "id"; sendFile.size = "1100"; diff --git a/libs/common/src/tools/send/models/domain/send-text.spec.ts b/libs/common/src/tools/send/models/domain/send-text.spec.ts index 6c5e8e5580d..60bf2bc4bb8 100644 --- a/libs/common/src/tools/send/models/domain/send-text.spec.ts +++ b/libs/common/src/tools/send/models/domain/send-text.spec.ts @@ -1,8 +1,17 @@ -import { mockEnc } from "../../../../../spec"; +import { of } from "rxjs"; + +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; +import { ContainerService } from "@bitwarden/common/platform/services/container.service"; +import mock from "@bitwarden/common/platform/spec/mock-deep"; +// eslint-disable-next-line no-restricted-imports +import { KeyService } from "@bitwarden/key-management"; + +import { makeSymmetricCryptoKey, mockContainerService, mockEnc } from "../../../../../spec"; import { SendTextData } from "../data/send-text.data"; import { SendText } from "./send-text"; + describe("SendText", () => { let data: SendTextData; @@ -33,6 +42,11 @@ describe("SendText", () => { }); it("Decrypt", async () => { + const containerService = mockContainerService(); + containerService.getKeyService().userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64))); + containerService.getEncryptService() + .decryptString.mockResolvedValue("text"); + const secureNote = new SendText(); secureNote.text = mockEnc("text"); secureNote.hidden = true; diff --git a/libs/common/src/tools/send/models/domain/send.spec.ts b/libs/common/src/tools/send/models/domain/send.spec.ts index ccaadd4dbd0..5a7c5699d81 100644 --- a/libs/common/src/tools/send/models/domain/send.spec.ts +++ b/libs/common/src/tools/send/models/domain/send.spec.ts @@ -1,16 +1,9 @@ -import { mock } from "jest-mock-extended"; import { of } from "rxjs"; +import mock from "@bitwarden/common/platform/spec/mock-deep"; import { emptyGuid, UserId } from "@bitwarden/common/types/guid"; -// 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 { makeStaticByteArray, mockEnc } from "../../../../../spec"; -import { EncryptService } from "../../../../key-management/crypto/abstractions/encrypt.service"; -import { SymmetricCryptoKey } from "../../../../platform/models/domain/symmetric-crypto-key"; -import { ContainerService } from "../../../../platform/services/container.service"; -import { UserKey } from "../../../../types/key"; +import { mockEnc, makeStaticByteArray, mockContainerService, makeSymmetricCryptoKey } from "../../../../../spec"; import { SendType } from "../../enums/send-type"; import { SendData } from "../data/send.data"; @@ -96,9 +89,18 @@ describe("Send", () => { }); it("Decrypt", async () => { + const containerService = mockContainerService(); + containerService.getKeyService().userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64))); + containerService.getEncryptService() + .decryptString + .mockResolvedValueOnce("name") + .mockResolvedValueOnce("notes"); + containerService.getEncryptService() + .decryptBytes + .mockResolvedValueOnce(makeStaticByteArray(32)); + const text = mock(); text.decrypt.mockResolvedValue("textView" as any); - const userKey = new SymmetricCryptoKey(new Uint8Array(32)) as UserKey; const userId = emptyGuid as UserId; const send = new Send(); @@ -117,19 +119,11 @@ describe("Send", () => { send.disabled = false; send.hideEmail = true; - const encryptService = mock(); - const keyService = mock(); - encryptService.decryptBytes - .calledWith(send.key, userKey) - .mockResolvedValue(makeStaticByteArray(32)); - keyService.makeSendKey.mockResolvedValue("cryptoKey" as any); - keyService.userKey$.calledWith(userId).mockReturnValue(of(userKey)); - - (window as any).bitwardenContainerService = new ContainerService(keyService, encryptService); + containerService.getKeyService().makeSendKey.mockResolvedValue("cryptoKey" as any); const view = await send.decrypt(userId); - expect(text.decrypt).toHaveBeenNthCalledWith(1, "cryptoKey"); + expect(text.decrypt).toHaveBeenNthCalledWith(1, userId, "cryptoKey"); expect(view).toMatchObject({ id: "id", diff --git a/libs/common/src/vault/models/domain/attachment.spec.ts b/libs/common/src/vault/models/domain/attachment.spec.ts index a7c871a9d5f..74fd5c546b9 100644 --- a/libs/common/src/vault/models/domain/attachment.spec.ts +++ b/libs/common/src/vault/models/domain/attachment.spec.ts @@ -1,4 +1,5 @@ import { mock, MockProxy } from "jest-mock-extended"; +import { of } from "rxjs"; // 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 @@ -80,11 +81,12 @@ describe("Attachment", () => { attachment.fileName = mockEnc("fileName"); const userKey = new SymmetricCryptoKey(makeStaticByteArray(64)); - keyService.getUserKey.mockResolvedValue(userKey as UserKey); + keyService.userKey$.mockReturnValue(of(userKey as UserKey)); encryptService.decryptFileData.mockResolvedValue(makeStaticByteArray(32)); encryptService.unwrapSymmetricKey.mockResolvedValue( new SymmetricCryptoKey(makeStaticByteArray(64)), ); + encryptService.decryptString.mockResolvedValueOnce("fileName"); const view = await attachment.decrypt(null, null); @@ -118,21 +120,22 @@ describe("Attachment", () => { it("gets an organization key if required", async () => { const orgKey = mock(); - keyService.getOrgKey.calledWith("orgId").mockResolvedValue(orgKey); + keyService.orgKeys$.mockReturnValue(of({ "orgId": orgKey })); await attachment.decrypt(null, "orgId", "", null); - expect(keyService.getOrgKey).toHaveBeenCalledWith("orgId"); + expect(keyService.orgKeys$).toHaveBeenCalledWith(null); expect(encryptService.unwrapSymmetricKey).toHaveBeenCalledWith(attachment.key, orgKey); }); it("gets the user's decryption key if required", async () => { - const userKey = mock(); - keyService.getUserKey.mockResolvedValue(userKey); + keyService.orgKeys$.mockReturnValue(of({ "orgId": mock() })); + const userKey = new SymmetricCryptoKey(makeStaticByteArray(64)); + keyService.userKey$.mockReturnValue(of(userKey as UserKey)); - await attachment.decrypt(null, "", null); + await attachment.decrypt(null, null, null, null); - expect(keyService.getUserKey).toHaveBeenCalled(); + expect(keyService.userKey$).toHaveBeenCalled(); expect(encryptService.unwrapSymmetricKey).toHaveBeenCalledWith(attachment.key, userKey); }); }); diff --git a/libs/common/src/vault/models/domain/attachment.ts b/libs/common/src/vault/models/domain/attachment.ts index 4cc66158caf..77acbbeb9bb 100644 --- a/libs/common/src/vault/models/domain/attachment.ts +++ b/libs/common/src/vault/models/domain/attachment.ts @@ -1,5 +1,7 @@ +import { firstValueFrom, map } from "rxjs"; import { Jsonify } from "type-fest"; +import { OrganizationId } from "@bitwarden/common/types/guid"; import { OrgKey, UserKey } from "@bitwarden/common/types/key"; import { Attachment as SdkAttachment } from "@bitwarden/sdk-internal"; import { UserId } from "@bitwarden/user-core"; @@ -51,7 +53,7 @@ export class Attachment extends Domain { ); if (this.key != null) { - view.key = await this.decryptAttachmentKey(orgId, encKey); + view.key = await this.decryptAttachmentKey(orgId, userId, encKey); view.encryptedKey = this.key; // Keep the encrypted key for the view } @@ -60,6 +62,7 @@ export class Attachment extends Domain { private async decryptAttachmentKey( orgId: string | undefined, + userId: UserId, encKey?: SymmetricCryptoKey, ): Promise { try { @@ -68,7 +71,7 @@ export class Attachment extends Domain { } if (encKey == null) { - const key = await this.getKeyForDecryption(orgId); + const key = await this.getKeyForDecryption(orgId, userId); // If we don't have a key, we can't decrypt if (key == null) { @@ -88,9 +91,12 @@ export class Attachment extends Domain { } } - private async getKeyForDecryption(orgId: string | undefined): Promise { + private async getKeyForDecryption(orgId: string | undefined, userId: UserId): Promise { const keyService = Utils.getContainerService().getKeyService(); - return orgId != null ? await keyService.getOrgKey(orgId) : await keyService.getUserKey(); + console.log("getKeyForDecryption", orgId, userId); + return orgId != null ? await firstValueFrom(keyService.orgKeys$(userId).pipe( + map((orgKeys) => orgKeys[orgId as OrganizationId] ?? null), + )) : await firstValueFrom(keyService.userKey$(userId)); } toAttachmentData(): AttachmentData { diff --git a/libs/common/src/vault/models/domain/card.spec.ts b/libs/common/src/vault/models/domain/card.spec.ts index 2e376490b95..f6e3c40fd55 100644 --- a/libs/common/src/vault/models/domain/card.spec.ts +++ b/libs/common/src/vault/models/domain/card.spec.ts @@ -1,4 +1,8 @@ -import { mockEnc, mockFromJson } from "../../../../spec"; +import { of } from "rxjs"; + +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; + +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"; @@ -50,6 +54,14 @@ describe("Card", () => { }); it("Decrypt", async () => { + const containerService = mockContainerService(); + containerService.getKeyService().userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64))); + containerService + .getEncryptService() + .decryptString.mockImplementation(async (encString: EncString, key: SymmetricCryptoKey) => { + return encString.data; + }) + const card = new Card(); card.cardholderName = mockEnc("cardHolder"); card.brand = mockEnc("brand"); diff --git a/libs/common/src/vault/models/domain/cipher.spec.ts b/libs/common/src/vault/models/domain/cipher.spec.ts index d0bcb3d5ae3..de399032455 100644 --- a/libs/common/src/vault/models/domain/cipher.spec.ts +++ b/libs/common/src/vault/models/domain/cipher.spec.ts @@ -1,4 +1,5 @@ import { mock } from "jest-mock-extended"; +import { of } from "rxjs"; import { Jsonify } from "type-fest"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; @@ -14,7 +15,7 @@ import { EncString as SdkEncString, } from "@bitwarden/sdk-internal"; -import { makeStaticByteArray, mockEnc, mockFromJson } from "../../../../spec/utils"; +import { makeStaticByteArray, makeSymmetricCryptoKey, 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"; @@ -69,6 +70,14 @@ describe("Cipher DTO", () => { }); it("Decrypt should handle cipher key error", async () => { + const containerService = mockContainerService(); + containerService.getKeyService().userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64))); + containerService + .getEncryptService() + .decryptString.mockImplementation(async (encString: EncString, key: SymmetricCryptoKey) => { + return encString.data; + }) + const cipher = new Cipher(); cipher.id = "id"; cipher.organizationId = "orgId"; diff --git a/libs/common/src/vault/models/domain/fido2-credential.spec.ts b/libs/common/src/vault/models/domain/fido2-credential.spec.ts index d22732414dc..95b4ac26ea6 100644 --- a/libs/common/src/vault/models/domain/fido2-credential.spec.ts +++ b/libs/common/src/vault/models/domain/fido2-credential.spec.ts @@ -1,4 +1,8 @@ -import { mockEnc } from "../../../../spec"; +import { of } from "rxjs"; + +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; + +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"; @@ -88,6 +92,14 @@ describe("Fido2Credential", () => { describe("decrypt", () => { it("decrypts and populates all fields when populated with EncStrings", async () => { + const containerService = mockContainerService(); + containerService.getKeyService().userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64))); + containerService + .getEncryptService() + .decryptString.mockImplementation(async (encString: EncString, key: SymmetricCryptoKey) => { + return encString.data; + }) + const credential = new Fido2Credential(); credential.credentialId = mockEnc("credentialId"); credential.keyType = mockEnc("keyType"); diff --git a/libs/common/src/vault/models/domain/field.spec.ts b/libs/common/src/vault/models/domain/field.spec.ts index 7214e2f7bae..64197b9e9bd 100644 --- a/libs/common/src/vault/models/domain/field.spec.ts +++ b/libs/common/src/vault/models/domain/field.spec.ts @@ -1,3 +1,5 @@ +import { of } from "rxjs"; + import { Field as SdkField, FieldType, @@ -6,7 +8,7 @@ import { IdentityLinkedIdType, } from "@bitwarden/sdk-internal"; -import { mockEnc, mockFromJson } from "../../../../spec"; +import { makeSymmetricCryptoKey, 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"; @@ -53,6 +55,13 @@ describe("Field", () => { }); it("Decrypt", async () => { + const containerService = mockContainerService(); + containerService.getKeyService().userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64))); + containerService.getEncryptService() + .decryptString.mockImplementation(async (encString: EncString, key: any) => { + return encString.data; + }); + const field = new Field(); field.type = FieldType.Text; field.name = mockEnc("encName"); diff --git a/libs/common/src/vault/models/domain/identity.spec.ts b/libs/common/src/vault/models/domain/identity.spec.ts index 9e9eda81e8a..e15a9853064 100644 --- a/libs/common/src/vault/models/domain/identity.spec.ts +++ b/libs/common/src/vault/models/domain/identity.spec.ts @@ -1,4 +1,8 @@ -import { mockEnc, mockFromJson } from "../../../../spec"; +import { of } from "rxjs"; + +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; + +import { makeSymmetricCryptoKey, 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"; @@ -86,6 +90,14 @@ describe("Identity", () => { }); it("Decrypt", async () => { + const containerService = mockContainerService(); + containerService.getKeyService().userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64))); + containerService + .getEncryptService() + .decryptString.mockImplementation(async (encString: EncString, key: SymmetricCryptoKey) => { + return encString.data; + }) + const identity = new Identity(); identity.title = mockEnc("mockTitle"); diff --git a/libs/common/src/vault/models/domain/login-uri.spec.ts b/libs/common/src/vault/models/domain/login-uri.spec.ts index c027fdbef1e..6baac552842 100644 --- a/libs/common/src/vault/models/domain/login-uri.spec.ts +++ b/libs/common/src/vault/models/domain/login-uri.spec.ts @@ -1,9 +1,12 @@ -import { MockProxy, mock } from "jest-mock-extended"; +import { MockProxy } from "jest-mock-extended"; +import { of } from "rxjs"; import { Jsonify } from "type-fest"; +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; +import { UserKey } from "@bitwarden/common/types/key"; import { UriMatchType } from "@bitwarden/sdk-internal"; -import { mockEnc, mockFromJson } from "../../../../spec"; +import { makeSymmetricCryptoKey, 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"; @@ -49,6 +52,14 @@ describe("LoginUri", () => { }); it("Decrypt", async () => { + const containerService = mockContainerService(); + containerService.getKeyService().userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64) as UserKey)); + containerService + .getEncryptService() + .decryptString.mockImplementation(async (encString: EncString, key: SymmetricCryptoKey) => { + return encString.data; + }) + const loginUri = new LoginUri(); loginUri.match = UriMatchStrategy.Exact; loginUri.uri = mockEnc("uri"); @@ -65,11 +76,15 @@ describe("LoginUri", () => { let encryptService: MockProxy; beforeEach(() => { - encryptService = mock(); - global.bitwardenContainerService = { - getEncryptService: () => encryptService, - getKeyService: () => null, - }; + const containerService = mockContainerService(); + encryptService = containerService.getEncryptService(); + + containerService.getKeyService().userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64) as UserKey)); + containerService + .getEncryptService() + .decryptString.mockImplementation(async (encString: EncString, key: SymmetricCryptoKey) => { + return encString.data; + }) }); it("returns true if checksums match", async () => { diff --git a/libs/common/src/vault/models/domain/login.spec.ts b/libs/common/src/vault/models/domain/login.spec.ts index 1e93d0f39e2..9076727900f 100644 --- a/libs/common/src/vault/models/domain/login.spec.ts +++ b/libs/common/src/vault/models/domain/login.spec.ts @@ -1,6 +1,9 @@ import { MockProxy, mock } from "jest-mock-extended"; +import { of } from "rxjs"; -import { mockEnc, mockFromJson } from "../../../../spec"; +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; + +import { makeSymmetricCryptoKey, 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"; @@ -64,6 +67,14 @@ describe("Login DTO", () => { }); describe("decrypt", () => { + const containerService = mockContainerService(); + containerService.getKeyService().userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64))); + containerService + .getEncryptService() + .decryptString.mockImplementation(async (encString: EncString, key: SymmetricCryptoKey) => { + return encString.data; + }) + let loginUri: MockProxy; const loginUriView = new LoginUriView(); const decryptedFido2Credential = Symbol(); diff --git a/libs/common/src/vault/models/domain/password.spec.ts b/libs/common/src/vault/models/domain/password.spec.ts index c8012c894e1..3ec9b69f6ce 100644 --- a/libs/common/src/vault/models/domain/password.spec.ts +++ b/libs/common/src/vault/models/domain/password.spec.ts @@ -1,5 +1,8 @@ -import { mockEnc, mockFromJson } from "../../../../spec"; -import { EncryptedString, EncString } from "../../../key-management/crypto/models/enc-string"; +import { of } from "rxjs"; + +import { EncString, EncryptedString } from "@bitwarden/common/key-management/crypto/models/enc-string"; + +import { mockEnc, mockFromJson, makeSymmetricCryptoKey, mockContainerService } from "../../../../spec"; import { PasswordHistoryData } from "../../models/data/password-history.data"; import { Password } from "../../models/domain/password"; @@ -37,6 +40,11 @@ describe("Password", () => { }); it("Decrypt", async () => { + const containerService = mockContainerService(); + containerService.getKeyService().userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64))); + containerService.getEncryptService() + .decryptString.mockResolvedValue("password"); + const password = new Password(); password.password = mockEnc("password"); password.lastUsedDate = new Date("2022-01-31T12:00:00.000Z"); diff --git a/libs/common/src/vault/models/domain/ssh-key.spec.ts b/libs/common/src/vault/models/domain/ssh-key.spec.ts index 33d9e471521..cf233c9302e 100644 --- a/libs/common/src/vault/models/domain/ssh-key.spec.ts +++ b/libs/common/src/vault/models/domain/ssh-key.spec.ts @@ -1,6 +1,8 @@ +import { of } from "rxjs"; + import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string"; -import { mockEnc } from "../../../../spec"; +import { makeSymmetricCryptoKey, mockContainerService, mockEnc } from "../../../../spec"; import { SshKeyApi } from "../api/ssh-key.api"; import { SshKeyData } from "../data/ssh-key.data"; @@ -45,6 +47,13 @@ describe("Sshkey", () => { }); it("Decrypt", async () => { + const containerService = mockContainerService(); + containerService.getKeyService().userKey$.mockReturnValue(of(makeSymmetricCryptoKey(64))); + containerService.getEncryptService() + .decryptString.mockResolvedValueOnce("privateKey") + .mockResolvedValueOnce("publicKey") + .mockResolvedValueOnce("keyFingerprint"); + const sshKey = Object.assign(new SshKey(), { privateKey: mockEnc("privateKey"), publicKey: mockEnc("publicKey"),