Fixes #69 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
34 lines
1.4 KiB
TypeScript
34 lines
1.4 KiB
TypeScript
import { useEffect } from 'react';
|
|
import { getFallbackSession, subscribeSessionChanges } from '../state/sessions';
|
|
|
|
/**
|
|
* #69 — `useSessionSync` (the full cross-tab session sync, with in-place token
|
|
* rotation handling) is mounted only inside the authenticated `ClientRoot`
|
|
* shell, so a tab parked on the login/register/OIDC-callback pages never
|
|
* learns that another tab just signed in. Left alone, that tab keeps showing
|
|
* the login form and, if submitted, starts a second device/session for the
|
|
* same account.
|
|
*
|
|
* This is a deliberately lighter watcher for the unauthenticated routes: it
|
|
* only cares about a session APPEARING where there was none before (a fresh
|
|
* login completed in another tab) and reloads so this tab picks up the
|
|
* authenticated shell instead. It does not need `useSessionSync`'s
|
|
* rotation/relogin handling since there is no running client here to keep in
|
|
* sync — do not import/duplicate that logic, just reload.
|
|
*/
|
|
export function useSessionAppeared(): void {
|
|
useEffect(() => {
|
|
// If we already have a session, there's nothing to watch for here — the
|
|
// authenticated shell's own useSessionSync takes over once mounted.
|
|
if (getFallbackSession()) return undefined;
|
|
|
|
const unsubscribe = subscribeSessionChanges((session) => {
|
|
if (session) {
|
|
window.location.reload();
|
|
}
|
|
});
|
|
|
|
return unsubscribe;
|
|
}, []);
|
|
}
|