feat(auth): tell the user when the session expired

Every 401 from Auth or Core now goes through useSessionExpired: the login page
says the session expired and returns to the last page after login. App no
longer removes a token that only the browser clock calls expired, so a backend
401 is the one signal. A 403 on the profile now shows an error instead.
This commit is contained in:
lobo committed 2026-09-24 13:29:09 +02:00
1 parent 03259d0515
commit d4c0f8d8f3
19 files changed
+351 -35

No files matched your search

+8 -1
View File
@@ -13,13 +13,16 @@ const INITIAL_SYNC_GRACE_MS = 15_000;
* @param {boolean} opts.expectInitialSync - if true and no row yet, keep polling (covers the
* gap between async sync dispatch and first DB write)
* @param {() => void} opts.onComplete - called once per transition to OK/FAILED
* @param {() => void} [opts.onUnauthorized] - called on a 401; polling stops
* @returns {{status: string|null, lastSyncedAt: string|null, isRunning: boolean, error: string|null}}
*/
export default function useLibrarySync({enabled, expectInitialSync = false, onComplete}) {
export default function useLibrarySync({enabled, expectInitialSync = false, onComplete, onUnauthorized}) {
const [state, setState] = useState({status: null, lastSyncedAt: null, error: null});
const previousRunningRef = useRef(null);
const onCompleteRef = useRef(onComplete);
onCompleteRef.current = onComplete;
const onUnauthorizedRef = useRef(onUnauthorized);
onUnauthorizedRef.current = onUnauthorized;
useEffect(() => {
if (!enabled) return undefined;
@@ -39,6 +42,10 @@ export default function useLibrarySync({enabled, expectInitialSync = false, onCo
);
if (cancelled) return;
if (response.status === 401) {
onUnauthorizedRef.current?.();
return;
}
if (!response.ok) {
setState((s) => ({...s, error: 'sync-status fetch failed'}));
return;