Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / shared / lib / keys / addressKeyActions.ts
blobe7a88bab3232207528c4647069f54ac686e7f1fc
1 import { removeAddressKeyRoute, setKeyFlagsRoute, setKeyPrimaryRoute } from '../api/keys';
2 import type {
3     ActiveKeyWithVersion} from '../interfaces';
4 import {
5     type Address,
6     type Api,
7     type DecryptedKey,
8     type KeyTransparencyVerify,
9 } from '../interfaces';
10 import { getActiveAddressKeys, getNormalizedActiveAddressKeys } from './getActiveKeys';
11 import { getSignedKeyListWithDeferredPublish } from './signedKeyList';
13 export const setPrimaryAddressKey = async (
14     api: Api,
15     address: Address,
16     keys: DecryptedKey[],
17     ID: string,
18     keyTransparencyVerify: KeyTransparencyVerify
19 ) => {
20     const activeKeys = await getActiveAddressKeys(address, address.SignedKeyList, address.Keys, keys);
21     const oldActiveKeyV4 = activeKeys.v4.find(({ ID: otherID }) => ID === otherID);
22     const oldActiveKeyV6 = oldActiveKeyV4 ? undefined : activeKeys.v6.find(({ ID: otherID }) => ID === otherID);
24     if (!oldActiveKeyV4 && !oldActiveKeyV6) {
25         throw new Error('Cannot set primary key');
26     }
27     const getKeysWithUpdatedPrimaryFlag = <V extends ActiveKeyWithVersion>(keys: V[], newPrimaryID: string) =>
28         keys
29             .map((activeKey) => {
30                 return {
31                     ...activeKey,
32                     primary: activeKey.ID === newPrimaryID ? 1 : 0,
33                 } as const;
34             })
35             .sort((a, b) => b.primary - a.primary);
36     const updatedActiveKeys = getNormalizedActiveAddressKeys(address, {
37         v4: oldActiveKeyV4 ? getKeysWithUpdatedPrimaryFlag(activeKeys.v4, ID) : [...activeKeys.v4],
38         v6: oldActiveKeyV6 ? getKeysWithUpdatedPrimaryFlag(activeKeys.v6, ID) : [...activeKeys.v6],
39     });
40     const [signedKeyList, onSKLPublishSuccess] = await getSignedKeyListWithDeferredPublish(
41         updatedActiveKeys,
42         address,
43         keyTransparencyVerify
44     );
45     await api(setKeyPrimaryRoute({ ID, SignedKeyList: signedKeyList }));
46     await onSKLPublishSuccess();
47     const newActivePrimaryKey = oldActiveKeyV4
48         ? updatedActiveKeys.v4.find((activeKey) => activeKey.ID === ID)!!
49         : updatedActiveKeys.v6.find((activeKey) => activeKey.ID === ID)!!;
50     const oldActiveKeys = activeKeys;
51     return [newActivePrimaryKey, updatedActiveKeys, oldActiveKeys] as const;
54 export const deleteAddressKey = async (
55     api: Api,
56     address: Address,
57     keys: DecryptedKey[],
58     ID: string,
59     keyTransparencyVerify: KeyTransparencyVerify
60 ) => {
61     const activeKeys = await getActiveAddressKeys(address, address.SignedKeyList, address.Keys, keys);
62     const oldActiveKeyV4 = activeKeys.v4.find(({ ID: otherID }) => ID === otherID);
63     const oldActiveKeyV6 = oldActiveKeyV4 ? undefined : activeKeys.v6.find(({ ID: otherID }) => ID === otherID);
65     if (oldActiveKeyV4?.primary || oldActiveKeyV6?.primary) {
66         throw new Error('Cannot delete primary key');
67     }
68     const updatedActiveKeys = getNormalizedActiveAddressKeys(address, {
69         v4: oldActiveKeyV4 ? activeKeys.v4.filter(({ ID: otherID }) => ID !== otherID) : activeKeys.v4,
70         v6: oldActiveKeyV6 ? activeKeys.v6.filter(({ ID: otherID }) => ID !== otherID) : activeKeys.v6,
71     });
72     const [signedKeyList, onSKLPublishSuccess] = await getSignedKeyListWithDeferredPublish(
73         updatedActiveKeys,
74         address,
75         keyTransparencyVerify
76     );
77     await api(removeAddressKeyRoute({ ID, SignedKeyList: signedKeyList }));
78     await onSKLPublishSuccess();
81 export const setAddressKeyFlags = async (
82     api: Api,
83     address: Address,
84     keys: DecryptedKey[],
85     ID: string,
86     flags: number,
87     keyTransparencyVerify: KeyTransparencyVerify
88 ) => {
89     const activeKeys = await getActiveAddressKeys(address, address.SignedKeyList, address.Keys, keys);
90     const setFlags = <V extends ActiveKeyWithVersion>(activeKey: V) => {
91         if (activeKey.ID === ID) {
92             return {
93                 ...activeKey,
94                 flags,
95             };
96         }
97         return activeKey;
98     };
100     const updatedActiveKeys = getNormalizedActiveAddressKeys(address, {
101         v4: activeKeys.v4.map(setFlags),
102         v6: activeKeys.v6.map(setFlags),
103     });
104     const [signedKeyList, onSKLPublishSuccess] = await getSignedKeyListWithDeferredPublish(
105         updatedActiveKeys,
106         address,
107         keyTransparencyVerify
108     );
109     await api(setKeyFlagsRoute({ ID, Flags: flags, SignedKeyList: signedKeyList }));
110     await onSKLPublishSuccess();