Commit Graph
2 Commits
Author SHA1 Message Date
newblaccandClaude Sonnet 4.6 5539235004 feat(security): harden canvas server with auth, rate-limiting, and validation
- Add security.ts: helmet, CORS allowlist, timing-safe API key auth, prototype
  pollution guard, Mermaid input limits, rate limiting (general/destructive/burst)
- WS auth challenge-response with 5 s timeout and close code 4001
- Fix sync crash: array check before logger access (500 → 400)
- Fix sync/v2: validate element type before write (invalid → 400)
- Upgrade zod 3.22.4 → 3.25.5 (fixes ERR_PACKAGE_PATH_NOT_EXPORTED on startup)
- Extract ElementSharedFieldsSchema; move VALID_ELEMENT_TYPES to module level
- Docker: resource limits, .dockerignore hardening
- Add .project-hooks/pre-commit; expand test coverage (369 tests)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 16:06:04 +02:00
Sanjib DevnathandClaude Opus 4.6 7c59972bb1 🐛 fix(mcp): resolve race conditions, sync failures, and preference regressions (#12)
Fix 6 bugs discovered during MCP tool usage:

1. syncToCanvas error handling: Distinguish network errors (return null)
   from API errors (re-throw with actual message). Fixes misleading
   "HTTP server unavailable" on batch_create_elements.

2. USER_PREFS fallbacks: create_element and batch_create_elements now
   apply fontFamily/roughness/fontSize/strokeWidth from preferences.json
   when not explicitly provided by the caller.

3. Hello handshake: Frontend sends `hello` on tenant_switched and handles
   `hello_ack`. Server resolves projectId from tenantId when absent.
   Fixes WS connections being registered under wrong scope.

4. Serialized broadcasts: Add serializedBroadcastWithAck() that queues
   broadcasts per tenant/project scope. Prevents race condition where
   parallel MCP create_element calls produce overlapping WS messages
   that clobber each other in the frontend.

5. Viewport screenshot: get_canvas_screenshot passes captureViewport=true,
   frontend captures DOM canvas via toDataURL() instead of exportToBlob()
   which always rendered the full scene bounding box.

6. Viewport animate:false: set_viewport uses animate:false for instant
   positioning, preventing mid-animation screenshot captures.

Tests: 14 new tests (8 API, 6 WS) + 9 E2E specs covering all fixes.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 08:28:00 +05:30