1 import { createAddressKeyRoute, createAddressKeyRouteV2 } from '../../api/keys';
2 import { DEFAULT_KEYGEN_TYPE, KEYGEN_CONFIGS } from '../../constants';
4 type ActiveKeyWithVersion,
5 type ActiveAddressKeysByVersion,
12 type KeyTransparencyVerify,
14 } from '../../interfaces';
15 import { generateAddressKey, getNewAddressKeyToken } from '../addressKeys';
16 import { getActiveKeyObject, getNormalizedActiveAddressKeys } from '../getActiveKeys';
17 import { getDefaultKeyFlags } from '../keyFlags';
18 import { getSignedKeyListWithDeferredPublish } from '../signedKeyList';
20 interface CreateAddressKeyLegacyArguments {
22 keyGenConfig?: KeyGenConfig; // no v6 key support for non-migrated users
25 activeKeys: ActiveAddressKeysByVersion;
26 keyTransparencyVerify: KeyTransparencyVerify;
27 addressForwardingID?: string;
30 export const removePrimary = <T extends ActiveKey>(activeKey: T): T => {
31 if (activeKey.primary) {
40 export const createAddressKeyLegacy = async ({
43 keyGenConfig = KEYGEN_CONFIGS[DEFAULT_KEYGEN_TYPE],
46 keyTransparencyVerify,
47 addressForwardingID: AddressForwardingID,
48 }: CreateAddressKeyLegacyArguments) => {
49 const { privateKey, privateKeyArmored } = await generateAddressKey({
54 const newActiveKey = await getActiveKeyObject(privateKey, {
57 flags: getDefaultKeyFlags(address),
59 // no v6 keys allowed with non-migrated keys
60 const updatedActiveKeys = getNormalizedActiveAddressKeys(address, {
61 v4: [newActiveKey, ...activeKeys.v4.map(removePrimary)],
64 const [SignedKeyList, onSKLPublishSuccess] = await getSignedKeyListWithDeferredPublish(
69 const { Key } = await api(
70 createAddressKeyRoute({
71 AddressID: address.ID,
72 Primary: newActiveKey.primary,
73 PrivateKey: privateKeyArmored,
78 await onSKLPublishSuccess();
79 newActiveKey.ID = Key.ID;
81 const formerActiveKeys = activeKeys;
82 return [newActiveKey, updatedActiveKeys, formerActiveKeys] as const;
85 interface CreateAddressKeyV2Arguments {
88 keyGenConfig?: KeyGenConfig | KeyGenConfigV6;
90 activeKeys: ActiveAddressKeysByVersion;
91 keyTransparencyVerify: KeyTransparencyVerify;
95 * Generates either a v4 or v6 address key based on `keyGenConfig`.
96 * NB: if a v6 key is requested, this does not take care of also generating a v4 one.
98 export const createAddressKeyV2 = async ({
101 keyGenConfig = KEYGEN_CONFIGS[DEFAULT_KEYGEN_TYPE],
104 keyTransparencyVerify,
105 }: CreateAddressKeyV2Arguments) => {
106 const { token, encryptedToken, signature } = await getNewAddressKeyToken({ address, userKeys });
108 const { privateKey, privateKeyArmored } = await generateAddressKey({
109 // also typeof keyGenConfig
110 email: address.Email,
114 const newActiveKey = (await getActiveKeyObject(privateKey, {
117 flags: getDefaultKeyFlags(address),
118 })) as ActiveKeyWithVersion;
120 const toNormalize = isActiveKeyV6(newActiveKey)
121 ? { v4: [...activeKeys.v4], v6: [newActiveKey, ...activeKeys.v6.map(removePrimary)] }
122 : { v4: [newActiveKey, ...activeKeys.v4.map(removePrimary)], v6: [...activeKeys.v6] };
124 const updatedActiveKeys = getNormalizedActiveAddressKeys(address, toNormalize);
126 const [SignedKeyList, onSKLPublishSuccess] = await getSignedKeyListWithDeferredPublish(
129 keyTransparencyVerify
131 const { Key } = await api(
132 createAddressKeyRouteV2({
133 AddressID: address.ID,
134 Primary: newActiveKey.primary,
135 PrivateKey: privateKeyArmored,
137 Signature: signature,
138 Token: encryptedToken,
141 // Only once the SKL is successfully posted we add it to the KT commit state.
142 await onSKLPublishSuccess();
143 newActiveKey.ID = Key.ID;
145 const formerActiveKeys = activeKeys;
146 return [newActiveKey, updatedActiveKeys, formerActiveKeys] as const;