feat(INDA-383): daily stats.
[ProtonMail-WebClient.git] / packages / shared / lib / keys / resetKeys.ts
blob6ac69eabe209a1fb010dc25c845dcf0c82a11440
1 import type { PrivateKeyReference, PrivateKeyReferenceV4, PrivateKeyReferenceV6 } from '@proton/crypto';
3 import { DEFAULT_KEYGEN_TYPE, KEYGEN_CONFIGS, KEYGEN_TYPES } from '../constants';
4 import type {
5     ActiveAddressKeysByVersion,
6     ActiveKey} from '../interfaces';
7 import {
8     type Address,
9     type AddressKeyPayloadV2,
10     type KeyGenConfig,
11     type PreAuthKTVerify,
12     isActiveKeyV6,
13 } from '../interfaces';
14 import { generateAddressKey, generateAddressKeyTokens } from './addressKeys';
15 import { getActiveKeyObject, getNormalizedActiveAddressKeys } from './getActiveKeys';
16 import { getDefaultKeyFlags } from './keyFlags';
17 import type { OnSKLPublishSuccess } from './signedKeyList';
18 import { getSignedKeyListWithDeferredPublish } from './signedKeyList';
19 import { generateUserKey } from './userKeys';
21 export interface ResetAddressKeysPayload {
22     privateKeys: {
23         userKey: PrivateKeyReference;
24         addressKeys: { privateKey: PrivateKeyReference; addressID: string }[];
25     };
26     userKeyPayload: string;
27     addressKeysPayload: AddressKeyPayloadV2[];
28     onSKLPublishSuccess: OnSKLPublishSuccess;
31 export const getResetAddressesKeysV2 = async ({
32     addresses = [],
33     passphrase = '',
34     supportV6Keys,
35     keyGenConfigForV4Keys = KEYGEN_CONFIGS[DEFAULT_KEYGEN_TYPE],
36     preAuthKTVerify,
37 }: {
38     addresses: Address[];
39     passphrase: string;
40     supportV6Keys: boolean;
41     keyGenConfigForV4Keys?: KeyGenConfig; // no option v6
42     preAuthKTVerify: PreAuthKTVerify;
43 }): Promise<ResetAddressKeysPayload | { [P in keyof ResetAddressKeysPayload]: undefined }> => {
44     if (!addresses.length) {
45         return {
46             privateKeys: undefined,
47             userKeyPayload: undefined,
48             addressKeysPayload: undefined,
49             onSKLPublishSuccess: undefined,
50         };
51     }
52     const { privateKey: userKey, privateKeyArmored: userKeyPayload } = await generateUserKey({
53         passphrase,
54         keyGenConfig: supportV6Keys ? KEYGEN_CONFIGS[KEYGEN_TYPES.PQC] : keyGenConfigForV4Keys,
55     });
57     const keyTransparencyVerify = preAuthKTVerify([
58         { ID: userKey.getKeyID(), privateKey: userKey, publicKey: userKey },
59     ]);
61     const addressKeysPayloadWithOnSKLPublishWithMaybeV6 = await Promise.all(
62         addresses.map(async (address) => {
63             const { ID: AddressID, Email } = address;
65             const generate = async (v6Key: boolean, activeKeys: ActiveAddressKeysByVersion) => {
66                 const { token, encryptedToken, signature } = await generateAddressKeyTokens(userKey);
68                 const { privateKey, privateKeyArmored } = await generateAddressKey({
69                     email: Email,
70                     passphrase: token,
71                     keyGenConfig: v6Key ? KEYGEN_CONFIGS[KEYGEN_TYPES.PQC] : keyGenConfigForV4Keys,
72                 });
74                 const newPrimaryKey = (await getActiveKeyObject(privateKey, {
75                     ID: 'tmp',
76                     primary: 1,
77                     flags: getDefaultKeyFlags(address),
78                 })) as ActiveKey<PrivateKeyReferenceV4> | ActiveKey<PrivateKeyReferenceV6>;
80                 const toNormalize = isActiveKeyV6(newPrimaryKey)
81                     ? { v4: activeKeys.v4, v6: [newPrimaryKey, ...activeKeys.v6] }
82                     : { v4: [newPrimaryKey, ...activeKeys.v4], v6: activeKeys.v6 };
84                 const newActiveKeys = getNormalizedActiveAddressKeys(address, toNormalize);
85                 const [signedKeyList, onSKLPublishSuccess] = await getSignedKeyListWithDeferredPublish(
86                     newActiveKeys,
87                     address,
88                     keyTransparencyVerify
89                 );
91                 return {
92                     newActiveKeys,
93                     addressKey: {
94                         privateKey,
95                         addressID: AddressID,
96                     },
97                     addressKeyPayload: {
98                         AddressID,
99                         PrivateKey: privateKeyArmored,
100                         SignedKeyList: signedKeyList,
101                         Token: encryptedToken,
102                         Signature: signature,
103                     },
104                     onSKLPublishSuccess,
105                 };
106             };
108             const v4KeyData = await generate(false, { v4: [], v6: [] });
109             return supportV6Keys ? [v4KeyData, await generate(true, v4KeyData.newActiveKeys)] : [v4KeyData];
110         })
111     );
113     const addressKeysPayloadWithOnSKLPublish = addressKeysPayloadWithOnSKLPublishWithMaybeV6.flat();
114     const addressKeysPayload = addressKeysPayloadWithOnSKLPublish.map(({ addressKeyPayload }) => addressKeyPayload);
115     const privateKeys = {
116         userKey,
117         addressKeys: addressKeysPayloadWithOnSKLPublish.map(({ addressKey }) => addressKey),
118     };
119     const onSKLPublishSuccessAll = async () => {
120         await Promise.all(addressKeysPayloadWithOnSKLPublish.map(({ onSKLPublishSuccess }) => onSKLPublishSuccess()));
121     };
122     return { privateKeys, userKeyPayload, addressKeysPayload, onSKLPublishSuccess: onSKLPublishSuccessAll };