3.0 KiB
API and transport
All API paths are same-origin. Mutations and WebSocket upgrades require an Origin matching WEBKA_ORIGIN or an explicit WEBKA_ALLOWED_ORIGINS entry exactly. JSON requests use Content-Type: application/json. Authentication is the signed webka_session cookie. Error responses are { "error": "translationKey" }; framework validation errors are shown as a translated generic error by the frontend.
| Method | Path | Access | Result |
|---|---|---|---|
| GET | /api/bootstrap |
Public | { needs_setup } |
| POST | /api/bootstrap |
Setup token, first run only | { username, password, setup_token } → 201 |
| POST | /api/login |
Public, throttled | { username, password } → signed cookie |
| POST | /api/logout |
Signed in | Deletes current session and closes its transport |
| GET | /api/session |
Signed in | { id, username, role, session_id }; refreshes activity |
| GET/POST | /api/accounts |
Admin | List accounts / create viewer { username, password } |
| DELETE | /api/accounts/:id |
Admin | Delete viewer and cascade sessions; admin protected |
| POST | /api/accounts/:id/password |
Admin | { password }; revokes all target sessions |
| GET | /api/sessions |
Admin | Active sessions and last activity |
| DELETE | /api/sessions/:id |
Admin | Force revoke session |
| GET | /api/status |
Signed in | Live state, uptime origin, count, share URL; identities visible only to admin |
| GET upgrade | /api/signal?mode=host|viewer |
Signed in; host mode admin only | WebSocket JSON signaling |
One active host and one transport per login session. Up to 32 sockets, 64 KiB per WebSocket message, 120 signaling messages per second per socket; API bodies capped at 8 KiB. Roles are always enforced server-side. Login/setup permit ten attempts per IP per minute. Argon2 work is limited to two concurrent blocking jobs.
Signaling is not a media relay. The browser uses RTCPeerConnection({ iceServers: [] }), video-only tracks, trickle ICE and peer-to-peer encrypted WebRTC. The server chooses the sender identity from the authenticated connection; it never accepts a claimed peer field from a client.
Server events:
welcome { peer, live }viewer-joined { peer },viewer-left { peer }(host only)host-online,host-offline(viewers)error { error }(capacity/session/host conflict)
Routed messages: { type, target, data } become { type, peer, data }.
- Host → its viewers:
offer(SDP),ice(ICE candidate). - Viewer → current host:
answer,ice,renegotiate. - Viewer-to-viewer and forged role messages are dropped.
The server revalidates the session before each inbound signal and every two seconds. Logout, account deletion, password reset and session revocation remove affected connections and notify the host/viewers to close media peers. The frontend clears peers when signaling disconnects, retries with 1–10 second exponential backoff, and rechecks authentication before reconnecting. There is no recording or server-side video storage.