import { useEffect } from 'react'; import { getFallbackSession, subscribeSessionChanges } from '../state/sessions'; /** * Keep this tab in sync with session changes performed in other tabs/windows. * * The coordinator mounts this once inside the authenticated client shell. * `storage` events fire only in tabs that did NOT perform the write, so the * callback here always represents an out-of-tab change. * * Default action is the safest one for auth-critical state — a full reload: * - session REMOVED elsewhere (logout / localStorage.clear()) → the access * token disappears, so we reload; the router bounces to auth on next boot. * - session APPEARED or its access token CHANGED elsewhere (a fresh login or * a token rotation) → we reload so the client re-initialises with the new * credentials rather than running on a stale/revoked token. * * A change that does not alter the access token (e.g. an OIDC metadata-only * rewrite) is ignored, which also collapses the several storage events emitted * by a single dual-write into at most one reload. */ export const useSessionSync = (): void => { useEffect(() => { // Snapshot the credential this tab booted with; compare against it so we // only reload on a genuine credential change. const initialAccessToken = getFallbackSession()?.accessToken ?? null; const unsubscribe = subscribeSessionChanges((session) => { const nextAccessToken = session?.accessToken ?? null; if (nextAccessToken === initialAccessToken) return; window.location.reload(); }); return unsubscribe; }, []); };