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

10 KiB

US-MGN001-001: Login con Email y Password

Identificacion

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

Historia de Usuario

Como usuario del sistema ERP Quiero poder iniciar sesion con mi email y contraseña Para acceder a las funcionalidades del sistema de forma segura


Descripcion

El usuario necesita un mecanismo seguro para autenticarse en el sistema utilizando sus credenciales (email y contraseña). Al autenticarse exitosamente, recibira tokens JWT que le permitiran acceder a los recursos protegidos.

Contexto

  • Primera interaccion del usuario con el sistema
  • Puerta de entrada a todas las funcionalidades
  • Base de la seguridad del sistema

Criterios de Aceptacion

Escenario 1: Login exitoso

Given un usuario registrado con email "user@example.com"
  And password "SecurePass123!"
  And el usuario no esta bloqueado
  And el usuario esta activo
When el usuario envia sus credenciales al endpoint /api/v1/auth/login
Then el sistema responde con status 200
  And el body contiene "accessToken" de tipo string
  And el body contiene "refreshToken" de tipo string
  And el body contiene "user" con id, email, firstName, lastName, roles
  And se establece cookie httpOnly "refresh_token"
  And se registra el login en session_history

Escenario 2: Login con email incorrecto

Given un email "noexiste@example.com" que no existe en el sistema
When el usuario intenta hacer login con ese email
Then el sistema responde con status 401
  And el mensaje es "Credenciales invalidas"
  And NO se revela que el email no existe
  And se registra el intento fallido en login_attempts

Escenario 3: Login con password incorrecto

Given un usuario registrado con email "user@example.com"
  And el password correcto es "SecurePass123!"
When el usuario intenta hacer login con password "wrongpassword"
Then el sistema responde con status 401
  And el mensaje es "Credenciales invalidas"
  And se incrementa failed_login_attempts del usuario
  And se registra el intento fallido en login_attempts

Escenario 4: Cuenta bloqueada por intentos fallidos

Given un usuario con email "user@example.com"
  And el usuario tiene 5 intentos fallidos de login
  And el campo locked_until es una fecha futura
When el usuario intenta hacer login con credenciales correctas
Then el sistema responde con status 423
  And el mensaje indica "Cuenta bloqueada"
  And se indica el tiempo restante de bloqueo

Escenario 5: Cuenta inactiva

Given un usuario con email "inactive@example.com"
  And el campo is_active del usuario es false
When el usuario intenta hacer login
Then el sistema responde con status 403
  And el mensaje es "Cuenta inactiva"

Escenario 6: Validacion de campos

Given un request al endpoint de login
When el email no es un email valido
Then el sistema responde con status 400
  And el mensaje indica "Email invalido"

When el password tiene menos de 8 caracteres
Then el sistema responde con status 400
  And el mensaje indica "Password debe tener minimo 8 caracteres"

When el email esta vacio
Then el sistema responde con status 400
  And el mensaje indica "Email es requerido"

Escenario 7: Desbloqueo automatico

Given un usuario con cuenta bloqueada
  And el tiempo de bloqueo (30 minutos) ha pasado
When el usuario intenta hacer login con credenciales correctas
Then el sistema permite el login
  And resetea failed_login_attempts a 0
  And limpia locked_until

Mockup / Wireframe

+------------------------------------------------------------------+
|                         ERP SUITE                                 |
|                                                                   |
|                  ╔═══════════════════════════╗                   |
|                  ║      INICIAR SESION       ║                   |
|                  ╚═══════════════════════════╝                   |
|                                                                   |
|                  Correo electronico                              |
|                  +---------------------------+                   |
|                  | user@example.com          |                   |
|                  +---------------------------+                   |
|                                                                   |
|                  Contraseña                                       |
|                  +---------------------------+                   |
|                  | ••••••••••••             |  [👁]              |
|                  +---------------------------+                   |
|                                                                   |
|                  [ ] Recordar sesion                             |
|                                                                   |
|                  [===== INICIAR SESION =====]                   |
|                                                                   |
|                  ¿Olvidaste tu contraseña?                       |
|                                                                   |
+------------------------------------------------------------------+

Estados de UI:
┌─────────────────────────────────────────────────────────────────┐
│ Estado: Loading                                                  │
│ - Boton deshabilitado                                           │
│ - Spinner visible en boton                                      │
│ - Campos deshabilitados                                         │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│ Estado: Error                                                    │
│ - Toast rojo con mensaje de error                               │
│ - Campos con borde rojo si invalidos                            │
│ - Texto de ayuda debajo del campo                               │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│ Estado: Bloqueado                                                │
│ - Mensaje: "Cuenta bloqueada. Intenta en XX minutos"            │
│ - Enlace a "¿Necesitas ayuda?"                                  │
└─────────────────────────────────────────────────────────────────┘

Notas Tecnicas

API

// Request
POST /api/v1/auth/login
Content-Type: application/json
X-Tenant-Id: optional-if-single-tenant

{
  "email": "user@example.com",
  "password": "SecurePass123!"
}

// Response 200
{
  "accessToken": "eyJhbGciOiJSUzI1NiIs...",
  "refreshToken": "eyJhbGciOiJSUzI1NiIs...",
  "tokenType": "Bearer",
  "expiresIn": 900,
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "roles": ["admin"]
  }
}

// Set-Cookie: refresh_token=...; HttpOnly; Secure; SameSite=Strict; Max-Age=604800

Validaciones

Campo Regla Mensaje Error
email Required, IsEmail "Email es requerido" / "Email invalido"
password Required, MinLength(8), MaxLength(128) "Password es requerido" / "Password debe tener minimo 8 caracteres"

Seguridad

  • Bcrypt con salt rounds = 12
  • Rate limiting: 10 requests/minuto por IP
  • No revelar si email existe
  • Tokens firmados con RS256

Definicion de Done

  • Endpoint POST /api/v1/auth/login implementado
  • Validaciones de DTO funcionando
  • Login exitoso retorna tokens JWT
  • Login fallido registra intento
  • Bloqueo despues de 5 intentos
  • Desbloqueo automatico despues de 30 min
  • Cookie httpOnly para refresh token
  • Registro en session_history
  • Tests unitarios (>80% coverage)
  • Tests e2e pasando
  • Documentacion Swagger actualizada
  • Code review aprobado

Dependencias

Requiere

Item Descripcion
Tabla users Con campos email, password_hash, is_active
Tabla login_attempts Para registro de intentos
Tabla session_history Para auditoria
TokenService Para generar tokens JWT

Bloquea

Item Descripcion
US-MGN001-002 Logout (necesita sesion)
US-MGN001-003 Refresh token (necesita login)
Todas las features Requieren autenticacion

Estimacion

Tarea Horas
Backend: AuthService.login() 4h
Backend: Validaciones y errores 2h
Backend: Tests unitarios 3h
Frontend: LoginPage 4h
Frontend: authStore 2h
Frontend: Tests 2h
Total 17h

Referencias


Historial

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