diff --git a/neode-ui/src/composables/useDemoIntro.ts b/neode-ui/src/composables/useDemoIntro.ts index 984835c9..93161d76 100644 --- a/neode-ui/src/composables/useDemoIntro.ts +++ b/neode-ui/src/composables/useDemoIntro.ts @@ -24,18 +24,19 @@ export function clearDemoIntroSeen(): void { // ── Demoable apps ─────────────────────────────────────────────────────────── // Only these apps actually do something in the demo (a mock UI or a real -// external site). Everything else shows "No demo" on a disabled install button +// proxied site). Everything else shows "No demo" on a disabled install button // and is not launchable. -// IndeeHub's real site sends X-Frame-Options: SAMEORIGIN, and the old -// same-origin nginx sub_filter proxy broke its runtime-built asset URLs — -// so the demo opens the real site directly instead. -const DEMO_EXTERNAL_URLS: Record = { - indeedhub: 'https://indee.tx1138.com/', +// IndeeHub's real site sends X-Frame-Options: SAMEORIGIN and its SPA uses +// absolute-root asset paths, so a /app/indeedhub/ path-prefix proxy broke it. +// Instead nginx-demo.conf runs a WHOLE-ORIGIN reverse proxy of +// https://indee.tx1138.com on a dedicated port (framing headers stripped, +// demo sign-in seeded) and the iframe loads http://:/. +const DEMO_PROXY_PORTS: Record = { + indeedhub: 2101, } -// Apps loaded in the in-app iframe via a same-origin path. IndeeHub and Mempool -// are reverse-proxied by nginx (X-Frame-Options/CSP stripped + asset paths -// rewritten) so the frame-busting real sites can be embedded. +// Apps loaded in the in-app iframe via a same-origin path served by the mock +// backend (per-app mock UIs and placeholder dashboards). const DEMO_MOCK_UI: Record = { mempool: '/app/mempool/', 'mempool-web': '/app/mempool/', @@ -66,18 +67,25 @@ const DEMO_MOCK_UI: Record = { /** * Whether a demo app opens externally (new tab / in-app browser) because its - * real site blocks iframing (X-Frame-Options). + * real site blocks iframing. Nothing does anymore — frame-busting sites are + * whole-origin proxied (DEMO_PROXY_PORTS) instead. Kept exported so call + * sites in appLauncher.ts / AppSession.vue compile unchanged. */ -export function isDemoExternal(appId: string): boolean { - return appId in DEMO_EXTERNAL_URLS +export function isDemoExternal(_appId: string): boolean { + return false } /** Can this app be launched/installed in the demo? */ export function isDemoApp(appId: string): boolean { - return appId in DEMO_EXTERNAL_URLS || appId in DEMO_MOCK_UI + return appId in DEMO_PROXY_PORTS || appId in DEMO_MOCK_UI } /** Resolve the demo launch URL for an app, or null if it isn't demoable. */ export function demoAppUrl(appId: string): string | null { - return DEMO_EXTERNAL_URLS[appId] ?? DEMO_MOCK_UI[appId] ?? null + const proxyPort = DEMO_PROXY_PORTS[appId] + if (proxyPort !== undefined && typeof window !== 'undefined') { + // Same host the demo itself is served from — never a hardcoded host/IP. + return `${window.location.protocol}//${window.location.hostname}:${proxyPort}/` + } + return DEMO_MOCK_UI[appId] ?? null } diff --git a/neode-ui/src/views/appSession/useAppIdentity.ts b/neode-ui/src/views/appSession/useAppIdentity.ts index ef10be85..aa92f7a7 100644 --- a/neode-ui/src/views/appSession/useAppIdentity.ts +++ b/neode-ui/src/views/appSession/useAppIdentity.ts @@ -2,6 +2,7 @@ import { type Ref } from 'vue' import { rpcClient } from '@/api/rpc-client' +import { IS_DEMO } from '@/composables/useDemoIntro' const IDENTITY_KEY = 'archipelago_app_identity_' @@ -54,6 +55,11 @@ export function useAppIdentity( /** Called on iframe load to inject identity if the app supports it */ function onIframeLoadIdentity() { + // Public demo: never interrupt the visitor with the identity picker — + // the embedded IndeeHub is already signed in via the seeded throwaway + // demo account (see docker/indee-demo-signin.js). Real-node behavior is + // untouched (IS_DEMO is compile-time false there). + if (IS_DEMO) return if (isIdentityAwareApp(appId.value)) { const stored = getStoredIdentity() if (stored) sendIdentity(stored) @@ -63,6 +69,7 @@ export function useAppIdentity( /** Handle identity request messages from iframe */ function handleIdentityRequest() { + if (IS_DEMO) return const stored = getStoredIdentity() if (stored) sendIdentity(stored) else showIdentityPicker.value = true