Add session_version to users table. Sessions now carry session_version
alongside user_id; @login_required rejects any session where the version
doesn't match the DB value.
- migration 0024: session_version INTEGER NOT NULL DEFAULT 1
- models/user.py: session_version Mapped[int] column
- auth.py: version mismatch → session.clear() + 401
- services/auth.py: change_password and reset_password_with_token both
increment session_version, evicting all other live sessions
- routes/auth.py: login/register/oauth_callback store session_version;
update_password rehydrates current session with new version so the
user who changed their password stays logged in
Existing sessions will require one re-login after the migration runs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>