backup commit

This commit is contained in:
Dorian
2026-03-17 00:03:08 +00:00
parent 9156eee017
commit 32f89fa8d5
43 changed files with 9514 additions and 308 deletions

View File

@@ -28,7 +28,35 @@
---
## Phase 3: Fix Iframe Embedding for All Apps
## Phase 3: Fix App Launching — Use Direct IP:Port URLs
- [ ] **Fix AppSession.vue — use direct IP:port URLs instead of nginx proxy paths**: The root cause of most iframe issues is `AppSession.vue` lines 240-276. The `APP_URLS` map hardcodes every app to `/app/{id}/` nginx subpath proxies (e.g., `'/app/filebrowser/'`). This breaks apps because root-relative asset paths (like `/static/main.js`) resolve to the Archy root instead of the app. The fix: replace the hardcoded proxy paths with direct `IP:port` URLs. Change `APP_URLS` to map app IDs to their actual ports instead:
```typescript
const APP_PORTS: Record<string, number> = {
'bitcoin-knots': 8334, 'electrs': 50002, 'btcpay-server': 23000,
'lnd': 8081, 'mempool': 4080, 'homeassistant': 8123, 'grafana': 3000,
'searxng': 8888, 'ollama': 11434, 'onlyoffice': 9980, 'penpot': 9001,
'nextcloud': 8085, 'vaultwarden': 8082, 'jellyfin': 8096,
'photoprism': 2342, 'immich': 2283, 'filebrowser': 8083,
'nginx-proxy-manager': 81, 'portainer': 9000, 'uptime-kuma': 3001,
'tailscale': 8240, 'fedimint': 8175, 'nostr-rs-relay': 18081,
'indeedhub': 7777, 'dwn': 3100, 'endurain': 8080,
}
```
Then compute the URL dynamically in `appUrl`:
- **On HTTP**: `http://${window.location.hostname}:${port}` (direct, no proxy, assets work perfectly)
- **On HTTPS**: `${window.location.origin}/app/${appId}/` (proxy needed to avoid mixed-content blocks)
- **External sites**: keep direct HTTPS URLs as-is (botfights, nwnn, etc.)
This matches what `appLauncher.ts` `toEmbeddableUrl()` already does (lines 70-96) but `AppSession.vue` was bypassing it. Keep the nginx proxy locations for HTTPS — they're still needed there. The `PORT_TO_PROXY` map in `appLauncher.ts` should also be updated to use the same `APP_PORTS` source of truth (import it, or move to a shared `src/data/appPorts.ts`). Run `cd neode-ui && npm run type-check`.
- [ ] **For apps that block iframes — still open in new tab at IP:port**: Update `mustOpenInNewTab()` in `appLauncher.ts` to check against `APP_PORTS` rather than hardcoded port strings. In `AppSession.vue`, add the same check: if `mustOpenInNewTab(url)`, redirect to `window.open(url, '_blank')` instead of loading in iframe. The blocked apps (BTCPay 23000, Grafana 3000, Vaultwarden 8082, PhotoPrism 2342, Nextcloud 8085, Uptime Kuma 3001, Home Assistant 8123) should open at `http://192.168.1.228:{port}` in a new tab. Verify each blocked app actually needs blocking by checking headers: `ssh archipelago@192.168.1.228 'for port in 23000 3000 8082 2342 8085 3001 8123; do echo "Port $port:"; curl -sI http://localhost:$port/ | grep -i "x-frame"; done'`. Remove from blocked list if nginx `proxy_hide_header X-Frame-Options` is stripping the header successfully (in which case they CAN iframe).
- [ ] **Remove unnecessary nginx sub_filter path rewriting**: With direct `IP:port` URLs on HTTP, the `sub_filter` rules in `image-recipe/configs/nginx-archipelago.conf` that rewrite asset paths (e.g., IndeedHub lines 334-367) are no longer needed for HTTP. Keep them for HTTPS proxy paths only. Review each `/app/{id}/` location block — the `proxy_hide_header X-Frame-Options` and `proxy_pass` are still needed for HTTPS, but `sub_filter` rules that rewrite `/static/` or `/_next/` paths are only needed in HTTPS mode. This simplifies the nginx config significantly. Test: load each app at `http://192.168.1.228:{port}` directly in a browser — all assets should load without any nginx intervention.
- [ ] **Inject nostr-provider.js for IndeedHub at IP:port**: When apps load at direct `IP:port` URLs (not through nginx proxy), nginx can't inject `nostr-provider.js` via `sub_filter`. Instead, the `AppSession.vue` iframe wrapper must inject it. In `AppSession.vue`, after the iframe loads, use `iframe.contentWindow.postMessage` to send a script injection request, OR — simpler — add a `<script>` tag to the iframe via the `onload` handler: `iframeEl.contentDocument?.head?.appendChild(script)`. This only works for same-origin iframes (same IP, different port counts as cross-origin in browsers). Since cross-origin blocks this, the Nostr provider needs a different approach for direct port access: either (1) keep IndeedHub specifically on the nginx proxy path since it needs NIP-07, or (2) have IndeedHub check for `window.nostr` and if missing, request it from parent via postMessage. Option 1 is simpler — keep identity-aware apps (`indeedhub`, `nostrudel`) on proxy paths even on HTTP, since they need the script injection. Update `AppSession.vue` to use proxy path for identity-aware apps and direct port for everything else.
- [x] **Audit X-Frame-Options headers for all proxied apps**: SSH to 192.168.1.228. For each app with a known port, check the actual response headers: `for port in 81 3000 3001 4080 7777 8080 8081 8082 8083 8085 8096 8123 8175 8176 8190 8240 8334 8888 9000 9001 9980 11434 2283 2342 23000 50002; do echo "Port $port:"; curl -sI http://localhost:$port/ 2>/dev/null | grep -i "x-frame\|content-security-policy" || echo " (no frame restrictions)"; done`. Record the results. Compare against the blocking list in `neode-ui/src/stores/appLauncher.ts` (lines 23-31, the `XFRAME_BLOCKED_PORTS` array). Update the blocking list to match reality — if an app no longer sends X-Frame-Options DENY, remove it from the blocked list. If an app sends it but isn't in the list, add it.