From 38072c2133f49c7bbc18c8fe0b7bacec67527322 Mon Sep 17 00:00:00 2001 From: giles Date: Tue, 24 Feb 2026 00:22:02 +0000 Subject: [PATCH] Emit rose:DeviceAuth activities on login and logout Signals external services (artdag) about device auth state changes via the AP internal bus, replacing shared-Redis coupling. Co-Authored-By: Claude Opus 4.6 --- bp/auth/routes.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/bp/auth/routes.py b/bp/auth/routes.py index 7e40820..2fe7413 100644 --- a/bp/auth/routes.py +++ b/bp/auth/routes.py @@ -339,6 +339,17 @@ def register(url_prefix="/auth"): "session_id": anon_session_id, }, ) + # Notify external services of device login + await emit_activity( + s, + activity_type="rose:DeviceAuth", + actor_uri="internal:system", + object_type="Device", + object_data={ + "device_id": g.device_id, + "action": "login", + }, + ) except SQLAlchemyError: current_app.logger.exception( "[auth] non-fatal DB update for user_id=%s", user_id @@ -391,6 +402,23 @@ def register(url_prefix="/auth"): except Exception: pass + # Notify external services of device logout + try: + async with get_session() as s: + async with s.begin(): + await emit_activity( + s, + activity_type="rose:DeviceAuth", + actor_uri="internal:system", + object_type="Device", + object_data={ + "device_id": g.device_id, + "action": "logout", + }, + ) + except Exception: + current_app.logger.exception("[auth] failed to emit DeviceAuth logout") + qsession.pop(SESSION_USER_KEY, None) qsession.pop(ACCOUNT_SESSION_KEY, None) from shared.infrastructure.urls import blog_url @@ -422,6 +450,23 @@ def register(url_prefix="/auth"): except Exception: pass + # Notify external services of device logout + try: + async with get_session() as s: + async with s.begin(): + await emit_activity( + s, + activity_type="rose:DeviceAuth", + actor_uri="internal:system", + object_type="Device", + object_data={ + "device_id": g.device_id, + "action": "logout", + }, + ) + except Exception: + current_app.logger.exception("[auth] failed to emit DeviceAuth logout") + qsession.pop(SESSION_USER_KEY, None) qsession.pop(ACCOUNT_SESSION_KEY, None) from shared.infrastructure.urls import blog_url