feat(INDA-383): daily stats.
[ProtonMail-WebClient.git] / packages / shared / lib / mail / send / sendSubPackages.ts
blob5c0e987641c1888000b1a89252b13212f7382aa3
1 import { PACKAGE_TYPE } from '@proton/shared/lib/mail/mailSettings';
3 /**
4  * Currently this is basically a copy of sendSubPackages from the mail repo. TO BE IMPROVED
5  */
6 import { MIME_TYPES } from '../../constants';
7 import type { Attachment } from '../../interfaces/mail/Message';
8 import type { PackageDirect, SendPreferences } from '../../interfaces/mail/crypto';
9 import type { SimpleMap } from '../../interfaces/utils';
11 const { PLAINTEXT, DEFAULT, MIME } = MIME_TYPES;
12 const { SEND_PM, SEND_CLEAR, SEND_PGP_INLINE, SEND_PGP_MIME, SEND_CLEAR_MIME } = PACKAGE_TYPE;
14 /**
15  * Package for a Proton Mail user.
16  */
17 const sendPM = async ({ publicKeys }: Pick<SendPreferences, 'publicKeys'>, attachments: Attachment[] = []) => ({
18     Type: SEND_PM,
19     PublicKey: (publicKeys?.length && publicKeys[0]) || undefined,
20     Signature: +attachments.every(({ Signature }) => Signature),
21 });
23 /**
24  * Package for a PGP/MIME user.
25  */
26 const sendPGPMime = async ({ encrypt, sign, publicKeys }: Pick<SendPreferences, 'encrypt' | 'sign' | 'publicKeys'>) => {
27     if (encrypt) {
28         return {
29             Type: SEND_PGP_MIME,
30             PublicKey: (publicKeys?.length && publicKeys[0]) || undefined,
31         };
32     }
34     // PGP/MIME signature only
35     return {
36         Type: SEND_CLEAR_MIME,
37         Signature: +sign,
38     };
41 /**
42  * Package for a PGP/Inline user.
43  */
44 const sendPGPInline = async (
45     { encrypt, sign, publicKeys }: Pick<SendPreferences, 'encrypt' | 'sign' | 'publicKeys'>,
46     attachments: Attachment[] = []
47 ) => {
48     if (encrypt) {
49         return {
50             Type: SEND_PGP_INLINE,
51             PublicKey: (publicKeys?.length && publicKeys[0]) || undefined,
52             Signature: +attachments.every(({ Signature }) => Signature),
53         };
54     }
56     // PGP/Inline signature only
57     return {
58         Type: SEND_CLEAR,
59         Signature: +sign,
60     };
63 /**
64  * Package for an unencrypted user
65  */
66 const sendClear = async () => ({ Type: SEND_CLEAR, Signature: 0 });
68 /**
69  * Attach the subpackages for encryptMessage to the given top level packages. The packages need to be encrypted before
70  * they can be send to the api. See encryptPackages for that.
71  */
72 export const attachSubPackages = async ({
73     packages,
74     attachments = [],
75     emails,
76     sendPreferencesMap,
77 }: {
78     packages: SimpleMap<PackageDirect>;
79     attachments: Attachment[];
80     emails: string[];
81     sendPreferencesMap: SimpleMap<SendPreferences>;
82 }): Promise<SimpleMap<PackageDirect>> => {
83     const bindPackageSet = async (promise: Promise<PackageDirect>, email: string, type: MIME_TYPES) => {
84         const pack = await promise;
85         const packageToUpdate = packages[type] as PackageDirect;
87         if (!packageToUpdate.Addresses) {
88             packageToUpdate.Addresses = {};
89         }
90         if (!packageToUpdate.Type) {
91             packageToUpdate.Type = 0;
92         }
94         packageToUpdate.Addresses[email] = pack;
95         packageToUpdate.Type |= pack.Type || 0;
96     };
98     const promises = emails.map((email: string) => {
99         const sendPrefs = sendPreferencesMap[email];
100         if (!sendPrefs) {
101             throw new Error('Missing send preferences');
102         }
103         const { encrypt, sign, pgpScheme, mimeType, publicKeys } = sendPrefs;
104         const packageType = mimeType === 'text/html' ? DEFAULT : PLAINTEXT;
106         switch (pgpScheme) {
107             case SEND_PM:
108                 return bindPackageSet(sendPM({ publicKeys }, attachments), email, packageType);
109             case SEND_PGP_MIME:
110                 if (!sign && !encrypt) {
111                     return bindPackageSet(sendClear(), email, DEFAULT);
112                 }
113                 return bindPackageSet(sendPGPMime({ encrypt, sign, publicKeys }), email, MIME);
114             case SEND_PGP_INLINE:
115                 return bindPackageSet(sendPGPInline({ encrypt, sign, publicKeys }, attachments), email, PLAINTEXT);
116             case SEND_CLEAR:
117                 // Sent encrypted for outside (EO) not supported here
118                 return bindPackageSet(sendClear(), email, packageType);
119             default:
120                 throw new Error('Invalid PGP scheme');
121         }
122     });
124     await Promise.all(promises);
125     return packages;