mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-21 19:41:55 +02:00
feat(auth): add session expired banner when token refresh fails
Users now see an amber banner with a re-login button instead of a broken empty page when their session expires. Uses pub/sub events from tokenManager, integrated in todo, calendar, zitare, contacts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
02db49175a
commit
d6440664ac
9 changed files with 376 additions and 0 deletions
68
packages/shared-auth/src/events/sessionExpired.ts
Normal file
68
packages/shared-auth/src/events/sessionExpired.ts
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* Session expired event system
|
||||
*
|
||||
* Provides a simple pub/sub mechanism for notifying UI layers
|
||||
* when a user's session has permanently expired (token refresh failed).
|
||||
*
|
||||
* This is intentionally kept framework-agnostic so it can be consumed
|
||||
* by Svelte, React, or plain JS consumers.
|
||||
*/
|
||||
|
||||
type SessionExpiredListener = () => void;
|
||||
|
||||
const listeners = new Set<SessionExpiredListener>();
|
||||
|
||||
let _sessionExpired = false;
|
||||
|
||||
/**
|
||||
* Subscribe to session expired events.
|
||||
* Returns an unsubscribe function.
|
||||
*/
|
||||
export function onSessionExpired(listener: SessionExpiredListener): () => void {
|
||||
listeners.add(listener);
|
||||
|
||||
// If session is already expired, notify immediately
|
||||
if (_sessionExpired) {
|
||||
try {
|
||||
listener();
|
||||
} catch {
|
||||
// Ignore listener errors
|
||||
}
|
||||
}
|
||||
|
||||
return () => {
|
||||
listeners.delete(listener);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit a session expired event.
|
||||
* Called internally by the token manager when refresh fails permanently.
|
||||
*/
|
||||
export function emitSessionExpired(): void {
|
||||
if (_sessionExpired) return; // Only emit once
|
||||
_sessionExpired = true;
|
||||
|
||||
listeners.forEach((listener) => {
|
||||
try {
|
||||
listener();
|
||||
} catch {
|
||||
// Ignore listener errors
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the session expired state.
|
||||
* Should be called when the user logs in again.
|
||||
*/
|
||||
export function resetSessionExpired(): void {
|
||||
_sessionExpired = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the session is currently marked as expired.
|
||||
*/
|
||||
export function isSessionExpired(): boolean {
|
||||
return _sessionExpired;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue