--- phase: quick-260729-gjd plan: 01 subsystem: public-demo tags: [demo, indeedhub, nginx, reverse-proxy, nostr, mock-backend] requires: [] provides: - "IndeeHub whole-origin demo proxy on :2101 (framing headers stripped, sign-in seeded)" - "Demo iframe launch of indeedhub via demoAppUrl → :2101/" - "IndeeHub pre-installed/running on every fresh demo session" affects: [demo-deploy, neode-ui demo image] tech-stack: added: [] patterns: - "Whole-origin per-port reverse proxy for frame-busting external SPAs (vs broken path-prefix sub_filter)" - "localStorage seeding via injected classic script on the proxied origin (applesauce-accounts nsec account)" key-files: created: - neode-ui/docker/indee-demo-signin.js modified: - neode-ui/docker/nginx-demo.conf - neode-ui/Dockerfile.web - docker-compose.demo.yml - demo-deploy/docker-compose.yml - neode-ui/src/composables/useDemoIntro.ts - neode-ui/src/views/appSession/useAppIdentity.ts - neode-ui/mock-backend.js decisions: - "Primary sign-in path used (seeded nsec account, self-signing) — NIP-07 bridge fallback NOT needed; verified against the live bundle" - "Dropped `sub_filter_types text/html` (text/html is nginx's default sub_filter type; explicit listing produced a duplicate-MIME warning)" metrics: duration: "~50 min" completed: 2026-07-29 status: complete --- # Quick Task 260729-gjd: IndeeHub in the Demo Summary **One-liner:** Whole-origin nginx proxy of indee.tx1138.com on :2101 with an injected throwaway-nsec sign-in seeder, demo iframe launch via same-host :2101, and IndeeHub pre-installed in every fresh mock-backend session. ## Commits | Task | Commit | Scope | |------|--------|-------| | 1 | 69bc3d3f | nginx :2101 whole-origin proxy + indee-demo-signin.js seeder + Dockerfile.web COPY/EXPOSE + both compose files publish 2101 | | 2 | 66d540f8 | useDemoIntro: DEMO_EXTERNAL_URLS → DEMO_PROXY_PORTS, demoAppUrl builds `//:2101/`; useAppIdentity: picker suppressed under IS_DEMO | | 3 | d00ca624 | mock-backend.js staticDevApps gains indeedhub (running, lanPort 8190) → installed on every fresh session | ## What was verified at exec time (live-bundle facts) - Live site still serves `X-Frame-Options: SAMEORIGIN`, no CSP; bundle `assets/index-BMWtjRCn.js`. - Account serialization confirmed by de-minifying the live bundle: private-key account class has `static type="nsec"`, `toJSON` → `{ signer: { key: }, id, pubkey, metadata, type }`; the manager registers the nsec type (`MM(Fe)` registers `mr`) and restores from `indeedhub-accounts` + activates by id from `indeedhub-active-account`. `Vn`/`je` confirmed hex decode/encode. - Pubkey math independently validated against BIP340 test vectors (sk=1 → Gx, sk=3 → F9308A01…) before embedding the generated pair. Mismatch would trigger the bundle's "Account signer mismatch" guard, so this was load-bearing. ## Throwaway demo identity Freshly generated 2026-07-29 for this task (generator ran in scratchpad, not committed): - pk `7261540160244ec65ce0bf86ba03997e9b1b3b35c277e416bf1c7ba4271fee31` - sk embedded in `neode-ui/docker/indee-demo-signin.js`, clearly labelled PUBLIC-DEMO-ONLY / not a secret (threat T-gjd-01: accepted by design). Never a real user key. ## Local verification results 1. **nginx parse:** `nginx -t` clean in `nginx:alpine` (podman, with `--add-host neode-backend:127.0.0.1` to satisfy the pre-existing upstream reference). 2. **Live proxy smoke (podman, config + seeder mounted):** `curl` through :2101 → 200, **no X-Frame-Options / CSP**, injected `