diff --git a/.planning/RESUME-2026-08-06-media-loop.md b/.planning/RESUME-2026-08-06-media-loop.md index 58a5269e..3287b55b 100644 --- a/.planning/RESUME-2026-08-06-media-loop.md +++ b/.planning/RESUME-2026-08-06-media-loop.md @@ -56,7 +56,23 @@ Live proof on archi-dev-box, authenticated with a real gate session: that authenticate with the `Authorization` header (Vaultwarden, Jellyfin, Nextcloud/WebDAV, Gitea tokens, Grafana). Same mechanism — not individually retested. -Still needs a human: an actual extension login in a browser. +**End-to-end proof, no browser required** (2026-08-06 ~20:20). The node signed a real +NIP-98 event with its own key via RPC (`auth.login` → `node.nostr-pubkey` → +`node.nostr-sign`, CSRF header required for the sign) and presented it to IndeeHub +**through the gate**, exactly as `nostr-provider.js` does: + +- `POST :7778/api/auth/nostr/session` → **200**, IndeeHub issued a real JWT pair + (`typ: nostr-session` / `nostr-refresh`, `sub` = the node's pubkey). A complete + Nostr login. +- Then the app's OWN bearer token back through the gate — the other half of the fix: + `/api/auth/me` **200**, `/api/projects/private` **200**, `/api/projects` **200**, + each identical to loopback. + +`/api/projects/private` was the endpoint recorded here as unreachable without a Nostr +session; it now answers 200 through the gate. Item 4's private-films path is unblocked. + +Still worth a human pass: a real NIP-07 **browser extension** login (this proved the +transport and the app's acceptance, using the node's key rather than the extension's). ### 2. AI Data Access grants → node-side (unblocks everything AI) `aiPermissions.ts` uses `localStorage` (`archipelago-ai-permissions`), which is PER-ORIGIN.