erp-core/docs/01-fase-foundation/MGN-002-users/requerimientos/RF-USER-003.md

13 KiB

RF-USER-003: Cambio de Email

Identificacion

Campo Valor
ID RF-USER-003
Modulo MGN-002
Nombre Modulo Users - Gestion de Usuarios
Prioridad P1
Complejidad Media
Estado Aprobado
Autor System
Fecha 2025-12-05

Descripcion

El sistema debe permitir a los usuarios cambiar su direccion de email de forma segura, requiriendo verificacion del nuevo email antes de completar el cambio. Este proceso protege contra cambios no autorizados y mantiene la integridad de las comunicaciones.

Contexto de Negocio

El cambio de email es sensible porque:

  • El email es el identificador principal de login
  • Se usa para recuperacion de password
  • Se usa para notificaciones importantes
  • Debe ser verificado antes del cambio efectivo

Criterios de Aceptacion

  • CA-001: El usuario debe poder solicitar cambio de email
  • CA-002: El sistema debe enviar verificacion al NUEVO email
  • CA-003: El cambio no se aplica hasta verificar el nuevo email
  • CA-004: El sistema debe validar que el nuevo email no exista en el tenant
  • CA-005: El token de verificacion expira en 24 horas
  • CA-006: El sistema debe notificar al email ANTERIOR sobre el cambio
  • CA-007: El usuario debe confirmar con su password actual
  • CA-008: Despues del cambio, todas las sesiones se invalidan

Ejemplos de Verificacion

Scenario: Solicitar cambio de email
  Given un usuario con email "viejo@empresa.com"
  When solicita cambiar a "nuevo@empresa.com"
  And confirma con su password actual
  Then el sistema valida que "nuevo@empresa.com" no existe
  And genera token de verificacion
  And envia email de verificacion a "nuevo@empresa.com"
  And el email actual permanece sin cambios
  And responde con status 200

Scenario: Verificar nuevo email
  Given una solicitud de cambio pendiente
  And un token de verificacion valido
  When el usuario hace clic en el link de verificacion
  Then el sistema actualiza el email del usuario
  And invalida todas las sesiones activas
  And envia notificacion al email anterior
  And redirige al login

Scenario: Token de verificacion expirado
  Given un token de verificacion de mas de 24 horas
  When el usuario intenta usarlo
  Then el sistema responde con error
  And el mensaje es "Token expirado, solicita nuevo cambio"

Scenario: Nuevo email ya existe
  Given un email "existente@empresa.com" ya registrado
  When un usuario intenta cambiar a ese email
  Then el sistema responde con status 409
  And el mensaje es "Email no disponible"

Reglas de Negocio

ID Regla Validacion
RN-001 Requiere password actual para solicitar cambio Verificacion bcrypt
RN-002 Nuevo email debe ser unico en tenant UNIQUE constraint
RN-003 Token de verificacion expira en 24 horas expires_at check
RN-004 Solo una solicitud activa a la vez Invalidar anteriores
RN-005 Notificar al email anterior Email de seguridad
RN-006 Logout-all despues del cambio Revocar tokens
RN-007 Nuevo email formato valido Regex validation

Flujo de Cambio de Email

┌─────────────────────────────────────────────────────────────────┐
│ 1. Usuario solicita cambio                                       │
│    POST /api/v1/users/me/email/request-change                   │
│    Body: { newEmail, currentPassword }                          │
└───────────────────────────┬─────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────────┐
│ 2. Validaciones                                                  │
│    - Password correcto                                           │
│    - Nuevo email formato valido                                  │
│    - Nuevo email no existe en tenant                            │
│    - No hay solicitud pendiente                                  │
└───────────────────────────┬─────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────────┐
│ 3. Crear solicitud                                               │
│    - Guardar en email_change_requests                           │
│    - Generar token (32 bytes, hex)                              │
│    - expires_at = now + 24 hours                                │
└───────────────────────────┬─────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────────┐
│ 4. Enviar email de verificacion                                  │
│    To: nuevo@email.com                                           │
│    Link: /verify-email-change?token={token}                     │
└───────────────────────────┬─────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────────┐
│ 5. Usuario hace clic en link                                     │
│    GET /api/v1/users/email/verify-change?token={token}          │
└───────────────────────────┬─────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────────┐
│ 6. Aplicar cambio                                                │
│    - Actualizar users.email                                      │
│    - Marcar solicitud como completada                           │
│    - Invalidar todas las sesiones                               │
│    - Enviar notificacion al email anterior                      │
└───────────────────────────┬─────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────────┐
│ 7. Redirigir al login                                            │
│    - Usuario debe iniciar sesion con nuevo email                │
└─────────────────────────────────────────────────────────────────┘

