diff --git a/README.md b/README.md index 8b7c541..573d871 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Beep backend handling WebRTC signaling. +**To run this service securely means to run it behind traefik forwarding auth to `backend-auth`** + ## Quickstart Docker: @@ -32,7 +34,7 @@ Unless otherwise noted, bodies and responses are with ```Content-Type: applicati ### Subscribe to SSE ``` -GET /subscribe/:user/device/:device +GET /subscribe ``` Subscribe a user's device to the signaling service. Recommended usage: @@ -45,17 +47,22 @@ es.onmessage = (e) => { }; ``` -#### URL Params +#### Required headers -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| user | String | User's ID. | ✓ | -| device | String | Device's ID. Must be unique to the device. I suggest something based on MAC address. | ✓ | +| Name | Description | +| ---- | ----------- | +| X-User-Claim | Stringified user claim, populated by `backend-auth` called by `traefik` | #### Success Response (200 OK) An [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) stream. +#### Errors + +| Code | Description | +| ---- | ----------- | +| 401| Invalid user claims header. | + --- ### Get a user's devices diff --git a/index.js b/index.js index 1a63e03..123d069 100644 --- a/index.js +++ b/index.js @@ -14,31 +14,41 @@ app.use((req, res, next) => { let connections = {}; -app.get('/subscribe/:user/device/:device', (req, res) => { - if (!connections[req.params.user]) { - connections[req.params.user] = {}; +app.get('/subscribe', (req, res) => { + if (!req.get("X-User-Claim")) { + res.sendStatus(401); + return; } - console.log(`Someone subscribed to ${req.params.user}, ${req.params.device}`); + try { + const user_claim = JSON.parse(req.get("X-User-Claim")); + if (!connections[user_claim.userid]) { + connections[user_claim.userid] = {}; + } - connections[req.params.user][req.params.device] = res; - res.writeHead(200, { - 'Content-Type': 'text/event-stream', - 'Cache-Control': 'no-cache' - }); + console.log(`Someone subscribed to ${user_claim.userid}, ${user_claim.clientid}`); - // So the connection doesn't timeout and die - let timeoutID = 0; - const refresh = () => { - res.write(':\n\n'); - timeoutID = setTimeout(refresh, 25000); - }; - refresh(); + connections[user_claim.userid][user_claim.clientid] = res; + res.writeHead(200, { + 'Content-Type': 'text/event-stream', + 'Cache-Control': 'no-cache' + }); - res.on('close', () => { - connections[req.params.user][req.params.device] = null; - clearTimeout(timeoutID); - }); + // So the connection doesn't timeout and die + let timeoutID = 0; + const refresh = () => { + res.write(':\n\n'); + timeoutID = setTimeout(refresh, 25000); + }; + refresh(); + + res.on('close', () => { + connections[user_claim.userid][user_claim.clientid] = null; + clearTimeout(timeoutID); + }); + } catch(e) { + res.sendStatus(401) + } }); app.get('/user/:user/devices', (req, res) => {