1
Web UI
Sulthan Zaki edited this page 2026-07-26 20:39:31 +07:00

Web UI

The same backend binary serves a password-gated browser UI on a second hostname, so you can view/edit bookmarks from any browser, not just via the userscript.

Enable / disable

Controlled entirely by WEB_PASSWORD:

  • Set → web routes registered, UI reachable, gated by the password.
  • Unset → web routes are not registered at all; / returns 404. The userscript's /bookmarks* API is unaffected either way.

Routes

Method Path Auth Purpose
GET / session or none List (or login page if no session)
POST /login password Sets session cookie
POST /logout session Clears cookie
GET /static/* none CSS/JS assets (go:embed)
GET /ui/list session htmx fragment: bookmark list
POST /ui/bookmarks/{key}/favorite session Toggle favourite
POST /ui/bookmarks/{key}/chapter session Manual chapter override
DELETE /ui/bookmarks/{key} session Remove a bookmark

Templates (templates/*.html) and assets (static/*) are go:embed-ed into the binary — backend/Dockerfile copies templates/ and static/ alongside the *.go files.

Sessions

Stateless — no session table. The cookie is:

<expiryMs>.<base64url HMAC-SHA256(expiryMs)>

signed with a key derived from both API_TOKEN and WEB_PASSWORD (SHA-256 of apiToken + "\x00" + webPassword + "mangabm-web-session-v1"). Rotating either secret invalidates every outstanding session at once — there's nothing to revoke individually, so this is the way to force a logout everywhere.

  • TTL: 60 days — long enough a phone stays logged in between reading sessions.
  • Verification order: shape → expiry → HMAC (constant-time compare last, so earlier cheap checks leak no timing information about the signature).
  • Login is rate-limited (see newLoginLimiter() in session.go).

Mutations stay consistent with the API

Every UI mutation (favourite, chapter override, delete) goes through the same Store.Get + Store.Upsert path the /bookmarks API uses — so the updated_at ordering rule (see Backend-API) applies identically whether the change came from the userscript or the web UI.

Design doc

Full design rationale: docs/superpowers/specs/2026-07-25-web-ui-design.md.