feat(INDA-383): daily stats.
[ProtonMail-WebClient.git] / packages / shared / lib / mail / send / sendTopPackages.ts
blobaea6ebce29fe875f04f582be56046d8c7be78955
1 /**
2  * Currently this is basically a copy of sendSubPackages from the mail repo. TO BE IMPROVED
3  */
4 import { PACKAGE_TYPE } from '@proton/shared/lib/mail/mailSettings';
5 import isTruthy from '@proton/utils/isTruthy';
7 import { MIME_TYPES } from '../../constants';
8 import type { Message } from '../../interfaces/mail/Message';
9 import type { AttachmentDirect, PackageDirect, PackageStatus, SendPreferences } from '../../interfaces/mail/crypto';
10 import type { RequireOnly, SimpleMap } from '../../interfaces/utils';
11 import { constructMime } from './helpers';
13 const { PLAINTEXT, DEFAULT, MIME } = MIME_TYPES;
15 /**
16  * Generates the mime top-level packages, which include all attachments in the body.
17  * Build the multipart/alternate MIME entity containing both the HTML and plain text entities.
18  */
19 const generateMimePackage = (
20     message: RequireOnly<Message, 'Body'>,
21     attachmentData: { attachment: AttachmentDirect; data: string }
22 ): PackageDirect => ({
23     Addresses: {},
24     MIMEType: MIME,
25     Body: constructMime(message.Body, attachmentData),
26 });
28 const generatePlainTextPackage = (message: RequireOnly<Message, 'Body'>): PackageDirect => ({
29     Addresses: {},
30     MIMEType: PLAINTEXT,
31     Body: message.Body,
32 });
34 const generateHTMLPackage = (message: RequireOnly<Message, 'Body'>): PackageDirect => ({
35     Addresses: {},
36     MIMEType: DEFAULT,
37     // We NEVER upconvert, if the user wants html: plaintext is actually fine as well
38     Body: message.Body,
39 });
41 /**
42  * Generates all top level packages. The top level packages have unencrypted bodies which are encrypted later on
43  * once the sub level packages are attached, so we know with which keys we need to encrypt the bodies with.
44  * Top level packages that are not needed are not generated.
45  */
46 export const generateTopPackages = ({
47     message,
48     sendPreferencesMap,
49     attachmentData,
50 }: {
51     message: RequireOnly<Message, 'Body'>;
52     sendPreferencesMap: SimpleMap<SendPreferences>;
53     attachmentData: { attachment: AttachmentDirect; data: string };
54 }): SimpleMap<PackageDirect> => {
55     const packagesStatus: PackageStatus = Object.values(sendPreferencesMap)
56         .filter(isTruthy)
57         .reduce(
58             (packages, { encrypt, sign, pgpScheme, mimeType }) => ({
59                 [PLAINTEXT]: packages[PLAINTEXT] || mimeType === MIME_TYPES.PLAINTEXT,
60                 [DEFAULT]:
61                     packages[DEFAULT] ||
62                     mimeType === DEFAULT ||
63                     (pgpScheme === PACKAGE_TYPE.SEND_PGP_MIME && !encrypt && !sign),
64                 [MIME]: packages[MIME] || (pgpScheme === PACKAGE_TYPE.SEND_PGP_MIME && (encrypt || sign)),
65             }),
66             {
67                 [PLAINTEXT]: false,
68                 [DEFAULT]: false,
69                 [MIME]: false,
70             } as PackageStatus
71         );
73     const demandedPackages = Object.values(MIME_TYPES).filter((k) => packagesStatus[k]);
75     const packages: SimpleMap<PackageDirect> = {};
77     demandedPackages.map(async (type) => {
78         switch (type) {
79             case MIME:
80                 packages[MIME] = generateMimePackage(message, attachmentData);
81                 return;
82             case PLAINTEXT:
83                 packages[PLAINTEXT] = generatePlainTextPackage(message);
84                 return;
85             case DEFAULT:
86                 packages[DEFAULT] = generateHTMLPackage(message);
87                 return;
88             default:
89                 throw new Error(); // Should never happen.
90         }
91     });
93     return packages;