-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
128 lines (106 loc) · 4.27 KB
/
index.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
/*
Index.js - Runs all modules and starts backend
*/
"use strict";
// Title of process in 'top' and 'ps' commands
process.title = 'elf-backend';
// Set global values
global.logger = require("./custom_modules/logger.daemon.js");
global.apiResponses = require("./custom_modules/apiResponses.daemon.js");
global.mongoConnect = require("./custom_modules/mongoConnect.daemon.js");
// Include required files + define variables
var config = require("./custom_modules/config/index.config.json"),
http = require("http"),
webSocketServer = require("ws").Server,
logger = global.logger,
apiResponses = global.apiResponses,
apis = [];
// Require API modules
for (var key in config.requireModules) {
if (config.requireModules.hasOwnProperty(key)) {
apis[key] = require("./custom_modules/" + config.requireModules[key]);
logger.log("Required API module '" + key + "' with path \"" + config.requireModules[key] + "\".", 6, false, config.moduleName, __line, __file);
}
}
// Configure server
logger.log("Starting API server...", 4, false, config.moduleName, __line, __file);
// Start HTTP server
var server = http.createServer(()=>{});
// Set up error handling
server.on("error", (e) => {
logger.log("There was an error starting the server on port " + config.usePort + ": " + e + ".", 1, true, config.moduleName, __line, __file);
process.exit(1);
});
server.listen(config.usePort, () => {
logger.log("API server started listening on port " + config.usePort + ".", 4, false, config.moduleName, __line, __file);
});
// Start WebSocket server
var wsServer = new webSocketServer({server});
wsServer.on('connection', (connection) => {
setTimeout(() => {
var firstMessageSent = false;
// limit messages per second
var messagesInLastSecond = 0,
freqBlock = false,
freqBlockTimeout;
// Reset every second
setInterval(() => {
messagesInLastSecond = 0;
}, 1000);
// accept message
connection.on('message', (message) => {
if(++messagesInLastSecond > config.freqBlock.messagesAllowedPerSecond) {
freqBlock = true;
clearTimeout(freqBlockTimeout);
freqBlockTimeout = setTimeout(() => {
freqBlock = false;
}, config.freqBlock.blockTime);
logger.log("Possibly malacious requests blocked for being too frequent from " + connection.remoteAddress + ".", 4, true, config.moduleName, __line, __file);
}
if(connection.isSpecialConnection) return; // This is a special connection, don't respond to the message
if(!freqBlock) {
if(!firstMessageSent && config.specialConnections[message]) {
var specReg = config.specialConnections[message];
// This request is a special request. Hand it off to be used by the module:
apis[specReg[0]][specReg[1]](connection);
// Respond to the message
connection.send(apiResponses.strings.success);
// Set a flag
connection.isSpecialConnection = true;
// End this function
return;
}
firstMessageSent = true;
var msgObject;
try {
msgObject = JSON.parse(message);
} catch(e) {
connection.send(apiResponses.strings.errors.malformedRequest);
return;
}
console.log(message);
if(msgObject.id) {
if(msgObject.action) {
if(config.apiRoutes[msgObject.action]) {
// This is the handoff - where the message is send to the registered (via config file) module with these three params.
apis[config.apiRoutes[msgObject.action][0]][config.apiRoutes[msgObject.action][1]](msgObject, connection);
} else {
connection.send(apiResponses.concatObj(apiResponses.JSON.errors.invalidAction, {"id": msgObject.id}, true));
return;
}
} else {
connection.send(apiResponses.concatObj(apiResponses.JSON.errors.malformedRequest, {"id": msgObject.id}, true));
return;
}
} else {
connection.send(apiResponses.strings.errors.missingParameters);
}
} else {
connection.send(apiResponses.strings.errors.tooManyRequests);
return;
}
});
});
}, 2000);
// Log successful start
logger.log("Elf started successfully.", 3, false, config.moduleName, __line, __file);