diff --git a/src/routes/idaa/(idaa)/+layout.svelte b/src/routes/idaa/(idaa)/+layout.svelte index 198c92e3..84048597 100644 --- a/src/routes/idaa/(idaa)/+layout.svelte +++ b/src/routes/idaa/(idaa)/+layout.svelte @@ -83,18 +83,29 @@ const IDAA_IFRAME_RELOAD_URL_KEY = 'idaa_iframe_reload_url'; onMount(() => { const uuid_in_url = new URLSearchParams(window.location.search).get('uuid'); - if (uuid_in_url && !sessionStorage.getItem(IDAA_IFRAME_RELOAD_URL_KEY)) { - sessionStorage.setItem(IDAA_IFRAME_RELOAD_URL_KEY, window.location.href); + if (uuid_in_url) { + // Guard: iOS Safari Private Browsing and some iframe sandbox configs throw on + // sessionStorage access. Graceful fallback: skip the save; reload_with_uuid() + // will fall back to location.reload() (loses UUID-preservation but doesn't crash). + try { + if (!sessionStorage.getItem(IDAA_IFRAME_RELOAD_URL_KEY)) { + sessionStorage.setItem(IDAA_IFRAME_RELOAD_URL_KEY, window.location.href); + } + } catch { + console.warn('IDAA Layout: sessionStorage unavailable — reload buttons will use location.reload() fallback.'); + } } }); function reload_with_uuid() { - const initial_url = sessionStorage.getItem(IDAA_IFRAME_RELOAD_URL_KEY); - if (initial_url && initial_url !== location.href) { - location.href = initial_url; - } else { - location.reload(); - } + try { + const initial_url = sessionStorage.getItem(IDAA_IFRAME_RELOAD_URL_KEY); + if (initial_url && initial_url !== location.href) { + location.href = initial_url; + return; + } + } catch { /* sessionStorage unavailable — fall through to location.reload() */ } + location.reload(); } // Clear stale db_events.event IDB data on IDAA session start. @@ -116,7 +127,13 @@ if (browser) { // 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; +// +// WHY 35s: worst-case auto-retry cycle is 27s (12s first timeout + 3s wait + 12s retry). +// If the auto-retries succeed or fail within that window, the spinner is already gone +// (content shown or error panel shown) before this fires. The escape hatch only appears +// for the rare case where the Novi API is slow-but-not-timing-out, or site_cfg_json +// never loads. Previously 8s — fired mid-flight and caused premature Reset & Retry clicks. +const VERIFY_TIMEOUT_MS = 35_000; let verifying_timed_out: boolean = $state(false); @@ -131,7 +148,7 @@ $effect(() => { } }); -const VERIFIED_TTL_MS_DEFAULT = 45 * 60 * 1000; // 25 minutes +const VERIFIED_TTL_MS_DEFAULT = 45 * 60 * 1000; // 45 minutes // Effect 1: Set URL origin and params $effect(() => {