Changelogs
Fase 3 (isla): dashboard de «Mi cuenta» en React/TSX
12 de julio de 2026 a las 21:23adevopg · b2069df
De las ~508 líneas de partials/my-account.html, solo la parte superior es dinámica (datos de cuenta, estado, puntos, token, personajes); el resto son paneles de navegación estáticos (enlaces), que se quedan en Django. - API: account_me_api -> /api/account/me/ (protegido por sesión, 401 si no hay): user_info, account_status, dp/vp, créditos Battlepay, token de seguridad y personajes. Reutiliza get_account_characters/get_account_status/formatear_fecha. Resiliente si acore no está disponible. - React: AccountDashboard.tsx (fieldsets de datos + estado con contador de baneo en vivo + rejilla de personajes). Entry my_account. - partials/my-account.html: los 2 fieldsets + la rejilla de personajes + el script del contador se sustituyen por #account-dashboard-app; los paneles de utilidades e historiales siguen en Django. Verificado: check OK, /api/account/me/ 401 sin sesión, my-account redirige a login. (El render con datos reales requiere sesión + BD AzerothCore.)
Añade Cloudflare Turnstile (captcha) a login, registro y recuperación
12 de julio de 2026 a las 21:15adevopg · cac0d28
- Backend: helper verify_turnstile en _base (verifica el token contra challenges.cloudflare.com/siteverify; fail-closed ante error de red; si no hay secreto configurado, no bloquea). Se exige en el POST de login_view, register_view y recover_account_view -> rechazo con mensaje si falla. - settings: TURNSTILE_SITE_KEY / TURNSTILE_SECRET_KEY desde .env (el secreto NO se commitea). La clave de sitio se expone a las plantillas por el context processor (TURNSTILE_SITE_KEY). - Frontend: hook useTurnstile (carga el script de Cloudflare una vez y renderiza el widget, devuelve el token). LoginForm/RegisterForm/RecoverForm incluyen el widget, mandan cf-turnstile-response y deshabilitan el submit hasta tener token. El sitekey llega por data-sitekey en el div de montaje. Verificado: sin token los 3 POST se rechazan; siteverify acepta la clave secreta (error invalid-input-response con token falso, no invalid-input-secret).
Implementa la recuperación de cuenta (contraseña / cuentas / activación) + islas
12 de julio de 2026 a las 21:00adevopg · 8920585
recover_account_view era un stub que solo renderizaba (los formularios no tenían backend y el HTML arrastraba un reCAPTCHA de otro dominio). Ahora es funcional: Backend: - Modelo PasswordReset (token+email+expiración 1h) + migración 0014. - recover_account_view maneja POST JSON con 3 tipos, todo por email (bnet), con respuestas genéricas anti-enumeración: * password: crea token y envía enlace de reset (emails/password_reset.html). * accountname: envía las cuentas de juego ligadas (emails/account_names.html). * activation: reenvía el enlace de activación pendiente (emails/activation.html). - reset_password_view: GET valida el token (isla), POST re-deriva el verifier SRP6 v2 de la cuenta bnet (bnet.bnet_make_registration) y lo actualiza; marca el token usado. Ruta 'reset-password'. - Resiliente si la BD de cuentas (AzerothCore) no está disponible: mensaje limpio, nunca 500. Frontend (islas Vite): RecoverForm.tsx (selector de tipo + email) y ResetPassword.tsx (nueva contraseña con token). Se elimina el reCAPTCHA roto; se puede añadir uno propio si se aportan claves. Verificado en producción: los 3 flujos devuelven éxito genérico; reset valida token y contraseñas; token válido no provoca 500.
Fase 2 (isla): selector de cuenta de juego en React/TSX, sin POST
12 de julio de 2026 a las 20:50adevopg · 45f48c2
El selector de cuenta de juego (bnet con varias) pasa a isla React y la selección se hace vía GET (a petición), no POST: - Nuevo endpoint GET /api/account/select/?account_id=<id> (account_select_api): idempotente y solo permite elegir cuentas ligadas a la bnet en sesión; fija la cuenta en sesión y devuelve {success, redirect}. 401 si no hay sesión bnet. - select_account_view: se elimina el manejo de POST (queda solo la lógica GET: redirect si no hay bnet, autoseleccionar si hay una, render si hay varias). - SelectAccount.tsx lee las cuentas embebidas con json_script y, al pulsar, hace fetch GET y redirige. Nueva entry 'select_account'. - select_account.html: el <form> POST se sustituye por la isla + json_script. Verificado: check OK, endpoint 401 sin sesión, /select-account/ redirige a login.
Fase 2 (isla): formulario de registro en React/TSX
12 de julio de 2026 a las 20:45adevopg · 8156bef
register_view ya devolvía JSON en POST, así que sin cambio de backend: RegisterForm.tsx replica register.js (password/conf con mostrar-ocultar, email/conf, reclutador opcional, checkbox de términos que habilita el botón) y hace fetch form-urlencoded + CSRF a {% url 'register' %}. El mensaje de éxito llega como HTML (dangerouslySetInnerHTML); los de error como texto en rojo. - partials/register.html: el <form> + register.js se sustituyen por #register-app (data-csrf/data-register-url) + {% vite_asset %}. Info-box y rama "ya conectado" siguen en Django. - Nueva entry 'register' en vite.config.ts. Verificado: check OK, la página monta la isla, POST con datos inválidos devuelve el JSON de validación correcto.


