feat(demo): launch IndeeHub in the in-app iframe via the :2101 proxy
- useDemoIntro: replace DEMO_EXTERNAL_URLS (external-tab workaround) with
DEMO_PROXY_PORTS; demoAppUrl('indeedhub') now resolves to
<protocol>//<current-hostname>:2101/ at runtime (no hardcoded host/IP);
isDemoExternal returns false (kept exported so call sites compile
unchanged); isDemoApp still true for indeedhub so the NEW_TAB bypass
keeps it in the in-app session
- useAppIdentity: suppress the identity-picker modal under IS_DEMO — the
embedded IndeeHub is already signed in via the seeded throwaway demo
account; real-node picker behavior untouched (IS_DEMO compile-time false)
Verified: 195 unit tests green (IS_DEMO=false path); VITE_DEMO=1 build
bundle contains the :2101 launch logic.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
69bc3d3f27
commit
66d540f8b5
@ -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<string, string> = {
|
||||
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://<demo-host>:<port>/.
|
||||
const DEMO_PROXY_PORTS: Record<string, number> = {
|
||||
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<string, string> = {
|
||||
mempool: '/app/mempool/',
|
||||
'mempool-web': '/app/mempool/',
|
||||
@ -66,18 +67,25 @@ const DEMO_MOCK_UI: Record<string, string> = {
|
||||
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user