diff --git a/neode-ui/src/components/PWAUpdatePrompt.vue b/neode-ui/src/components/PWAUpdatePrompt.vue index 91d0c9b9..5c3a9eb9 100644 --- a/neode-ui/src/components/PWAUpdatePrompt.vue +++ b/neode-ui/src/components/PWAUpdatePrompt.vue @@ -109,14 +109,24 @@ onMounted(() => { registration.waiting.postMessage({ type: 'SKIP_WAITING' }) } } - // The kiosk is unattended — nobody can click "Update Now", - // so it kept running stale bundles forever (stale FIPS state, - // old assets). Auto-apply there; prompt everywhere else. - if (localStorage.getItem('kiosk')) { - updateCallback() - } else { - showUpdatePrompt.value = true - } + // Auto-apply everywhere (alpha, user-approved 2026-07-31): + // a prompt only reaches users who happen to click it, so + // security fixes sat unapplied in long-lived sessions (the + // installed PWA and kiosk displays especially). The kiosk + // already auto-applied for exactly that reason; the rest of + // the fleet now does too. + // + // Deliberately still routed through SKIP_WAITING rather than + // build-time `skipWaiting: true`, so activation keeps the two + // guards below: reloadAfterCinematic() holds the reload until + // the splash/dashboard cinematic is over, and the + // hadController check ignores the first-install claim. A + // build-time skipWaiting would bypass both and could reload + // the app out from under someone. + // + // Revisit at beta: restore the prompt (showUpdatePrompt.value + // = true) if users should choose their own update moment. + updateCallback() } }) }