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

57 lines
2.5 KiB
Markdown

# 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.