# Plan: Fix Iframe Apps, Detail Pages, Kiosk, Identity Pairing, NIP-07 ## Context Three web-only apps (BotFights, 484 Kitchen, Arch Presentation) show black screens in iframe despite nginx reverse proxies being set up. The kiosk on .228 isn't running. Web-only apps need proper detail pages. The user wants Nostr identity formally paired with DID and NIP-07 browser integration for frictionless login to embedded apps. --- ## Task 1: Fix iframe black screen (HIGH) **Root cause**: Proxied HTML contains root-relative paths (`href="/css/main.css"`). Browser resolves these against the origin root, not `/ext/botfights/`, so all assets 404. **Fix**: Add `sub_filter` to nginx proxy blocks to rewrite root-relative paths. **File**: `image-recipe/configs/nginx-archipelago.conf` (6 location blocks — 3 HTTP, 3 HTTPS) Key additions per block: ```nginx proxy_set_header Accept-Encoding ""; # Disable gzip so sub_filter works sub_filter_once off; sub_filter_types text/html text/css application/javascript; sub_filter 'href="/' 'href="/ext/{app}/'; sub_filter 'src="/' 'src="/ext/{app}/'; sub_filter 'action="/' 'action="/ext/{app}/'; sub_filter "href='/" "href='/ext/{app}/"; sub_filter "src='/" "src='/ext/{app}/"; ``` Deploy + nginx reload. Verify in browser DevTools (Network tab — no 404s on assets). --- ## Task 2: Detail pages for web-only apps (MEDIUM) **Problem**: Clicking a web-only app card navigates to `/dashboard/apps/{id}`. AppDetails.vue can't resolve it because web-only apps aren't in `store.packages` or `dummyApps`. **Fix**: 1. Add 7 web-only apps to `dummyApps` in AppDetails.vue (botfights, nwnn, 484-kitchen, call-the-operator, arch-presentation, syntropy-institute, t-zero) — same pattern as IndeeHub 2. Add URL mappings in AppDetails.vue `appUrls` for all 7 (if not already present) 3. Hide uninstall/start/stop buttons for web-only apps in AppDetails.vue **Files**: `neode-ui/src/views/AppDetails.vue` --- ## Task 3: Kiosk on .228 (MEDIUM) **Problem**: Code exists but was never installed on server. No X11/Chromium packages. **Steps** (SSH to .228, no code changes): 1. `sudo apt-get install -y xorg chromium unclutter xinit` 2. `cd ~/archy && sudo ./scripts/setup-kiosk.sh archipelago` 3. `sudo systemctl enable --now archipelago-kiosk.service` 4. Verify on monitor --- ## Task 4: Pair Nostr identity with DID (LOW) **Current state**: Ed25519 (DID) and secp256k1 (Nostr) are separate key pairs, both generated at startup. Not formally linked. **Fix**: Include the Nostr secp256k1 pubkey in the DID Document as an additional verification method: - Modify `did_document_from_pubkey_hex()` in `identity.rs` to accept optional Nostr pubkey - Add `EcdsaSecp256k1VerificationKey2019` entry to `verificationMethod` array - Pass Nostr pubkey from server startup context **Files**: `core/archipelago/src/identity.rs`, `core/archipelago/src/server.rs` --- ## Task 5: NIP-07 Nostr login via iframe injection (EXPLORATORY) **Goal**: Web apps in iframe (like IndeeHub) can call `window.nostr.getPublicKey()` and `window.nostr.signEvent()` for frictionless Nostr login. **Approach**: Inject a `window.nostr` shim into proxied pages via `sub_filter`, communicating with the parent Archipelago frame via `postMessage`. **Steps**: 1. Create `neode-ui/public/nostr-provider.js` — implements `window.nostr` interface, uses `postMessage` to parent 2. Add `sub_filter '' '';` to nginx ext proxy blocks 3. Add `postMessage` listener in AppLauncherOverlay that handles `nostr-getPublicKey` and `nostr-signEvent` by calling backend RPC 4. Backend already has `identity.nostr-sign` and `node.nostr-pubkey` RPC endpoints **Security**: Validate postMessage origin, prompt user before signing, never expose secret key to frontend. **Files**: new `neode-ui/public/nostr-provider.js`, `image-recipe/configs/nginx-archipelago.conf`, AppLauncherOverlay component, `neode-ui/src/stores/appLauncher.ts` --- ## Execution Order 1. Task 1 — fix iframe black screen (deploy nginx) 2. Task 2 — detail pages (deploy frontend) 3. Task 3 — kiosk on .228 (SSH ops) 4. Task 4 — DID+Nostr pairing (deploy backend) 5. Task 5 — NIP-07 injection (deploy full) ## Verification - Task 1: Open BotFights/484 Kitchen/Arch Presentation in iframe — page renders with styles and interactivity - Task 2: Click web-only app card → detail page shows with title, description, launch button, no container buttons - Task 3: .228 monitor shows kiosk app grid - Task 4: `node.did` RPC returns DID Document with Nostr pubkey in verificationMethod - Task 5: Open IndeeHub in iframe, browser console `window.nostr.getPublicKey()` returns hex pubkey