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:
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.