# 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

```gherkin
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

```gherkin
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

```gherkin
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

```gherkin
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

```gherkin
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

```typescript
// 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

- [RF-AUTH-004](../../01-requerimientos/RF-auth/RF-AUTH-004.md) - Requerimiento funcional
- [ET-auth-backend](../../02-modelado/especificaciones-tecnicas/ET-auth-backend.md) - Spec tecnica

---

## Historial

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