--- id: "US-AUTH-002" title: "Login con Email" type: "User Story" status: "To Do" priority: "Alta" epic: "OQI-001" story_points: 3 created_date: "2025-12-05" updated_date: "2026-01-04" --- # US-AUTH-002: Login con Email **Version:** 1.0.0 **Fecha:** 2025-12-05 **Estado:** Pendiente **Story Points:** 3 **Prioridad:** P0 (Crítica) **Épica:** [OQI-001](../_MAP.md) --- ## Historia de Usuario **Como** usuario registrado de Trading Platform **Quiero** iniciar sesión con mi email y contraseña **Para** acceder a mi cuenta y utilizar la plataforma --- ## Criterios de Aceptación ### AC-001: Formulario de login **Dado** que soy un usuario registrado **Cuando** accedo a la página de login **Entonces** debería ver un formulario con: - Campo de email - Campo de contraseña - Checkbox "Recordarme" - Botón "Iniciar sesión" - Link "¿Olvidaste tu contraseña?" - Opciones de OAuth ### AC-002: Validación de campos **Dado** que estoy en el formulario de login **Cuando** intento enviar el formulario con campos vacíos **Entonces** debería ver mensajes de error: - "El email es requerido" - "La contraseña es requerida" ### AC-003: Login exitoso **Dado** que ingresé credenciales válidas **Cuando** hago click en "Iniciar sesión" **Entonces** debería: 1. Recibir un JWT token 2. Ser redirigido al dashboard 3. Ver mi nombre en el header 4. Tener la sesión activa ### AC-004: Credenciales incorrectas **Dado** que ingreso credenciales incorrectas **Cuando** hago click en "Iniciar sesión" **Entonces** debería ver un mensaje: - "Email o contraseña incorrectos" **Y** los campos no deberían limpiarse **Y** debería poder intentar de nuevo ### AC-005: Email no verificado **Dado** que mi cuenta no ha verificado el email **Cuando** intento hacer login **Entonces** debería ver un mensaje: - "Por favor verifica tu email antes de iniciar sesión" **Y** debería ver un botón "Reenviar email de verificación" ### AC-006: Cuenta bloqueada **Dado** que mi cuenta ha sido bloqueada por seguridad **Cuando** intento hacer login **Entonces** debería ver un mensaje: - "Tu cuenta ha sido bloqueada. Contacta soporte." ### AC-007: Recordarme **Dado** que marqué la opción "Recordarme" **Cuando** inicio sesión exitosamente **Entonces** el token debería tener una duración de 30 días **Y** cuando cierre el navegador y vuelva a abrir **Entonces** debería seguir con sesión activa ### AC-008: Rate limiting **Dado** que he fallado 5 intentos de login **Cuando** intento iniciar sesión nuevamente **Entonces** debería ver un mensaje: - "Demasiados intentos. Intenta en 15 minutos" --- ## Mockup ``` ┌─────────────────────────────────────────────────────────────┐ │ │ │ 🌟 Inicia sesión en Trading Platform │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Email │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ │ │ usuario@example.com │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Contraseña │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ │ │ •••••••••••• 👁 │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ☐ Recordarme ¿Olvidaste tu contraseña? │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Iniciar sesión │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ─────────────────── O continúa con ─────────────────── │ │ │ │ [Google] [Facebook] [X] [Apple] [GitHub] │ │ │ │ ¿No tienes cuenta? Regístrate │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Tareas Técnicas ### Database (DB) - [ ] Crear tabla `login_attempts` para rate limiting ```sql CREATE TABLE login_attempts ( id UUID PRIMARY KEY, email VARCHAR(255), ip_address VARCHAR(45), attempt_time TIMESTAMP, success BOOLEAN, created_at TIMESTAMP DEFAULT NOW() ); ``` - [ ] Índice en `email` y `attempt_time` ### Backend (BE) - [ ] Endpoint `POST /api/v1/auth/login` - Validación de entrada con Zod - Verificar email verificado - Verificar cuenta no bloqueada - Comparar hash con bcrypt - Generar JWT token - Rate limiting (5 intentos / 15 min) - Logging de intentos - [ ] Service `AuthService.login()` - [ ] Middleware de rate limiting - [ ] Tests unitarios (8 casos) - [ ] Tests de integración (5 escenarios) ### Frontend (FE) - [ ] Componente `apps/frontend/src/modules/auth/pages/Login.tsx` - [ ] Form validation con React Hook Form + Zod - [ ] Estado de loading durante autenticación - [ ] Manejo de errores específicos - [ ] Almacenamiento de token en localStorage/sessionStorage - [ ] Redirección post-login - [ ] Tests con React Testing Library (6 casos) ### Testing (QA) - [ ] E2E: Login exitoso (Playwright) - [ ] E2E: Credenciales incorrectas - [ ] E2E: Email no verificado - [ ] E2E: Rate limiting - [ ] E2E: Recordarme funcionalidad - [ ] Test de seguridad: SQL injection - [ ] Test de seguridad: XSS - [ ] Performance: < 500ms response time --- ## Dependencias - **Bloqueantes:** - US-AUTH-001: Necesita usuarios registrados para poder hacer login - **Deseables:** - US-AUTH-011: Para el flujo de "¿Olvidaste tu contraseña?" --- ## Definition of Ready (DoR) - [ ] Mockups aprobados por UX - [ ] Esquema de base de datos revisado - [ ] API contract definido - [ ] Criterios de aceptación claros - [ ] Estimación acordada por el equipo --- ## Definition of Done (DoD) - [ ] Código implementado y revisado (code review) - [ ] Tests unitarios con 80%+ cobertura - [ ] Tests de integración pasando - [ ] Tests E2E implementados - [ ] Documentación API actualizada - [ ] Rate limiting configurado - [ ] Logs implementados - [ ] Seguridad validada (OWASP) - [ ] QA aprobado en staging - [ ] Deploy a producción exitoso --- ## Notas Técnicas ### JWT Token Structure ```json { "sub": "user-id", "email": "user@example.com", "role": "user", "iat": 1234567890, "exp": 1234567890 } ``` ### Rate Limiting Strategy - 5 intentos fallidos por email - Ventana de 15 minutos - Reset después de login exitoso - Bloqueo temporal, no permanente ### Security Considerations - HTTPS obligatorio - Password no visible en logs - Tokens con expiración - CSRF protection - Content-Security-Policy headers --- ## Requerimientos Relacionados - [RF-AUTH-002: Autenticación por Email](../requerimientos/RF-AUTH-002-email.md) ## Especificaciones Relacionadas - [ET-AUTH-002: JWT Tokens](../especificaciones/ET-AUTH-002-jwt.md) - [ET-AUTH-003: Database](../especificaciones/ET-AUTH-003-database.md)