diff --git a/web/database/database-module-provider.js b/web/database/database-module-provider.js --- a/web/database/database-module-provider.js +++ b/web/database/database-module-provider.js @@ -81,6 +81,20 @@ } } + async clearSensitiveData(): Promise { + this.status = databaseStatuses.notSupported; + await this.workerProxy.scheduleOnWorker({ + type: workerRequestMessageTypes.CLEAR_SENSITIVE_DATA, + }); + } + + async isDatabaseWorkable(): Promise { + if (this.status === databaseStatuses.initInProgress) { + await this.initPromise; + } + return this.status === databaseStatuses.initSuccess; + } + async schedule( payload: WorkerRequestMessage, ): Promise { diff --git a/web/database/sqlite-data-handler.js b/web/database/sqlite-data-handler.js new file mode 100644 --- /dev/null +++ b/web/database/sqlite-data-handler.js @@ -0,0 +1,60 @@ +// @flow + +import * as React from 'react'; + +import { databaseModule } from './database-module-provider.js'; +import { useSelector } from '../redux/redux-utils.js'; +import { workerRequestMessageTypes } from '../types/worker-types.js'; + +function SQLiteDataHandler(): React.Node { + const rehydrateConcluded = useSelector( + state => !!(state._persist && state._persist.rehydrated), + ); + const currentLoggedInUserID = useSelector(state => + state.currentUserInfo?.anonymous ? undefined : state.currentUserInfo?.id, + ); + + const handleSensitiveData = React.useCallback(async () => { + try { + const currentUserData = await databaseModule.schedule({ + type: workerRequestMessageTypes.GET_CURRENT_USER_ID, + }); + + if ( + currentUserData?.userID && + currentUserData.userID !== currentLoggedInUserID + ) { + await databaseModule.clearSensitiveData(); + } + if (currentLoggedInUserID) { + await databaseModule.schedule({ + type: workerRequestMessageTypes.SET_CURRENT_USER_ID, + userID: currentLoggedInUserID, + }); + } + } catch (error) { + console.error(error); + } + }, [currentLoggedInUserID]); + + React.useEffect(() => { + (async () => { + if (currentLoggedInUserID) { + await databaseModule.userLoggedIn(currentLoggedInUserID); + } + if (!rehydrateConcluded) { + return; + } + + const isWorkable = await databaseModule.isDatabaseWorkable(); + if (!isWorkable) { + return; + } + await handleSensitiveData(); + })(); + }, [currentLoggedInUserID, handleSensitiveData, rehydrateConcluded]); + + return null; +} + +export { SQLiteDataHandler }; diff --git a/web/database/worker/db-worker.js b/web/database/worker/db-worker.js --- a/web/database/worker/db-worker.js +++ b/web/database/worker/db-worker.js @@ -171,6 +171,13 @@ if (message.type === workerRequestMessageTypes.INIT) { await initDatabase(message.sqljsFilePath, message.sqljsFilename); return; + } else if (message.type === workerRequestMessageTypes.CLEAR_SENSITIVE_DATA) { + encryptionKey = null; + if (sqliteDb) { + sqliteDb.close(); + } + await localforage.clear(); + return; } if (!sqliteDb) { diff --git a/web/types/worker-types.js b/web/types/worker-types.js --- a/web/types/worker-types.js +++ b/web/types/worker-types.js @@ -17,6 +17,7 @@ GET_PERSIST_STORAGE_ITEM: 7, SET_PERSIST_STORAGE_ITEM: 8, REMOVE_PERSIST_STORAGE_ITEM: 9, + CLEAR_SENSITIVE_DATA: 10, }); export type PingWorkerRequestMessage = { @@ -68,6 +69,10 @@ +key: string, }; +export type ClearSensitiveDataRequestMessage = { + +type: 10, +}; + export type WorkerRequestMessage = | PingWorkerRequestMessage | InitWorkerRequestMessage @@ -78,7 +83,8 @@ | GetCurrentUserIDRequestMessage | GetPersistStorageItemRequestMessage | SetPersistStorageItemRequestMessage - | RemovePersistStorageItemRequestMessage; + | RemovePersistStorageItemRequestMessage + | ClearSensitiveDataRequestMessage; export type WorkerRequestProxyMessage = { +id: number,