Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / applications / drive / src / app / store / _search / indexing / processEvent.ts
blob3388a2d9740b95b7d01018b98250f5e37ab55038
1 import type { PrivateKeyReference } from '@proton/crypto';
2 import type { ESEvent, ESItemEvent, EventsObject } from '@proton/encrypted-search';
3 import { ES_SYNC_ACTIONS } from '@proton/encrypted-search';
4 import { EVENT_TYPES } from '@proton/shared/lib/drive/constants';
5 import { decryptUnsigned } from '@proton/shared/lib/keys/driveKeys';
7 import type { DriveEvent, DriveEvents } from '../../_events';
8 import type { ESLink } from '../types';
9 import { createItemId, generateOrder } from '../utils';
11 type SearchEventItem = ESItemEvent<ESLink>;
12 type SearchEvent = ESEvent<ESLink>;
14 /**
15  * Formats regular events into a ESEvent batch that will be processed by ES lib
16  */
17 export default async function convertDriveEventsToSearchEvents(
18     shareId: string,
19     events: DriveEvents,
20     getLinkPrivateKey: (abortSignal: AbortSignal, shareId: string, linkId: string) => Promise<PrivateKeyReference>
21 ): Promise<SearchEvent> {
22     let eventsToStore: EventsObject = {};
23     eventsToStore[shareId] = events.eventId;
24     return {
25         eventsToStore,
26         Refresh: events.refresh ? 1 : 0,
27         attemptReDecryption: false,
28         Items: await Promise.all(
29             events.events.map((event) => convertDriveEventToSearchEvent(shareId, event, getLinkPrivateKey))
30         ),
31     };
34 const convertEventTypesToSearchEventAction = Object.fromEntries([
35     [EVENT_TYPES.CREATE, ES_SYNC_ACTIONS.CREATE],
36     [EVENT_TYPES.UPDATE, ES_SYNC_ACTIONS.UPDATE_CONTENT],
37     [EVENT_TYPES.UPDATE_METADATA, ES_SYNC_ACTIONS.UPDATE_METADATA],
38     [EVENT_TYPES.DELETE, ES_SYNC_ACTIONS.DELETE],
39 ]);
41 async function convertDriveEventToSearchEvent(
42     shareId: string,
43     event: DriveEvent,
44     getLinkPrivateKey: (abortSignal: AbortSignal, shareId: string, linkId: string) => Promise<PrivateKeyReference>
45 ): Promise<SearchEventItem> {
46     const result: SearchEventItem = {
47         ID: createItemId(shareId, event.encryptedLink.linkId),
48         Action: convertEventTypesToSearchEventAction[event.eventType],
49         ItemMetadata: undefined,
50     };
51     // There's no link meta sent from BE in case of delete event
52     if (event.eventType === EVENT_TYPES.DELETE) {
53         return result;
54     }
56     const parentPrivateKey = await getLinkPrivateKey(
57         new AbortController().signal,
58         shareId,
59         event.encryptedLink.parentLinkId
60     );
61     result.ItemMetadata = await decryptAndGenerateSearchEvent(shareId, event, parentPrivateKey);
63     return result;
66 async function decryptAndGenerateSearchEvent(shareId: string, event: DriveEvent, privateKey: PrivateKeyReference) {
67     const link = event.encryptedLink;
68     const name = await decryptUnsigned({ armoredMessage: link.name, privateKey });
69     const id = createItemId(shareId, link.linkId);
71     return {
72         decryptedName: name,
73         MIMEType: link.mimeType,
74         createTime: link.createTime,
75         id,
76         linkId: link.linkId,
77         parentLinkId: link.parentLinkId,
78         size: link.size,
79         modifiedTime: link.metaDataModifyTime,
80         shareId,
81         order: await generateOrder(id),
82     };