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>;
15 * Formats regular events into a ESEvent batch that will be processed by ES lib
17 export default async function convertDriveEventsToSearchEvents(
20 getLinkPrivateKey: (abortSignal: AbortSignal, shareId: string, linkId: string) => Promise<PrivateKeyReference>
21 ): Promise<SearchEvent> {
22 let eventsToStore: EventsObject = {};
23 eventsToStore[shareId] = events.eventId;
26 Refresh: events.refresh ? 1 : 0,
27 attemptReDecryption: false,
28 Items: await Promise.all(
29 events.events.map((event) => convertDriveEventToSearchEvent(shareId, event, getLinkPrivateKey))
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],
41 async function convertDriveEventToSearchEvent(
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,
51 // There's no link meta sent from BE in case of delete event
52 if (event.eventType === EVENT_TYPES.DELETE) {
56 const parentPrivateKey = await getLinkPrivateKey(
57 new AbortController().signal,
59 event.encryptedLink.parentLinkId
61 result.ItemMetadata = await decryptAndGenerateSearchEvent(shareId, event, parentPrivateKey);
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);
73 MIMEType: link.mimeType,
74 createTime: link.createTime,
77 parentLinkId: link.parentLinkId,
79 modifiedTime: link.metaDataModifyTime,
81 order: await generateOrder(id),