Commit Graph

9 Commits

Author SHA1 Message Date
Jakub Zych
32f92591d6 fix: account link proof by auth_time, code in the URL fragment and POST show
- BackendLinkConfirm reads the session's auth_time (bouncer.VerifyAuthTime);
  a token without it, or a refreshed old session, answers 409 stale_session
- POST /_user/api/v1/backend-link/show takes the code in the body; GET
  /backend-link/{code} stays, deprecated; both answer Cache-Control no-store
- My account answers <frontend_url><page_path>#code=<code>; new key
  golem15.user.backend_links.page_path (default /link-admin)
- TestBackendLink now crafts auth_time tokens; TestBackendLinkAuthTimeSmoke
2026-10-23 16:38:55 +02:00
Jakub Zych
7ac80c9aea feat: verified frontend account link for administrators
- golem15_user_backend_links (1:1, both sides unique) and one-shot hashed
  golem15_user_backend_link_requests (golem15.user.backend_links.request_ttl, 10m)
- classes.BackendLinks: CreateLinkRequest, ConfirmLinkRequest (row lock,
  JWT iat not before the request), SetLink, RemoveLink, LinkedBackendUser;
  published as *classes.BackendLinks and pact.MCPLinkedBackendResolver
- GET /_user/api/v1/backend-link/{code} and POST /backend-link/confirm (jwt.auth)
- My account section frontend_account with link and unlink
- BackendLinkedEvent, BackendUnlinkedEvent and pact.MCPSubjectChanged after commit;
  deleting or deactivating a frontend user removes its link
- golem15.user.frontend_url (falls back to app.url)
2026-10-23 12:03:26 +02:00
Jakub Zych
3828a65481 feat: golem15.user.password.public_routes false leaves POST /login, /forgot-password and /reset-password unregistered, so they 404 like any unknown path
The key defaults to true, so the route table is unchanged. False skips only
those three registrations: they get the router's own 404, with no custom
handler and no framework change. /register keeps allow_registration and the
turnstile guard. The key is read at boot, and a value other than true or
false fails boot like golem15.user.turnstile.
2026-10-23 00:09:38 +02:00
Jakub Zych
8bdf2c7d1a feat: opt-in golem15.user.jwt.token_cookie sets the HttpOnly session cookie on /login, /register and /activate-by-code instead of returning the token
Default off, so body-token clients are unchanged. When on, the cookie carries the auth.cookie attributes via bouncer.LoadCookieConfig and the body keeps user (and message); SameSite stays Lax, with no CSRF token; personal API tokens are untouched.
2026-10-22 23:44:44 +02:00
Jakub Zych
7b9faa3419 feat: opt-in Cloudflare Turnstile on login and register (golem15.user.turnstile)
- empty (default) adds nothing; open or closed appends turnstile:{mode} to
  POST /login and /register only; any other value fails boot naming the key
- TestTurnstileRoutesSmoke records the declared routes with a recording router
2026-10-20 14:45:22 +02:00
Jakub Zych
b410a7fea9 feat: register the Users admin screen with the privileged-member guard
- permissions (the four Winter codes and manage_privileged_groups),
  the user navigation item and the embedded admin YAML
- Users controller: list with deactivated users, row states, the
  groups, created date and activated filters, and the form's name,
  surname and email
- a member of a group in golem15.user.privileged_groups (default
  admin) keeps their email, password and row unless the administrator
  holds golem15.users.manage_privileged_groups; the refusal is a 403
  that saves nothing
2026-10-05 13:01:48 +02:00
Jakub Zych
0fe5b91b63 feat: own shared user API tokens 2026-10-04 22:30:20 +02:00
Jakub Zych
1311bd6cad feat(07-02): add user session schema, throttle table, and jwt config
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-22 13:53:16 +02:00
Jakub Zych
f975ad94bb feat(03-01): initialize fonoteka workspace with user and genre migrations
Add compiled golem15.user and golem15.fonoteka plugins, squash schema
to the genre slice tables, and seed the 15 canonical genres on ICU pl-PL.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 19:55:36 +02:00