Fase 3 (islas): cambiar contraseña y token de seguridad en React/TSX

Ambas vistas ya devolvían JSON en POST y exigen sesión, así que sin cambio de backend:

- ChangePasswordForm.tsx: 4 campos (actual/nueva/confirmar/token) con mostrar-ocultar;
  POST form-urlencoded + CSRF a change_password; mensaje HTML; si el backend responde
  redirect:true (logout por seguridad), redirige a login.
- SecurityTokenForm.tsx: muestra la fecha del token y un botón que solicita uno nuevo;
  POST -> actualiza la fecha con token_date de la respuesta.
- Plantillas: los <form> + scripts jQuery se sustituyen por las islas
  (#change-password-app / #security-token-app) con data-csrf/data-url. El texto
  informativo y los enlaces se quedan en Django.

Verificado: check OK; ambas vistas siguen redirigiendo a login/index sin sesión.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 21:26:30 +00:00
parent b2069df4c3
commit d0febb4855
7 changed files with 220 additions and 39 deletions
+8 -28
View File
@@ -13,34 +13,14 @@
<div class="centered">
<br>
<br>
<form action="" method="POST" id="nw-change-password-form" accept-charset="utf-8">
<table class="middle-center-table">
<script
src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/change_password_response.js">
</script>
<tbody><tr>
<td><input type="password" maxlength="16" name="cur-password" id="cur-password" placeholder="Contraseña actual" autofocus="">
<span class="far fa-eye toggle-cur-password"></span></td>
</tr>
<tr>
<td><input type="password" maxlength="16" name="new-password" id="new-password" placeholder="Contraseña nueva">
<span class="far fa-eye toggle-new-password"></span></td>
</tr>
<tr>
<td><input type="password" maxlength="16" name="conf-new-password" id="conf-new-password" placeholder="Confirmar contraseña nueva">
<span class="far fa-eye toggle-conf-new-password"></span></td>
</tr>
<tr>
<td><input type="password" maxlength="6" name="security-token" id="security-token" placeholder="Token de seguridad">
<span class="far fa-eye toggle-token"></span></td>
</tr>
<tr>
<td><button type="submit" name="changepassword" class="change-password-button" data-id="CambiarPassword">Cambiar contraseña</button></td>
</tr>
</tbody></table>
</form>
<hr>
<div class="alert-message" id="change-password-response"></div>
{% load django_vite %}
<!-- Isla React (Vite): cambio de contraseña. POST a la propia
vista (JSON) -> re-deriva el verifier bnet. -->
<div id="change-password-app"
data-csrf="{{ csrf_token }}"
data-url="{% url 'change_password' %}"
data-login-url="{% url 'login' %}"></div>
{% vite_asset 'src/entries/change_password.tsx' %}
<br>
</div>
</div>