Skip to content

fix(sessions): a password change ends the sessions opened before it - #13

Merged
inkly merged 1 commit into
mainfrom
fix/session-revocation
Nov 10, 2026
Merged

inkly merged 1 commit into
mainfrom
fix/session-revocation

Conversation

@inkly

@inkly inkly commented Nov 10, 2026

Copy link
Copy Markdown
Collaborator

A refresh token is good for seven days and for a new pair each time, and POST /v1/users/refresh never read the account again. A copy of a token went on working after the password was changed, and after the account was gone.

What changes

  • The account numbers its sessions (SessionVersion on the user row, added by the migration). The refresh token carries the number the row had when it was made, in the standard jti claim: Common's claims have no field for it, and every service reads them.
  • The refresh reads the account again and answers 401 when it is gone or at another session.
  • A password change (PUT /v1/users/current/password) and the reset from the command line add one to the number: every session opened before ends.
  • A new account starts at a number of its own, not at 0: the database gives the id of an account that is gone to the next one made.
  • Saving a profile leaves the number alone.

For the callers

  • PUT /v1/users/current/password now answers with the body of a login (token and user), where it answered with the user alone: the session that made the change goes on with that pair. The dashboard stores it in ReCasaOS/CasaOS-UI (pull request to come); an older dashboard ignores the body and is asked to sign in again when its token runs out.
  • A token made before this change says nothing of its session and is of session 0, like the accounts that were there: the update signs nobody out.

Tests

route/v1_sessions_test.go, each failing before its change:

  • a copied token, and the one it was renewed into, after the password changed; the session that changed it goes on;
  • the token of an account that is gone;
  • the token of an account that is gone, when the next account gets its id;
  • a token of before the update: good, then ended by a password change;
  • a token of before a reset from the command line;
  • a profile saved from a row read before the sessions ended.

go test ./... passes on the four packages.

A refresh token is good for seven days and for a new pair each time,
and the refresh never read the account again: a copy of a token went on
working after the password was changed, and after the account was gone.

The account now numbers its sessions (SessionVersion). The refresh
token carries the number the row had when it was made, in the token's
ID: Common's claims have no field for it, and every service reads them.
The refresh reads the account again and answers 401 when it is gone or
at another session.

- A password change, and the reset from the command line, add one to
  the number: every session opened before ends.
- The password change answers with the body of a login, so that the
  session that made the change goes on with a pair of the new session.
- A new account starts at a number of its own, not at 0: the database
  gives the id of an account that is gone to the next one made, and a
  token of the first is not of the second.
- A token made before sessions were numbered says nothing and is of
  session 0, like the accounts that were there: an update signs nobody
  out.
- Saving a profile leaves the number alone.
@inkly
inkly marked this pull request as ready for review November 10, 2026 22:33
@inkly
inkly merged commit df6e3bc into main Nov 10, 2026
1 check passed
inkly added a commit to ReCasaOS/CasaOS-UI that referenced this pull request Nov 10, 2026
…tokens the change answers with (#175)

A password change now ends every session of the account, the one that made it too, and the user service answers with the pair that session goes on with (ReCasaOS/CasaOS-UserService#13). The account panel stores it where the requests and the message bus read their token. An older user service answers with the user alone, and the session is left as it is.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant