Summary
Logout now revokes by bumping one users.session_version per user. Every token the user holds carries the same version, so signing out on one device signs out every other device and browser too, not just the one that clicked logout.
Severity
P4 (behaviour regression). No security impact, but it changes what "log out" means for anyone signed in on a phone and a desktop.
Reproduction
Two tokens issued at sv = 0 (device A and device B). Device A logs out, which runs revokeUserSessions(userId, 0): UPDATE users SET session_version = session_version + 1 WHERE id = ... AND session_version = 0. Device B's next request runs the trusted check, token.sv (0) === getSessionVersion() (1), which is false, so B gets 401. Checked the UPDATE and comparison against a pg-mem fixture: current version 1, device B token no longer valid.
Code: revokeUserSessions in packages/db/src/repository.ts and the logout handler and trusted hook in apps/api/src/server.ts.
Fix
Either keep the user-wide version only for disable, delete and "sign out everywhere", and give each login its own session id (a user_sessions row or a per-token jti denylist) so logout only revokes the token that was used. If signing out everywhere is the intended behaviour, say so in the logout UI copy.
Summary
Logout now revokes by bumping one
users.session_versionper user. Every token the user holds carries the same version, so signing out on one device signs out every other device and browser too, not just the one that clicked logout.Severity
P4 (behaviour regression). No security impact, but it changes what "log out" means for anyone signed in on a phone and a desktop.
Reproduction
Two tokens issued at
sv = 0(device A and device B). Device A logs out, which runsrevokeUserSessions(userId, 0):UPDATE users SET session_version = session_version + 1 WHERE id = ... AND session_version = 0. Device B's next request runs thetrustedcheck,token.sv (0) === getSessionVersion() (1), which is false, so B gets 401. Checked the UPDATE and comparison against a pg-mem fixture: current version 1, device B token no longer valid.Code:
revokeUserSessionsinpackages/db/src/repository.tsand the logout handler andtrustedhook inapps/api/src/server.ts.Fix
Either keep the user-wide version only for disable, delete and "sign out everywhere", and give each login its own session id (a
user_sessionsrow or a per-tokenjtidenylist) so logout only revokes the token that was used. If signing out everywhere is the intended behaviour, say so in the logout UI copy.