-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwebSocketHandler.js
131 lines (111 loc) · 4.58 KB
/
webSocketHandler.js
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
const { decodeUserID } = require('./utils');
const tempAuth = require('./actions/tempAuth/index');
const { handleAction } = require('./actionHandler');
const logUserIP = require('./serverActions/logUserIP/index');
const checkIPInfo = require('./serverActions/checkIPInfo/index');
const url = require('url');
const { checkMessageRateLimit } = require('./messageLimitChecker');
let connectedUsers = [];
function setupWebSocket(wss) {
wss.on('connection', async (ws, req) => {
try {
const clientIp = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
let ipv4 = clientIp.split(":")[0];
const banned = await checkIPInfo(ipv4);
if (banned) {
console.log(`Banned IP ${clientIp} attempted to connect`);
ws.close(4001, 'Banned IP');
return;
}
const parameters = url.parse(req.url, true);
const token = parameters.query.token;
let userData = decodeUserID(token);
if (userData.auth) {
ws.UserID = userData.UserID;
} else {
let guestInfo = await tempAuth(ws, { "ipv4": ipv4 })
if (guestInfo.auth && guestInfo.token) {
userData = decodeUserID(guestInfo.token);
if (userData.auth) {
ws.UserID = userData.UserID;
ws.send(JSON.stringify({
type: 'guest_auth',
token: guestInfo.token
}));
} else {
// This means there was an error while generating the guest token. Handle this error as required.
ws.close(1008, 'Error generating guest token');
return;
}
} else {
// This means there was an error while generating the guest account. Handle this error as required.
ws.close(1008, 'Error generating guest account');
return;
}
}
try {
logUserIP(ws.UserID, ipv4);
} catch (error) {
console.log(error);
}
if (connectedUsers.every((obj) => obj.UserID !== ws.UserID)) {
console.log(`Client UserID ${ws.UserID} connected`);
connectedUsers.push({
UserID: ws.UserID,
connectedAt: Date.now(),
lastActive: Date.now(),
userWs: ws
})
} else {
console.log(`Client UserID ${ws.UserID} reconnected`);
}
ws.on('message', async (message) => {
try {
let user = connectedUsers.find(u => u.UserID === ws.UserID);
if (user) user.lastActive = Date.now()
if (checkMessageRateLimit(user.UserID)) {
ws.close(1008, "Server message rate limit")
return
}
const parsedMessage = JSON.parse(message);
const action = parsedMessage.action;
const MESSAGE_ID = parsedMessage.MESSAGE_ID;
const params = { ...parsedMessage }
delete params.action;
delete params.MESSAGE_ID;
handleAction(ws, MESSAGE_ID, action, params)
} catch (error) {
console.log(error)
}
});
ws.on('close', () => {
console.log(`Client ${ws.UserID} disconnected`);
connectedUsers = connectedUsers.filter((obj) => obj.UserID !== ws.UserID)
});
} catch (error) {
console.log(error)
}
});
wss.on('connection', function connection(ws) {
ws.lastAlive = Date.now();
ws.on('pong', function heartbeat() {
ws.lastAlive = Date.now();
});
// Send a ping to the client every 30 seconds
const interval = setInterval(function ping() {
wss.clients.forEach(function each(client) {
if (client.lastAlive + (30 * 60 * 1000) < Date.now()) {
console.log("terminating ", client.UserID);
return client.terminate();
}
client.ping();
});
}, 30000);
ws.on('close', function clear() {
clearInterval(interval);
});
});
}
module.exports = {
setupWebSocket
};