feat(relay): WebSocket relay server for managed recovery sessions #1

Open
hug wants to merge 2 commits from feat/managed-tunnel into main
Owner

Summary

Complete relay server implementation for the managed recovery tunnel.

Packages

  • internal/handlers/device.goGET /agent WebSocket; authenticates device, creates session, forwards MCP frames to agent, broadcasts push_event to portal SSE
  • internal/handlers/agent.goGET /mcp/:sessionID WebSocket; authenticates agent, drains buffered device frames, bidirectional proxy
  • internal/handlers/portal.goGET /portal/:sessionID/events SSE stream + POST /api/session/:id/approval endpoint; JWT auth
  • internal/auth/middleware.goServiceTokenAuth (constant-time compare) and JWTAuth (HS256) chi middleware
  • cmd/recova-relay/main.go — chi router wiring, env config (RELAY_SERVICE_TOKEN, RELAY_JWT_SECRET, PORT)
  • tests/integration/relay_test.go — end-to-end test covering all 5 message flows in-process

Test plan

  • go test ./... passes (auth, handler unit tests + integration test)
  • go build ./... clean
## Summary Complete relay server implementation for the managed recovery tunnel. ### Packages - `internal/handlers/device.go` — `GET /agent` WebSocket; authenticates device, creates session, forwards MCP frames to agent, broadcasts push_event to portal SSE - `internal/handlers/agent.go` — `GET /mcp/:sessionID` WebSocket; authenticates agent, drains buffered device frames, bidirectional proxy - `internal/handlers/portal.go` — `GET /portal/:sessionID/events` SSE stream + `POST /api/session/:id/approval` endpoint; JWT auth - `internal/auth/middleware.go` — `ServiceTokenAuth` (constant-time compare) and `JWTAuth` (HS256) chi middleware - `cmd/recova-relay/main.go` — chi router wiring, env config (`RELAY_SERVICE_TOKEN`, `RELAY_JWT_SECRET`, `PORT`) - `tests/integration/relay_test.go` — end-to-end test covering all 5 message flows in-process ## Test plan - [ ] `go test ./...` passes (auth, handler unit tests + integration test) - [ ] `go build ./...` clean
Adds the complete HTTP layer for recova-relay:
- internal/handlers/device.go  — GET /agent WebSocket handler (device-side)
- internal/handlers/agent.go   — GET /mcp/:sessionID WebSocket handler (agent-side)
- internal/handlers/portal.go  — GET /portal/:id/events SSE + POST approval
- internal/auth/middleware.go  — ServiceTokenAuth and JWTAuth chi middleware
- cmd/recova-relay/main.go     — chi router, env config, ListenAndServe

Each handler delegates all session state to session.Manager; no state is
held in the handlers themselves.
Spins up the full relay server in-process and exercises: device connect +
session_assigned, agent connect + MCP frame transit, agent push_event →
portal SSE delivery, and portal approval POST endpoint.
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/managed-tunnel:feat/managed-tunnel
git switch feat/managed-tunnel

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff feat/managed-tunnel
git switch feat/managed-tunnel
git rebase main
git switch main
git merge --ff-only feat/managed-tunnel
git switch feat/managed-tunnel
git rebase main
git switch main
git merge --no-ff feat/managed-tunnel
git switch main
git merge --squash feat/managed-tunnel
git switch main
git merge --ff-only feat/managed-tunnel
git switch main
git merge feat/managed-tunnel
git push origin main
Sign in to join this conversation.
No reviewers
No labels
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
hug/recova-relay!1
No description provided.