diff --git a/backend/linkpulse/dependencies.py b/backend/linkpulse/dependencies.py index 969a3e9..41f721e 100644 --- a/backend/linkpulse/dependencies.py +++ b/backend/linkpulse/dependencies.py @@ -59,6 +59,7 @@ class SessionDependency: # If not present, raise 401 if required if session_token is None: + logger.debug("No session cookie found", required=self.required) if self.required: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Unauthorized") return None diff --git a/backend/linkpulse/models.py b/backend/linkpulse/models.py index 57b2725..9782eb2 100644 --- a/backend/linkpulse/models.py +++ b/backend/linkpulse/models.py @@ -91,6 +91,7 @@ class Session(BaseModel): now = utc_now() if self.expiry_utc < now: + logger.debug("Session expired", token=self.token, user=self.user.email, revoke=revoke) if revoke: self.delete_instance() return True diff --git a/backend/linkpulse/routers/auth.py b/backend/linkpulse/routers/auth.py index ccb247d..275b878 100644 --- a/backend/linkpulse/routers/auth.py +++ b/backend/linkpulse/routers/auth.py @@ -121,9 +121,10 @@ async def logout( # We can assume the session is valid via the dependency if not all: session.delete_instance() + logger.debug("Session deleted", user=session.user.email, token=session.token) else: count = Session.delete().where(Session.user == session.user).execute() - logger.debug("All sessions deleted", user=session.user.email, count=count) + logger.debug("All sessions deleted", user=session.user.email, count=count, source_token=session.token) response.set_cookie("session", "", max_age=0) diff --git a/backend/linkpulse/tests/test_auth.py b/backend/linkpulse/tests/test_auth.py index 928ae9c..f65dbb1 100644 --- a/backend/linkpulse/tests/test_auth.py +++ b/backend/linkpulse/tests/test_auth.py @@ -64,6 +64,18 @@ def test_auth_login_logout(user): def test_auth_logout_expired(expired_session): + # Test that an expired session cannot be used to logout, but still removes the cookie with TestClient(app) as client: response = client.post("/api/logout") assert response.status_code == status.HTTP_401_UNAUTHORIZED + + # Add expired session cookie + client.cookies.set("session", expired_session.token) + assert client.cookies.get("session") is not None + + # Attempt to logout + response = client.post("/api/logout") + assert response.status_code == status.HTTP_401_UNAUTHORIZED + assert client.cookies.get("session") is None + + # TODO: Ensure ?all=True doesn't do anything either