1 import type { PrivateKeyReference, PrivateKeyReferenceV4, PrivateKeyReferenceV6 } from '@proton/crypto';
3 import { DEFAULT_KEYGEN_TYPE, KEYGEN_CONFIGS, KEYGEN_TYPES } from '../constants';
5 ActiveAddressKeysByVersion,
6 ActiveKey} from '../interfaces';
9 type AddressKeyPayloadV2,
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 {
23 userKey: PrivateKeyReference;
24 addressKeys: { privateKey: PrivateKeyReference; addressID: string }[];
26 userKeyPayload: string;
27 addressKeysPayload: AddressKeyPayloadV2[];
28 onSKLPublishSuccess: OnSKLPublishSuccess;
31 export const getResetAddressesKeysV2 = async ({
35 keyGenConfigForV4Keys = KEYGEN_CONFIGS[DEFAULT_KEYGEN_TYPE],
40 supportV6Keys: boolean;
41 keyGenConfigForV4Keys?: KeyGenConfig; // no option v6
42 preAuthKTVerify: PreAuthKTVerify;
43 }): Promise<ResetAddressKeysPayload | { [P in keyof ResetAddressKeysPayload]: undefined }> => {
44 if (!addresses.length) {
46 privateKeys: undefined,
47 userKeyPayload: undefined,
48 addressKeysPayload: undefined,
49 onSKLPublishSuccess: undefined,
52 const { privateKey: userKey, privateKeyArmored: userKeyPayload } = await generateUserKey({
54 keyGenConfig: supportV6Keys ? KEYGEN_CONFIGS[KEYGEN_TYPES.PQC] : keyGenConfigForV4Keys,
57 const keyTransparencyVerify = preAuthKTVerify([
58 { ID: userKey.getKeyID(), privateKey: userKey, publicKey: userKey },
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({
71 keyGenConfig: v6Key ? KEYGEN_CONFIGS[KEYGEN_TYPES.PQC] : keyGenConfigForV4Keys,
74 const newPrimaryKey = (await getActiveKeyObject(privateKey, {
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(
99 PrivateKey: privateKeyArmored,
100 SignedKeyList: signedKeyList,
101 Token: encryptedToken,
102 Signature: signature,
108 const v4KeyData = await generate(false, { v4: [], v6: [] });
109 return supportV6Keys ? [v4KeyData, await generate(true, v4KeyData.newActiveKeys)] : [v4KeyData];
113 const addressKeysPayloadWithOnSKLPublish = addressKeysPayloadWithOnSKLPublishWithMaybeV6.flat();
114 const addressKeysPayload = addressKeysPayloadWithOnSKLPublish.map(({ addressKeyPayload }) => addressKeyPayload);
115 const privateKeys = {
117 addressKeys: addressKeysPayloadWithOnSKLPublish.map(({ addressKey }) => addressKey),
119 const onSKLPublishSuccessAll = async () => {
120 await Promise.all(addressKeysPayloadWithOnSKLPublish.map(({ onSKLPublishSuccess }) => onSKLPublishSuccess()));
122 return { privateKeys, userKeyPayload, addressKeysPayload, onSKLPublishSuccess: onSKLPublishSuccessAll };