docs: user-plugin escalations released in sm-user-plugin v0.1.9, reply ready to send

This commit is contained in:
Jakub Zych
2026-10-23 00:25:24 +02:00
parent eadd58414d
commit e2759d668f
7 changed files with 46 additions and 24 deletions

View File

@@ -9,9 +9,7 @@ g15office: bhoyg8z4
Reviewed 2026-10-22. The list is `golem15.user` (sm-user-plugin), not cabana admin auth. Phase 19.6 (2FA) is not mid-flight. Reviewed 2026-10-22. The list is `golem15.user` (sm-user-plugin), not cabana admin auth. Phase 19.6 (2FA) is not mid-flight.
**Release hold (2026-10-22):** nothing is pushed or tagged until the **SummerCMS v0.5.0** wave is finished. That wave is these six user-plugin quicks, admin keyboard shortcuts (`261022-k9k`), and the MCP feature (phase 19.7). Plugin commits stay local; the plugin tag and app pointer bumps go out with v0.5.0, not as a v0.1.9-shaped mid-wave release. Changelog post the same day as the framework tag. **Released (2026-10-23):** sm-user-plugin **v0.1.9** carries all six quicks and still requires SummerCMS v0.4.3, so the external app needs no framework upgrade for these fixes. The earlier hold for a v0.5.0 wave is withdrawn: v0.5.0 is reserved for the finished MCP phase (19.7), and the framework's own next patch is v0.4.4, which is not needed for anything below. The reply is ready to send.
**How to use this file.** Each quick fills its row in the tracker and the matching paragraph under [Reply to send](#reply-to-send). When all six are done **and** v0.5.0 is tagged, send that section as-is. Do not send, push or tag before then.
**Do not run the six quicks in parallel on one working tree.** They share `sm-user-plugin` (`api_controller.go`, `plugin.go`, `routes.go`, README). Sequential fresh sessions. **Do not run the six quicks in parallel on one working tree.** They share `sm-user-plugin` (`api_controller.go`, `plugin.go`, `routes.go`, README). Sequential fresh sessions.
@@ -19,18 +17,18 @@ Reviewed 2026-10-22. The list is `golem15.user` (sm-user-plugin), not cabana adm
| # | Their label | Verdict | Quick / todo | g15office | Status | Shipped | | # | Their label | Verdict | Quick / todo | g15office | Status | Shipped |
|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|
| 1 | G2 login ignores `is_activated` | Fix | [261022-tb4](../quick/261022-tb4-password-login-must-refuse-is-activated-/) · [todo](../todos/pending/2026-10-22-user-login-ignores-is-activated.md) | 3r4or1ex | done (unreleased) | `15ff979` → v0.5.0 | | 1 | G2 login ignores `is_activated` | Fix | [261022-tb4](../quick/261022-tb4-password-login-must-refuse-is-activated-/) · [todo](../todos/done/2026-10-22-user-login-ignores-is-activated.md) | 3r4or1ex | released | `15ff979` → user v0.1.9 |
| 2 | G3 cookie-only 401 | Fix remaining four; logout already done | [261022-tto](../quick/261022-tto-fetch-refresh-update-change-password-mus/) · [todo](../todos/pending/2026-10-22-user-session-routes-ignore-cookie.md) | kkknstxl | done (unreleased) | `8e4b863` → v0.5.0 | | 2 | G3 cookie-only 401 | Fix remaining four; logout already done | [261022-tto](../quick/261022-tto-fetch-refresh-update-change-password-mus/) · [todo](../todos/done/2026-10-22-user-session-routes-ignore-cookie.md) | kkknstxl | released | `8e4b863` → user v0.1.9 |
| 3 | G4 logout blacklist under `serve` | Fix | [261022-usi](../quick/261022-usi-user-plugin-jwt-blacklist-and-hooks-wire/) · [todo](../todos/pending/2026-10-22-user-logout-blacklist-missing-under-serve.md) | ud0gficu | done (unreleased) | `4bf44fc` → v0.5.0 | | 3 | G4 logout blacklist under `serve` | Fix | [261022-usi](../quick/261022-usi-user-plugin-jwt-blacklist-and-hooks-wire/) · [todo](../todos/done/2026-10-22-user-logout-blacklist-missing-under-serve.md) | ud0gficu | released | `4bf44fc` → user v0.1.9 |
| 4 | G6 `/update` email without proof | Decline | — | — | declined | n/a | | 4 | G6 `/update` email without proof | Decline | — | — | declined | n/a |
| 5 | G7 Users form has no role field | Decline | — | — | declined | n/a | | 5 | G7 Users form has no role field | Decline | — | — | declined | n/a |
| 6 | G8 API token guard ignores `tokens_valid_after` | Decline | — | — | declined | n/a | | 6 | G8 API token guard ignores `tokens_valid_after` | Decline | — | — | declined | n/a |
| 7 | Cookie option on `/login` | Feature | [261022-wah](../quick/261022-wah-opt-in-httponly-session-cookie-on-user-p/) · [todo](../todos/pending/2026-10-22-user-login-opt-in-session-cookie.md) | strnsccy | done (unreleased) | `846087d`, `8bdf2c7` → v0.5.0 | | 7 | Cookie option on `/login` | Feature | [261022-wah](../quick/261022-wah-opt-in-httponly-session-cookie-on-user-p/) · [todo](../todos/done/2026-10-22-user-login-opt-in-session-cookie.md) | strnsccy | released | `846087d`, `8bdf2c7` → user v0.1.9 |
| 8 | Password-routes 404 switch | Feature | [261022-x7a](../quick/261022-x7a-user-plugin-golem15-user-password-public/) · [todo](../todos/pending/2026-10-22-user-password-routes-404-switch.md) | h7yrafgd | done (unreleased) | `3828a65` → v0.5.0 | | 8 | Password-routes 404 switch | Feature | [261022-x7a](../quick/261022-x7a-user-plugin-golem15-user-password-public/) · [todo](../todos/done/2026-10-22-user-password-routes-404-switch.md) | h7yrafgd | released | `3828a65` → user v0.1.9 |
| 9 | Lockout keyed on `RemoteAddr` | Fix | [261022-vfz](../quick/261022-vfz-user-plugin-login-throttle-via-surf-clie/) · [todo](../todos/pending/2026-10-22-user-login-lockout-and-same-second-cutoff.md) | sniewiif | done (unreleased) | `b6f8055` → v0.5.0 | | 9 | Lockout keyed on `RemoteAddr` | Fix | [261022-vfz](../quick/261022-vfz-user-plugin-login-throttle-via-surf-clie/) · [todo](../todos/done/2026-10-22-user-login-lockout-and-same-second-cutoff.md) | sniewiif | released | `b6f8055` → user v0.1.9 |
| 10 | Same-second token refusal | Fix | [261022-vfz](../quick/261022-vfz-user-plugin-login-throttle-via-surf-clie/) · [todo](../todos/pending/2026-10-22-user-login-lockout-and-same-second-cutoff.md) | sniewiif | done (unreleased) | `a484d0e` → v0.5.0 | | 10 | Same-second token refusal | Fix | [261022-vfz](../quick/261022-vfz-user-plugin-login-throttle-via-surf-clie/) · [todo](../todos/done/2026-10-22-user-login-lockout-and-same-second-cutoff.md) | sniewiif | released | `a484d0e` → user v0.1.9 |
Status values: `open` · `done` · `declined`. Shipped: local commit now; replace with the v0.5.0 plugin/framework tags at release. Do not write a mid-wave plugin tag. Status values: `open` · `done` · `declined`. Shipped: plugin commit → sm-user-plugin tag.
## Six invocations (fresh session each, sequential) ## Six invocations (fresh session each, sequential)
@@ -48,7 +46,7 @@ Status values: `open` · `done` · `declined`. Shipped: local commit now; replac
/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 /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. All six are done locally; item 8 (password-routes 404) was the last. Do not overlap on the same plugin files. Do not send the reply until v0.5.0 is tagged. Suggested order if you care about risk: G4 (serve blacklist), then G3, G2, 9+10, then the two features. All six are done locally; item 8 (password-routes 404) was the last. Do not overlap on the same plugin files. Released in sm-user-plugin v0.1.9.
## Verdicts (kept for the sessions) ## Verdicts (kept for the sessions)
@@ -65,22 +63,22 @@ Suggested order if you care about risk: G4 (serve blacklist), then G3, G2, 9+10,
## Reply to send ## Reply to send
Copy from here when the tracker is complete. Replace every `TODO` as a quick lands. Declined items are already written. Ready to send as-is (all items filled, released in sm-user-plugin v0.1.9).
``` ```
Thanks for the escalation list. We reviewed the current golem15.user plugin (and the framework boot order). Here is what we will ship, what is already true, and what we are not changing. Thanks for the escalation list. We reviewed the current golem15.user plugin (and the framework boot order). Here is what we shipped, what is already true, and what we are not changing. The fixes and the two new options are in sm-user-plugin v0.1.9, which still requires SummerCMS v0.4.3: bump the plugin, no framework upgrade is needed.
G2 — login ignores is_activated G2 — login ignores is_activated
Agreed. require_activation defaults to true and /register already withholds a token in admin mode; /login did not check is_activated. That is not the same as deactivation (deleted_at), which stays self-service: a later password login still restores the account. Agreed. require_activation defaults to true and /register already withholds a token in admin mode; /login did not check is_activated. That is not the same as deactivation (deleted_at), which stays self-service: a later password login still restores the account.
Ships in SummerCMS v0.5.0 (sm-user-plugin 15ff979, tagged with that wave): with require_activation on (the default), /login answers an account that is not activated with the same opaque invalid-login response as a bad password (counted as a failed attempt); deactivation stays self-service. /activate still serves a not-activated session so the mailed-code flow works. Ships in sm-user-plugin v0.1.9 (15ff979): with require_activation on (the default), /login answers an account that is not activated with the same opaque invalid-login response as a bad password (counted as a failed attempt); deactivation stays self-service. /activate still serves a not-activated session so the mailed-code flow works.
G3 — some routes ignore the cookie G3 — some routes ignore the cookie
Partly already fixed, rest agreed. POST /logout already accepts the token/auth_token cookies (and blacklists every JWT the request carries). GET /fetch, POST /refresh, POST /update and POST /change-password still required the Authorization header. Partly already fixed, rest agreed. POST /logout already accepts the token/auth_token cookies (and blacklists every JWT the request carries). GET /fetch, POST /refresh, POST /update and POST /change-password still required the Authorization header.
Ships in SummerCMS v0.5.0 (sm-user-plugin 8e4b863, tagged with that wave): GET /fetch, POST /refresh, POST /update and POST /change-password (and the other signed-in routes: /activate, /marketing-consent, /avatar, /avatar/remove) read the session token like jwt.auth: the Authorization header first, then the token and auth_token cookies. A /refresh carried by the session cookie named in auth.cookie (token by default) rewrites that cookie with the rotated token and answers {} (see "Cookie on /login" below). A /refresh carried by the Authorization header, or by the auth_token cookie, returns the rotated token in the body and writes no cookie; the previous token is revoked, so store the new one yourself. Ships in sm-user-plugin v0.1.9 (8e4b863): GET /fetch, POST /refresh, POST /update and POST /change-password (and the other signed-in routes: /activate, /marketing-consent, /avatar, /avatar/remove) read the session token like jwt.auth: the Authorization header first, then the token and auth_token cookies. A /refresh carried by the session cookie named in auth.cookie (token by default) rewrites that cookie with the rotated token and answers {} (see "Cookie on /login" below). A /refresh carried by the Authorization header, or by the auth_token cookie, returns the rotated token in the body and writes no cookie; the previous token is revoked, so store the new one yourself.
G4 — logout does not blacklist under serve G4 — logout does not blacklist under serve
Agreed. Plugin Boot runs before serve publishes the database, so the in-process blacklist store was never wired in production (the jwt_blacklist table exists; nothing wrote to it). Tests hid this because they publish the DB before Boot. Agreed. Plugin Boot runs before serve publishes the database, so the in-process blacklist store was never wired in production (the jwt_blacklist table exists; nothing wrote to it). Tests hid this because they publish the DB before Boot.
Ships in SummerCMS v0.5.0 (sm-user-plugin 4bf44fc, tagged with that wave): the plugin installs its jwt_blacklist store, the blacklist sweep and its GORM hooks when serve publishes the database, and the jwt guard reads that store on every request. Logout under serve now writes the jti to jwt_blacklist, and the next request with that token (jwt.auth routes, /fetch, /refresh) answers 401. A regression test boots in serve order (plugins first, database second). The jwt guard also takes its cookie names from the same list as the session routes (token, auth_token). Ships in sm-user-plugin v0.1.9 (4bf44fc): the plugin installs its jwt_blacklist store, the blacklist sweep and its GORM hooks when serve publishes the database, and the jwt guard reads that store on every request. Logout under serve now writes the jti to jwt_blacklist, and the next request with that token (jwt.auth routes, /fetch, /refresh) answers 401. A regression test boots in serve order (plugins first, database second). The jwt guard also takes its cookie names from the same list as the session routes (token, auth_token).
G6 — /update changes email without proof G6 — /update changes email without proof
As designed, not a bug. A new address clears email_verified_at and stays unproven until the owner completes an activation code or a reset-password. We are not adding a “confirm the new inbox before the change sticks” flow in this round. Say if you need that as a later feature. As designed, not a bug. A new address clears email_verified_at and stays unproven until the owner completes an activation code or a reset-password. We are not adding a “confirm the new inbox before the change sticks” flow in this round. Say if you need that as a later feature.
@@ -92,18 +90,18 @@ G8 — API token guard ignores tokens_valid_after
As designed. Personal API tokens are revoked through revoked_at, not the JWT cutoff. Deactivate and ban already revoke those rows (RevokeUserAccess). A password reset is not supposed to kill API tokens; if you want that, say so and we will revoke the rows, not mix the two mechanisms. As designed. Personal API tokens are revoked through revoked_at, not the JWT cutoff. Deactivate and ban already revoke those rows (RevokeUserAccess). A password reset is not supposed to kill API tokens; if you want that, say so and we will revoke the rows, not mix the two mechanisms.
Cookie on /login Cookie on /login
Agreed as an opt-in. Sociallogin already has token_cookie for OAuth complete; password /login will grow the same kind of flag (default off, so body-token clients stay unchanged). Agreed as an opt-in. Sociallogin already has token_cookie for OAuth complete; password /login now has the same kind of flag (default off, so body-token clients stay unchanged).
Ships in SummerCMS v0.5.0 (sm-user-plugin 846087d and 8bdf2c7, tagged with that wave): set golem15.user.jwt.token_cookie: true (default false) and POST /login, POST /register (when it signs the new account in) and POST /activate-by-code set the HttpOnly session cookie with the auth.cookie attributes (bouncer.LoadCookieConfig: name token, path /, SameSite=Lax, Secure from app.url, Max-Age the refresh window) and leave token out of the body; user (and message) stay. A POST /refresh carried by that cookie rewrites it with the rotated token and answers {}; a bearer refresh is unchanged. With the key off nothing changes. SameSite stays Lax and there is no CSRF token. Keep auth.cookie.name at token or auth_token, the cookies the session routes read. Ships in sm-user-plugin v0.1.9 (846087d and 8bdf2c7): set golem15.user.jwt.token_cookie: true (default false) and POST /login, POST /register (when it signs the new account in) and POST /activate-by-code set the HttpOnly session cookie with the auth.cookie attributes (bouncer.LoadCookieConfig: name token, path /, SameSite=Lax, Secure from app.url, Max-Age the refresh window) and leave token out of the body; user (and message) stay. A POST /refresh carried by that cookie rewrites it with the rotated token and answers {}; a bearer refresh is unchanged. With the key off, /login, /register and /activate-by-code return the body token as before; the /refresh cookie rewrite applies either way, because it follows the cookie the refresh arrived with, not this key. That is a change for a client that refreshes with only the token cookie and no Authorization header: it now gets {} and a rewritten cookie instead of the token in the body. SameSite stays Lax and there is no CSRF token. Keep auth.cookie.name at token or auth_token, the cookies the session routes read.
Password-routes switch Password-routes switch
Agreed, in the user plugin, not as a framework “wrap another plugin’s routes” seam. A config key will stop registering /login, /forgot-password and /reset-password so they 404. Agreed, in the user plugin, not as a framework “wrap another plugin’s routes” seam. A config key stops registering /login, /forgot-password and /reset-password so they 404.
Ships in SummerCMS v0.5.0 (sm-user-plugin 3828a65, tagged with that wave): set golem15.user.password.public_routes: false (default true; SUMMER_GOLEM15__USER__PASSWORD__PUBLIC_ROUTES=false in the environment) and POST /login, POST /forgot-password and POST /reset-password are not registered, so they answer the same 404 as any unknown path, whatever the method. POST /register stays (allow_registration still decides whether it takes accounts, and golem15.user.turnstile still guards it), as do /activate, /activate-by-code, /fetch, /refresh, /logout, /update, /change-password and /tokens. With the key true or unset nothing changes. The key is read when the routes are built, so a change needs a restart; a value other than true or false stops boot with an error naming the key. Ships in sm-user-plugin v0.1.9 (3828a65): set golem15.user.password.public_routes: false (default true; SUMMER_GOLEM15__USER__PASSWORD__PUBLIC_ROUTES=false in the environment) and POST /login, POST /forgot-password and POST /reset-password are not registered, so they answer the same 404 as any unknown path, whatever the method. POST /register stays (allow_registration still decides whether it takes accounts, and golem15.user.turnstile still guards it), as do /activate, /activate-by-code, /fetch, /refresh, /logout, /update, /change-password and /tokens. With the key true or unset nothing changes. The key is read when the routes are built, so a change needs a restart; a value other than true or false stops boot with an error naming the key.
Login lockout keyed on RemoteAddr Login lockout keyed on RemoteAddr
Agreed. /login used RemoteAddr; /register already uses the trusted-proxy client address. Behind a reverse proxy five failures locked everyone. Agreed. /login used RemoteAddr; /register already uses the trusted-proxy client address. Behind a reverse proxy five failures locked everyone.
Ships in SummerCMS v0.5.0 (sm-user-plugin b6f8055, tagged with that wave): /login counts failed logins per account and client address, and the client address is now the one /register and the user-api rate limit use: behind a proxy listed in http.trusted_proxies, the X-Forwarded-For client; otherwise the connection address. An X-Forwarded-For header from an address not in http.trusted_proxies is ignored, so it cannot dodge or move a lockout. List your nginx/Caddy address in http.trusted_proxies; without it every visitor still counts as the proxy. Ships in sm-user-plugin v0.1.9 (b6f8055): /login counts failed logins per account and client address, and the client address is now the one /register and the user-api rate limit use: behind a proxy listed in http.trusted_proxies, the X-Forwarded-For client; otherwise the connection address. An X-Forwarded-For header from an address not in http.trusted_proxies is ignored, so it cannot dodge or move a lockout. List your nginx/Caddy address in http.trusted_proxies; without it every visitor still counts as the proxy.
Same-second token refusal Same-second token refusal
Agreed. JWT iat is whole seconds; some tokens_valid_after writers stamped sub-second time. RevokeUserAccess already truncates. Reset-password and the admin password set will too. Agreed. JWT iat is whole seconds; some tokens_valid_after writers stamped sub-second time. RevokeUserAccess already truncates. Reset-password and the admin password set now do too.
Ships in SummerCMS v0.5.0 (sm-user-plugin a484d0e, tagged with that wave): POST /reset-password and an administrator's password set on the Users form stamp tokens_valid_after with the current whole second, as deactivate and ban already do, so a token minted in the same second as the reset (the login right after it) is accepted and every token from an earlier second is still refused. As with deactivate and ban, a token issued earlier within that same second also stays valid, because iat has no finer resolution. /change-password and the guard's comparison are unchanged. Ships in sm-user-plugin v0.1.9 (a484d0e): POST /reset-password and an administrator's password set on the Users form stamp tokens_valid_after with the current whole second, as deactivate and ban already do, so a token minted in the same second as the reset (the login right after it) is accepted and every token from an earlier second is still refused. As with deactivate and ban, a token issued earlier within that same second also stays valid, because iat has no finer resolution. /change-password and the guard's comparison are unchanged.
``` ```

View File

@@ -37,3 +37,7 @@ Quick `261022-tb4`. Fix commit `15ff979` on sm-user-plugin master (base v0.1.8 /
``` ```
/msd-quick --validate Password /login must refuse is_activated=false when golem15.user.activation.require_activation is true (default), same opaque invalid-login body as a bad password. Do not change deleted_at restore-on-login. See .planning/todos/pending/2026-10-22-user-login-ignores-is-activated.md and .planning/notes/2026-10-22-external-user-plugin-escalations.md /msd-quick --validate Password /login must refuse is_activated=false when golem15.user.activation.require_activation is true (default), same opaque invalid-login body as a bad password. Do not change deleted_at restore-on-login. See .planning/todos/pending/2026-10-22-user-login-ignores-is-activated.md and .planning/notes/2026-10-22-external-user-plugin-escalations.md
``` ```
## Closed 2026-10-23
Shipped in sm-user-plugin v0.1.9 (15ff979), quick task 261022-tb4. Requires SummerCMS v0.4.3.

View File

@@ -42,3 +42,7 @@ Quick `261022-vfz`. Two fix commits on sm-user-plugin master, `b6f8055` and `a48
``` ```
/msd-quick --validate User-plugin /login throttle must use surf.ClientIP (trusted proxies), not RemoteAddr. Leave exported RemoteIP as the RemoteAddr helper. Remaining tokens_valid_after writers (reset-password, admin password set) must Truncate(time.Second) like RevokeUserAccess; leave change-password and bouncer's comparison alone. See .planning/todos/pending/2026-10-22-user-login-lockout-and-same-second-cutoff.md and .planning/notes/2026-10-22-external-user-plugin-escalations.md /msd-quick --validate User-plugin /login throttle must use surf.ClientIP (trusted proxies), not RemoteAddr. Leave exported RemoteIP as the RemoteAddr helper. Remaining tokens_valid_after writers (reset-password, admin password set) must Truncate(time.Second) like RevokeUserAccess; leave change-password and bouncer's comparison alone. See .planning/todos/pending/2026-10-22-user-login-lockout-and-same-second-cutoff.md and .planning/notes/2026-10-22-external-user-plugin-escalations.md
``` ```
## Closed 2026-10-23
Shipped in sm-user-plugin v0.1.9 (b6f8055, a484d0e), quick task 261022-vfz. Requires SummerCMS v0.4.3.

View File

@@ -48,3 +48,7 @@ Quick `261022-wah`. Two commits on sm-user-plugin master, `846087d` then `8bdf2c
``` ```
/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 --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
``` ```
## Closed 2026-10-23
Shipped in sm-user-plugin v0.1.9 (846087d, 8bdf2c7), quick task 261022-wah. Requires SummerCMS v0.4.3.

View File

@@ -39,3 +39,7 @@ Quick `261022-usi`. Fix commit `4bf44fc` on sm-user-plugin master (base `8e4b863
``` ```
/msd-quick --discuss --validate Under serve, user-plugin Boot runs before lagoon.Publish so the jwt blacklist is never wired and logout does not revoke. Wire BlacklistStore and RegisterHooks through lagoon.OnDatabase; test Activate-then-Publish. When re-registering the jwt guard, pass classes.SessionCookieNames() instead of the hardcoded token/auth_token names (G3 leftover). See .planning/todos/pending/2026-10-22-user-logout-blacklist-missing-under-serve.md and .planning/notes/2026-10-22-external-user-plugin-escalations.md /msd-quick --discuss --validate Under serve, user-plugin Boot runs before lagoon.Publish so the jwt blacklist is never wired and logout does not revoke. Wire BlacklistStore and RegisterHooks through lagoon.OnDatabase; test Activate-then-Publish. When re-registering the jwt guard, pass classes.SessionCookieNames() instead of the hardcoded token/auth_token names (G3 leftover). See .planning/todos/pending/2026-10-22-user-logout-blacklist-missing-under-serve.md and .planning/notes/2026-10-22-external-user-plugin-escalations.md
``` ```
## Closed 2026-10-23
Shipped in sm-user-plugin v0.1.9 (4bf44fc), quick task 261022-usi. Requires SummerCMS v0.4.3.

View File

@@ -38,3 +38,7 @@ Quick `261022-x7a`. One commit on sm-user-plugin master, `3828a65` (base `8bdf2c
``` ```
/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 /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
``` ```
## Closed 2026-10-23
Shipped in sm-user-plugin v0.1.9 (3828a65), quick task 261022-x7a. Requires SummerCMS v0.4.3.

View File

@@ -35,3 +35,7 @@ Quick `261022-tto`. Fix commit `8e4b863` on sm-user-plugin master (base `15ff979
``` ```
/msd-quick --validate /fetch /refresh /update /change-password must accept the token/auth_token cookies the same way jwt.auth and EndSession already do. Logout is already fixed. See .planning/todos/pending/2026-10-22-user-session-routes-ignore-cookie.md and .planning/notes/2026-10-22-external-user-plugin-escalations.md /msd-quick --validate /fetch /refresh /update /change-password must accept the token/auth_token cookies the same way jwt.auth and EndSession already do. Logout is already fixed. See .planning/todos/pending/2026-10-22-user-session-routes-ignore-cookie.md and .planning/notes/2026-10-22-external-user-plugin-escalations.md
``` ```
## Closed 2026-10-23
Shipped in sm-user-plugin v0.1.9 (8e4b863), quick task 261022-tto. Requires SummerCMS v0.4.3.