1 import type { ActiveAddressKeyPayload } from '../api/keys';
2 import { AddressActiveStatus, updateAddressActiveKeysRoute } from '../api/keys';
3 import type { ActiveKey, Address, AddressKey, Api, DecryptedKey, KeyTransparencyVerify } from '../interfaces';
4 import { getActiveAddressKeys, getNormalizedActiveAddressKeys } from './getActiveKeys';
5 import { getInactiveKeys } from './getInactiveKeys';
6 import { getSignedKeyListWithDeferredPublish } from './signedKeyList';
9 * Filters the decrypted keys to include only those that have been migrated and have a matching
11 * A key is considered migrated if it has a Token and a Signature associated with it.
13 function filterMigratedDecryptedKeys(decryptedKeys: DecryptedKey[], addressKeys: AddressKey[]) {
14 return decryptedKeys.filter(({ ID }) => {
15 const matchingAddressKey = addressKeys.find((addressKey) => ID === addressKey.ID);
16 return matchingAddressKey && matchingAddressKey.Token && matchingAddressKey.Signature;
21 * Checks if there is a mismatch between active keys reported by the server
22 * and decrypted keys of the client.
24 export const hasActiveKeysMismatch = (address: Address, decryptedKeys: DecryptedKey[]): Boolean => {
25 if (!decryptedKeys.length || !address.SignedKeyList) {
26 // If there are no decrypted keys or no skl, do not update.
29 // Only consider migrated keys as active.
30 const migratedDecryptedKeys = filterMigratedDecryptedKeys(decryptedKeys, address.Keys);
31 const activeKeysIDs = new Set(migratedDecryptedKeys.map(({ ID }) => ID));
32 return address.Keys.some(({ Active, ID }) => Active && !activeKeysIDs.has(ID));
36 * Updates the active keys in the backend with the current active keys at the client.
37 * Should be called if a mismatch of active keys between the server and the client has been detected.
39 export const updateActiveKeys = async (
42 decryptedKeys: DecryptedKey[],
43 keyTransparencyVerify: KeyTransparencyVerify
45 // Only consider migrated keys as active.
46 const migratedDecryptedKeys = filterMigratedDecryptedKeys(decryptedKeys, address.Keys);
47 const [activeKeys, inactiveKeys] = await Promise.all([
48 getActiveAddressKeys(address, address.SignedKeyList, address.Keys, migratedDecryptedKeys),
49 getInactiveKeys(address.Keys, migratedDecryptedKeys),
51 const normalizedActiveKeysByVersion = getNormalizedActiveAddressKeys(address, activeKeys);
52 const [signedKeyList, onSKLPublishSuccess] = await getSignedKeyListWithDeferredPublish(
53 normalizedActiveKeysByVersion,
57 const normalizedActiveKeys = (normalizedActiveKeysByVersion.v4 as ActiveKey[]).concat(
58 normalizedActiveKeysByVersion.v6
60 const activeKeysPayload = normalizedActiveKeys.map<ActiveAddressKeyPayload>(({ ID }) => {
63 Active: AddressActiveStatus.ACTIVE,
66 const inactiveKeysPayload = inactiveKeys.map<ActiveAddressKeyPayload>(({ Key }) => {
69 Active: AddressActiveStatus.INACTIVE,
73 updateAddressActiveKeysRoute({
74 AddressID: address.ID,
75 Keys: activeKeysPayload.concat(inactiveKeysPayload),
76 SignedKeyList: signedKeyList,
79 await onSKLPublishSuccess();