Skip to content

fix: authenticate WebSockets with subprotocols - #370

Draft
Adamskiee wants to merge 1 commit into
developfrom
bugfix/225-websocket-auth
Draft

fix: authenticate WebSockets with subprotocols#370
Adamskiee wants to merge 1 commit into
developfrom
bugfix/225-websocket-auth

Conversation

@Adamskiee

Copy link
Copy Markdown
Collaborator

Summary

  • move JWT authentication for signaling and GPS WebSockets from query parameters to Sec-WebSocket-Protocol
  • require clients to offer ["sapot.jwt", "<access-token>"] and have the server select sapot.jwt
  • reject missing, malformed, expired, ambiguous, and query-string credentials with close code 1008
  • enforce secure WebSocket origins outside local development in mobile and admin clients
  • remove the obsolete GET /ws/ HTML test client and regenerate OpenAPI and Postman artifacts
  • update security, WebSocket, GPS, deployment, mobile architecture, audit, and legacy documentation

Why

WebSocket JWTs were included in request URLs, which can expose credentials through browser history, proxies, access logs, and observability systems. The server and every supported client must adopt the new handshake together because query-token compatibility is intentionally removed.

Closes #225.

Impact

This is a coordinated breaking migration for the server, admin frontend, and mobile app. Updated clients send token-free URLs and authenticate through WebSocket subprotocol negotiation. Preview and production configurations reject plaintext ws:// origins, while explicit local development may still use them.

Validation

  • focused server WebSocket and GPS regression suite: 43 passed
  • mobile pnpm run testAll: 132 suites and 1,113 tests passed; typecheck, lint, and Expo Doctor passed
  • admin production build passed
  • changed admin WebSocket manager ESLint passed
  • OpenAPI and database documentation drift checks passed
  • Postman generator tests: 15 runs and 77 assertions passed
  • full Docker/Postman suite through Nginx passed
  • live WSS handshake selected sapot.jwt and returned pong
  • Nginx access log contained GET /ws/ with no JWT in the path
  • git diff --check passed

Remaining manual checks

  • confirm the admin browser Network entry uses a configurable token-free wss://.../ws/ URL and negotiates sapot.jwt
  • test two updated mobile devices in server/auto mode for presence, relayed messaging, call signaling, reconnect, and GPS streaming

Existing baseline limitations

Full admin lint and TypeScript checks still report unrelated pre-existing repository errors. The modified admin file passes ESLint and the production build succeeds. The full server pytest suite has existing rate-limit, database, and test-isolation failures; all focused issue #225 regressions pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant