3 Commits
Author SHA1 Message Date
jwinterm fe2fc91cdd fix(admin-ui): repair Keys tab + console UX
- Keys tab crashed on render: api.keys() expected an array but the
  backend returns {keys:[...]}; unwrap it (KeysTab maps over the array).
- Config save now sends only CHANGED fields, not the whole section, so
  the backend stops spuriously flagging restarts and pinning env-sourced
  values into the DB overlay.
- Config edit state survives a reload (saving one section no longer
  discards unsaved edits in others); numeric inputs ignore empty/NaN
  instead of silently coercing to 0.
- Mint and Revoke now surface errors instead of swallowing them.
Rebuilt admin-ui/dist.
2026-07-19 05:30:33 -04:00
jwinterm e125f4fcc2 fix(admin): console requests challenge with POST, matching the route
The SPA issued GET /admin/auth/challenge but the route is POST (nonce
issuance is a write). Left as-is the login flow 405'd at step one. Fixed
the client verb and rebuilt dist.
2026-07-18 16:18:33 -04:00
jwinterm 35447868d4 feat(admin): serve Operator Console SPA at /admin (rust-embed)
Preact + Vite standalone admin-ui bundled into the server binary via
rust-embed. Login is NIP-07 (Smirk wallet signs the NIP-98 admin
challenge); tabs cover instance status, admin keys, invite codes, and
the effective-config editor (live vs restart-required per field).

admin-ui/dist is committed because rust-embed reads it at compile time;
node_modules is gitignored (npm ci reproduces it). A lib test asserts
index.html and the /admin/ asset base are embedded so an unbuilt
console fails the build instead of an operator.

The console is served on the admin plane only (loopback bind), behind
the existing NIP-98 admin_guard + MAC allowlist.
2026-07-18 16:03:03 -04:00