From 174c3af66d07e863379add19329e5843cda9a976 Mon Sep 17 00:00:00 2001 From: Paul Tran-Van Date: Mon, 28 Oct 2024 17:43:44 +0100 Subject: [PATCH 1/4] feat: Better naming for setup API BREAKING CHANGE: the DataProxy must be initialized with `setup` rather than `setClient` --- src/dataproxy/common/DataProxyInterface.ts | 2 +- src/dataproxy/worker/SharedWorkerProvider.tsx | 2 +- src/dataproxy/worker/shared-worker.ts | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/dataproxy/common/DataProxyInterface.ts b/src/dataproxy/common/DataProxyInterface.ts index 7b6309d..0c7fb2b 100644 --- a/src/dataproxy/common/DataProxyInterface.ts +++ b/src/dataproxy/common/DataProxyInterface.ts @@ -5,7 +5,7 @@ export type { SearchIndexes } from '@/search/types' export interface DataProxyWorker { search: (query: string) => unknown - setClient: (clientData: ClientData) => Promise + setup: (clientData: ClientData) => Promise } export interface DataProxyWorkerPartialState { diff --git a/src/dataproxy/worker/SharedWorkerProvider.tsx b/src/dataproxy/worker/SharedWorkerProvider.tsx index 462efd1..f8cdbe0 100644 --- a/src/dataproxy/worker/SharedWorkerProvider.tsx +++ b/src/dataproxy/worker/SharedWorkerProvider.tsx @@ -57,7 +57,7 @@ export const SharedWorkerProvider = React.memo( log.debug('Provide CozyClient data to SharedWorker') const { uri, token } = client.getStackClient() - obj.setClient({ + obj.setup({ uri, token: token.token, instanceOptions: client.instanceOptions, diff --git a/src/dataproxy/worker/shared-worker.ts b/src/dataproxy/worker/shared-worker.ts index 67b669b..0e47b94 100644 --- a/src/dataproxy/worker/shared-worker.ts +++ b/src/dataproxy/worker/shared-worker.ts @@ -23,8 +23,7 @@ let searchEngine: SearchEngine const broadcastChannel = new BroadcastChannel('DATA_PROXY_BROADCAST_CHANANEL') const dataProxy: DataProxyWorker = { - // FIXME: change setClient name - setClient: async (clientData: ClientData) => { + setup: async (clientData: ClientData) => { log.debug('Received data for setting client') if (client) return updateState() From 9491e0eadc9e8ba73fe436ecaa79d1e3ba475df2 Mon Sep 17 00:00:00 2001 From: Paul Tran-Van Date: Mon, 4 Nov 2024 16:35:53 +0100 Subject: [PATCH 2/4] feat: Better permissions description --- manifest.webapp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/manifest.webapp b/manifest.webapp index 43cace2..eab9cb1 100644 --- a/manifest.webapp +++ b/manifest.webapp @@ -27,14 +27,16 @@ ], "permissions": { "apps": { - "description": "Required by the cozy-bar to display the icons of the apps", + "description": "Required to search in apps", "type": "io.cozy.apps", "verbs": ["GET"] }, "files": { + "description": "Required to search in files", "type": "io.cozy.files" }, "contacts": { + "description": "Required to search in contacts", "type": "io.cozy.contacts" } } From 607d33660e9ce0b38e0f9382760f3748f5724632 Mon Sep 17 00:00:00 2001 From: Paul Tran-Van Date: Tue, 5 Nov 2024 11:20:52 +0100 Subject: [PATCH 3/4] feat: Destroy at logout --- package.json | 4 ++-- src/dataproxy/worker/platformWorker.ts | 16 +++++++++++++++ yarn.lock | 28 +++++++++++++------------- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 9b9b730..a66050e 100644 --- a/package.json +++ b/package.json @@ -14,12 +14,12 @@ "dependencies": { "comlink": "^4.4.1", "cozy-app-publish": "^0.34.0", - "cozy-client": "^49.8.0", + "cozy-client": "^50.1.0", "cozy-device-helper": "^3.1.0", "cozy-flags": "^4.0.0", "cozy-logger": "^1.10.4", "cozy-minilog": "^3.3.1", - "cozy-pouch-link": "^49.8.0", + "cozy-pouch-link": "^50.1.0", "cozy-realtime": "^5.0.2", "cozy-tsconfig": "^1.2.0", "flexsearch": "^0.7.43", diff --git a/src/dataproxy/worker/platformWorker.ts b/src/dataproxy/worker/platformWorker.ts index 670ca36..8df5a3c 100644 --- a/src/dataproxy/worker/platformWorker.ts +++ b/src/dataproxy/worker/platformWorker.ts @@ -77,6 +77,22 @@ const storage = { resolve() } + request.onerror = (): void => { + reject(request.error) + } + }) + }, + destroy: async (): Promise => { + return new Promise((resolve, reject) => { + if (db) { + db.close() + db = null + } + const request = indexedDB.deleteDatabase(dbName) + + request.onsuccess = (): void => { + resolve() + } request.onerror = (): void => { reject(request.error) } diff --git a/yarn.lock b/yarn.lock index f4f326c..eb8bfd4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2248,16 +2248,16 @@ cozy-app-publish@^0.34.0: tar "^6.1.11" verror "^1.10.1" -cozy-client@^49.8.0: - version "49.8.0" - resolved "https://registry.yarnpkg.com/cozy-client/-/cozy-client-49.8.0.tgz#d4f6b3a2fb26dc6bfa561046b075eb6e221af73e" - integrity sha512-peb2n+buOihzqqNN3/zULmytQI8wOtQZsIqLWEaw2WfNXha1T23wNBrMuE7SaMOof361f011MrM5+WVYhKj+VA== +cozy-client@^50.1.0: + version "50.1.0" + resolved "https://registry.yarnpkg.com/cozy-client/-/cozy-client-50.1.0.tgz#f21be140f97dbece22c6ffde3f2dc2a0104fe8ec" + integrity sha512-1RJ5nJGxZy4MrJ6ZOiyiYCLDHScqKtJ8Aja89M28zvzgg5e0HUyEjTQEgnh9f0cpfKuiUOQtLmoMCtd2OWIOXA== dependencies: "@cozy/minilog" "1.0.0" "@types/jest" "^26.0.20" "@types/lodash" "^4.14.170" btoa "^1.2.1" - cozy-stack-client "^49.8.0" + cozy-stack-client "^50.1.0" date-fns "2.29.3" json-stable-stringify "^1.0.1" lodash "^4.17.13" @@ -2302,12 +2302,12 @@ cozy-minilog@^3.3.1: dependencies: microee "0.0.6" -cozy-pouch-link@^49.8.0: - version "49.8.0" - resolved "https://registry.yarnpkg.com/cozy-pouch-link/-/cozy-pouch-link-49.8.0.tgz#a5361bbc0ed23b9bc4d804d31869c615fdf1d13e" - integrity sha512-c5+dWx5BNi37JuLVpil9SB91vy3EtB7B8Qa6Krx+znzPYcRoK3Bqjuns5c7hXG5rD8MV2qls1yvxQWUrfy82kA== +cozy-pouch-link@^50.1.0: + version "50.1.0" + resolved "https://registry.yarnpkg.com/cozy-pouch-link/-/cozy-pouch-link-50.1.0.tgz#b9aa635b9347a9d0a30c2b803d57b67f066bbdeb" + integrity sha512-M3/wbX85ccM1qzUdOnRkLdhQ7XTmv3K1cYBhOx6DN/dSzhADkmDl4OeqmhJJmV3GyncGZVEnjOWkPi1J/Wc7gg== dependencies: - cozy-client "^49.8.0" + cozy-client "^50.1.0" pouchdb-browser "^7.2.2" pouchdb-find "^7.2.2" @@ -2319,10 +2319,10 @@ cozy-realtime@^5.0.2: "@cozy/minilog" "^1.0.0" cozy-device-helper "^3.1.0" -cozy-stack-client@^49.8.0: - version "49.8.0" - resolved "https://registry.yarnpkg.com/cozy-stack-client/-/cozy-stack-client-49.8.0.tgz#c57dfefe50e47f228fee7e1921c438d35f4e0877" - integrity sha512-sYJL2o+DsNs7V5eQghXpWKcMzxc39QAKtM8zAdmWl2MMCyiqO3lBehRomhstcJHtuZrMLXXPQPr1A0ONBlMmZg== +cozy-stack-client@^50.1.0: + version "50.1.0" + resolved "https://registry.yarnpkg.com/cozy-stack-client/-/cozy-stack-client-50.1.0.tgz#ec48a55732efc87956739f63a211719c3dd87b32" + integrity sha512-WHkNznIiUJa6nKlRgbhDiypMLTRv+DCEfcz9Kp6bRA5VlSc8Lk0igNjclS+bglrXBz7cTUF4Q0QSCQlWcFEpiQ== dependencies: detect-node "^2.0.4" mime "^2.4.0" From be4523e44e51477f86a0339cac24ec27406218c3 Mon Sep 17 00:00:00 2001 From: Paul Tran-Van Date: Mon, 4 Nov 2024 16:41:08 +0100 Subject: [PATCH 4/4] feat: Add public route to reset local data When the stack serves the login page, we take this opportunity to remove any remaining local data, i.e. indexedDB and localstorage data. See how it is done for the stack part: https://github.com/cozy/cozy-stack/pull/4483 --- manifest.webapp | 5 ++++ rsbuild.config.ts | 14 +++++++--- src/dataproxy/worker/SharedWorkerProvider.tsx | 5 ++++ src/dataproxy/worker/shared-worker.ts | 3 ++- src/dataproxy/worker/utils.ts | 26 +++++++++++++++++++ src/search/consts.ts | 2 ++ src/targets/browser/index.ejs | 1 - src/targets/public/index.html | 6 +++++ src/targets/public/reset.js | 22 ++++++++++++++++ 9 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 src/dataproxy/worker/utils.ts create mode 100644 src/targets/public/index.html create mode 100644 src/targets/public/reset.js diff --git a/manifest.webapp b/manifest.webapp index eab9cb1..151d9c0 100644 --- a/manifest.webapp +++ b/manifest.webapp @@ -16,6 +16,11 @@ "folder": "/", "index": "index.html", "public": false + }, + "/reset": { + "folder": "/reset", + "index": "index.html", + "public": true } }, "intents": [ diff --git a/rsbuild.config.ts b/rsbuild.config.ts index fa6a734..c405920 100644 --- a/rsbuild.config.ts +++ b/rsbuild.config.ts @@ -9,8 +9,8 @@ export default defineConfig({ output: { cleanDistPath: true, distPath: { - root: 'build' - } + root: 'build', + }, }, html: { template: './src/targets/browser/index.ejs', @@ -49,7 +49,15 @@ export default defineConfig({ }, { from: 'icon.svg' - } + }, + { + from: 'src/targets/public/index.html', + to: 'reset/index.html' + }, + { + from: 'src/targets/public/reset.js', + to: 'reset/reset.js' + }, ], }) ] diff --git a/src/dataproxy/worker/SharedWorkerProvider.tsx b/src/dataproxy/worker/SharedWorkerProvider.tsx index f8cdbe0..6b305fe 100644 --- a/src/dataproxy/worker/SharedWorkerProvider.tsx +++ b/src/dataproxy/worker/SharedWorkerProvider.tsx @@ -10,6 +10,7 @@ import { DataProxyWorkerPartialState } from '@/dataproxy/common/DataProxyInterface' import { TabCountSync } from '@/dataproxy/common/TabCountSync' +import { removeStaleLocalData } from '@/dataproxy/worker/utils' const log = Minilog('👷‍♂️ [SharedWorkerProvider]') @@ -44,7 +45,11 @@ export const SharedWorkerProvider = React.memo( if (!client) return const doAsync = async (): Promise => { + // Cleanup any remaining local data + await removeStaleLocalData() + log.debug('Init SharedWorker') + const workerInst = new SharedWorker( new URL('./shared-worker.ts', import.meta.url), { diff --git a/src/dataproxy/worker/shared-worker.ts b/src/dataproxy/worker/shared-worker.ts index 0e47b94..0daba01 100644 --- a/src/dataproxy/worker/shared-worker.ts +++ b/src/dataproxy/worker/shared-worker.ts @@ -24,7 +24,7 @@ const broadcastChannel = new BroadcastChannel('DATA_PROXY_BROADCAST_CHANANEL') const dataProxy: DataProxyWorker = { setup: async (clientData: ClientData) => { - log.debug('Received data for setting client') + log.debug('Received data for setting up client') if (client) return updateState() @@ -62,6 +62,7 @@ const dataProxy: DataProxyWorker = { searchEngine = new SearchEngine(client) + log.debug('Setup done') updateState() }, diff --git a/src/dataproxy/worker/utils.ts b/src/dataproxy/worker/utils.ts new file mode 100644 index 0000000..999dd02 --- /dev/null +++ b/src/dataproxy/worker/utils.ts @@ -0,0 +1,26 @@ +import Minilog from 'cozy-minilog' + +import { LOCALSTORAGE_KEY_DELETING_DATA } from '@/search/consts' +const log = Minilog('👷‍♂️ [Worker utils]') + +const deleteDatabases = async (): Promise => { + const databases = await window.indexedDB.databases() + // Remove all indexedDB databases + for (const db of databases) { + if (db.name) { + window.indexedDB.deleteDatabase(db.name) + log.info('Deleted indexedDB database : ', db.name) + } + } +} + +export const removeStaleLocalData = async (): Promise => { + // Check flag existence proving the reset process was incomplete + const hasStaleData = localStorage.getItem(LOCALSTORAGE_KEY_DELETING_DATA) + if (hasStaleData) { + log.info('Found stale data: remove it') + await deleteDatabases() + localStorage.removeItem(LOCALSTORAGE_KEY_DELETING_DATA) + } + return +} diff --git a/src/search/consts.ts b/src/search/consts.ts index 51ac525..eac32e5 100644 --- a/src/search/consts.ts +++ b/src/search/consts.ts @@ -40,3 +40,5 @@ export const DOCTYPE_ORDER = { [CONTACTS_DOCTYPE]: 1, [FILES_DOCTYPE]: 2 } + +export const LOCALSTORAGE_KEY_DELETING_DATA = 'deletingLocalData' diff --git a/src/targets/browser/index.ejs b/src/targets/browser/index.ejs index 4cd1c9e..89c5ed1 100644 --- a/src/targets/browser/index.ejs +++ b/src/targets/browser/index.ejs @@ -6,7 +6,6 @@ - diff --git a/src/targets/public/index.html b/src/targets/public/index.html new file mode 100644 index 0000000..63ab2d1 --- /dev/null +++ b/src/targets/public/index.html @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/src/targets/public/reset.js b/src/targets/public/reset.js new file mode 100644 index 0000000..87a9753 --- /dev/null +++ b/src/targets/public/reset.js @@ -0,0 +1,22 @@ +/* eslint-disable no-console */ + +function resetData() { + // Remove localstorage + window.localStorage.clear() + console.log('Deleted localStorage') + + // Add this flag for future check + window.localStorage.setItem('deletingLocalData', new Date().toISOString()) + + // Remove all indexedDB databases + window.indexedDB.databases().then(function (databases) { + databases.forEach(function (db) { + window.indexedDB.deleteDatabase(db.name) + console.log('Deleted indexedDB database : ', db.name) + }) + // Everything is done, remove the flag + window.localStorage.removeItem('deletingLocalData') + }) +} + +resetData()