From a78417e954694202d101d5e9ec6d5afb9c73617b Mon Sep 17 00:00:00 2001 From: adevopg Date: Wed, 15 Jul 2026 17:43:46 +0000 Subject: [PATCH] =?UTF-8?q?Activaci=C3=B3n=20de=20cuenta:=20recuperar=20el?= =?UTF-8?q?=20dise=C3=B1o=20del=20tema=20y=20decir=20QU=C3=89=20cuenta=20s?= =?UTF-8?q?e=20activ=C3=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La página mostraba un genérico «¡Cuenta activada!» + enlace a iniciar sesión. Se recupera la estructura de las plantillas del tema (activation_success.html / activation_invalid.html): bienvenida, la cuenta en `yellow-info`, y el aviso de enlace inválido en `red-info2` con la línea de contacto. El original dejaba un hueco: renderizaba `{{ username }}` pero la vista hacía `render(...)` SIN contexto, así que salía «La cuenta ha sido activada». Aquí `activateAccount` devuelve el email y sí se muestra. Va el email tal cual se registró, no el normalizado: ese va en MAYÚSCULAS porque lo exige el SRP6 de Battle.net y en pantalla quedaría como INNA@INNA.CL. El nombre del servidor sale de `getRealmName()` (acore_auth.realmlist), como en el resto de páginas, en vez de escribirlo a mano. Verificado en producción: el caso inválido lo pinta el servidor y sale idéntico al del tema; y activando una fila de prueba, el API devuelve {success, email} y reutilizar el enlace o mandar un hash que no existe dan `invalidLink` (filas de prueba borradas después). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../activate-account/ActivateClient.tsx | 36 ++++++++++++------- .../app/[locale]/activate-account/page.tsx | 4 ++- web-next/lib/register.ts | 6 +++- web-next/messages/en.json | 10 +++--- web-next/messages/es.json | 10 +++--- 5 files changed, 44 insertions(+), 22 deletions(-) diff --git a/web-next/app/[locale]/activate-account/ActivateClient.tsx b/web-next/app/[locale]/activate-account/ActivateClient.tsx index 2a03a8b..098f4d8 100644 --- a/web-next/app/[locale]/activate-account/ActivateClient.tsx +++ b/web-next/app/[locale]/activate-account/ActivateClient.tsx @@ -2,17 +2,17 @@ import { useEffect, useRef, useState } from 'react' import { useTranslations } from 'next-intl' -import { Link } from '@/i18n/navigation' const ERROR_KEYS = ['invalidLink', 'expiredLink'] as const -export function ActivateClient({ hash }: { hash: string }) { +export function ActivateClient({ hash, realm }: { hash: string; realm: string }) { const t = useTranslations('Activate') // Sin hash el error se sabe YA, al renderizar (y 'invalidLink' es justo el // errorKey por defecto): se deriva del prop en vez de ponerlo con setState // dentro del efecto, que encadena un render de más. const [state, setState] = useState<'loading' | 'ok' | 'error'>(hash ? 'loading' : 'error') const [errorKey, setErrorKey] = useState('invalidLink') + const [email, setEmail] = useState('') const ran = useRef(false) useEffect(() => { @@ -24,9 +24,11 @@ export function ActivateClient({ hash }: { hash: string }) { body: JSON.stringify({ hash }), }) .then((r) => r.json()) - .then((d: { success?: boolean; error?: string }) => { - if (d.success) setState('ok') - else { + .then((d: { success?: boolean; error?: string; email?: string }) => { + if (d.success) { + setEmail(d.email ?? '') + setState('ok') + } else { setErrorKey((ERROR_KEYS as readonly string[]).includes(d.error ?? '') ? d.error! : 'invalidLink') setState('error') } @@ -34,18 +36,28 @@ export function ActivateClient({ hash }: { hash: string }) { .catch(() => setState('error')) }, [hash]) + // El envoltorio ya lo pone la página (`body-box-content centered`), así que aquí + // van los

sueltos: es la estructura que tenían las plantillas del tema. return ( -

+ <> {state === 'loading' &&

{t('activating')}

} {state === 'ok' && ( <> - {t('success')} -

- {t('goLogin')} -

+
+

{t('welcome', { realm })}

+

{t.rich('activated', { email, account: (c) => {c} })}

+
+

{t('canPlay')}

+
)} - {state === 'error' && {t(errorKey)}} -
+ {state === 'error' && ( + <> +

{t(errorKey)}

+
+

{t('needHelp', { realm })}

+ + )} + ) } diff --git a/web-next/app/[locale]/activate-account/page.tsx b/web-next/app/[locale]/activate-account/page.tsx index 761e4ef..69e706d 100644 --- a/web-next/app/[locale]/activate-account/page.tsx +++ b/web-next/app/[locale]/activate-account/page.tsx @@ -1,5 +1,6 @@ import { getTranslations, setRequestLocale } from 'next-intl/server' import { PageShell } from '@/components/PageShell' +import { getRealmName } from '@/lib/realm' import { ActivateClient } from './ActivateClient' export default async function ActivatePage({ @@ -13,12 +14,13 @@ export default async function ActivatePage({ setRequestLocale(locale) const { act } = await searchParams const t = await getTranslations('Activate') + const realm = await getRealmName() return (
- +
diff --git a/web-next/lib/register.ts b/web-next/lib/register.ts index 2b37230..6b96dae 100644 --- a/web-next/lib/register.ts +++ b/web-next/lib/register.ts @@ -18,6 +18,8 @@ export interface RegisterInput { export interface Result { success: boolean error?: string + /** Solo al activar: el correo de la cuenta, para poder decir cuál se activó. */ + email?: string } export async function registerAccount(input: RegisterInput): Promise { @@ -111,5 +113,7 @@ export async function activateAccount(hash: string, lastIp = '0.0.0.0'): Promise ) await db(DB.default).query('DELETE FROM accountactivation WHERE id = ?', [act.id]) - return { success: true } + // El correo tal cual se registró, no `emailNorm`: ese va en MAYÚSCULAS porque lo + // exige el SRP6 de Battle.net, y en pantalla quedaría como INNA@INNA.CL. + return { success: true, email: act.email } } diff --git a/web-next/messages/en.json b/web-next/messages/en.json index 3b78385..bbca6f9 100644 --- a/web-next/messages/en.json +++ b/web-next/messages/en.json @@ -201,10 +201,12 @@ }, "Activate": { "activating": "Activating your account…", - "success": "Account activated! You can now sign in.", - "invalidLink": "The link is invalid or has already been used.", - "expiredLink": "The link has expired. Please request a new one.", - "goLogin": "Go to sign in", + "welcome": "Welcome to {realm}!", + "activated": "The account {email} has been activated successfully.", + "canPlay": "You can now log in to the website or start enjoying the server.", + "invalidLink": "The activation link is invalid", + "expiredLink": "The activation link has expired", + "needHelp": "If you need help creating an account, you can contact the {realm} team.", "title": "Account activation" }, "Recover": { diff --git a/web-next/messages/es.json b/web-next/messages/es.json index 09505d0..415d355 100644 --- a/web-next/messages/es.json +++ b/web-next/messages/es.json @@ -201,10 +201,12 @@ }, "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", + "welcome": "¡Bienvenido a {realm}!", + "activated": "La cuenta {email} ha sido activada exitosamente.", + "canPlay": "Ya puedes conectar a la página web o empezar a disfrutar del servidor.", + "invalidLink": "El enlace de activación es inválido", + "expiredLink": "El enlace de activación ha caducado", + "needHelp": "Si necesitas ayuda para crear una cuenta, puedes contactar con el equipo de {realm}.", "title": "Activación de cuenta" }, "Recover": {