diff --git a/src/routes/idaa/(idaa)/+layout.svelte b/src/routes/idaa/(idaa)/+layout.svelte index f8d2164f..b80f3bcc 100644 --- a/src/routes/idaa/(idaa)/+layout.svelte +++ b/src/routes/idaa/(idaa)/+layout.svelte @@ -43,6 +43,23 @@ let novi_verifying: boolean = $state(!!url_uuid); // which would cause the guard to fire immediately and skip verification entirely. let verify_in_flight = false; +// Show a manual reset button if the spinner is still visible after this many ms. +// Handles the case where site_cfg_json loads without novi_idaa_api_key (stale cache) +// or the Novi API call hangs — the user would otherwise be stuck with no escape. +const VERIFY_TIMEOUT_MS = 8000; +let verifying_timed_out: boolean = $state(false); + +$effect(() => { + if (novi_verifying) { + const id = setTimeout(() => { + verifying_timed_out = true; + }, VERIFY_TIMEOUT_MS); + return () => clearTimeout(id); + } else { + verifying_timed_out = false; + } +}); + const VERIFIED_TTL_MS_DEFAULT = 5 * 60 * 1000; // 5 minutes // Effect 1: Set URL origin and params @@ -253,6 +270,25 @@ async function verify_novi_uuid( Verifying identity...

+ {#if verifying_timed_out} + +

+ This is taking longer than expected. +

+ + {/if} {:else if $ae_loc.trusted_access || ($ae_loc.authenticated_access && $idaa_loc.novi_uuid)} {@render children?.()}