Files
cinny/src/app/utils/searchCacheInvalidation.ts
T

44 lines
1.6 KiB
TypeScript
Raw Normal View History

import { useEffect } from 'react';
import { useAtomValue } from 'jotai';
import { MatrixEvent, Room, RoomEvent } from 'matrix-js-sdk';
import { useMatrixClient } from '../hooks/useMatrixClient';
import { searchCacheEnabledAtom } from '../state/searchCacheEnabled';
import { clearRoom, deleteRow } from './searchCache';
/**
* Gitea #14 — the persistent search cache (`searchCache.ts`) had no
* invalidation path other than logout or the manual "Clear cached index"
* button, so redacted messages and rooms the user left kept their decrypted
* plaintext searchable on disk indefinitely.
*
* While the cache is enabled, listen client-wide for redactions (delete the
* redacted row) and for leaving/being banned from a room (wipe the room's
* cached rows via the existing `clearRoom`).
*/
export const useSearchCacheInvalidation = (): void => {
const mx = useMatrixClient();
const cacheEnabled = useAtomValue(searchCacheEnabledAtom);
useEffect(() => {
if (!cacheEnabled) return undefined;
const onRedaction = (event: MatrixEvent, room: Room) => {
const redactedEventId = event.getAssociatedId();
if (redactedEventId) deleteRow(room.roomId, redactedEventId);
};
const onMyMembership = (room: Room, membership: string) => {
if (membership === 'leave' || membership === 'ban') {
clearRoom(room.roomId);
}
};
mx.on(RoomEvent.Redaction, onRedaction);
mx.on(RoomEvent.MyMembership, onMyMembership);
return () => {
mx.off(RoomEvent.Redaction, onRedaction);
mx.off(RoomEvent.MyMembership, onMyMembership);
};
}, [mx, cacheEnabled]);
};