# RF-MGN-001-007: Gestión de Sesiones

**Módulo:** MGN-001 - Fundamentos
**Prioridad:** P0 (MVP)
**Story Points:** 5
**Estado:** Definido
**Fecha:** 2025-11-23

## Descripción

El sistema debe gestionar sesiones de usuarios mediante JWT tokens con refresh tokens. Incluye creación, renovación, invalidación de tokens y logout en múltiples dispositivos.

## Actores

- **Actor Principal:** Usuario autenticado
- **Actores Secundarios:** Sistema (gestión automática de tokens)

## Precondiciones

1. Usuario debe estar autenticado (tiene JWT válido)
2. Redis debe estar disponible para almacenar tokens

## Flujo Principal

1. Usuario inicia sesión exitosamente (RF-MGN-001-001)
2. Sistema genera access token (JWT, expira en 8h) con claims:
   - user_id, tenant_id, email, roles[], permissions[]
3. Sistema genera refresh token (UUID, expira en 30 días)
4. Sistema almacena refresh token en auth.sessions con:
   - token, user_id, expires_at, ip_address, user_agent
5. Sistema retorna ambos tokens al cliente
6. Cliente almacena tokens (localStorage o httpOnly cookie)
7. Cliente usa access token en cada request (Authorization: Bearer {token})
8. Cuando access token expira (8h), cliente usa refresh token
9. Sistema valida refresh token en auth.sessions
10. Sistema genera nuevo par de tokens (access + refresh)
11. Sistema invalida refresh token anterior
12. Cliente continúa usando nuevo access token

## Flujos Alternativos

### FA-1: Access Token Expirado
1. Cliente envía request con access token expirado
2. Sistema retorna error 401: "Token expirado"
3. Cliente automáticamente usa refresh token para obtener nuevo access token
4. Cliente reintenta request original con nuevo token

### FA-2: Refresh Token Inválido o Expirado
1. Cliente intenta renovar con refresh token inválido/expirado
2. Sistema retorna error 401: "Sesión expirada. Inicie sesión nuevamente"
3. Cliente redirige a login

### FA-3: Logout Simple
1. Usuario hace clic en "Cerrar sesión"
2. Sistema invalida refresh token actual (marca como used_at=NOW())
3. Sistema elimina token de Redis (si se usa caché)
4. Cliente elimina tokens almacenados
5. Usuario es redirigido a login

### FA-4: Logout de Todos los Dispositivos
1. Usuario solicita "Cerrar sesión en todos los dispositivos"
2. Sistema invalida TODOS los refresh tokens del usuario
3. Sistema elimina sesiones del usuario en Redis
4. Todas las sesiones activas quedan invalidadas
5. Usuario debe iniciar sesión nuevamente en todos los dispositivos

### FA-5: Logout Forzado (Administrativo)
1. Administrador desactiva usuario o cambia contraseña
2. Sistema invalida todos los refresh tokens del usuario
3. Usuario no puede renovar tokens
4. Usuario debe iniciar sesión con nueva contraseña

### FA-6: Detección de Token Robado (Reuse Detection)
1. Sistema detecta intento de usar refresh token ya utilizado
2. Sistema invalida TODOS los tokens del usuario (posible robo)
3. Sistema registra evento de seguridad en audit_log
4. Sistema notifica al usuario por email

## Reglas de Negocio

- **RN-1:** Access token expira en 8 horas
- **RN-2:** Refresh token expira en 30 días
- **RN-3:** Refresh token solo puede usarse una vez (one-time use)
- **RN-4:** Usuario puede tener múltiples sesiones activas (diferentes dispositivos)
- **RN-5:** Cambio de contraseña invalida todas las sesiones
- **RN-6:** Desactivación de usuario invalida todas las sesiones
- **RN-7:** Sistema registra IP y user agent de cada sesión
- **RN-8:** Reuso de refresh token invalida todas las sesiones (seguridad)

## Criterios de Aceptación

- [ ] Sistema genera access token (JWT, 8h) y refresh token (UUID, 30d) en login
- [ ] Access token contiene claims: user_id, tenant_id, roles, permissions
- [ ] Cliente puede renovar access token usando refresh token
- [ ] Refresh token solo puede usarse una vez
- [ ] Usuario puede cerrar sesión (invalida refresh token actual)
- [ ] Usuario puede cerrar sesión en todos los dispositivos
- [ ] Cambio de contraseña invalida todas las sesiones
- [ ] Sistema detecta reuso de refresh token y invalida todas las sesiones
- [ ] Sistema registra IP y user agent en auth.sessions
- [ ] Administrador puede ver sesiones activas de un usuario

## Entidades Involucradas

- **Principales:**
  - auth.sessions (refresh_token, user_id, expires_at, ip_address, user_agent, used_at)
  - auth.users (usuario propietario de sesión)
- **Relacionadas:**
  - Redis (caché de tokens para validación rápida)

## Referencias

- [ALCANCE-POR-MODULO.md - MGN-001](../../01-definicion-modulos/ALCANCE-POR-MODULO.md#mgn-001-fundamentos)
- [Auth Domain Model](../domain-models/auth-domain.md)
- [Auth Schema DDL](../database-design/schemas/auth-schema-ddl.sql)
- [Gap Analysis MGN-001](../../01-definicion-modulos/gaps/GAP-ANALYSIS-MGN-001.md)

## Notas Técnicas

- **JWT Estructura:**
  ```json
  {
    "sub": "user_id",
    "tenant_id": 123,
    "email": "user@example.com",
    "roles": ["admin", "user"],
    "permissions": ["sale.order.create", "sale.order.read"],
    "iat": 1234567890,
    "exp": 1234596690
  }
  ```
- **Refresh Token:** UUID v4 almacenado en DB + Redis
- **Redis Caché:**
  - Key: `session:refresh_token:{token}`
  - Value: `{user_id, expires_at}`
  - TTL: 30 días
- **Seguridad:**
  - httpOnly cookies (no accesible por JS)
  - Secure flag (solo HTTPS)
  - SameSite=Strict (prevenir CSRF)
- **Backend:** NestJS Guards + JWT Strategy
- **Frontend:** Axios interceptors para auto-refresh

## Dependencias

- **RF Dependientes:** RF-MGN-001-001 (Autenticación)
- **Bloqueante para:** Todos los RF (sesión es requisito para operar)
