diff --git a/application/controllers/DemoController.php b/application/controllers/DemoController.php index 0910cf9..f6ab4b0 100644 --- a/application/controllers/DemoController.php +++ b/application/controllers/DemoController.php @@ -66,9 +66,12 @@ class DemoController extends BaseController 'demo_jwt' => $demoJwt, 'company_id' => $orgId, // alias di compatibilità standard 'organization_id' => $orgId, - 'spa_iframe_url' => self::DEMO_BASE . '/?demo=' . $sessionId, - 'manifest_url' => self::DEMO_BASE . '/api/demo/manifest?session_id=' . $sessionId, - 'credentials_url' => self::DEMO_BASE . '/api/demo/credentials?session_id=' . $sessionId, + // spa_iframe_url atterra su dashboard e porta il demo_jwt nel FRAGMENT (#djwt): + // common-bi.js lo imposta come token API in modo SINCRONO (prima di checkAuth), + // così la SPA si auto-autentica anche cross-origin (niente sessionStorage same-origin). + 'spa_iframe_url' => $this->demoBase() . '/dashboard.html?demo=' . $sessionId . '#djwt=' . $demoJwt, + 'manifest_url' => $this->demoBase() . '/api/demo/manifest?session_id=' . $sessionId, + 'credentials_url' => $this->demoBase() . '/api/demo/credentials?session_id=' . $sessionId, 'expires_at' => gmdate('Y-m-d\TH:i:s\Z', $expiresTs), 'hmac_key_seed' => $hmacKeySeed, 'presentation_mode' => 'realtime', @@ -200,6 +203,15 @@ class DemoController extends BaseController // ═══ Helpers ═════════════════════════════════════════════════════════════ + /** Base URL della SPA demo (override via env DEMO_BASE_URL per switch a sottodominio). */ + private function demoBase(): string + { + return getenv('DEMO_BASE_URL') + ?: ($_SERVER['DEMO_BASE_URL'] ?? '') + ?: ($_ENV['DEMO_BASE_URL'] ?? '') + ?: self::DEMO_BASE; + } + /** Risolve la sessione da Bearer demo_jwt (preferito) o ?session_id=. */ private function resolveSession(): ?array { diff --git a/public/js/common-bi.js b/public/js/common-bi.js index ca2528d..1228454 100644 --- a/public/js/common-bi.js +++ b/public/js/common-bi.js @@ -176,6 +176,21 @@ (function () { try { if (!new URLSearchParams(window.location.search).get('demo')) return; + // Auto-auth SINCRONA: il demo_jwt arriva nel fragment (#djwt=) dello spa_iframe_url. + // Lo impostiamo come token API PRIMA che la pagina chiami checkAuth() (common-bi.js gira + // prima dello script inline della pagina). Origin demo separato → nessuna pollution di sessioni reali. + try { + var h = new URLSearchParams((window.location.hash || '').replace(/^#/, '')); + var djwt = h.get('djwt'); + if (djwt && !localStorage.getItem('nis2_access_token')) { + localStorage.setItem('nis2_access_token', djwt); + localStorage.setItem('nis2_user_role', 'compliance_manager'); + try { + var pl = JSON.parse(atob(djwt.split('.')[1].replace(/-/g, '+').replace(/_/g, '/'))); + if (pl && pl.org_id) localStorage.setItem('nis2_org_id', String(pl.org_id)); + } catch (e2) { /* jwt opaco: org via credentials */ } + } + } catch (e1) { /* noop */ } var css = document.createElement('link'); css.rel = 'stylesheet'; css.href = '/css/demo.css'; document.head.appendChild(css); var inject = function () { var s1 = document.createElement('script'); s1.src = '/js/demo-selectors.js';