erp-core/docs/01-fase-foundation/MGN-001-auth/historias-usuario/US-MGN001-002.md

9.2 KiB

US-MGN001-002: Logout y Cierre de Sesion

Identificacion

Campo Valor
ID US-MGN001-002
Modulo MGN-001 Auth
Sprint Sprint 1
Prioridad P0 - Critica
Story Points 5
Estado Ready
Autor System
Fecha 2025-12-05

Historia de Usuario

Como usuario autenticado del sistema ERP Quiero poder cerrar mi sesion de forma segura Para proteger mi cuenta cuando dejo de usar el sistema o en dispositivos compartidos


Descripcion

El usuario necesita poder cerrar su sesion actual, revocando los tokens de acceso para que no puedan ser reutilizados. Tambien debe poder cerrar todas sus sesiones activas en caso de sospecha de compromiso de cuenta.

Contexto

  • Seguridad en dispositivos compartidos
  • Cumplimiento de politicas corporativas
  • Proteccion contra robo de tokens

Criterios de Aceptacion

Escenario 1: Logout exitoso

Given un usuario autenticado con sesion activa
  And tiene un access token valido
  And tiene un refresh token en cookie
When el usuario hace POST /api/v1/auth/logout
Then el sistema responde con status 200
  And el mensaje es "Sesion cerrada exitosamente"
  And el refresh token es revocado en BD
  And el access token es agregado a la blacklist
  And la cookie refresh_token es eliminada
  And se registra el logout en session_history

Escenario 2: Logout de todas las sesiones

Given un usuario autenticado
  And tiene 3 sesiones activas en diferentes dispositivos
When el usuario hace POST /api/v1/auth/logout-all
Then el sistema responde con status 200
  And el mensaje es "Todas las sesiones han sido cerradas"
  And el response incluye "sessionsRevoked": 3
  And TODOS los refresh tokens del usuario son revocados
  And se registra el logout_all en session_history

Escenario 3: Logout sin autenticacion

Given un usuario sin token de acceso
When intenta hacer logout
Then el sistema responde con status 401
  And el mensaje es "Token requerido"

Escenario 4: Logout con token expirado

Given un usuario con access token expirado
  And tiene refresh token valido en cookie
When intenta hacer logout
Then el sistema permite el logout usando solo el refresh token
  And responde con status 200

Escenario 5: Verificacion post-logout

Given un usuario que acaba de hacer logout
When intenta acceder a un endpoint protegido
  With el access token anterior
Then el sistema responde con status 401
  And el mensaje es "Token revocado"

Mockup / Wireframe

+------------------------------------------------------------------+
|  [Logo]                              [Usuario ▼]                 |
+------------------------------------------------------------------+
                                       ┌─────────────────┐
                                       │ Mi Perfil       │
                                       │ Configuracion   │
                                       │ ─────────────── │
                                       │ Cerrar Sesion   │ ← Click
                                       │ Cerrar Todas    │
                                       └─────────────────┘

┌──────────────────────────────────────────────────────────────────┐
│                    CONFIRMACION DE LOGOUT                        │
├──────────────────────────────────────────────────────────────────┤
│                                                                   │
│   ¿Estas seguro que deseas cerrar sesion?                        │
│                                                                   │
│   [  Cancelar  ]    [ Cerrar Sesion ]                            │
│                                                                   │
└──────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────┐
│                 CERRAR TODAS LAS SESIONES                        │
├──────────────────────────────────────────────────────────────────┤
│                                                                   │
│   ⚠️ Esta accion cerrara tu sesion en todos los dispositivos.   │
│                                                                   │
│   Sesiones activas: 3                                            │
│   - Chrome (Windows) - Hace 2 horas                              │
│   - Firefox (Mac) - Hace 1 dia                                   │
│   - Safari (iPhone) - Ahora                                      │
│                                                                   │
│   [  Cancelar  ]    [ Cerrar Todas ]                             │
│                                                                   │
└──────────────────────────────────────────────────────────────────┘

Notas Tecnicas

API

// Logout individual
POST /api/v1/auth/logout
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
Cookie: refresh_token=eyJhbGciOiJSUzI1NiIs...

// Response 200
{
  "message": "Sesion cerrada exitosamente"
}
// Set-Cookie: refresh_token=; Max-Age=0; HttpOnly; Secure; SameSite=Strict

// Logout all
POST /api/v1/auth/logout-all
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...

// Response 200
{
  "message": "Todas las sesiones han sido cerradas",
  "sessionsRevoked": 3
}

Flujo de Logout

┌─────────────┐      ┌─────────────┐      ┌─────────────┐
│   Frontend  │      │   Backend   │      │    Redis    │
└──────┬──────┘      └──────┬──────┘      └──────┬──────┘
       │                    │                    │
       │ POST /logout       │                    │
       │───────────────────>│                    │
       │                    │                    │
       │                    │ Revoke refresh     │
       │                    │ token in DB        │
       │                    │                    │
       │                    │ Blacklist access   │
       │                    │───────────────────>│
       │                    │                    │
       │                    │ Delete cookie      │
       │                    │                    │
       │    200 OK          │                    │
       │<───────────────────│                    │
       │                    │                    │
       │ Clear local state  │                    │
       │ Redirect to login  │                    │
       │                    │                    │

Seguridad

  • Blacklist en Redis con TTL
  • Logout idempotente (no falla si ya esta logged out)
  • Rate limiting: 10 requests/minuto

Definicion de Done

  • Endpoint POST /api/v1/auth/logout implementado
  • Endpoint POST /api/v1/auth/logout-all implementado
  • Refresh token revocado en BD
  • Access token blacklisteado en Redis
  • Cookie eliminada correctamente
  • Registro en session_history
  • Frontend limpia estado local
  • Frontend redirige a login
  • Tests unitarios (>80% coverage)
  • Tests e2e pasando
  • Code review aprobado

Dependencias

Requiere

Item Descripcion
US-MGN001-001 Login (sesion activa)
BlacklistService Para invalidar tokens
Redis Para almacenar blacklist

Bloquea

Item Descripcion
- No bloquea otras historias

Estimacion

Tarea Horas
Backend: logout() 2h
Backend: logoutAll() 2h
Backend: Tests 2h
Frontend: Logout button 1h
Frontend: Confirmation modal 2h
Frontend: Tests 1h
Total 10h

Referencias


Historial

Version Fecha Autor Cambios
1.0 2025-12-05 System Creacion inicial