feat(INDA-383): daily stats.
[ProtonMail-WebClient.git] / packages / shared / lib / mail / send / attachments.ts
blobddbc9a35dde1e2a5d327f52788f9eb16557c24ec
1 import type { PrivateKeyReference, PublicKeyReference, SessionKey } from '@proton/crypto';
2 import { CryptoProxy } from '@proton/crypto';
3 import { binaryStringToArray, decodeBase64 } from '@proton/crypto/lib/utils';
5 import type { MIME_TYPES } from '../../constants';
6 import { hasBitBigInt } from '../../helpers/bitset';
7 import type { Attachment } from '../../interfaces/mail/Message';
8 import type { Packets } from '../../interfaces/mail/crypto';
9 import { MESSAGE_FLAGS } from '../constants';
11 export const encryptAttachment = async (
12     data: Uint8Array | string,
13     { name, type, size }: File = {} as File,
14     inline: boolean,
15     publicKeys: PublicKeyReference[],
16     privateKeys: PrivateKeyReference[] = []
17 ): Promise<Packets> => {
18     const dataType = data instanceof Uint8Array ? 'binaryData' : 'textData';
19     const sessionKey = await CryptoProxy.generateSessionKey({ recipientKeys: publicKeys });
21     // we encrypt using `sessionKey` directly instead of `encryptionKeys` so that returned message only includes
22     // symmetrically encrypted data
23     const { message: encryptedData, signature } = await CryptoProxy.encryptMessage({
24         format: 'binary',
25         detached: privateKeys.length > 0, // Only relevant if private keys are given
26         [dataType]: data,
27         stripTrailingSpaces: dataType === 'textData',
28         sessionKey,
29         signingKeys: privateKeys,
30     });
32     const encryptedSessionKey = await CryptoProxy.encryptSessionKey({
33         ...sessionKey,
34         encryptionKeys: publicKeys[0],
35         format: 'binary',
36     });
38     return {
39         Filename: name,
40         MIMEType: type as MIME_TYPES,
41         FileSize: size,
42         Inline: inline,
43         signature: signature,
44         Preview: data,
45         keys: encryptedSessionKey,
46         data: encryptedData,
47     };
50 export const getSessionKey = async (
51     attachment: Pick<Attachment, 'KeyPackets'>,
52     privateKeys: PrivateKeyReference[],
53     messageFlags?: number
54 ): Promise<SessionKey> => {
55     // if (attachment.sessionKey) {
56     //     return attachment;
57     // }
59     const keyPackets = binaryStringToArray(decodeBase64(attachment.KeyPackets) || '');
60     const options = {
61         binaryMessage: keyPackets,
62         decryptionKeys: privateKeys,
63         config: {
64             allowForwardedMessages: hasBitBigInt(BigInt(messageFlags || 0), MESSAGE_FLAGS.FLAG_AUTO_FORWARDEE),
65         },
66     };
68     // if (isOutside()) {
69     //     options.passwords = [eoStore.getPassword()];
70     // } else {
71     //     options.privateKeys = keysModel.getPrivateKeys(message.AddressID);
72     // }
74     const sessionKey = await CryptoProxy.decryptSessionKey(options);
76     if (sessionKey === undefined) {
77         throw new Error('Error while decrypting session keys');
78     }
80     return sessionKey;
83 export const getEOSessionKey = async (attachment: Attachment, password: string): Promise<SessionKey> => {
84     const keyPackets = binaryStringToArray(decodeBase64(attachment.KeyPackets) || '');
85     const options = { binaryMessage: keyPackets, passwords: [password] };
87     const sessionKey = await CryptoProxy.decryptSessionKey(options);
89     if (sessionKey === undefined) {
90         throw new Error('Error while decrypting session keys');
91     }
93     return sessionKey;