Commit Graph

7 Commits

Author SHA1 Message Date
Inna 4303e9fc88 Los correos de cambio de correo saludan con la cuenta, no con «15#1»
Decían «Hola 15#1»: el username interno, que no le dice nada a nadie. Ahora
«Hola INNA@INNA.CL (WOW1)» — el correo, que es la cuenta con Battle.net, y la
cuenta de juego con su nombre visible. Si no se sabe cuál es, va el correo solo,
sin paréntesis vacío.

Afecta a las 3 plantillas del cambio de correo. En la que va al correo NUEVO se
saluda con `old_email`: el cambio aún no ha terminado, así que la cuenta se sigue
identificando con el correo viejo (hay que añadirlo al SELECT).

El original de Django también decía «Hola {{ username }}», así que esto es un
arreglo, no una copia.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 19:26:46 +00:00
Inna c255724ebf Aceptar el correo en MAYÚSCULAS y mostrar las cuentas como WOW1, no 17#1
Dos fallos que se juntaban justo en «recuperar nombre de cuenta»:

- La validación de Gmail era sensible a mayúsculas (`/@gmail\.com$/` sin la `i`),
  así que NOVAWOW86@GMAIL.COM se rechazaba con invalidEmail. Y desde que los
  correos muestran la cuenta en MAYÚSCULAS, quien la copiara de ahí y la pegara
  no podía recuperar la cuenta, ni registrarse, ni cambiar el correo: la misma
  regex estaba repetida en register/change-email/recover. Ahora es una sola, con
  la `i`, en lib/bnet.ts (junto a normalizeEmail). El dominio de un correo NO
  distingue mayúsculas.

