feat(idaa): show reset button if Novi verification stalls after 8s

If the "Verifying identity..." spinner is still visible after 8 seconds,
show an escape-hatch button that clears ae_loc + ae_idaa_loc from
localStorage and reloads — forcing a fresh site config fetch which
re-populates novi_idaa_api_key so verification can actually run.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-03-30 17:45:17 -04:00
parent 0d49ff3b8d
commit 847d89054d

View File

@@ -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(
<span class="fas fa-spinner fa-spin"></span>
Verifying identity...
</p>
{#if verifying_timed_out}
<!-- Escape hatch: shown after VERIFY_TIMEOUT_MS if still spinning.
Most likely cause: stale localStorage missing novi_idaa_api_key.
Clearing both stores and reloading forces a fresh site config fetch. -->
<p class="mt-2 text-center text-xs text-gray-400">
This is taking longer than expected.
</p>
<button
type="button"
class="btn btn-sm preset-tonal-primary border-primary-500 mt-1 border"
onclick={() => {
localStorage.removeItem('ae_loc');
localStorage.removeItem('ae_idaa_loc');
location.reload();
}}>
<span class="fas fa-redo m-1"></span>
Reset &amp; Retry
</button>
{/if}
</div>
{:else if $ae_loc.trusted_access || ($ae_loc.authenticated_access && $idaa_loc.novi_uuid)}
{@render children?.()}