fix: drive logout from real 401s, not local storage changes

apiFetch now redirects to login only on a genuine backend 401 (auth endpoints excluded, only when previously logged in). AuthSyncWatcher no longer treats localStorage.clear()/unrelated writes as a logout, fixing spurious sign-outs (e.g. when uploading skills).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
AdministratorandClaude Opus 4.8 committed 2026-06-04 17:41:46 +08:00
1 parent 6c30e649e3
commit e3b0958c23
2 files changed
+46 -11

No files matched your search

+9 -5
View File
@@ -23,7 +23,12 @@ export function AuthSyncWatcher() {
useEffect(() => {
function handleStorage(event: StorageEvent) {
if (event.key !== null && event.key !== AUTH_STORAGE_KEY) {
// Only react to explicit changes of the auth key. Ignore unrelated keys
// AND `localStorage.clear()` (event.key === null) — embedded sub-apps /
// iframes wiping their own storage used to spuriously log the user out
// here even though the backend session was still valid. Genuine session
// loss is now detected centrally via 401 responses in apiFetch.
if (event.key !== AUTH_STORAGE_KEY) {
return;
}
const nextUserId = readUserId();
@@ -31,12 +36,11 @@ export function AuthSyncWatcher() {
return;
}
lastUserIdRef.current = nextUserId;
if (nextUserId === null) {
window.location.replace("#/login");
// Only resync on a genuine account switch in another tab (different,
// non-null user). Do NOT force a login redirect on null here.
if (nextUserId !== null) {
window.location.reload();
return;
}
window.location.reload();
}
window.addEventListener("storage", handleStorage);