fix(auth): wire cross-session logout through rspace-header
The actual logout UI is in rspace-header.ts (not the encryptid login button component). clearSession() now calls /api/session/logout, and on page load the header validates the session with the server to detect revocation from another browser session. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
aec42ef976
commit
bfbf1d14cd
|
|
@ -47,7 +47,22 @@ function getSession(): SessionState | null {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function clearSession(): void {
|
function clearSession(): void {
|
||||||
|
// Notify server so all other browser sessions get revoked
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem(SESSION_KEY);
|
||||||
|
if (stored) {
|
||||||
|
const session = JSON.parse(stored) as SessionState;
|
||||||
|
if (session.accessToken) {
|
||||||
|
fetch(`${ENCRYPTID_URL}/api/session/logout`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Authorization': `Bearer ${session.accessToken}` },
|
||||||
|
}).catch(() => { /* best-effort */ });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch { /* ignore */ }
|
||||||
|
|
||||||
localStorage.removeItem(SESSION_KEY);
|
localStorage.removeItem(SESSION_KEY);
|
||||||
localStorage.removeItem('rspace-username');
|
localStorage.removeItem('rspace-username');
|
||||||
}
|
}
|
||||||
|
|
@ -921,6 +936,24 @@ export function mountHeader(options: HeaderOptions): void {
|
||||||
}
|
}
|
||||||
} catch { /* silently ignore */ }
|
} catch { /* silently ignore */ }
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// Validate session with server — detects logout from another browser session
|
||||||
|
(async () => {
|
||||||
|
const session = getSession();
|
||||||
|
if (!session) return;
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${ENCRYPTID_URL}/api/session/verify`, {
|
||||||
|
headers: { 'Authorization': `Bearer ${session.accessToken}` },
|
||||||
|
});
|
||||||
|
if (!res.ok) {
|
||||||
|
// Session revoked or invalid — clear locally and re-render
|
||||||
|
localStorage.removeItem(SESSION_KEY);
|
||||||
|
localStorage.removeItem('rspace-username');
|
||||||
|
renderHeader();
|
||||||
|
onAuthChange?.();
|
||||||
|
}
|
||||||
|
} catch { /* network error — let token expire naturally */ }
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue