mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 21:33:27 +00:00
Updates the InputPasswordComponent so that it can eventually be used in multiple set/change password scenarios. Most importantly, this PR adds an InputPasswordFlow enum and @Input so that parent components can dictate which UI elements to show.
128 lines
4.6 KiB
TypeScript
128 lines
4.6 KiB
TypeScript
import { MockProxy, mock } from "jest-mock-extended";
|
|
|
|
import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service";
|
|
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 { DEFAULT_KDF_CONFIG, 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<KeyService>;
|
|
let accountApiService: MockProxy<AccountApiService>;
|
|
|
|
beforeEach(() => {
|
|
keyService = mock<KeyService>();
|
|
accountApiService = mock<AccountApiService>();
|
|
|
|
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,
|
|
serverMasterKeyHash: "serverMasterKeyHash",
|
|
localMasterKeyHash: "localMasterKeyHash",
|
|
kdfConfig: DEFAULT_KDF_CONFIG,
|
|
hint: "hint",
|
|
newPassword: "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.serverMasterKeyHash,
|
|
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,
|
|
// Web only fields should be undefined
|
|
orgInviteToken: undefined,
|
|
organizationUserId: undefined,
|
|
orgSponsoredFreeFamilyPlanToken: undefined,
|
|
acceptEmergencyAccessInviteToken: undefined,
|
|
acceptEmergencyAccessId: undefined,
|
|
providerInviteToken: undefined,
|
|
providerUserId: undefined,
|
|
}),
|
|
);
|
|
});
|
|
});
|
|
});
|