import getPublicKeysVcardHelper from '@proton/shared/lib/api/helpers/getPublicKeysVcardHelper' ; import { MINUTE , RECIPIENT_TYPES } from '@proton/shared/lib/constants' ; import { canonizeEmail , canonizeInternalEmail } from '@proton/shared/lib/helpers/email' ; import { GetEncryptionPreferences } from '@proton/shared/lib/interfaces/hooks/GetEncryptionPreferences' ; import { splitKeys } from '@proton/shared/lib/keys/keys' ; import { getContactPublicKeyModel } from '@proton/shared/lib/keys/publicKeys' ; import extractEncryptionPreferences from '@proton/shared/lib/mail/encryptionPreferences' ; import { useCallback } from 'react' ; import { useGetAddresses } from './useAddresses' ; import useApi from './useApi' ; import useCache from './useCache' ; import { getPromiseValue } from './useCachedModelResult' ; import { useGetAddressKeys } from './useGetAddressKeys' ; import useGetPublicKeys from './useGetPublicKeys' ; import { useGetMailSettings } from './useMailSettings' ; import { useGetUserKeys } from './useUserKeys' ; export const CACHE_KEY = 'ENCRYPTION_PREFERENCES' ; const DEFAULT_LIFETIME = 5 * MINUTE ; /**
 * Given an email address and the user mail settings, return the encryption preferences for sending to that email.
 * The logic for how those preferences are determined is laid out in the
 * Confluence document 'Encryption preferences for outgoing email'
 */ const useGetEncryptionPreferences = ( ) => { const api = useApi ( ) ; const cache = useCache ( ) ; const getAddresses = useGetAddresses ( ) ; const getUserKeys = useGetUserKeys ( ) ; const getAddressKeys = useGetAddressKeys ( ) ; const getPublicKeys = useGetPublicKeys ( ) ; const getMailSettings = useGetMailSettings ( ) ; const getEncryptionPreferences = useCallback < GetEncryptionPreferences > ( async ( emailAddress , lifetime , contactEmailsMap ) => { const [ addresses , mailSettings ] = await Promise . all ( [ getAddresses ( ) , getMailSettings ( ) ] ) ; const canonicalEmail = canonizeInternalEmail ( emailAddress ) ; const selfAddress = addresses . filter ( ( { Receive } ) => ! ! Receive ) . find ( ( { Email } ) => canonizeInternalEmail ( Email ) === canonicalEmail ) ; let selfSend ; let apiKeysConfig ; let pinnedKeysConfig ; if ( selfAddress ) { const selfPublicKey = ( await getAddressKeys ( selfAddress . ID ) ) [ 0 ] ?. publicKey ; selfSend = { address : selfAddress , publicKey : selfPublicKey } ; apiKeysConfig = { Keys : [ ] , publicKeys : [ ] , RecipientType : RECIPIENT_TYPES . TYPE_INTERNAL } ; pinnedKeysConfig = { pinnedKeys : [ ] , isContact : false } ; } else { const { publicKeys } = splitKeys ( await getUserKeys ( ) ) ; apiKeysConfig = await getPublicKeys ( emailAddress , lifetime , ! lifetime ) ; const isInternal = apiKeysConfig . RecipientType === RECIPIENT_TYPES . TYPE_INTERNAL ; pinnedKeysConfig = await getPublicKeysVcardHelper ( api , emailAddress , publicKeys , isInternal , contactEmailsMap ) ; } const publicKeyModel = await getContactPublicKeyModel ( { emailAddress , apiKeysConfig , pinnedKeysConfig , } ) ; return extractEncryptionPreferences ( publicKeyModel , mailSettings , selfSend ) ; } , [ api , getAddressKeys , getAddresses , getPublicKeys , getMailSettings ] ) ; return useCallback < GetEncryptionPreferences > ( ( email , lifetime = DEFAULT_LIFETIME , contactEmailsMap ) => { if ( ! cache . has ( CACHE_KEY ) ) { cache . set ( CACHE_KEY , new Map ( ) ) ; } const subCache = cache . get ( CACHE_KEY ) ; const canonicalEmail = canonizeEmail ( email ) ; const miss = ( ) => getEncryptionPreferences ( canonicalEmail , lifetime , contactEmailsMap ) ; return getPromiseValue ( subCache , canonicalEmail , miss , lifetime ) ; } , [ cache , getEncryptionPreferences ] ) ; } ; export default useGetEncryptionPreferences ;