Files
ObsiGate/docs/features/deconnexion-globale-bug-122.md
T
Spark b8949b2ddc
CI / lint (pull_request) Successful in 1m17s
CI / security (pull_request) Successful in 16s
CI / test (pull_request) Successful in 3m40s
CI / build (pull_request) Successful in 32s
CI / e2e (pull_request) Failing after 15m40s
fix: point d'entrée navigable de la déconnexion globale GET /sso/logout (BUG-122, fusion #141) — 2.86.0
2026-11-06 18:56:04 +00:00

2.5 KiB

BUG-122 — Déconnexion globale navigable : GET /sso/logout

Carte : fusion #141 (signalement de Bruno, 2026-11-06, capture depuis la console Spark). Version : 2.86.0. Prérequis : ACC-3.1 (#216) — la déconnexion globale existe déjà dans POST /api/auth/logout.

Constat

Le bouton « Déconnexion » du menu compte de la barre commune (dracodev-commons) est une action relayée à l'hôte (cfg.onAction, sinon événement draco:bar) : la barre ne déconnecte jamais elle-même. Or :

  • console Spark, ObsiGate, Flowdeck, TikTak, ShaarIt et Hub ne branchaient aucune action deconnexion (clic sans effet, reproduit en navigateur réel sur la console : session draco intacte après le clic) ;
  • Kanbante, seul branché, ne détruisait que sa session locale — la session SSO survivait ;
  • et de toute façon, aucun hôte n'aurait pu terminer la session globale : POST /api/auth/logout n'est appelable qu'en same-origin depuis l'interface d'ObsiGate. Il manquait le point d'entrée navigable, symétrique de GET /sso/authorize.

Livraison (cette PR, côté émettrice)

Méthode Chemin Effet
GET /sso/logout?return_to=<url> Déconnexion globale, puis redirection 302 vers le return_to validé (repli « / »)
  • La logique de POST /api/auth/logout est extraite dans apply_global_logout(request, response) (backend/auth/router.py) et partagée par les deux entrées : révocation des jetons natifs refresh/access, révocation du jti du cookie draco_session, effacement des cookies (dont draco_session sur le domaine parent).
  • return_to passe par la liste blanche existante (draco_session.validate_return_to : https + dracodev.net ou sous-domaine) — aucun relais ouvert.
  • Idempotente : sans session, la route redirige quand même (les hôtes y naviguent même si leur session a déjà expiré).

Côté hôtes (PR sœurs, carte fusion #141)

Chaque hôte branche son action deconnexion : destruction de sa session locale d'abord (Flowdeck, TikTak, Kanbante, ShaarIt), puis navigation vers <émettrice>/sso/logout?return_to=<sa base>. La console et le Hub (session draco seule) naviguent directement. Après le parcours complet, « Déconnexion » termine la session de la suite entière et la session locale de l'hôte courant.

Tests

tests/test_draco_session.py (+3) : révocation du jti + redirection vers le return_to + cookie effacé (Max-Age=0), liste blanche (relais refusé, repli « / »), idempotence sans session.