mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 06:52:04 +00:00
fix(pwa): stop the offline cache from persisting sensitive health data
The offline layer wrote far too much to disk and cleared it too rarely. The query persister used a denylist (only auth/session/admin/tokens), so every other family — coach, insights, illness, labs, mood, cycle — was dehydrated to IndexedDB in plaintext; the service worker likewise prefix-cached GET /api/insights, which serves decrypted Coach conversations. Neither store carried an account marker and both were wiped only on explicit logout, so a session that ended by expiry or a 401 left health data on disk for the next account on a shared profile. Flip the persister to a strict allowlist (dashboard snapshot, per-chart series, widget layout — the offline-dashboard set only) and stamp each payload with the live account id, discarding on mismatch. Drop /api/insights and /api/analytics from the worker allowlist. Wipe the IndexedDB blob and the data/page caches on every session end — the 401/expiry redirect and the logout path both route through one helper.
This commit is contained in:
1 parent
3cf9a262ca
commit
b474ea1489
7 files changed
+273
-59
No files matched your search
@@ -8,6 +8,7 @@ import { MaintainershipBanner } from "@/components/i18n/maintainership-banner";
|
||||
import { LayoutCoachFab } from "@/components/insights/layout-coach-fab";
|
||||
import { LayoutCoachMount } from "@/components/insights/layout-coach-mount";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import { clearOfflineCachesForSessionEnd } from "@/lib/pwa/query-persister";
|
||||
import { useTranslations } from "@/lib/i18n/context";
|
||||
import { CoachLaunchProvider } from "@/lib/insights/coach-launch-context";
|
||||
import { BottomNav } from "./bottom-nav";
|
||||
@@ -91,6 +92,13 @@ export function AuthShell({
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoading && !isAuthenticated && !isPublicPage) {
|
||||
// Session END (expired / invalidated cookie → `/api/auth/me` 401). Wipe
|
||||
// every client-side cache that can hold the previous account's health
|
||||
// data before bouncing to login, so it never leaks to the next account
|
||||
// on a shared device. Logout does the same from `useLogout`; this covers
|
||||
// the expiry path that logout never runs through. Best-effort; the
|
||||
// redirect proceeds regardless.
|
||||
void clearOfflineCachesForSessionEnd();
|
||||
router.replace("/auth/login");
|
||||
}
|
||||
}, [isLoading, isAuthenticated, isPublicPage, router]);
|
||||
|
||||
Reference in new issue
Block a user