1 import { CryptoProxy } from '@proton/crypto';
2 import isTruthy from '@proton/utils/isTruthy';
4 import type { API_KEY_SOURCE } from '../../constants';
9 KeyTransparencyVerificationResult,
11 VerifyOutboundPublicKeys,
12 } from '../../interfaces';
13 import { getAllPublicKeys } from '../keys';
15 export interface ApiKeysWithKTStatus {
17 Keys: ApiAddressKey[];
18 SignedKeyList: FetchedSignedKeyList | null;
20 addressKeys: ProcessedApiKey[];
21 addressKTResult?: KeyTransparencyVerificationResult;
22 catchAllKeys?: ProcessedApiKey[];
23 catchAllKTResult?: KeyTransparencyVerificationResult;
24 unverifiedKeys?: ProcessedApiKey[];
25 hasValidProtonMX?: boolean;
30 interface ApiAddressKey {
33 Source: API_KEY_SOURCE;
36 const importKeys = async (keys: ApiAddressKey[], checkCompatibility?: boolean): Promise<ProcessedApiKey[]> => {
37 const promises = await Promise.all(
38 keys.map(async ({ PublicKey: armoredKey, Flags, Source }) => {
39 const publicKey = await CryptoProxy.importPublicKey({ armoredKey, checkCompatibility }).catch(() => null);
54 return promises.filter(isTruthy);
57 export const getAndVerifyApiKeys = async ({
61 verifyOutboundPublicKeys,
62 skipVerificationOfExternalDomains = false,
69 internalKeysOnly: boolean;
70 /** KT verification function, or `null` for legacy use-case where KT is disabled */
71 verifyOutboundPublicKeys: VerifyOutboundPublicKeys | null;
72 userContext?: KTUserContext;
73 /** Optimisations _only_ for apps where users with external domains do not have valid keys (e.g. Mail) */
74 skipVerificationOfExternalDomains?: boolean;
77 }): Promise<ApiKeysWithKTStatus> => {
78 const config: any = { ...getAllPublicKeys({ Email: email, InternalOnly: internalKeysOnly ? 1 : 0 }), silence };
80 config.cache = 'no-cache';
82 const { Address, CatchAll, Unverified, ProtonMX, ...rest } = await api<{
84 Keys: ApiAddressKey[];
85 SignedKeyList: FetchedSignedKeyList | null;
89 Keys: ApiAddressKey[];
90 SignedKeyList: FetchedSignedKeyList | null;
94 Keys: ApiAddressKey[];
99 const addressKeys = await importKeys(Address.Keys);
100 const unverifiedKeys = Unverified ? await importKeys(Unverified.Keys, true) : undefined;
101 const catchAllKeys = CatchAll ? await importKeys(CatchAll.Keys) : undefined;
102 const ktResult = verifyOutboundPublicKeys
103 ? await verifyOutboundPublicKeys({
107 skipVerificationOfExternalDomains,
108 address: { keyList: addressKeys, signedKeyList: Address.SignedKeyList },
109 catchAll: CatchAll ? { keyList: catchAllKeys!, signedKeyList: CatchAll.SignedKeyList } : undefined,
117 hasValidProtonMX: ProtonMX,