fix: purge every private offline store (Closes #889)
This commit is contained in:
1 parent
2eea42859e
commit
a60f2cfac3
10 files changed
+95
-18
No files matched your search
@@ -1243,6 +1243,7 @@
|
||||
|
||||
<div class="footer">Creative AI-imbued UI • stackchain-dashboard</div>
|
||||
|
||||
<script src="static/private-data-registry.js"></script>
|
||||
<script src="static/session.js"></script>
|
||||
<script src="static/feature-loader.js"></script>
|
||||
<script src="static/conversation-action-hydrator.js"></script>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
(function (root) {
|
||||
const databases = Object.freeze([
|
||||
'stackchain-background-outbox-v1',
|
||||
'stackchain-offline-work-v2',
|
||||
'stackchain-unfiled-captures-v1',
|
||||
]);
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = databases;
|
||||
else root.stackchainPrivateDatabases = databases;
|
||||
})(typeof globalThis !== 'undefined' ? globalThis : this);
|
||||
@@ -1,5 +1,10 @@
|
||||
(function (root, factory) {
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = factory;
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = options => factory({
|
||||
...options,
|
||||
privateDatabases: require('./private-data-registry.js'),
|
||||
});
|
||||
}
|
||||
else root.stackchainPrivateDeviceData = factory({
|
||||
localStorage: root.localStorage,
|
||||
sessionStorage: root.sessionStorage,
|
||||
@@ -7,9 +12,10 @@
|
||||
caches: root.caches,
|
||||
serviceWorker: root.navigator?.serviceWorker,
|
||||
MessageChannel: root.MessageChannel,
|
||||
privateDatabases: root.stackchainPrivateDatabases,
|
||||
});
|
||||
})(typeof window !== 'undefined' ? window : this, function createPrivateDeviceDataPurger({
|
||||
localStorage, sessionStorage, indexedDB, caches, serviceWorker, MessageChannel,
|
||||
localStorage, sessionStorage, indexedDB, caches, serviceWorker, MessageChannel, privateDatabases,
|
||||
}) {
|
||||
function removeOwnedStorage(storage) {
|
||||
if (!storage) return;
|
||||
@@ -52,9 +58,7 @@
|
||||
removeOwnedStorage(localStorage);
|
||||
if (sessionStorage !== localStorage) removeOwnedStorage(sessionStorage);
|
||||
await stopWorkerOutbox();
|
||||
await deletePrivateDatabase('stackchain-background-outbox-v1');
|
||||
await deletePrivateDatabase('stackchain-offline-work-v2');
|
||||
await deletePrivateDatabase('stackchain-unfiled-captures-v1');
|
||||
for (const name of privateDatabases) await deletePrivateDatabase(name);
|
||||
const keys = await caches?.keys?.() || [];
|
||||
await Promise.all(
|
||||
keys.filter(key => key.startsWith('stackchain-dashboard-')).map(key => caches.delete(key))
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
const BASE = new URL('./', self.location.href).pathname;
|
||||
importScripts(BASE + 'static/private-data-registry.js');
|
||||
importScripts(BASE + 'static/background-issue-sync.js');
|
||||
const CACHE = 'stackchain-dashboard-shell-v102';
|
||||
const OFFLINE_LEASE_URL = new URL(BASE + '__offline-session-lease', self.location.origin).href;
|
||||
const OUTAGE_STATUSES = new Set([500, 502, 503, 504]);
|
||||
const NAVIGATION_TIMEOUT_MS = self.__STACKCHAIN_NAVIGATION_TIMEOUT_MS || 4000;
|
||||
const PUSH_ACTION_TIMEOUT_MS = self.__STACKCHAIN_PUSH_ACTION_TIMEOUT_MS || 8000;
|
||||
const PRIVATE_DATABASES = self.stackchainPrivateDatabases;
|
||||
const SHELL = [
|
||||
BASE,
|
||||
BASE + 'manifest.webmanifest',
|
||||
@@ -210,9 +212,13 @@ async function deletePrivateDatabase(name) {
|
||||
});
|
||||
}
|
||||
|
||||
async function deletePrivateDatabases() {
|
||||
for (const name of PRIVATE_DATABASES) await deletePrivateDatabase(name);
|
||||
}
|
||||
|
||||
async function purgeRevokedSessionData() {
|
||||
await issueSync.purge();
|
||||
await deletePrivateDatabase('stackchain-unfiled-captures-v1');
|
||||
await deletePrivateDatabases();
|
||||
const keys = await caches.keys();
|
||||
await Promise.all(
|
||||
keys.filter(key => key.startsWith('stackchain-dashboard-')).map(key => caches.delete(key))
|
||||
@@ -249,7 +255,7 @@ async function offlineLeaseState(cache) {
|
||||
|
||||
async function expiredOfflineResponse() {
|
||||
await issueSync.purge();
|
||||
await deletePrivateDatabase('stackchain-unfiled-captures-v1');
|
||||
await deletePrivateDatabases();
|
||||
const keys = await caches.keys();
|
||||
await Promise.all(
|
||||
keys.filter(key => key.startsWith('stackchain-dashboard-')).map(key => caches.delete(key))
|
||||
@@ -370,7 +376,7 @@ self.addEventListener('message', event => {
|
||||
if (event.data?.type === 'stackchain-purge-outbox') event.waitUntil((async () => {
|
||||
try {
|
||||
await issueSync.purge();
|
||||
await deletePrivateDatabase('stackchain-unfiled-captures-v1');
|
||||
await deletePrivateDatabases();
|
||||
event.ports?.[0]?.postMessage({ ok: true });
|
||||
} catch (error) {
|
||||
event.ports?.[0]?.postMessage({ ok: false, error: String(error?.message || 'Outbox purge failed.') });
|
||||
|
||||
+9
-5
@@ -1,5 +1,10 @@
|
||||
(function (root, factory) {
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = factory;
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = options => factory({
|
||||
...options,
|
||||
privateDatabases: require('./private-data-registry.js'),
|
||||
});
|
||||
}
|
||||
else {
|
||||
const base = new URL('./', root.location.href).pathname;
|
||||
const originalFetch = root.fetch.bind(root);
|
||||
@@ -15,6 +20,7 @@
|
||||
serviceWorker: root.navigator?.serviceWorker,
|
||||
credentials: root.navigator?.credentials,
|
||||
MessageChannel: root.MessageChannel,
|
||||
privateDatabases: root.stackchainPrivateDatabases,
|
||||
location: root.location,
|
||||
addActivityListener: (type, listener, options) => root.addEventListener(type, listener, options),
|
||||
confirmAction: message => root.confirm(message),
|
||||
@@ -82,7 +88,7 @@
|
||||
root.stackchainSession = boundary;
|
||||
}
|
||||
})(typeof window !== 'undefined' ? window : this, function createSessionBoundary({
|
||||
cookie, origin, base, fetchImpl, localStorage, sessionStorage, indexedDB, caches, serviceWorker, credentials, MessageChannel, location, confirmAction, addActivityListener,
|
||||
cookie, origin, base, fetchImpl, localStorage, sessionStorage, indexedDB, caches, serviceWorker, credentials, MessageChannel, privateDatabases, location, confirmAction, addActivityListener,
|
||||
promptAuthorization = () => null,
|
||||
onExpired = () => {},
|
||||
onClearError = () => {},
|
||||
@@ -454,9 +460,7 @@
|
||||
if (sessionStorage !== localStorage) removeDashboardStorage(sessionStorage);
|
||||
try {
|
||||
await stopWorkerOutbox();
|
||||
await deletePrivateDatabase('stackchain-background-outbox-v1');
|
||||
await deletePrivateDatabase('stackchain-offline-work-v2');
|
||||
await deletePrivateDatabase('stackchain-unfiled-captures-v1');
|
||||
for (const name of privateDatabases) await deletePrivateDatabase(name);
|
||||
} catch (_error) {
|
||||
const error = new Error('Could not clear private queued work from this device.');
|
||||
onClearError(error);
|
||||
|
||||
Reference in new issue
Block a user