- revoke_all_refresh_tokens: add skip_token_hash optional param (exclude
current session while revoking others)
- change_password, enable_totp, disable_totp: call revoke with skip hash
derived from refresh cookie; return sessions_revoked in response and
write to audit log metadata_
- 3 new tests: test_{change_password,enable_totp,disable_totp}_revokes_other_sessions
— all PASSED; 373 total passing, 0 regressions
- Frontend toasts: SettingsAccountTab + TotpEnrollment show
"Other sessions have been terminated." when sessions_revoked > 0
- Companion fixes: rate_limiting get_client_ip refactor, deps/auth.py
request.state.current_user, locustfile refresh-token task removal
- Version bump: 0.1.0 → 0.1.1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1.3 KiB
1.3 KiB
Plan 07.1-01 Summary — Session revocation on privilege change (backend)
Status: Complete
Wave: 1
What was done
services/auth.py
- Extended
revoke_all_refresh_tokenssignature: addedskip_token_hash: Optional[str] = None - When
skip_token_hashis set, the WHERE clause excludes that token (RefreshToken.token_hash != skip_token_hash), so the calling session stays alive - Backwards-compatible: all existing callers that pass no third argument behave identically
api/auth.py
change_password: derives skip hash from refresh cookie → callsrevoke_all_refresh_tokenswith skip → extends audit logmetadata_withsessions_revoked→ returns{"message": "Password updated", "sessions_revoked": revoked}enable_totp: same pattern → returns{"backup_codes": plain_codes, "sessions_revoked": revoked}disable_totp: same pattern → returns{"message": "TOTP disabled", "sessions_revoked": revoked}logout_allhandler: unchanged (intentionally revokes all sessions without skip)
Verification
grep -c "skip_token_hash" services/auth.py → 4
grep -c "sessions_revoked" api/auth.py → 7
grep -c "skip_token_hash" api/auth.py → 6
python3 -c "import api.auth; import services.auth" → exits 0