import { decryptMessage , DecryptResultPmcrypto , getMessage , getSignature , OpenPGPKey , SessionKey , VERIFICATION_STATUS , binaryStringToArray , concatArrays , } from 'pmcrypto' ; import { getAttachment } from '@proton/shared/lib/api/attachments' ; import { decodeBase64 } from '@proton/shared/lib/helpers/base64' ; import { Api } from '@proton/shared/lib/interfaces' ; import { Attachment } from '@proton/shared/lib/interfaces/mail/Message' ; import { getSessionKey } from '@proton/shared/lib/mail/send/attachments' ; import { MessageKeys , MessageVerification } from '../../logic/messages/messagesTypes' ; export const decrypt = async ( encryptedBinaryBuffer , sessionKey , signature ? , publicKeys ? ) : Promise < DecryptResultPmcrypto & { data : Uint8Array | ReadableStream < Uint8Array > ; } > => { const encryptedBinary = new Uint8Array ( encryptedBinaryBuffer ) ; try { return await decryptMessage ( { message : await getMessage ( encryptedBinary ) , sessionKeys : [ sessionKey ] , signature : signature ? await getSignature ( signature ) : undefined , publicKeys , format : 'binary' , } ) ; } catch ( err ) { console . error ( err ) ; throw err ; } } ; export const getRequest = ( { ID = '' } = { } , api ) : Promise < ArrayBuffer > => { return api ( getAttachment ( ID ) ) ; } ; export const getDecryptedAttachment = async ( attachment , verification , messageKeys , api ) : Promise < DecryptResultPmcrypto > => { const encryptedBinary = await getRequest ( attachment , api ) ; try { const sessionKey = await getSessionKey ( attachment , messageKeys . privateKeys ) ; const publicKeys = verification ?. senderVerified ? verification . senderPinnedKeys : undefined ; return await decrypt ( encryptedBinary , sessionKey , attachment . Signature , publicKeys ) ; } catch ( error ) { const blob = concatArrays ( [ binaryStringToArray ( decodeBase64 ( attachment . KeyPackets ) || '' ) , new Uint8Array ( encryptedBinary ) , ] ) ; const newError = new Error ( 'Attachment decryption error' ) ; Object . assign ( newError , { data : attachment , binary : blob , error } ) ; throw newError ; } } ; export const getAndVerify = async ( attachment = { } , verification , messageKeys , reverify = false , getAttachment , onUpdateAttachment , api ) : Promise < DecryptResultPmcrypto > => { let attachmentdata ; const attachmentID = attachment . ID || '' ; if ( attachment . Preview ) { return { data : attachment . Preview , filename : 'preview' , signatures : [ ] , verified : VERIFICATION_STATUS . NOT_SIGNED , } ; } const attachmentInState = getAttachment ( attachmentID ) ; if ( ! reverify && attachmentInState ) { attachmentdata = attachmentInState ; } else { const isMIMEAttachment = ! attachment . KeyPackets ; attachmentdata = isMIMEAttachment ? ( attachmentInState as DecryptResultPmcrypto ) : await getDecryptedAttachment ( attachment , verification , messageKeys , api ) ; } onUpdateAttachment ( attachmentID , attachmentdata ) ; return attachmentdata ; } ; export const get = ( attachment = { } , verification , messageKeys , getAttachment , onUpdateAttachment , api ) : Promise < DecryptResultPmcrypto > => { const reverify = false ; return getAndVerify ( attachment , verification , messageKeys , reverify , getAttachment , onUpdateAttachment , api ) ; } ; export const reverify = ( attachment = { } , verification , messageKeys , getAttachment , onUpdateAttachment , api ) : Promise < DecryptResultPmcrypto > => { const reverify = true ; return getAndVerify ( attachment , verification , messageKeys , reverify , getAttachment , onUpdateAttachment , api ) ; } ;