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