import { MockProxy, mock } from "jest-mock-extended"; import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service"; import { DEFAULT_KDF_CONFIG } from "@bitwarden/common/auth/models/domain/kdf-config"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { CsprngArray } from "@bitwarden/common/types/csprng"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { KeyService } from "@bitwarden/key-management"; import { PasswordInputResult } from "../../input-password/password-input-result"; import { DefaultRegistrationFinishService } from "./default-registration-finish.service"; describe("DefaultRegistrationFinishService", () => { let service: DefaultRegistrationFinishService; let keyService: MockProxy; let accountApiService: MockProxy; beforeEach(() => { keyService = mock(); accountApiService = mock(); service = new DefaultRegistrationFinishService(keyService, accountApiService); }); it("instantiates", () => { expect(service).not.toBeFalsy(); }); describe("getMasterPasswordPolicyOptsFromOrgInvite()", () => { it("returns null", async () => { const result = await service.getMasterPasswordPolicyOptsFromOrgInvite(); expect(result).toBeNull(); }); }); describe("getOrgNameFromOrgInvite()", () => { it("returns null", async () => { const result = await service.getOrgNameFromOrgInvite(); expect(result).toBeNull(); }); }); describe("finishRegistration()", () => { let email: string; let emailVerificationToken: string; let masterKey: MasterKey; let passwordInputResult: PasswordInputResult; let userKey: UserKey; let userKeyEncString: EncString; let userKeyPair: [string, EncString]; let capchaBypassToken: string; beforeEach(() => { email = "test@email.com"; emailVerificationToken = "emailVerificationToken"; masterKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as MasterKey; passwordInputResult = { masterKey: masterKey, masterKeyHash: "masterKeyHash", localMasterKeyHash: "localMasterKeyHash", kdfConfig: DEFAULT_KDF_CONFIG, hint: "hint", password: "password", }; userKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as UserKey; userKeyEncString = new EncString("userKeyEncrypted"); userKeyPair = ["publicKey", new EncString("privateKey")]; capchaBypassToken = "capchaBypassToken"; }); it("throws an error if the user key cannot be created", async () => { keyService.makeUserKey.mockResolvedValue([null, null]); await expect(service.finishRegistration(email, passwordInputResult)).rejects.toThrow( "User key could not be created", ); }); it("registers the user and returns a captcha bypass token when given valid email verification input", async () => { keyService.makeUserKey.mockResolvedValue([userKey, userKeyEncString]); keyService.makeKeyPair.mockResolvedValue(userKeyPair); accountApiService.registerFinish.mockResolvedValue(capchaBypassToken); const result = await service.finishRegistration( email, passwordInputResult, emailVerificationToken, ); expect(result).toEqual(capchaBypassToken); expect(keyService.makeUserKey).toHaveBeenCalledWith(masterKey); expect(keyService.makeKeyPair).toHaveBeenCalledWith(userKey); expect(accountApiService.registerFinish).toHaveBeenCalledWith( expect.objectContaining({ email, emailVerificationToken: emailVerificationToken, masterPasswordHash: passwordInputResult.masterKeyHash, masterPasswordHint: passwordInputResult.hint, userSymmetricKey: userKeyEncString.encryptedString, userAsymmetricKeys: { publicKey: userKeyPair[0], encryptedPrivateKey: userKeyPair[1].encryptedString, }, kdf: passwordInputResult.kdfConfig.kdfType, kdfIterations: passwordInputResult.kdfConfig.iterations, kdfMemory: undefined, kdfParallelism: undefined, orgInviteToken: undefined, // OrgInvite only handled in web organizationUserId: undefined, // OrgInvite only handled in web }), ); }); }); });