A service worker intercepts requests by scope, not by a user's server authorization. Cache API entries and IndexedDB rows can remain on a shared device after logout unless the application removes them. A cache name containing an account ID is an organization aid, not a security boundary; same-origin scripts can inspect origin storage. Decide which private data may be stored locally at all, minimize it, and enforce server authorization for every network response. Account switch must invalidate open views and pending work as well as remove local bytes.
Private Offline Cache and Account Switch
Working case
Reviewer 47 reads a private case summary offline, then signs out and lends the device to reviewer 62. The application clears its in-memory case model, terminates file previews, closes database connections, removes account-47 cache and draft partitions, and refuses to replay account-47 mutations under the new session. Reviewer 62 opens a fresh signed-in session and sees only authorized server data. A delayed response from the former account is discarded by an identity generation check. The logout UI does not claim the browser erased data already copied into screenshots or another process.
Implementation boundary
function mayReplayOfflineEdit(edit, session) {
return edit.ownerId === session.userId && edit.identityGeneration === session.generation;
}
console.log(mayReplayOfflineEdit({ ownerId: 47, identityGeneration: 6 }, { userId: 62, generation: 7 }));
// Output: falseTreat cache writes as explicit opt-in by response type. Never put private authenticated responses into a shared shell cache with a broad URL-only key. Include an account or session generation in local record metadata and verify it before display or replay. On logout or account switch, stop fetches, revoke object URLs, close database handles, delete owned Cache API entries and draft rows, and reset visible state before the next account renders. Coordinate open tabs with a generation message, but assume a crashed tab may miss it and recheck on resume. Keep authorization on the server even if the offline view has already hidden a record.
Cost and boundaries
Account partitioning adds storage and cleanup work; duplicated shell assets should remain public and shared only when they carry no private response. Deleting many draft rows can be O(n), so show cleanup progress for a large queue and block new-account display until isolation is complete. Late network responses need a generation comparison at their application boundary. Test memory, object URLs, Cache API, IndexedDB, and open tabs. Avoid recording private case titles in cleanup telemetry; counts and failure categories are enough for operations.
Failure trace
The worker caches a case response under its URL and serves it after the browser receives a different account cookie. Another tab misses the logout event and replays a mutation from reviewer 47 while reviewer 62 is signed in. Reproduce both cases. The cache must refuse an account mismatch, and outbox records must carry an owner identity that is checked before replay. Also test a failed cleanup transaction, interrupted logout, back navigation, and a delayed fetch. The UI should block private content rather than show stale data during recovery.
Verification
- Private responses never enter a public shell cache.
- Late replies and queued edits check identity generation.
- Open tabs clear prior-account views before rendering a new account.
Practice drill
Populate two private case summaries and one pending edit for reviewer 47. Switch to reviewer 62 in another tab, then resume the first tab from sleep. Confirm every display and replay checks the current identity generation. Inspect Cache API, IndexedDB, in-memory state, and object URLs after cleanup. Cause deletion to fail once and verify the new account cannot view or use the prior account's data while cleanup is incomplete.
Decision note
Account separation requires server checks plus explicit browser cleanup and generation gates on delayed work.
Common Mistakes
- Treating a cache name as isolation from same-origin scripts.
- Clearing only visible React state while retaining private Cache API entries.
- Replaying old-account writes with a new account cookie.
Related lessons
Offline Storage and Upgrade Safety; Service Worker Activation and Unsent Work; IndexedDB Version Changes and Blocked Tabs; Browser Storage Quota, Eviction, and Recovery; Browser Storage Cleanup on Account Change; Tenant Scope in Cache and Background Work.
Connected practice
Build Project: offline case review across upgrades and review Web Development: offline and browser-key decisions quiz.
