1 import type { PrivateKeyReference } from '@proton/crypto';
2 import { CryptoProxy } from '@proton/crypto';
3 import { getDefaultKeyFlags } from '@proton/shared/lib/keys';
5 import { createAddressKeyRouteV2 } from '../../api/keys';
6 import type { Address, Api, DecryptedKey, KeyTransparencyVerify } from '../../interfaces';
7 import { generateAddressKeyTokens } from '../addressKeys';
8 import { getActiveKeyObject, getActiveKeys, getNormalizedActiveKeys, getPrimaryFlag } from '../getActiveKeys';
9 import { getInactiveKeys } from '../getInactiveKeys';
10 import { reactivateAddressKeysV2 } from '../reactivation/reactivateKeysProcessV2';
11 import { getSignedKeyListWithDeferredPublish } from '../signedKeyList';
12 import { getFilteredImportRecords } from './helper';
13 import type { KeyImportData, OnKeyImportCallback } from './interface';
15 export interface ImportKeysProcessV2Arguments {
17 keyImportRecords: KeyImportData[];
18 onImport: OnKeyImportCallback;
21 addressKeys: DecryptedKey[];
22 userKey: PrivateKeyReference;
23 keyTransparencyVerify: KeyTransparencyVerify;
26 const importKeysProcessV2 = async ({
33 keyTransparencyVerify,
34 }: ImportKeysProcessV2Arguments) => {
35 const activeKeys = await getActiveKeys(address, address.SignedKeyList, address.Keys, addressKeys);
36 const inactiveKeys = await getInactiveKeys(address.Keys, activeKeys);
38 const [keysToReactivate, keysToImport, existingKeys] = getFilteredImportRecords(
44 existingKeys.forEach((keyImportRecord) => {
45 onImport(keyImportRecord.id, new Error('Key already active'));
48 let mutableActiveKeys = activeKeys;
50 for (const keyImportRecord of keysToImport) {
52 const { privateKey } = keyImportRecord;
54 const { token, encryptedToken, signature } = await generateAddressKeyTokens(userKey);
55 const privateKeyArmored = await CryptoProxy.exportPrivateKey({
60 const newActiveKey = await getActiveKeyObject(privateKey, {
62 primary: getPrimaryFlag(mutableActiveKeys),
63 flags: getDefaultKeyFlags(address),
65 const updatedActiveKeys = getNormalizedActiveKeys(address, [...mutableActiveKeys, newActiveKey]);
66 const [SignedKeyList, onSKLPublishSuccess] = await getSignedKeyListWithDeferredPublish(
72 const { Key } = await api(
73 createAddressKeyRouteV2({
74 AddressID: address.ID,
75 Primary: newActiveKey.primary,
76 PrivateKey: privateKeyArmored,
79 Token: encryptedToken,
82 // Only once the SKL is successfully posted we add it to the KT commit state.
83 await onSKLPublishSuccess();
85 // Mutably update the key with the latest value from the real ID.
86 newActiveKey.ID = Key.ID;
88 mutableActiveKeys = updatedActiveKeys;
90 onImport(keyImportRecord.id, 'ok');
92 onImport(keyImportRecord.id, e);
96 await reactivateAddressKeysV2({
99 activeKeys: mutableActiveKeys,
102 onReactivation: onImport,
103 keyTransparencyVerify,
107 export default importKeysProcessV2;