feat(frontend): add CSRF injection, rate-limit i18n, and 429 login handling

- handleFetch injects X-XSRF-TOKEN + XSRF-TOKEN cookie on all mutating
  backend API requests (double-submit cookie pattern); generates a fresh
  UUID when no XSRF-TOKEN cookie exists yet
- ErrorCode union gains CSRF_TOKEN_MISSING and TOO_MANY_LOGIN_ATTEMPTS;
  getErrorMessage maps both to i18n keys
- de/en/es messages add error_csrf_token_missing and
  error_too_many_login_attempts translations
- Login action maps HTTP 429 to fail(429, { ..., rateLimited: true });
  page shows a muted clock icon with aria-invalid on rate-limit errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-18 12:59:56 +02:00
committed by marcel
parent 4d6fb06e02
commit 78fd9e026e
8 changed files with 105 additions and 30 deletions

View File

@@ -19,6 +19,8 @@
"error_session_expired_explainer": "Por razones de seguridad, las sesiones se terminan automáticamente tras 8 horas de inactividad.",
"error_unauthorized": "No ha iniciado sesión.",
"error_forbidden": "No tiene permiso para realizar esta acción.",
"error_csrf_token_missing": "Error de sesión. Recargue la página.",
"error_too_many_login_attempts": "Demasiados intentos. Por favor, inténtelo más tarde.",
"error_validation_error": "La entrada no es válida.",
"error_internal_error": "Se ha producido un error inesperado.",
"nav_documents": "Documentos",