Use same lock values as mobile clients
[ProtonMail-WebClient.git] / packages / shared / lib / mnemonic / helpers.ts
blob9739803a274e6369eeb372ec5e01db0f0090d12f
1 import { CryptoProxy } from '@proton/crypto';
2 import { computeKeyPassword, generateKeySalt } from '@proton/srp';
4 import { getHasMigratedAddressKeys } from '../../lib/keys';
5 import { isPrivate } from '../../lib/user/helpers';
6 import type { APP_NAMES } from '../constants';
7 import { APPS } from '../constants';
8 import { MNEMONIC_STATUS } from '../interfaces';
9 import type { Address, Api, DecryptedKey, User } from '../interfaces';
10 import { srpGetVerify } from '../srp';
11 import { generateMnemonicBase64RandomBytes, generateMnemonicFromBase64RandomBytes } from './bip39Wrapper';
13 export interface MnemonicData {
14     salt: string;
15     randomBytes: string;
16     mnemonic: string;
19 export const generateMnemonicWithSalt = async () => {
20     const salt = generateKeySalt();
21     const randomBytes = generateMnemonicBase64RandomBytes();
22     const mnemonic = await generateMnemonicFromBase64RandomBytes(randomBytes);
24     return {
25         salt,
26         randomBytes,
27         mnemonic,
28     };
31 interface GenerateMnemonicPayloadParams {
32     randomBytes: string;
33     salt: string;
34     userKeys: DecryptedKey[];
35     api: Api;
36     username: string;
39 export const generateMnemonicPayload = async ({
40     randomBytes,
41     salt,
42     userKeys,
43     api,
44     username,
45 }: GenerateMnemonicPayloadParams) => {
46     const hashedPassphrase = await computeKeyPassword(randomBytes, salt);
47     const reEncryptedKeys = await Promise.all(
48         userKeys.map(async ({ ID, privateKey }) => {
49             const PrivateKey = await CryptoProxy.exportPrivateKey({
50                 privateKey,
51                 passphrase: hashedPassphrase,
52             });
53             return {
54                 ID,
55                 PrivateKey,
56             };
57         })
58     );
60     const { Auth } = await srpGetVerify({
61         api,
62         credentials: {
63             username,
64             password: randomBytes,
65         },
66     });
68     return {
69         MnemonicUserKeys: reEncryptedKeys,
70         MnemonicSalt: salt,
71         MnemonicAuth: Auth,
72     };
75 export const getIsMnemonicAvailable = ({
76     addresses,
77     user,
78     app,
79 }: {
80     addresses: Address[];
81     user: User;
82     app: APP_NAMES;
83 }) => {
84     const hasMigratedKeys = getHasMigratedAddressKeys(addresses);
85     const isNonPrivateUser = !isPrivate(user);
86     return hasMigratedKeys && !isNonPrivateUser && app !== APPS.PROTONVPN_SETTINGS;
89 export const getCanReactiveMnemonic = (user: User) => {
90     return (
91         user.MnemonicStatus === MNEMONIC_STATUS.PROMPT ||
92         user.MnemonicStatus === MNEMONIC_STATUS.ENABLED ||
93         user.MnemonicStatus === MNEMONIC_STATUS.OUTDATED
94     );