From a9e3f2434d31ab12b263e53ad14acf2a14c4473d Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Thu, 22 Oct 2026 23:53:43 +0200 Subject: [PATCH] docs: tune item 8 password-routes quick after item 7 --- .../2026-10-22-external-user-plugin-escalations.md | 6 +++--- .../2026-10-22-user-password-routes-404-switch.md | 10 +++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.planning/notes/2026-10-22-external-user-plugin-escalations.md b/.planning/notes/2026-10-22-external-user-plugin-escalations.md index 2614b93b..d88297b1 100644 --- a/.planning/notes/2026-10-22-external-user-plugin-escalations.md +++ b/.planning/notes/2026-10-22-external-user-plugin-escalations.md @@ -45,10 +45,10 @@ Status values: `open` · `done` · `declined`. Shipped: local commit now; replac /msd-quick --discuss --validate Opt-in HttpOnly session cookie on user-plugin POST /login: golem15.user.jwt.token_cookie (default off), attributes from auth.cookie via bouncer.LoadCookieConfig, omit body token when the cookie is set (sociallogin writeSession). Cookie-carried POST /refresh must rotate that cookie (G3 left body-only); bearer-only refresh stays body-only. SameSite=Lax, no CSRF. Base a484d0e. See .planning/todos/pending/2026-10-22-user-login-opt-in-session-cookie.md and .planning/notes/2026-10-22-external-user-plugin-escalations.md -/msd-quick --validate User-plugin config switch that does not register POST /login /forgot-password /reset-password so they 404. Default keeps today’s routes. No framework route-wrap seam. See .planning/todos/pending/2026-10-22-user-password-routes-404-switch.md and .planning/notes/2026-10-22-external-user-plugin-escalations.md +/msd-quick --validate User-plugin golem15.user.password.public_routes (default true). When false, do not register POST /login /forgot-password /reset-password so they 404 like unknown paths. Leave /register and the rest. No framework wrap, no custom 404. Base 8bdf2c7. See .planning/todos/pending/2026-10-22-user-password-routes-404-switch.md and .planning/notes/2026-10-22-external-user-plugin-escalations.md ``` -Suggested order if you care about risk: G4 (serve blacklist), then G3, G2, 9+10, then the two features. Bugs and item 7 (cookie) are done locally; item 8 (password-routes 404) remains. Do not overlap on the same plugin files. +Suggested order if you care about risk: G4 (serve blacklist), then G3, G2, 9+10, then the two features. Bugs and item 7 are done locally; item 8 (password-routes 404) is the last of the six. Do not overlap on the same plugin files. Do not send the reply until v0.5.0 is tagged. ## Verdicts (kept for the sessions) @@ -59,7 +59,7 @@ Suggested order if you care about risk: G4 (serve blacklist), then G3, G2, 9+10, - **G7.** Stock form omission was a 12.1 decision. Stale `organisation_role` is already cleared (`ClearOnChange`, v0.1.8). Apps extend the form. - **G8.** Personal tokens die via `revoked_at`. `RevokeUserAccess` already sets that on deactivate/ban. Do not teach the API-token guard a JWT cutoff. Password reset killing API tokens would be a separate, explicit revoke. - **7.** Done locally (`846087d`, `8bdf2c7`). `846087d`: a `/refresh` carried by the `auth.cookie` cookie (`token` by default, no bearer) rewrites it and answers `{}`, whatever `token_cookie` says; bearer and other-cookie refreshes stay body-only; refusals write no cookie. `8bdf2c7`: `golem15.user.jwt.token_cookie` (default off) makes /login, /register (auto sign-in) and /activate-by-code set the HttpOnly `auth.cookie` cookie via `bouncer.LoadCookieConfig` and omit body `token`; off keeps today's bodies. SameSite=Lax, no CSRF; API tokens untouched. -- **8.** Plugin config; no framework wrap. +- **8.** Plugin config; no framework wrap. Next: `golem15.user.password.public_routes` (default true). When false, skip registering `/login`, `/forgot-password`, `/reset-password`. `/register` stays (`allow_registration` already gates it). - **9.** Done locally (`b6f8055`). /login keys the throttle on surf.ClientIP with http.trusted_proxies (the /register expression); RemoteIP stays the RemoteAddr helper; without trusted proxies X-Forwarded-For is ignored. - **10.** Done locally (`a484d0e`). /reset-password and the admin password set truncate the cutoff to whole seconds like RevokeUserAccess; change-password and bouncer unchanged. diff --git a/.planning/todos/pending/2026-10-22-user-password-routes-404-switch.md b/.planning/todos/pending/2026-10-22-user-password-routes-404-switch.md index cd632a23..7fc62220 100644 --- a/.planning/todos/pending/2026-10-22-user-password-routes-404-switch.md +++ b/.planning/todos/pending/2026-10-22-user-password-routes-404-switch.md @@ -21,12 +21,16 @@ They do not need a framework wrap. The user plugin owns those routes and can ski ## Solution -A user-plugin config key (name it in the plan; default keeps today’s routes). When on, do not register `POST /login`, `/forgot-password` and `/reset-password` so they 404 like any unknown path. `/register`, `/activate*`, `/fetch` and the rest stay. Document the key. A test boots both values and checks the route table (or a 404 vs 401/200 probe). No change in `pact` / `surf`. +Key: `golem15.user.password.public_routes` (default `true`, next to `password.min_length`). When `false`, do not register `POST /login`, `/forgot-password` and `/reset-password` so they 404 like any unknown path. Do not mount a custom 404 handler. -After the commit, fill item 8 in `.planning/notes/2026-10-22-external-user-plugin-escalations.md`. +Leave registered: `/register` (`allow_registration` already refuses at the handler), `/activate*`, `/fetch`, `/refresh`, `/logout`, `/change-password`, `/tokens`, the rest. `golem15.user.turnstile` still wraps `/register` when login is off. No change in `pact` / `surf`. Off (the default) is byte-identical to today’s route table. + +`turnstile_routes_test` already records the route table — reuse that pattern. Probe 404 vs the current login/forgot/reset status when the key is on. Existing tests keep the default. + +Base is sm-user-plugin `8bdf2c7` (item 7). Hold push/tag for SummerCMS v0.5.0. After the commit, fill item 8 in `.planning/notes/2026-10-22-external-user-plugin-escalations.md` like the earlier rows (`done (unreleased)`, ships in v0.5.0, name the key). Leave the todo in pending with an Outcome. Do not send the reply; the hold stands until the rest of the v0.5.0 wave (keyboard shortcuts, MCP / 19.7) is tagged. ## Invoke ``` -/msd-quick --validate User-plugin config switch that does not register POST /login /forgot-password /reset-password so they 404. Default keeps today’s routes. No framework route-wrap seam. See .planning/todos/pending/2026-10-22-user-password-routes-404-switch.md and .planning/notes/2026-10-22-external-user-plugin-escalations.md +/msd-quick --validate User-plugin golem15.user.password.public_routes (default true). When false, do not register POST /login /forgot-password /reset-password so they 404 like unknown paths. Leave /register and the rest. No framework wrap, no custom 404. Base 8bdf2c7. See .planning/todos/pending/2026-10-22-user-password-routes-404-switch.md and .planning/notes/2026-10-22-external-user-plugin-escalations.md ```