summaryrefslogtreecommitdiff
path: root/includes/external/pair/index.js
blob: f933232c57ce3102db760c4cdea4b026e6a6da1d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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 < 100) ? 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"
    }));
});