feat: add WebSocket server with ticket auth and heartbeat (#38) #45

Merged
maximus merged 1 commit from issue-38-websocket into issue-35-web-setup 2026-04-06 16:07:01 +00:00
Owner

Fixes #38

Summary

  • Custom server (server.ts) wrapping Next.js + ws on the same HTTP port
  • Ticket-based WebSocket auth (validates ephemeral nonce from /api/ws-ticket)
  • Origin validation against allowlist
  • Session revalidation every 15 min (auto-close expired sessions)
  • Heartbeat every 30s (ping/pong)
  • broadcastToUser() function for API routes
  • Shared ticket store via globalThis between API route and WS server
  • Health endpoint now reports active WS connections
  • Dockerfile updated to use node server.ts

Security

  • No query params logged on /ws route
  • Tickets are single-use and expire after 30s
  • Origin checked against allowlist
  • Dead connections terminated via heartbeat

Depends on

  • PR #42 (setup), PR #44 (API, merged into #42)
Fixes #38 ## Summary - Custom server (`server.ts`) wrapping Next.js + `ws` on the same HTTP port - Ticket-based WebSocket auth (validates ephemeral nonce from `/api/ws-ticket`) - Origin validation against allowlist - Session revalidation every 15 min (auto-close expired sessions) - Heartbeat every 30s (ping/pong) - `broadcastToUser()` function for API routes - Shared ticket store via globalThis between API route and WS server - Health endpoint now reports active WS connections - Dockerfile updated to use `node server.ts` ## Security - No query params logged on /ws route - Tickets are single-use and expire after 30s - Origin checked against allowlist - Dead connections terminated via heartbeat ## Depends on - PR #42 (setup), PR #44 (API, merged into #42)
maximus added 1 commit 2026-04-06 15:55:58 +00:00
- Custom server (server.ts) wrapping Next.js + ws on same port
- Ticket-based auth: validates ephemeral nonce from /api/ws-ticket
- Origin validation against allowlist
- Session revalidation every 15 min (sends auth_expired, closes)
- Heartbeat every 30s (ping/pong, terminates dead connections)
- broadcastToUser() for API routes to notify connected clients
- Shared ticket store between API route and WS server via globalThis
- Health endpoint now reports active WS connections
- Dockerfile updated to use custom server

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author
Owner

Review — APPROVE

Clean WebSocket implementation with proper security (ticket auth, origin validation, session revalidation, heartbeat).

  • Ticket single-use + 30s TTL
  • Origin allowlist enforced
  • Session revalidation every 15 min
  • Heartbeat 30s with dead connection cleanup
  • No query param logging on /ws
  • TypeScript compiles
  • Dockerfile updated correctly
## Review — APPROVE Clean WebSocket implementation with proper security (ticket auth, origin validation, session revalidation, heartbeat). - [x] Ticket single-use + 30s TTL - [x] Origin allowlist enforced - [x] Session revalidation every 15 min - [x] Heartbeat 30s with dead connection cleanup - [x] No query param logging on /ws - [x] TypeScript compiles - [x] Dockerfile updated correctly
maximus merged commit 2f2a48f644 into issue-35-web-setup 2026-04-06 16:07:01 +00:00
maximus deleted branch issue-38-websocket 2026-04-06 16:07:01 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: maximus/simpl-liste#45
No description provided.