feat: session-expired banner via ae_auth_error store
- Add ae_auth_error writable store to ae_stores.ts - Wire api_get_object, api_post_object, api_patch_object to set ae_auth_error on 401/403 (browser-only guard, never fires SSR) - Root layout watches ae_auth_error; only raises flag_expired when a JWT is present (prevents false trigger on unauthenticated loads) - Dismissible amber banner added to root layout (non-blocking, above content) - Tested via debug menu trigger; banner fires and clears correctly
This commit is contained in:
@@ -37,7 +37,7 @@
|
||||
|
||||
// *** Import Aether specific variables and functions
|
||||
// import Analytics from '$lib/app_components/analytics.svelte';
|
||||
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/stores/ae_stores';
|
||||
import { ae_loc, ae_sess, ae_api, slct, slct_trigger, ae_auth_error } from '$lib/stores/ae_stores';
|
||||
// import { events_loc, events_slct } from '$lib/stores/ae_events_stores';
|
||||
|
||||
// import MyClipboard from '$lib/app_components/e_app_clipboard.svelte';
|
||||
@@ -272,6 +272,17 @@
|
||||
|
||||
return () => window.removeEventListener('message', handler);
|
||||
});
|
||||
|
||||
// 5. SESSION EXPIRED EFFECT — watches ae_auth_error and raises the banner when the API signals 401/403.
|
||||
// Guards on $ae_loc.jwt so that unauthenticated first-loads (no stored JWT) never trigger it —
|
||||
// 401s are expected on first visit and should not look like a session expiry.
|
||||
$effect(() => {
|
||||
if ($ae_auth_error?.type === 'expired') {
|
||||
untrack(() => {
|
||||
if ($ae_loc?.jwt) flag_expired = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@@ -285,6 +296,16 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if browser && flag_expired}
|
||||
<div class="fixed top-0 left-0 right-0 z-50 px-4 py-2 bg-amber-500 text-white shadow-xl flex items-center justify-between gap-4">
|
||||
<p class="text-sm font-semibold">Your session has expired. Please reload or sign in again.</p>
|
||||
<div class="flex gap-2 items-center shrink-0">
|
||||
<button class="btn btn-sm variant-filled-white text-amber-700" onclick={() => window.location.reload()}>Reload</button>
|
||||
<button class="btn btn-sm" onclick={() => { flag_expired = false; ae_auth_error.set({ type: null, ts: null }); }}>✕</button>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if browser && $ae_loc?.allow_access}
|
||||
{@render children?.()}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user