- Los correos enseñaban el username interno («17#1»), que no le dice nada a
  nadie, en vez del nombre visible («WOW1»). Afectaba a DOS plantillas: la de
  nombres de cuenta y la de la lista de tokens. La conversión existía, pero como
  helper local de my-account; sube a lib/bnet.ts como `gameAccountDisplayName`
  (el inverso de `makeGameAccountUsername`) y la aplican las propias plantillas,
  para que ningún sitio que las use pueda olvidarse.

Verificado: la regex acepta las 3 variantes de caja y sigue rechazando no-Gmail;
los dos correos renderizados muestran «Cuenta: WOW1 / WOW2».

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 18:53:09 +00:00
Inna 4f8f101ba8 Impedir cuentas Battle.net duplicadas al activar; citar el límite real de 8
`registerAccount` ya rechazaba un correo con cuenta bnet, pero `activateAccount`
insertaba SIN volver a comprobarlo, y entre registrarse y activar el correo puede
dejar de estar libre. Como `battlenet_accounts.email` no tiene índice único, la
BD tampoco lo frenaba: hay 3 filas TEST@TEST.COM de 2024 que lo demuestran.
Ahora se recomprueba antes del INSERT y se borra la activación, que ya no sirve.
Nuevo error `emailExists` (ES/EN) para no soltar un «enlace inválido» que despista.

MAX_GAME_ACCOUNTS sube a lib/bnet.ts y lo usa el correo de activación: el texto
prometía 10 cuentas mientras el código cortaba en 8, justo por estar el número
escrito a mano en los dos sitios. El límite del panel ya funcionaba (API + aviso
«Has alcanzado el máximo de cuentas»); solo se centraliza la constante.

Verificado en producción con una activación pendiente de un correo que ya tenía
bnet: devuelve emailExists, no crea la cuenta y el contador no sube.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 18:02:54 +00:00
Inna 1285d3398b Correo de activación: saludar con la cuenta y ajustar los textos
- El <h1> decía «Bienvenido» a secas; ahora lleva la cuenta detrás, como la
  plantilla original (`Bienvenido, {{ username }}`), donde `username` era el
  mismo correo que sale en «Cuenta:».
- «Para empezar a usarla, actívala pulsando el botón» -> «Para poder empezar a
  usar tu cuenta, deberás activarla haciendo clic en el botón ACTIVAR LA CUENTA».
- La segunda línea de «Recuerda» pasa a hablar del panel de usuario en vez de
  «hasta 10 cuentas de juego».

Verificado renderizando el correo y extrayendo su texto visible.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 17:57:56 +00:00
Inna fa7897c195 Prefijos del tema nw- y uw- -> ns- (carpetas, ficheros, clases y rutas)
Renombrado completo de los prefijos heredados: 19 carpetas, 11 ficheros y 318
referencias en 35 ficheros de código, más las clases y las rutas url() de dentro
del CSS del tema. Se usa git mv para conservar el historial.

También fuera del código, que un sed no ve:
- BD: votesite.image_url (4 filas) apuntaba a /nw-themes/...
- Ficheros con la marca vieja en el NOMBRE: novawow-maintenance.webp ->
  nightspire-maintenance.webp (lo usa la página de mantenimiento) y
  store_novawow_response.js.

⚠ Alias en Caddy /nw-themes/* -> /ns-themes/*: los correos ENVIADOS antes del
rebranding llevan esas rutas escritas y están en las bandejas de los usuarios.
Sin el alias, sus imágenes se romperían. Verificado que las rutas viejas siguen
sirviendo 200.

Nota: ns-js/ y ns-js-handlers/ son CÓDIGO MUERTO (manejadores jQuery del portal
Django, que ya se borró). Se midió en el navegador: la web no pide ni un solo JS
del tema. Se renombran igualmente por consistencia, pero son candidatos a
borrarse.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 15:50:43 +00:00
Inna 579396c34a Rebranding a NightSpire en toda la web
Marca, dominios y correos: UltimoWoW/Nova WoW -> NightSpire, cualquier URL de
esos dominios -> https://www.nightspire.gg y los correos -> consultas@nightspire.gg.
98 sustituciones en 16 ficheros de textos de usuario (messages/, app/, components/).

Assets: logo largo de cabecera y vídeo sustituidos por los de NightSpire (el logo
nuevo es 214x28, igual que el viejo, así que no hace falta tocar el CSS).

Redes: apuntan a las cuentas de NightSpire, tanto en el pie de la web como en el
de los correos (que seguían enlazando a las de NovaWoW desde el porte del diseño).

Cookie de sesión novawow_session -> nightspire_session. Cierra la sesión de todos
los conectados una vez; se asume ahora, recién hecho el cutover.

Ficheros del tema renombrados: novawow-style.css -> nightspire-style.css y
novawow-main-logo-transparent.webp -> nightspire-main-logo-transparent.webp, para
que la marca vieja no quede ni en las rutas.

El foro externo (foro.ultimowow.com) pasa a ser el nuestro: <Link> a /forum, que
respeta el idioma y no abre pestaña nueva.

NO se tocan y es a propósito:
- Los comentarios que nombran AzerothCore: describen el comportamiento REAL del
  core (límite de 12 ítems por correo, convención de baneos, SOAP...). Cambiarlos
  a NightSpire los volvería falsos. Además AzerothCore no aparece en la web: las
  14 menciones son todas comentarios de código.
- El regex de brandify() sigue buscando los nombres VIEJOS: son los que hay
  escritos en las noticias de la BD.
- lib/changelog.ts REPO='Inna/NovaWoW': es la ruta real del repo en Gitea.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 15:15:57 +00:00
Inna 9390eefa93 Correos: portar el diseño del tema y unificarlos en lib/emails.ts
Los correos usaban un shell inline distinto en cada remitente. Ahora salen
todos de una sola maqueta, la de security_token, portada de las plantillas de
Django. De las 7 de Django solo security_token y activation traían el diseño;
las otras 5 eran HTML soso.

Las plantillas de Django eran un volcado del DOM de Gmail. Al portarlas se
quitó lo que no era diseño: los enlaces iban envueltos en el rastreador de
Mailjet (079xk.mjt.lu), que además redirigía a ultimowow.com en vez de a
nosotros; había un píxel de apertura, un "Click on me" oculto y atributos que
mete Gmail al mostrar el correo. Las imágenes apuntaban al proxy de Gmail
(ci3.googleusercontent.com), no a nuestro /static/, así que el diseño se
rompía el día que Google dejara de servirlas.

Ninguna URL va a fuego: todas cuelgan de SITE_URL, así que cambiar de dominio
es tocar el .env. En un correo han de ser absolutas (se abre desde Gmail), así
que se construyen a partir de esa variable.

El logo nw-mail-logo.png daba 404: solo existía el .webp del tema, que es el de
UltimoWoW (león negro + letras "UW"). El auténtico de NovaWoW, un león de acero
sin letras, sobrevivía únicamente en la caché de Gmail y se recuperó de ahí
(600x320 RGBA, íntegro).

Verificado renderizando el original y el nuestro en un navegador y comparando:
cuadran pixel a pixel. Eso destapó dos fallos que se corrigen aquí: faltaba la
etiqueta <h1> de apertura, y el estilo de los párrafos de datos era el de la
letra pequeña del pie (11px/17px) en vez del real (14px/21px).

El activation de Django mandaba la contraseña en texto plano; aquí no se manda.

mail.ts: leía EMAIL_USE_SSL pero ignoraba EMAIL_USE_TLS, así que en el puerto
587 el STARTTLS era oportunista y, si el servidor no lo ofrecía, nodemailer
enviaba en claro. Ahora requireTLS lo hace obligatorio.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 14:33:32 +00:00