Component: PasswordService
Responsabilidad
Gestionar el cambio de contraseña de usuarios autenticados. Validar contraseña actual, verificar requisitos de seguridad de la nueva contraseña, y invalidar sesiones existentes.
Tipo
Interfaces
API REST
Dependencias
| Servicio/Biblioteca |
Tipo |
Notas |
| PostgreSQL |
Database |
Almacenamiento de usuarios |
| Redis |
Cache |
Invalidation de sesiones |
| AuthService |
Internal |
Verificación de token |
Validaciones de contraseña
| Regla |
Requisito |
Mensaje de error |
| Longitud mínima |
8 caracteres |
"La contraseña debe tener al menos 8 caracteres" |
| Longitud máxima |
128 caracteres |
"La contraseña debe tener máximo 128 caracteres" |
| Mayúsculas |
Al menos 1 |
"La contraseña debe contener al menos una mayúscula" |
| Minúsculas |
Al menos 1 |
"La contraseña debe contener al menos una minúscula" |
| Números |
Al menos 1 |
"La contraseña debe contener al menos un número" |
| Caracteres especiales |
Al menos 1 |
"La contraseña debe contener al menos un carácter especial (!@#$%^&*...)" |
| No usar password anterior |
Diferente |
"La nueva contraseña no puede ser igual a la anterior" |
Límites
Alcance
- ✅ Cambio de contraseña con validación
- ✅ Requisitos de seguridad
- ✅ Invalidación de sesiones
- ❌ NO maneja recuperación de contraseña (ver ForgotPasswordService)
- ❌ NO maneja reset forzado por admin (ver AdminService)
Constraints
- Rate limit: 5 intentos por hora por usuario
- Timeout máximo: 1 segundo
- Máximo 3 passwords válidas en historial (evitar reutilización inmediata)
Criterios de éxito
| Criterio |
Métrica |
Target |
| Disponibilidad |
uptime |
99.9% |
| Latencia |
p99 change_password |
< 500ms |
| Rate limit |
blocked attempts |
100% |
| Sesiones invalidées |
después de cambio |
100% |
Diagrama
Estados
| Estado |
Trigger |
Acción |
| Initial |
started |
Connect to DB |
| Ready |
db_connected |
Accept requests |
| RateLimited |
>5 attempts/hour |
Return 429 |
| Error |
db_failure |
Return 503 |
Seguridad
- Password hashing: bcrypt, cost 12 (nuevo), verificar contra hash existente
- Timing attack prevention: usar constant-time comparison
- Rate limiting: 5 req/hour por user_id
- Sesiones: invalidar TODAS las sesiones del usuario tras cambio
- Logs: NO registrar passwords, solo intentos fallidos (user_id anonymized)
Observabilidad
- Metrics:
password_change_total, password_change_failed, password_change_latency
- Logs: structured JSON con request_id
- Traces: OpenTelemetry span por request
Tests BDD
- Ver
spec/bdd/features/password/change-password.feature