Foro (escritura): crear tema y responder, con saneado HTML

- lib/forum-sanitize.ts: cleanPostHtml con sanitize-html (misma allowlist que
  forum/sanitize.py de nh3: formato básico + a/img/tablas, rel nofollow, esquemas
  http/https/mailto). Verificado XSS-safe (script/onclick/javascript: eliminados).
- lib/forum-write.ts: createTopic (tema + primer post), createPost (respuesta +
  updated_at), forumIsPostable / topicIsReplyable.
- Routes /api/forum/topic y /api/forum/reply (guard de sesión; identidad = cuenta de
  juego: poster=username, poster_id=accountId). Componentes NewTopicForm y ReplyForm
  (clientes). Se muestran solo si hay sesión; el tema cerrado no admite respuesta.

Verificado: escritura 401 sin sesión, saneado correcto. Pendiente: editar/borrar,
moderación (fijar/cerrar/mover), búsqueda, editor enriquecido.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 23:49:53 +00:00
parent e743d98777
commit 239392b876
12 changed files with 516 additions and 3 deletions
+11 -1
View File
@@ -254,6 +254,16 @@
"backToTopics": "Volver al foro",
"notFound": "No encontrado",
"newTopic": "Nuevo tema",
"reply": "Responder"
"reply": "Responder",
"newTopicName": "Título del tema",
"newTopicText": "Escribe tu mensaje…",
"publish": "Publicar tema",
"publishing": "Publicando…",
"replyText": "Escribe tu respuesta…",
"sendReply": "Responder",
"sending": "Enviando…",
"loginToPost": "Inicia sesión para participar.",
"emptyError": "Completa todos los campos.",
"genericError": "Algo ha salido mal. Inténtalo más tarde."
}
}