Impacto en Capas

Database

Elemento Accion Descripcion
Tabla crear email_change_requests
Columna - id UUID PK
Columna - user_id UUID FK
Columna - tenant_id UUID FK
Columna - current_email VARCHAR(255)
Columna - new_email VARCHAR(255)
Columna - token_hash VARCHAR(255)
Columna - expires_at TIMESTAMPTZ
Columna - completed_at TIMESTAMPTZ
Columna - created_at TIMESTAMPTZ
Indice crear idx_email_change_user

Backend

Elemento Accion Descripcion
Controller agregar UsersController.requestEmailChange()
Controller agregar UsersController.verifyEmailChange()
Method crear UsersService.requestEmailChange()
Method crear UsersService.verifyEmailChange()
DTO crear RequestEmailChangeDto
Entity crear EmailChangeRequest
Endpoint crear POST /api/v1/users/me/email/request-change
Endpoint crear GET /api/v1/users/email/verify-change

Frontend

Elemento Accion Descripcion
Componente crear ChangeEmailForm
Pagina crear VerifyEmailChangePage
Modal crear ConfirmPasswordModal

Dependencias

Depende de (Bloqueantes)

ID Requerimiento Estado
RF-USER-001 CRUD Usuarios Tabla users
RF-AUTH-004 Logout Para logout-all

Dependencias Externas

Servicio Descripcion
Email Service Envio de verificacion

Especificaciones Tecnicas

Endpoint POST /api/v1/users/me/email/request-change

// Request
{
  "newEmail": "nuevo@empresa.com",
  "currentPassword": "MiPasswordActual123!"
}

// Response 200
{
  "message": "Se ha enviado un email de verificacion a nuevo@empresa.com",
  "expiresAt": "2025-12-06T10:30:00Z"
}

// Response 400 - Password incorrecto
{
  "statusCode": 400,
  "message": "Password incorrecto"
}

// Response 409 - Email existe
{
  "statusCode": 409,
  "message": "Email no disponible"
}

Endpoint GET /api/v1/users/email/verify-change

// Request
GET /api/v1/users/email/verify-change?token=abc123...

// Response 200 (redirect)
// Redirect to: /login?emailChanged=true

// Response 400 - Token invalido
{
  "statusCode": 400,
  "message": "Token invalido o expirado"
}

Template de Email - Verificacion

Asunto: Verifica tu nuevo email - ERP Suite

<h2>Hola {{firstName}},</h2>

<p>Recibimos una solicitud para cambiar tu email de:</p>
<p><strong>{{currentEmail}}</strong> a <strong>{{newEmail}}</strong></p>

<p>Haz clic en el siguiente enlace para confirmar el cambio:</p>
<a href="{{verifyUrl}}">Verificar nuevo email</a>

<p><strong>Este enlace expira en 24 horas.</strong></p>

<p>Si no solicitaste este cambio, ignora este email y considera
cambiar tu password por seguridad.</p>

Template de Email - Notificacion al Email Anterior

Asunto: Tu email ha sido cambiado - ERP Suite

<h2>Hola {{firstName}},</h2>

<p>Te informamos que el email de tu cuenta ha sido cambiado.</p>

<p><strong>Email anterior:</strong> {{oldEmail}}</p>
<p><strong>Email nuevo:</strong> {{newEmail}}</p>
<p><strong>Fecha:</strong> {{changeDate}}</p>

<p>Si no realizaste este cambio, contacta inmediatamente a soporte.</p>

Datos de Prueba

Escenario Entrada Resultado
Solicitud valida newEmail, password correcto 200, email enviado
Password incorrecto password erroneo 400, "Password incorrecto"
Email ya existe email de otro usuario 409, "Email no disponible"
Email invalido "notanemail" 400, "Email invalido"
Verificar token valido token < 24h 200, email cambiado
Token expirado token > 24h 400, "Token expirado"
Token ya usado solicitud completada 400, "Token ya utilizado"

Estimacion

Capa Story Points Notas
Database 1 Tabla email_change_requests
Backend 3 Endpoints, validaciones, emails
Frontend 2 Form y pagina verificacion
Total 6

Notas Adicionales

  • Considerar periodo de gracia donde se puede revertir el cambio
  • Implementar notificacion push ademas de email
  • Rate limiting en solicitudes (max 3 por dia)
  • Log de todos los cambios de email para auditoria

Historial de Cambios

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

Aprobaciones

Rol Nombre Fecha Firma
Analista System 2025-12-05 [x]
Tech Lead - - [ ]
Product Owner - - [ ]