Registro + activación por email en Next.js (SRP6 + nodemailer)

- lib/mail.ts: transporte SMTP (nodemailer, mismas creds Gmail que Django).
- lib/register.ts: registerAccount (valida, comprueba email existente, crea fila en
  home_accountactivation reutilizando la tabla de Django, envía email de activación);
  activateAccount (crea battlenet_accounts con SRP6 v2 + account con SRP6 Grunt, como
  activate_account_view: expansion=2, battlenet_index=1; borra la activación).
- Route handlers /api/auth/register y /api/auth/activate.
- Páginas app/[locale]/register (RegisterForm cliente) y app/[locale]/activate-account
  (ActivateClient auto-POST al abrir el enlace). Textos en messages (Register, Activate).

Validado: validaciones (missingFields/passwordMismatch/invalidEmail/passwordTooLong);
ciclo completo activación->crea bnet+account->login OK con la cuenta creada
(needsSelection=false), password mala->invalidCredentials. Todo en TS, crypto validada.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 22:53:09 +00:00
parent e00a439dd9
commit f332fc39ca
12 changed files with 429 additions and 0 deletions
+27
View File
@@ -44,5 +44,32 @@
"noAccounts": "No se han encontrado cuentas de juego asociadas a esta cuenta Battle.net.",
"entering": "Entrando…",
"error": "No se pudo seleccionar la cuenta."
},
"Register": {
"title": "Creación de cuenta",
"info": "Tu cuenta es de tipo Battle.net: se identifica con tu correo electrónico. La contraseña debe ser alfanumérica y de hasta 16 caracteres. El correo debe ser de Gmail.",
"password": "Contraseña",
"confPassword": "Confirmar contraseña",
"email": "Correo electrónico de Gmail",
"confEmail": "Confirmar correo electrónico",
"recruiter": "Reclutante (opcional)",
"terms": "Acepto las Normas, los Términos y Condiciones y la Política de Privacidad",
"submit": "Crear cuenta",
"creating": "Creando…",
"success": "La cuenta se ha creado. Revisa tu correo para activarla.",
"missingFields": "Por favor, complete todos los campos.",
"passwordMismatch": "Las contraseñas no coinciden.",
"passwordTooLong": "La contraseña no debe exceder los 16 caracteres.",
"invalidEmail": "El correo electrónico no es válido.",
"emailExists": "Ya existe una cuenta con ese correo electrónico.",
"recruiterNotFound": "El reclutador ingresado no existe.",
"genericError": "Algo ha salido mal. Inténtalo más tarde."
},
"Activate": {
"activating": "Activando tu cuenta…",
"success": "¡Cuenta activada! Ya puedes iniciar sesión.",
"invalidLink": "El enlace no es válido o ya se ha usado.",
"expiredLink": "El enlace ha caducado. Solicita uno nuevo.",
"goLogin": "Ir a iniciar sesión"
}
}