From 0569ec95172a13de9b8340be37229119d49dd6f5 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Fri, 20 Feb 2026 19:09:52 +0100 Subject: [PATCH] [PM-31880 | BEEEP] Move random out of keyservice to PureCrypto (#18838) * Move random to PureCrypto * Rename and fix builds * Fix tests * Fix build * Prettier * Fix tests --- .../src/abstractions/key.service.ts | 1 - libs/key-management/src/key.service.ts | 35 -------- .../src/generator-services.module.ts | 2 +- .../core/src/engine/email-calculator.spec.ts | 4 + .../core/src/engine/email-randomizer.spec.ts | 4 + .../core/src/engine/forwarder-context.spec.ts | 4 + libs/tools/generator/core/src/engine/index.ts | 2 +- .../src/engine/password-randomizer.spec.ts | 4 + ....spec.ts => purecrypto-randomizer.spec.ts} | 87 ++++++++++--------- ...randomizer.ts => purecrypto-randomizer.ts} | 22 +++-- .../src/engine/username-randomizer.spec.ts | 4 + libs/tools/generator/core/src/factories.ts | 8 +- .../core/src/metadata/email/catchall.spec.ts | 4 + .../src/metadata/email/plus-address.spec.ts | 4 + .../metadata/password/eff-word-list.spec.ts | 4 + .../metadata/password/random-password.spec.ts | 4 + .../metadata/username/eff-word-list.spec.ts | 4 + .../available-algorithms-policy.spec.ts | 4 + ...ynamic-password-policy-constraints.spec.ts | 4 + .../passphrase-policy-constraints.spec.ts | 4 + .../providers/credential-preferences.spec.ts | 4 + .../generator-metadata-provider.spec.ts | 4 + ...fault-credential-generator.service.spec.ts | 4 + .../catchall-generator-strategy.spec.ts | 4 + .../eff-username-generator-strategy.spec.ts | 4 + .../forwarder-generator-strategy.spec.ts | 4 + .../passphrase-generator-strategy.spec.ts | 4 + .../password-generator-strategy.spec.ts | 4 + .../subaddress-generator-strategy.spec.ts | 4 + .../src/types/generated-credential.spec.ts | 4 + .../history/src/generated-credential.spec.ts | 4 + .../local-generator-history.service.spec.ts | 4 + ...eate-legacy-password-generation-service.ts | 4 +- ...eate-legacy-username-generation-service.ts | 4 +- ...legacy-password-generation.service.spec.ts | 4 + ...legacy-username-generation.service.spec.ts | 4 + ...fault-generator-navigation.service.spec.ts | 4 + .../generator-navigation-evaluator.spec.ts | 4 + 38 files changed, 187 insertions(+), 94 deletions(-) rename libs/tools/generator/core/src/engine/{key-service-randomizer.spec.ts => purecrypto-randomizer.spec.ts} (59%) rename libs/tools/generator/core/src/engine/{key-service-randomizer.ts => purecrypto-randomizer.ts} (73%) diff --git a/libs/key-management/src/abstractions/key.service.ts b/libs/key-management/src/abstractions/key.service.ts index 2dedc78a027..e9844ede4bb 100644 --- a/libs/key-management/src/abstractions/key.service.ts +++ b/libs/key-management/src/abstractions/key.service.ts @@ -316,7 +316,6 @@ export abstract class KeyService { * @throws Error when provided userId is null or undefined */ abstract clearKeys(userId: UserId): Promise; - abstract randomNumber(min: number, max: number): Promise; /** * Generates a new cipher key * @returns A new cipher key diff --git a/libs/key-management/src/key.service.ts b/libs/key-management/src/key.service.ts index 7b4e8d83127..7258857d889 100644 --- a/libs/key-management/src/key.service.ts +++ b/libs/key-management/src/key.service.ts @@ -493,41 +493,6 @@ export class DefaultKeyService implements KeyServiceAbstraction { await this.accountCryptographyStateService.clearAccountCryptographicState(userId); } - // EFForg/OpenWireless - // ref https://github.com/EFForg/OpenWireless/blob/master/app/js/diceware.js - async randomNumber(min: number, max: number): Promise { - let rval = 0; - const range = max - min + 1; - const bitsNeeded = Math.ceil(Math.log2(range)); - if (bitsNeeded > 53) { - throw new Error("We cannot generate numbers larger than 53 bits."); - } - - const bytesNeeded = Math.ceil(bitsNeeded / 8); - const mask = Math.pow(2, bitsNeeded) - 1; - // 7776 -> (2^13 = 8192) -1 == 8191 or 0x00001111 11111111 - - // Fill a byte array with N random numbers - const byteArray = new Uint8Array(await this.cryptoFunctionService.randomBytes(bytesNeeded)); - - let p = (bytesNeeded - 1) * 8; - for (let i = 0; i < bytesNeeded; i++) { - rval += byteArray[i] * Math.pow(2, p); - p -= 8; - } - - // Use & to apply the mask and reduce the number of recursive lookups - rval = rval & mask; - - if (rval >= range) { - // Integer out of acceptable range - return this.randomNumber(min, max); - } - - // Return an integer that falls within the range - return min + rval; - } - // ---HELPERS--- async validateUserKey(key: UserKey | MasterKey | null, userId: UserId): Promise { if (key == null) { diff --git a/libs/tools/generator/components/src/generator-services.module.ts b/libs/tools/generator/components/src/generator-services.module.ts index 935f7dc2d60..28e1a325e76 100644 --- a/libs/tools/generator/components/src/generator-services.module.ts +++ b/libs/tools/generator/components/src/generator-services.module.ts @@ -57,7 +57,7 @@ export const SYSTEM_SERVICE_PROVIDER = new SafeInjectionToken { diff --git a/libs/tools/generator/core/src/engine/email-randomizer.spec.ts b/libs/tools/generator/core/src/engine/email-randomizer.spec.ts index 2ebe50d12d4..41ffc8431cd 100644 --- a/libs/tools/generator/core/src/engine/email-randomizer.spec.ts +++ b/libs/tools/generator/core/src/engine/email-randomizer.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { EFFLongWordList } from "@bitwarden/common/platform/misc/wordlist"; diff --git a/libs/tools/generator/core/src/engine/forwarder-context.spec.ts b/libs/tools/generator/core/src/engine/forwarder-context.spec.ts index 9838dbcdbda..e7d848cfed5 100644 --- a/libs/tools/generator/core/src/engine/forwarder-context.spec.ts +++ b/libs/tools/generator/core/src/engine/forwarder-context.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; diff --git a/libs/tools/generator/core/src/engine/index.ts b/libs/tools/generator/core/src/engine/index.ts index f8008a866e4..1e9cdeb2d39 100644 --- a/libs/tools/generator/core/src/engine/index.ts +++ b/libs/tools/generator/core/src/engine/index.ts @@ -1,4 +1,4 @@ -export { KeyServiceRandomizer } from "./key-service-randomizer"; +export { PureCryptoRandomizer } from "./purecrypto-randomizer"; export { ForwarderConfiguration, AccountRequest } from "./forwarder-configuration"; export { ForwarderContext } from "./forwarder-context"; export * from "./settings"; diff --git a/libs/tools/generator/core/src/engine/password-randomizer.spec.ts b/libs/tools/generator/core/src/engine/password-randomizer.spec.ts index 1d9f58fddd7..83216ece3e3 100644 --- a/libs/tools/generator/core/src/engine/password-randomizer.spec.ts +++ b/libs/tools/generator/core/src/engine/password-randomizer.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { EFFLongWordList } from "@bitwarden/common/platform/misc/wordlist"; diff --git a/libs/tools/generator/core/src/engine/key-service-randomizer.spec.ts b/libs/tools/generator/core/src/engine/purecrypto-randomizer.spec.ts similarity index 59% rename from libs/tools/generator/core/src/engine/key-service-randomizer.spec.ts rename to libs/tools/generator/core/src/engine/purecrypto-randomizer.spec.ts index 459a05618f9..cc8d9d86196 100644 --- a/libs/tools/generator/core/src/engine/key-service-randomizer.spec.ts +++ b/libs/tools/generator/core/src/engine/purecrypto-randomizer.spec.ts @@ -1,19 +1,28 @@ -import { mock } from "jest-mock-extended"; +import { PureCryptoRandomizer } from "./purecrypto-randomizer"; -import { KeyService } from "@bitwarden/key-management"; +jest.mock("@bitwarden/sdk-internal", () => ({ + PureCrypto: { + random_number: jest.fn(), + }, +})); -import { KeyServiceRandomizer } from "./key-service-randomizer"; +jest.mock("@bitwarden/common/platform/abstractions/sdk/sdk-load.service", () => ({ + SdkLoadService: { + Ready: Promise.resolve(), + }, +})); -describe("KeyServiceRandomizer", () => { - const keyService = mock(); +const mockRandomNumber = jest.requireMock("@bitwarden/sdk-internal").PureCrypto + .random_number as jest.Mock; +describe("PureCryptoRandomizer", () => { afterEach(() => { jest.resetAllMocks(); }); describe("pick", () => { it.each([[null], [undefined], [[]]])("throws when the list is %p", async (list) => { - const randomizer = new KeyServiceRandomizer(keyService); + const randomizer = new PureCryptoRandomizer(); await expect(() => randomizer.pick(list)).rejects.toBeInstanceOf(Error); @@ -21,8 +30,8 @@ describe("KeyServiceRandomizer", () => { }); it("picks an item from the list", async () => { - const randomizer = new KeyServiceRandomizer(keyService); - keyService.randomNumber.mockResolvedValue(1); + const randomizer = new PureCryptoRandomizer(); + mockRandomNumber.mockReturnValue(1); const result = await randomizer.pick([0, 1]); @@ -32,7 +41,7 @@ describe("KeyServiceRandomizer", () => { describe("pickWord", () => { it.each([[null], [undefined], [[]]])("throws when the list is %p", async (list) => { - const randomizer = new KeyServiceRandomizer(keyService); + const randomizer = new PureCryptoRandomizer(); await expect(() => randomizer.pickWord(list)).rejects.toBeInstanceOf(Error); @@ -40,8 +49,8 @@ describe("KeyServiceRandomizer", () => { }); it("picks a word from the list", async () => { - const randomizer = new KeyServiceRandomizer(keyService); - keyService.randomNumber.mockResolvedValue(1); + const randomizer = new PureCryptoRandomizer(); + mockRandomNumber.mockReturnValue(1); const result = await randomizer.pickWord(["foo", "bar"]); @@ -49,8 +58,8 @@ describe("KeyServiceRandomizer", () => { }); it("capitalizes the word when options.titleCase is true", async () => { - const randomizer = new KeyServiceRandomizer(keyService); - keyService.randomNumber.mockResolvedValue(1); + const randomizer = new PureCryptoRandomizer(); + mockRandomNumber.mockReturnValue(1); const result = await randomizer.pickWord(["foo", "bar"], { titleCase: true }); @@ -58,9 +67,9 @@ describe("KeyServiceRandomizer", () => { }); it("appends a random number when options.number is true", async () => { - const randomizer = new KeyServiceRandomizer(keyService); - keyService.randomNumber.mockResolvedValueOnce(1); - keyService.randomNumber.mockResolvedValueOnce(2); + const randomizer = new PureCryptoRandomizer(); + mockRandomNumber.mockReturnValueOnce(1); + mockRandomNumber.mockReturnValueOnce(2); const result = await randomizer.pickWord(["foo", "bar"], { number: true }); @@ -70,7 +79,7 @@ describe("KeyServiceRandomizer", () => { describe("shuffle", () => { it.each([[null], [undefined], [[]]])("throws when the list is %p", async (list) => { - const randomizer = new KeyServiceRandomizer(keyService); + const randomizer = new PureCryptoRandomizer(); await expect(() => randomizer.shuffle(list)).rejects.toBeInstanceOf(Error); @@ -78,18 +87,18 @@ describe("KeyServiceRandomizer", () => { }); it("returns a copy of the list without shuffling it when theres only one entry", async () => { - const randomizer = new KeyServiceRandomizer(keyService); + const randomizer = new PureCryptoRandomizer(); const result = await randomizer.shuffle(["foo"]); expect(result).toEqual(["foo"]); expect(result).not.toBe(["foo"]); - expect(keyService.randomNumber).not.toHaveBeenCalled(); + expect(mockRandomNumber).not.toHaveBeenCalled(); }); it("shuffles the tail of the list", async () => { - const randomizer = new KeyServiceRandomizer(keyService); - keyService.randomNumber.mockResolvedValueOnce(0); + const randomizer = new PureCryptoRandomizer(); + mockRandomNumber.mockReturnValueOnce(0); const result = await randomizer.shuffle(["bar", "foo"]); @@ -97,9 +106,9 @@ describe("KeyServiceRandomizer", () => { }); it("shuffles the list", async () => { - const randomizer = new KeyServiceRandomizer(keyService); - keyService.randomNumber.mockResolvedValueOnce(0); - keyService.randomNumber.mockResolvedValueOnce(1); + const randomizer = new PureCryptoRandomizer(); + mockRandomNumber.mockReturnValueOnce(0); + mockRandomNumber.mockReturnValueOnce(1); const result = await randomizer.shuffle(["baz", "bar", "foo"]); @@ -107,8 +116,8 @@ describe("KeyServiceRandomizer", () => { }); it("returns the input list when options.copy is false", async () => { - const randomizer = new KeyServiceRandomizer(keyService); - keyService.randomNumber.mockResolvedValueOnce(0); + const randomizer = new PureCryptoRandomizer(); + mockRandomNumber.mockReturnValueOnce(0); const expectedResult = ["foo"]; const result = await randomizer.shuffle(expectedResult, { copy: false }); @@ -119,7 +128,7 @@ describe("KeyServiceRandomizer", () => { describe("chars", () => { it("returns an empty string when the length is 0", async () => { - const randomizer = new KeyServiceRandomizer(keyService); + const randomizer = new PureCryptoRandomizer(); const result = await randomizer.chars(0); @@ -127,8 +136,8 @@ describe("KeyServiceRandomizer", () => { }); it("returns an arbitrary lowercase ascii character", async () => { - const randomizer = new KeyServiceRandomizer(keyService); - keyService.randomNumber.mockResolvedValueOnce(0); + const randomizer = new PureCryptoRandomizer(); + mockRandomNumber.mockReturnValueOnce(0); const result = await randomizer.chars(1); @@ -136,38 +145,38 @@ describe("KeyServiceRandomizer", () => { }); it("returns a number of ascii characters based on the length", async () => { - const randomizer = new KeyServiceRandomizer(keyService); - keyService.randomNumber.mockResolvedValue(0); + const randomizer = new PureCryptoRandomizer(); + mockRandomNumber.mockReturnValue(0); const result = await randomizer.chars(2); expect(result).toEqual("aa"); - expect(keyService.randomNumber).toHaveBeenCalledTimes(2); + expect(mockRandomNumber).toHaveBeenCalledTimes(2); }); it("returns a new random character each time its called", async () => { - const randomizer = new KeyServiceRandomizer(keyService); - keyService.randomNumber.mockResolvedValueOnce(0); - keyService.randomNumber.mockResolvedValueOnce(1); + const randomizer = new PureCryptoRandomizer(); + mockRandomNumber.mockReturnValueOnce(0); + mockRandomNumber.mockReturnValueOnce(1); const resultA = await randomizer.chars(1); const resultB = await randomizer.chars(1); expect(resultA).toEqual("a"); expect(resultB).toEqual("b"); - expect(keyService.randomNumber).toHaveBeenCalledTimes(2); + expect(mockRandomNumber).toHaveBeenCalledTimes(2); }); }); describe("uniform", () => { it("forwards requests to the crypto service", async () => { - const randomizer = new KeyServiceRandomizer(keyService); - keyService.randomNumber.mockResolvedValue(5); + const randomizer = new PureCryptoRandomizer(); + mockRandomNumber.mockReturnValue(5); const result = await randomizer.uniform(0, 5); expect(result).toBe(5); - expect(keyService.randomNumber).toHaveBeenCalledWith(0, 5); + expect(mockRandomNumber).toHaveBeenCalledWith(0, 5); }); }); }); diff --git a/libs/tools/generator/core/src/engine/key-service-randomizer.ts b/libs/tools/generator/core/src/engine/purecrypto-randomizer.ts similarity index 73% rename from libs/tools/generator/core/src/engine/key-service-randomizer.ts rename to libs/tools/generator/core/src/engine/purecrypto-randomizer.ts index 5fc719042b7..bbd43b8a231 100644 --- a/libs/tools/generator/core/src/engine/key-service-randomizer.ts +++ b/libs/tools/generator/core/src/engine/purecrypto-randomizer.ts @@ -1,14 +1,18 @@ -import { KeyService } from "@bitwarden/key-management"; +import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service"; +import { PureCrypto } from "@bitwarden/sdk-internal"; import { Randomizer } from "../abstractions"; import { WordOptions } from "../types"; -/** A randomizer backed by a KeyService. */ -export class KeyServiceRandomizer implements Randomizer { - /** instantiates the type. - * @param keyService generates random numbers +/** + * A randomizer backed by the SDK. + * Note: This should be replaced by higher level functions in the SDK eventually. + **/ +export class PureCryptoRandomizer implements Randomizer { + /** + * instantiates the type. */ - constructor(private keyService: KeyService) {} + constructor() {} async pick(list: Array): Promise { const length = list?.length ?? 0; @@ -28,7 +32,8 @@ export class KeyServiceRandomizer implements Randomizer { } if (options?.number ?? false) { - const num = await this.keyService.randomNumber(1, 9); + await SdkLoadService.Ready; + const num = PureCrypto.random_number(0, 9); word = word + num.toString(); } @@ -63,6 +68,7 @@ export class KeyServiceRandomizer implements Randomizer { } async uniform(min: number, max: number) { - return this.keyService.randomNumber(min, max); + await SdkLoadService.Ready; + return PureCrypto.random_number(min, max); } } diff --git a/libs/tools/generator/core/src/engine/username-randomizer.spec.ts b/libs/tools/generator/core/src/engine/username-randomizer.spec.ts index be0650fe16e..e8e288b74f9 100644 --- a/libs/tools/generator/core/src/engine/username-randomizer.spec.ts +++ b/libs/tools/generator/core/src/engine/username-randomizer.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { EFFLongWordList } from "@bitwarden/common/platform/misc/wordlist"; diff --git a/libs/tools/generator/core/src/factories.ts b/libs/tools/generator/core/src/factories.ts index 479545c78fe..0cd716f28af 100644 --- a/libs/tools/generator/core/src/factories.ts +++ b/libs/tools/generator/core/src/factories.ts @@ -1,11 +1,9 @@ // contains logic that constructs generator services dynamically given // a generator id. -import { KeyService } from "@bitwarden/key-management"; - import { Randomizer } from "./abstractions"; -import { KeyServiceRandomizer } from "./engine/key-service-randomizer"; +import { PureCryptoRandomizer } from "./engine/purecrypto-randomizer"; -export function createRandomizer(keyService: KeyService): Randomizer { - return new KeyServiceRandomizer(keyService); +export function createRandomizer(): Randomizer { + return new PureCryptoRandomizer(); } diff --git a/libs/tools/generator/core/src/metadata/email/catchall.spec.ts b/libs/tools/generator/core/src/metadata/email/catchall.spec.ts index 1099a6d59ea..4074b4639b6 100644 --- a/libs/tools/generator/core/src/metadata/email/catchall.spec.ts +++ b/libs/tools/generator/core/src/metadata/email/catchall.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { EmailRandomizer } from "../../engine"; diff --git a/libs/tools/generator/core/src/metadata/email/plus-address.spec.ts b/libs/tools/generator/core/src/metadata/email/plus-address.spec.ts index befc900ceab..78054133020 100644 --- a/libs/tools/generator/core/src/metadata/email/plus-address.spec.ts +++ b/libs/tools/generator/core/src/metadata/email/plus-address.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { EmailRandomizer } from "../../engine"; diff --git a/libs/tools/generator/core/src/metadata/password/eff-word-list.spec.ts b/libs/tools/generator/core/src/metadata/password/eff-word-list.spec.ts index bdf021c50f3..aacb82a51c4 100644 --- a/libs/tools/generator/core/src/metadata/password/eff-word-list.spec.ts +++ b/libs/tools/generator/core/src/metadata/password/eff-word-list.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; diff --git a/libs/tools/generator/core/src/metadata/password/random-password.spec.ts b/libs/tools/generator/core/src/metadata/password/random-password.spec.ts index 9efd5350c21..743a8d53a2b 100644 --- a/libs/tools/generator/core/src/metadata/password/random-password.spec.ts +++ b/libs/tools/generator/core/src/metadata/password/random-password.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; diff --git a/libs/tools/generator/core/src/metadata/username/eff-word-list.spec.ts b/libs/tools/generator/core/src/metadata/username/eff-word-list.spec.ts index beebb016504..0f6653360db 100644 --- a/libs/tools/generator/core/src/metadata/username/eff-word-list.spec.ts +++ b/libs/tools/generator/core/src/metadata/username/eff-word-list.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { IdentityConstraint } from "@bitwarden/common/tools/state/identity-state-constraint"; diff --git a/libs/tools/generator/core/src/policies/available-algorithms-policy.spec.ts b/libs/tools/generator/core/src/policies/available-algorithms-policy.spec.ts index 7de8c708dcf..085ea72e5d5 100644 --- a/libs/tools/generator/core/src/policies/available-algorithms-policy.spec.ts +++ b/libs/tools/generator/core/src/policies/available-algorithms-policy.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; import { PolicyId } from "@bitwarden/common/types/guid"; diff --git a/libs/tools/generator/core/src/policies/dynamic-password-policy-constraints.spec.ts b/libs/tools/generator/core/src/policies/dynamic-password-policy-constraints.spec.ts index 0bebb0825bf..4d4d54a6e18 100644 --- a/libs/tools/generator/core/src/policies/dynamic-password-policy-constraints.spec.ts +++ b/libs/tools/generator/core/src/policies/dynamic-password-policy-constraints.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { ObjectKey } from "@bitwarden/common/tools/state/object-key"; import { BuiltIn, Profile } from "../metadata"; diff --git a/libs/tools/generator/core/src/policies/passphrase-policy-constraints.spec.ts b/libs/tools/generator/core/src/policies/passphrase-policy-constraints.spec.ts index 6306382c84e..c640b05da8e 100644 --- a/libs/tools/generator/core/src/policies/passphrase-policy-constraints.spec.ts +++ b/libs/tools/generator/core/src/policies/passphrase-policy-constraints.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { BuiltIn, Profile } from "../metadata"; import { PassphrasePolicyConstraints } from "./passphrase-policy-constraints"; diff --git a/libs/tools/generator/core/src/providers/credential-preferences.spec.ts b/libs/tools/generator/core/src/providers/credential-preferences.spec.ts index 6fd747f3823..cb1ed620c5b 100644 --- a/libs/tools/generator/core/src/providers/credential-preferences.spec.ts +++ b/libs/tools/generator/core/src/providers/credential-preferences.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { AlgorithmsByType, Type } from "../metadata"; import { CredentialPreference } from "../types"; diff --git a/libs/tools/generator/core/src/providers/generator-metadata-provider.spec.ts b/libs/tools/generator/core/src/providers/generator-metadata-provider.spec.ts index 39ff74ad901..58b7c1f6804 100644 --- a/libs/tools/generator/core/src/providers/generator-metadata-provider.spec.ts +++ b/libs/tools/generator/core/src/providers/generator-metadata-provider.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { BehaviorSubject, ReplaySubject, firstValueFrom } from "rxjs"; diff --git a/libs/tools/generator/core/src/services/default-credential-generator.service.spec.ts b/libs/tools/generator/core/src/services/default-credential-generator.service.spec.ts index e459bb47f47..5c8389b7377 100644 --- a/libs/tools/generator/core/src/services/default-credential-generator.service.spec.ts +++ b/libs/tools/generator/core/src/services/default-credential-generator.service.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { BehaviorSubject, Subject, firstValueFrom, of } from "rxjs"; import { Account } from "@bitwarden/common/auth/abstractions/account.service"; diff --git a/libs/tools/generator/core/src/strategies/catchall-generator-strategy.spec.ts b/libs/tools/generator/core/src/strategies/catchall-generator-strategy.spec.ts index 99f618a4520..2de938c13dc 100644 --- a/libs/tools/generator/core/src/strategies/catchall-generator-strategy.spec.ts +++ b/libs/tools/generator/core/src/strategies/catchall-generator-strategy.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { of, firstValueFrom } from "rxjs"; diff --git a/libs/tools/generator/core/src/strategies/eff-username-generator-strategy.spec.ts b/libs/tools/generator/core/src/strategies/eff-username-generator-strategy.spec.ts index d3582127ade..ba98eb75e23 100644 --- a/libs/tools/generator/core/src/strategies/eff-username-generator-strategy.spec.ts +++ b/libs/tools/generator/core/src/strategies/eff-username-generator-strategy.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { of, firstValueFrom } from "rxjs"; diff --git a/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.spec.ts b/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.spec.ts index 99834a25417..3038d9bbdf6 100644 --- a/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.spec.ts +++ b/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { of, firstValueFrom } from "rxjs"; diff --git a/libs/tools/generator/core/src/strategies/passphrase-generator-strategy.spec.ts b/libs/tools/generator/core/src/strategies/passphrase-generator-strategy.spec.ts index ee521d753ae..9c9bf92aa64 100644 --- a/libs/tools/generator/core/src/strategies/passphrase-generator-strategy.spec.ts +++ b/libs/tools/generator/core/src/strategies/passphrase-generator-strategy.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { of, firstValueFrom } from "rxjs"; diff --git a/libs/tools/generator/core/src/strategies/password-generator-strategy.spec.ts b/libs/tools/generator/core/src/strategies/password-generator-strategy.spec.ts index 94e7c16be28..52d0d4fa272 100644 --- a/libs/tools/generator/core/src/strategies/password-generator-strategy.spec.ts +++ b/libs/tools/generator/core/src/strategies/password-generator-strategy.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { of, firstValueFrom } from "rxjs"; diff --git a/libs/tools/generator/core/src/strategies/subaddress-generator-strategy.spec.ts b/libs/tools/generator/core/src/strategies/subaddress-generator-strategy.spec.ts index 0be5132c67f..fdd08dccb6b 100644 --- a/libs/tools/generator/core/src/strategies/subaddress-generator-strategy.spec.ts +++ b/libs/tools/generator/core/src/strategies/subaddress-generator-strategy.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { of, firstValueFrom } from "rxjs"; diff --git a/libs/tools/generator/core/src/types/generated-credential.spec.ts b/libs/tools/generator/core/src/types/generated-credential.spec.ts index 3d8d2c9bd4d..bb4cce34052 100644 --- a/libs/tools/generator/core/src/types/generated-credential.spec.ts +++ b/libs/tools/generator/core/src/types/generated-credential.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { Type } from "../metadata"; import { GeneratedCredential } from "./generated-credential"; diff --git a/libs/tools/generator/extensions/history/src/generated-credential.spec.ts b/libs/tools/generator/extensions/history/src/generated-credential.spec.ts index 26a48cb83ea..3d3bd43126a 100644 --- a/libs/tools/generator/extensions/history/src/generated-credential.spec.ts +++ b/libs/tools/generator/extensions/history/src/generated-credential.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { Type } from "@bitwarden/generator-core"; import { GeneratedCredential } from "."; diff --git a/libs/tools/generator/extensions/history/src/local-generator-history.service.spec.ts b/libs/tools/generator/extensions/history/src/local-generator-history.service.spec.ts index 81335887f0d..5724b201f30 100644 --- a/libs/tools/generator/extensions/history/src/local-generator-history.service.spec.ts +++ b/libs/tools/generator/extensions/history/src/local-generator-history.service.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { firstValueFrom, of } from "rxjs"; diff --git a/libs/tools/generator/extensions/legacy/src/create-legacy-password-generation-service.ts b/libs/tools/generator/extensions/legacy/src/create-legacy-password-generation-service.ts index 0048ce15499..6fbdf4afbed 100644 --- a/libs/tools/generator/extensions/legacy/src/create-legacy-password-generation-service.ts +++ b/libs/tools/generator/extensions/legacy/src/create-legacy-password-generation-service.ts @@ -13,7 +13,7 @@ import { LegacyPasswordGenerationService } from "./legacy-password-generation.se import { PasswordGenerationServiceAbstraction } from "./password-generation.service.abstraction"; const { PassphraseGeneratorStrategy, PasswordGeneratorStrategy } = strategies; -const { KeyServiceRandomizer, PasswordRandomizer } = engine; +const { PureCryptoRandomizer, PasswordRandomizer } = engine; const DefaultGeneratorService = services.DefaultGeneratorService; @@ -24,7 +24,7 @@ export function legacyPasswordGenerationServiceFactory( accountService: AccountService, stateProvider: StateProvider, ): PasswordGenerationServiceAbstraction { - const randomizer = new KeyServiceRandomizer(keyService); + const randomizer = new PureCryptoRandomizer(); const passwordRandomizer = new PasswordRandomizer(randomizer, Date.now); const passwords = new DefaultGeneratorService( diff --git a/libs/tools/generator/extensions/legacy/src/create-legacy-username-generation-service.ts b/libs/tools/generator/extensions/legacy/src/create-legacy-username-generation-service.ts index 36b4a20aec7..2507c5f7ecd 100644 --- a/libs/tools/generator/extensions/legacy/src/create-legacy-username-generation-service.ts +++ b/libs/tools/generator/extensions/legacy/src/create-legacy-username-generation-service.ts @@ -14,7 +14,7 @@ import { KeyService } from "@bitwarden/key-management"; import { LegacyUsernameGenerationService } from "./legacy-username-generation.service"; import { UsernameGenerationServiceAbstraction } from "./username-generation.service.abstraction"; -const { KeyServiceRandomizer, UsernameRandomizer, EmailRandomizer, EmailCalculator } = engine; +const { PureCryptoRandomizer, UsernameRandomizer, EmailRandomizer, EmailCalculator } = engine; const DefaultGeneratorService = services.DefaultGeneratorService; const { CatchallGeneratorStrategy, @@ -32,7 +32,7 @@ export function legacyUsernameGenerationServiceFactory( accountService: AccountService, stateProvider: StateProvider, ): UsernameGenerationServiceAbstraction { - const randomizer = new KeyServiceRandomizer(keyService); + const randomizer = new PureCryptoRandomizer(); const restClient = new RestClient(apiService, i18nService); const usernameRandomizer = new UsernameRandomizer(randomizer); const emailRandomizer = new EmailRandomizer(randomizer); diff --git a/libs/tools/generator/extensions/legacy/src/legacy-password-generation.service.spec.ts b/libs/tools/generator/extensions/legacy/src/legacy-password-generation.service.spec.ts index f575cd3b619..7846d78c77b 100644 --- a/libs/tools/generator/extensions/legacy/src/legacy-password-generation.service.spec.ts +++ b/libs/tools/generator/extensions/legacy/src/legacy-password-generation.service.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { of } from "rxjs"; diff --git a/libs/tools/generator/extensions/legacy/src/legacy-username-generation.service.spec.ts b/libs/tools/generator/extensions/legacy/src/legacy-username-generation.service.spec.ts index 5a4dce4f4a5..de2059f86ef 100644 --- a/libs/tools/generator/extensions/legacy/src/legacy-username-generation.service.spec.ts +++ b/libs/tools/generator/extensions/legacy/src/legacy-username-generation.service.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { mock } from "jest-mock-extended"; diff --git a/libs/tools/generator/extensions/navigation/src/default-generator-navigation.service.spec.ts b/libs/tools/generator/extensions/navigation/src/default-generator-navigation.service.spec.ts index 37e8ec6e379..cd98ea30ace 100644 --- a/libs/tools/generator/extensions/navigation/src/default-generator-navigation.service.spec.ts +++ b/libs/tools/generator/extensions/navigation/src/default-generator-navigation.service.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { mock } from "jest-mock-extended"; import { firstValueFrom, of } from "rxjs"; diff --git a/libs/tools/generator/extensions/navigation/src/generator-navigation-evaluator.spec.ts b/libs/tools/generator/extensions/navigation/src/generator-navigation-evaluator.spec.ts index 82b9e29e91a..999edb2d25c 100644 --- a/libs/tools/generator/extensions/navigation/src/generator-navigation-evaluator.spec.ts +++ b/libs/tools/generator/extensions/navigation/src/generator-navigation-evaluator.spec.ts @@ -1,3 +1,7 @@ +/// SDK/WASM code relies on TextEncoder/TextDecoder being available globally +import { TextEncoder, TextDecoder } from "util"; +Object.assign(global, { TextDecoder, TextEncoder }); + import { DefaultGeneratorNavigation } from "./default-generator-navigation"; import { GeneratorNavigationEvaluator } from "./generator-navigation-evaluator";