1 import { CryptoProxy } from '@proton/crypto';
2 import isTruthy from '@proton/utils/isTruthy';
3 import noop from '@proton/utils/noop';
5 import type { DecryptedKey, KeyPair, User, Key as tsKey } from '../interfaces';
6 import { getDecryptedOrganizationKey } from './getDecryptedOrganizationKey';
7 import { decryptMemberToken } from './memberToken';
9 export const getUserKeyPassword = ({ Token }: tsKey, keyPassword: string, organizationKey?: KeyPair) => {
10 if (Token && organizationKey) {
11 return decryptMemberToken(Token, [organizationKey.privateKey], [organizationKey.publicKey]);
16 const getDecryptedUserKey = async (Key: tsKey, keyPassword: string, organizationKey?: KeyPair) => {
17 const { ID, PrivateKey } = Key;
18 const userKeyPassword = await getUserKeyPassword(Key, keyPassword, organizationKey);
19 const privateKey = await CryptoProxy.importPrivateKey({ armoredKey: PrivateKey, passphrase: userKeyPassword });
20 const publicKey = await CryptoProxy.importPublicKey({
21 binaryKey: await CryptoProxy.exportPublicKey({ key: privateKey, format: 'binary' }),
31 export const getDecryptedUserKeys = async (
32 userKeys: tsKey[] = [],
34 organizationKey?: KeyPair
35 ): Promise<DecryptedKey[]> => {
36 if (userKeys.length === 0) {
40 // Attempts to first decrypt the primary key. If this fails, there's no reason to continue with the rest because something is broken.
41 const [primaryKey, ...restKeys] = userKeys;
42 const primaryKeyResult = await getDecryptedUserKey(primaryKey, keyPassword, organizationKey).catch(noop);
43 if (!primaryKeyResult) {
47 const restKeysResult = await Promise.all(
48 restKeys.map((restKey) => getDecryptedUserKey(restKey, keyPassword, organizationKey).catch(noop))
50 return [primaryKeyResult, ...restKeysResult].filter(isTruthy);
53 export const getDecryptedUserKeysHelper = async (user: User, keyPassword: string): Promise<DecryptedKey[]> => {
54 if (!user.OrganizationPrivateKey) {
55 return getDecryptedUserKeys(user.Keys, keyPassword);
57 const organizationKey = user.OrganizationPrivateKey
58 ? await getDecryptedOrganizationKey(user.OrganizationPrivateKey, keyPassword).catch(noop)
60 if (!organizationKey) {
63 return getDecryptedUserKeys(user.Keys, keyPassword, organizationKey);