diff options
Diffstat (limited to 'includes/external/pair/index.js')
-rw-r--r-- | includes/external/pair/index.js | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/includes/external/pair/index.js b/includes/external/pair/index.js new file mode 100644 index 0000000..af7c3e4 --- /dev/null +++ b/includes/external/pair/index.js @@ -0,0 +1,117 @@ +const { WebSocketServer } = require('ws'); +const crypto = require('crypto'); +const version = 1; + +const wss = new WebSocketServer({ port: 12378 }); +// wss://ponies.equestria.horse/_PairingServices-WebSocket-EntryPoint/socket + +let clients = {}; + +function generateCode() { + return crypto.randomBytes(32).toString("base64").replace(/[\/=+]/gm, "").substring(0, 5).toUpperCase(); +} + +wss.on('connection', (ws, req) => { + ws.code = generateCode(); + ws.ipAddress = req.headers['x-forwarded-for'] ? req.headers['x-forwarded-for'].split(',')[0].trim() : req.socket.remoteAddress; + + ws.on('error', (e) => { + console.error(e); + ws.close(); + }); + + ws.on('close', () => { + if (clients[ws.code]) { + delete clients[ws.code]; + } + }); + + ws.on('message', function message(raw) { + try { + let data = JSON.parse(raw.toString()); + + switch (data.type) { + case "fetch": + if (clients[data.code ?? ""] && clients[data.code ?? ""].socket) { + clients[data.code ?? ""].socket.send(JSON.stringify({ + type: "preflight", + identity: { + name: data.identity ? (data.identity.name ?? "<Unknown name>") : "<Unknown name>", + platform: data.identity ? (data.identity.platform ?? "<Unknown device>") : "<Unknown device>" + } + })); + ws.send(JSON.stringify({ + type: "device", + identity: { + name: clients[data.code ?? ""].name, + address: clients[data.code ?? ""].socket.ipAddress + } + })) + } else { + ws.send(JSON.stringify({ + type: "invalid" + })); + } + break; + + case "confirm": + if (clients[data.code ?? ""] && clients[data.code ?? ""].socket && data.token && ws.token) { + clients[data.code ?? ""].socket.send(JSON.stringify({ + type: "confirm", + token: data.token + })); + + delete clients[data.code ?? ""]; + } else { + ws.send(JSON.stringify({ + type: "invalid" + })); + } + break; + + case "reject": + if (clients[data.code ?? ""] && clients[data.code ?? ""].socket && ws.token) { + clients[data.code ?? ""].socket.send(JSON.stringify({ + type: "reject", + token: null + })); + + delete clients[data.code ?? ""]; + } else { + ws.send(JSON.stringify({ + type: "invalid" + })); + } + break; + + case "init": + if (data.token) { + ws.token = data.token; + } else { + clients[ws.code] = { + socket: ws, + name: (typeof data.name === "string" && data.name.length > 2 && data.name.length < 50) ? data.name : "<Unknown client>" + } + + ws.send(JSON.stringify({ + type: "waiting", + code: ws.code + })) + } + + break; + + default: + ws.close(); + } + } catch (e) { + console.error(e); + ws.close(); + } + }); + + ws.send(JSON.stringify({ + version, + type: "init" + })); +});
\ No newline at end of file |