From ca023e705c153b48b6608954301ce0564b5e7871 Mon Sep 17 00:00:00 2001 From: Finn Stutzenstein Date: Wed, 21 Oct 2026 11:01:55 +0000 Subject: [PATCH] Invalidate sessions server-side on logout and deactivation Session.clear() set the id to None before clearing, so on_update assigned a new id and save_session deleted the store entry of that new id. The entry of the old id with the user_id stayed valid: a copied cookie survived the logout, and a session "logged out" by the auth middleware for a disabled user was valid again after re-enabling. - Session.clear() now removes the store entry of the current id. - Deactivating a user removes all of their sessions immediately, like deleting a user does. Co-Authored-By: Claude Opus 5.5 --- max/routes/user/toggle_enabled.py | 3 +++ max/sessions.py | 2 ++ 2 files changed, 5 insertions(+) diff --git a/max/routes/user/toggle_enabled.py b/max/routes/user/toggle_enabled.py index 48e106f..e8eb537 100644 --- a/max/routes/user/toggle_enabled.py +++ b/max/routes/user/toggle_enabled.py @@ -2,6 +2,7 @@ from flask import flash from max.db import is_last_enabled_admin, update_user from max.permissions import AllowAdmin +from max.sessions import session_storage from max.translations import t from max.views import BaseView @@ -20,6 +21,8 @@ class UserToggleEnabled(AllowAdmin, FetchUserMixin, BackToUsersMixin, BaseView): ) else: update_user(self.user.id, enabled=(not self.user.enabled)) + if self.user.enabled: # the user was deactivated + session_storage.remove_user_sessions(self.user.id) _, back_url = self.get_back_text_and_url() return self.redirect(back_url) diff --git a/max/sessions.py b/max/sessions.py index 07f20b2..ea31493 100644 --- a/max/sessions.py +++ b/max/sessions.py @@ -68,6 +68,8 @@ class Session(CallbackDict, SessionMixin): return len(self) == 0 def clear(self): + """Removes all data, including the entry in the session storage""" + del session_storage[self.id] self.id = None super().clear()