Merge branch 'IDTEAM-1.26.0' into 'main'
[ProtonMail-WebClient.git] / packages / shared / lib / calendar / formatData.ts
blob82af00b8bbac589bfb068f8806b0fb2ac1f102c9
1 import type {
2     CalendarNotificationSettings,
3     CreateOrUpdateCalendarEventData,
4 } from '@proton/shared/lib/interfaces/calendar';
5 import isTruthy from '@proton/utils/isTruthy';
7 import { uint8ArrayToBase64String } from '../helpers/encoding';
8 import type { SimpleMap } from '../interfaces';
9 import type { AttendeeClearPartResult } from '../interfaces/calendar/Attendee';
10 import type { EncryptPartResult, SignPartResult } from '../interfaces/calendar/PartResult';
11 import { CALENDAR_CARD_TYPE } from './constants';
13 const { ENCRYPTED_AND_SIGNED, SIGNED } = CALENDAR_CARD_TYPE;
15 /**
16  * Format the data into what the API expects.
17  */
18 interface FormatDataArguments {
19     sharedSignedPart?: SignPartResult;
20     sharedEncryptedPart?: EncryptPartResult;
21     sharedSessionKey?: Uint8Array;
22     cancelledOccurrenceSignedPart?: SignPartResult;
23     calendarSignedPart?: SignPartResult;
24     calendarEncryptedPart?: EncryptPartResult;
25     calendarSessionKey?: Uint8Array;
26     attendeesEncryptedPart?: EncryptPartResult;
27     attendeesClearPart?: AttendeeClearPartResult[];
28     removedAttendeesEmails?: string[];
29     attendeesEncryptedSessionKeysMap?: SimpleMap<Uint8Array>;
30     notificationsPart?: CalendarNotificationSettings[];
31     colorPart?: string;
33 export const formatData = ({
34     sharedSignedPart,
35     sharedEncryptedPart,
36     sharedSessionKey,
37     cancelledOccurrenceSignedPart,
38     calendarSignedPart,
39     calendarEncryptedPart,
40     calendarSessionKey,
41     notificationsPart,
42     colorPart,
43     attendeesEncryptedPart,
44     attendeesClearPart,
45     removedAttendeesEmails,
46     attendeesEncryptedSessionKeysMap,
47 }: FormatDataArguments) => {
48     const result: Omit<CreateOrUpdateCalendarEventData, 'Permissions'> = {
49         Notifications: notificationsPart || null,
50         Color: colorPart || null,
51     };
53     if (sharedSessionKey) {
54         result.SharedKeyPacket = uint8ArrayToBase64String(sharedSessionKey);
55     }
57     if (sharedSignedPart && sharedEncryptedPart) {
58         result.SharedEventContent = [
59             {
60                 Type: SIGNED,
61                 Data: sharedSignedPart.data,
62                 Signature: sharedSignedPart.signature,
63             },
64             {
65                 Type: ENCRYPTED_AND_SIGNED,
66                 Data: uint8ArrayToBase64String(sharedEncryptedPart.dataPacket),
67                 Signature: sharedEncryptedPart.signature,
68             },
69         ];
70     }
72     if (cancelledOccurrenceSignedPart) {
73         result.CancelledOccurrenceContent = [
74             {
75                 Type: SIGNED,
76                 Data: cancelledOccurrenceSignedPart.data,
77                 Signature: cancelledOccurrenceSignedPart.signature,
78             },
79         ];
80     }
82     if (calendarEncryptedPart && calendarSessionKey) {
83         result.CalendarKeyPacket = uint8ArrayToBase64String(calendarSessionKey);
84     }
86     if (calendarSignedPart || calendarEncryptedPart) {
87         result.CalendarEventContent = [
88             calendarSignedPart && {
89                 Type: SIGNED,
90                 Data: calendarSignedPart.data,
91                 Signature: calendarSignedPart.signature,
92             },
93             calendarEncryptedPart && {
94                 Type: ENCRYPTED_AND_SIGNED,
95                 Data: uint8ArrayToBase64String(calendarEncryptedPart.dataPacket),
96                 Signature: calendarEncryptedPart.signature,
97             },
98         ].filter(isTruthy);
99     }
101     if (attendeesEncryptedPart) {
102         result.AttendeesEventContent = [
103             {
104                 Type: ENCRYPTED_AND_SIGNED,
105                 Data: uint8ArrayToBase64String(attendeesEncryptedPart.dataPacket),
106                 Signature: attendeesEncryptedPart.signature,
107             },
108         ];
109     }
111     if (attendeesClearPart) {
112         result.Attendees = attendeesClearPart.map(({ token, status }) => ({
113             Token: token,
114             Status: status,
115         }));
116     }
118     if (removedAttendeesEmails?.length) {
119         result.RemovedAttendeeAddresses = removedAttendeesEmails;
120     }
122     if (attendeesEncryptedSessionKeysMap) {
123         result.AddedProtonAttendees = Object.keys(attendeesEncryptedSessionKeysMap)
124             .map((email) => {
125                 const sharedEncryptedSessionKey = attendeesEncryptedSessionKeysMap[email];
126                 if (!sharedEncryptedSessionKey) {
127                     return;
128                 }
129                 return { Email: email, AddressKeyPacket: uint8ArrayToBase64String(sharedEncryptedSessionKey) };
130             })
131             .filter(isTruthy);
132     }
134     return result;