summaryrefslogtreecommitdiff
path: root/includes/external/pair/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'includes/external/pair/index.js')
-rw-r--r--includes/external/pair/index.js117
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