0.24.0

Итерация 20 плана аудита: WebUI — безопасность WebSocket, XSS-защита, валидация.

Added

  • WS ticket endpoint (POST /api/v1/ws/ticket): одноразовый 32-байтный nonce (TTL 30s) вместо JWT в query string. Проверка membership (agentID ∈ claims.Agents) при создании ticket.
  • WS origin check: same-origin по умолчанию, CORS whitelist при настройке. Убран OriginPatterns: ["*"].
  • WS membership check: CreateWSTicket проверяет, что пользователь имеет доступ к агенту. HandleWebSocket проверяет agentID == ticket.agentID.
  • WS reconnect на фронте: exponential backoff 1s→30s, max 10 попыток.
  • sendMessage retry: лимит 5 попыток с increasing delay, ошибка при превышении.
  • Уникальные ID сообщений: crypto.randomUUID() вместо Date.now().
  • Server-side валидация имён: resourceNameRegex + resourceNameDenied для cron.name, heartbeat.title, mcp.name.
  • Delegated click handler в MarkdownRenderer: data-action="copy-code" + document.addEventListener вместо inline onclick.

Changed

  • XSS в ConfirmModal: {@html message} убран, новый API (messagePrefix, messageHighlight, messageSuffix). Все 7 calling-файлов обновлены.
  • MCP handler: полностью мигрирован с http.Error на writeJSONError/writeJSON/writeNotFound/writeForbidden.
  • CORSOriginsFromEnv: экспортирован из server.go, используется и в router, и в ChatHandler.

Tests

  • 17 новых тестов в internal/server/handler/iter20_test.go: WS ticket (auth, membership, admin bypass, one-time, expired, mismatch), origin check (same, cross, CORS, no header), resource name validation (10 кейсов), expired ticket cleanup.