123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- import log from "@/next/log";
- import type { SRPAttributes } from "@ente/accounts/types/srp";
- import { Input, type ButtonProps } from "@mui/material";
- import { t } from "i18next";
- import SingleInputForm, {
- type SingleInputFormProps,
- } from "../components/SingleInputForm";
- import ComlinkCryptoWorker from "../crypto";
- import { CustomError } from "../error";
- import type { KeyAttributes, User } from "../user/types";
- export interface VerifyMasterPasswordFormProps {
- user: User;
- keyAttributes: KeyAttributes;
- callback: (
- key: string,
- kek: string,
- keyAttributes: KeyAttributes,
- passphrase?: string,
- ) => void;
- buttonText: string;
- submitButtonProps?: ButtonProps;
- getKeyAttributes?: (kek: string) => Promise<KeyAttributes>;
- srpAttributes?: SRPAttributes;
- }
- export default function VerifyMasterPasswordForm({
- user,
- keyAttributes,
- srpAttributes,
- callback,
- buttonText,
- submitButtonProps,
- getKeyAttributes,
- }: VerifyMasterPasswordFormProps) {
- const verifyPassphrase: SingleInputFormProps["callback"] = async (
- passphrase,
- setFieldError,
- ) => {
- try {
- const cryptoWorker = await ComlinkCryptoWorker.getInstance();
- let kek: string;
- try {
- if (srpAttributes) {
- kek = await cryptoWorker.deriveKey(
- passphrase,
- srpAttributes.kekSalt,
- srpAttributes.opsLimit,
- srpAttributes.memLimit,
- );
- } else {
- kek = await cryptoWorker.deriveKey(
- passphrase,
- keyAttributes.kekSalt,
- keyAttributes.opsLimit,
- keyAttributes.memLimit,
- );
- }
- } catch (e) {
- log.error("failed to derive key", e);
- throw Error(CustomError.WEAK_DEVICE);
- }
- if (!keyAttributes && typeof getKeyAttributes === "function") {
- keyAttributes = await getKeyAttributes(kek);
- }
- if (!keyAttributes) {
- throw Error("couldn't get key attributes");
- }
- try {
- const key = await cryptoWorker.decryptB64(
- keyAttributes.encryptedKey,
- keyAttributes.keyDecryptionNonce,
- kek,
- );
- callback(key, kek, keyAttributes, passphrase);
- } catch (e) {
- log.error("user entered a wrong password", e);
- throw Error(CustomError.INCORRECT_PASSWORD);
- }
- } catch (e) {
- if (e instanceof Error) {
- if (e.message === CustomError.TWO_FACTOR_ENABLED) {
- // two factor enabled, user has been redirected to two factor page
- return;
- }
- log.error("failed to verify passphrase", e);
- switch (e.message) {
- case CustomError.WEAK_DEVICE:
- setFieldError(t("WEAK_DEVICE"));
- break;
- case CustomError.INCORRECT_PASSWORD:
- setFieldError(t("INCORRECT_PASSPHRASE"));
- break;
- default:
- setFieldError(`${t("UNKNOWN_ERROR")} ${e.message}`);
- }
- }
- }
- };
- return (
- <SingleInputForm
- callback={verifyPassphrase}
- placeholder={t("RETURN_PASSPHRASE_HINT")}
- buttonText={buttonText}
- submitButtonProps={submitButtonProps}
- hiddenPreInput={
- <Input
- sx={{ display: "none" }}
- id="email"
- name="email"
- autoComplete="username"
- type="email"
- value={user?.email}
- />
- }
- autoComplete={"current-password"}
- fieldType="password"
- />
- );
- }
|