snakeia-server 1.1.3-6 → 1.1.4-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +1 -1
- package/README.md +37 -7
- package/config/default.json +2 -1
- package/docker-compose.yml +4 -0
- package/package.json +10 -10
- package/server.js +19 -8
- package/views/admin.html +9 -9
package/Dockerfile
CHANGED
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ A server for my [SnakeIA](https://github.com/Eliastik/snakeia) game, written in
|
|
|
8
8
|
|
|
9
9
|
## About this server
|
|
10
10
|
|
|
11
|
-
* Version 1.1.
|
|
11
|
+
* Version 1.1.4.1 (1/1/2025)
|
|
12
12
|
* Made in France by Eliastik - [eliastiksofts.com](http://eliastiksofts.com) - Contact : [eliastiksofts.com/contact](http://eliastiksofts.com/contact)
|
|
13
13
|
* License: GNU GPLv3 (see LICENCE.txt file)
|
|
14
14
|
|
|
@@ -74,9 +74,10 @@ You can create another configuration file in the **config** directory named **lo
|
|
|
74
74
|
````
|
|
75
75
|
{
|
|
76
76
|
"ServerConfig": {
|
|
77
|
-
"version": "1.1.
|
|
77
|
+
"version": "1.1.4.1", // The server version
|
|
78
78
|
"port": 3000, // The port where the server runs
|
|
79
|
-
"proxyMode": false, //
|
|
79
|
+
"proxyMode": false, // Sets this value to true if your server is behind a proxy - defaults to false
|
|
80
|
+
"numberOfProxies": 1, // Sets the number of reverse proxies in front of the server. Default to 1. See: https://expressjs.com/en/guide/behind-proxies.html / https://express-rate-limit.mintlify.app/guides/troubleshooting-proxy-issues
|
|
80
81
|
"enableMultithreading": true, // Enabling the use of different threads for the game engine, improves performance / requires a version of Nodejs that supports Worker Threads
|
|
81
82
|
"maxPlayers": 20, // The maximum number of players for each room
|
|
82
83
|
"maxRooms": 20, // The maximum number of room
|
|
@@ -119,6 +120,20 @@ You can create another configuration file in the **config** directory named **lo
|
|
|
119
120
|
|
|
120
121
|
## Changelog
|
|
121
122
|
|
|
123
|
+
* Version 1.1.4.1 (1/1/2024):
|
|
124
|
+
- Updated dependencies
|
|
125
|
+
|
|
126
|
+
* Version 1.1.4 (11/23/2024):
|
|
127
|
+
- Switched to csrf-csrf library instead of csurf (no longer maintained) for CSRF protection
|
|
128
|
+
- Added "numberOfProxies" parameter (default 1) to server configuration file
|
|
129
|
+
- Updated dependencies
|
|
130
|
+
|
|
131
|
+
* Version 1.1.3.8 (9/29/2024) :
|
|
132
|
+
- Updated dependencies
|
|
133
|
+
|
|
134
|
+
* Version 1.1.3.7 (9/19/2024) :
|
|
135
|
+
- Updated dependencies
|
|
136
|
+
|
|
122
137
|
* Version 1.1.3.6 (7/25/2024) :
|
|
123
138
|
- Updated dependencies
|
|
124
139
|
|
|
@@ -167,7 +182,7 @@ Un serveur pour mon jeu [SnakeIA](https://github.com/Eliastik/snakeia), écrit e
|
|
|
167
182
|
|
|
168
183
|
## À propos de ce serveur
|
|
169
184
|
|
|
170
|
-
* Version 1.1.
|
|
185
|
+
* Version 1.1.4.1 (1/1/2025)
|
|
171
186
|
* Made in France by Eliastik - [eliastiksofts.com](http://eliastiksofts.com) - Contact : [eliastiksofts.com/contact](http://eliastiksofts.com/contact)
|
|
172
187
|
* Licence : GNU GPLv3 (voir le fichier LICENCE.txt)
|
|
173
188
|
|
|
@@ -233,9 +248,10 @@ Vous pouvez créer un fichier de configuration **local.json** dans le dossier **
|
|
|
233
248
|
````
|
|
234
249
|
{
|
|
235
250
|
"ServerConfig": {
|
|
236
|
-
"version": "1.1.
|
|
251
|
+
"version": "1.1.4.1", // La version du serveur
|
|
237
252
|
"port": 3000, // Le port sur lequel lancer le server
|
|
238
253
|
"proxyMode": false, // Mettez à true si votre serveur est derrière un proxy - par défaut false
|
|
254
|
+
"numberOfProxies": 1, // Configure le nombre de proxies devant votre serveur. Par défaut 1. Voir : https://expressjs.com/en/guide/behind-proxies.html / https://express-rate-limit.mintlify.app/guides/troubleshooting-proxy-issues
|
|
239
255
|
"enableMultithreading": true, // Activer l'utilisation de threads différents pour le moteur de jeu, améliore les performances / nécessite une version de Nodejs qui supporte les Worker Threads
|
|
240
256
|
"maxPlayers": 20, // Le nombre maximal d'utilisateurs par salle
|
|
241
257
|
"maxRooms": 20, // Le nombre maximal de salles
|
|
@@ -278,6 +294,20 @@ Vous pouvez créer un fichier de configuration **local.json** dans le dossier **
|
|
|
278
294
|
|
|
279
295
|
## Journal des changements
|
|
280
296
|
|
|
297
|
+
* Version 1.1.4.1 (1/1/2025) :
|
|
298
|
+
- Mise à jour des dépendences
|
|
299
|
+
|
|
300
|
+
* Version 1.1.4 (23/11/2024) :
|
|
301
|
+
- Passage à la bibliothèque logicielle csrf-csrf au lieu de csurf (qui n'était plus maintenue) pour la protection CSRF
|
|
302
|
+
- Ajout du paramètre "numberOfProxies" (par défaut à 1) dans le fichier de configuration du serveur
|
|
303
|
+
- Mise à jour des dépendences
|
|
304
|
+
|
|
305
|
+
* Version 1.1.3.8 (29/09/2024) :
|
|
306
|
+
- Mise à jour des dépendences
|
|
307
|
+
|
|
308
|
+
* Version 1.1.3.7 (19/09/2024) :
|
|
309
|
+
- Mise à jour des dépendences
|
|
310
|
+
|
|
281
311
|
* Version 1.1.3.6 (25/07/2024) :
|
|
282
312
|
- Mise à jour des dépendences
|
|
283
313
|
|
|
@@ -329,7 +359,7 @@ Vous pouvez créer un fichier de configuration **local.json** dans le dossier **
|
|
|
329
359
|
|
|
330
360
|
## Déclaration de licence
|
|
331
361
|
|
|
332
|
-
Copyright (C) 2020-
|
|
362
|
+
Copyright (C) 2020-2025 Eliastik (eliastiksofts.com)
|
|
333
363
|
|
|
334
364
|
Ce programme est un logiciel libre ; vous pouvez le redistribuer ou le modifier suivant les termes de la GNU General Public License telle que publiée par la Free Software Foundation ; soit la version 3 de la licence, soit (à votre gré) toute version ultérieure.
|
|
335
365
|
|
|
@@ -339,7 +369,7 @@ Vous devez avoir reçu une copie de la GNU General Public License en même temps
|
|
|
339
369
|
|
|
340
370
|
----
|
|
341
371
|
|
|
342
|
-
Copyright (C) 2020-
|
|
372
|
+
Copyright (C) 2020-2025 Eliastik (eliastiksofts.com)
|
|
343
373
|
|
|
344
374
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
345
375
|
|
package/config/default.json
CHANGED
package/docker-compose.yml
CHANGED
|
@@ -3,6 +3,7 @@ version: "3.4"
|
|
|
3
3
|
services:
|
|
4
4
|
snakeia-server:
|
|
5
5
|
image: eliastik/snakeia-server:latest
|
|
6
|
+
container_name: snakeia-server
|
|
6
7
|
restart: unless-stopped
|
|
7
8
|
# uncomment to build the image
|
|
8
9
|
# build:
|
|
@@ -12,5 +13,8 @@ services:
|
|
|
12
13
|
NODE_ENV: production
|
|
13
14
|
volumes:
|
|
14
15
|
- ./config/default.json:/home/snakeia-server/server/config/default.json
|
|
16
|
+
# - ./config/local.json:/home/snakeia-server/server/config/local.json
|
|
17
|
+
- ./error.log:/home/snakeia-server/server/logs/error.log
|
|
18
|
+
- ./server.log:/home/snakeia-server/server/logs/server.log
|
|
15
19
|
ports:
|
|
16
20
|
- "3000:3000"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "snakeia-server",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4-1",
|
|
4
4
|
"description": "Server for multiplaying in SnakeIA (https://github.com/Eliastik/snakeia)",
|
|
5
5
|
"main": "server.js",
|
|
6
6
|
"scripts": {
|
|
@@ -18,21 +18,21 @@
|
|
|
18
18
|
},
|
|
19
19
|
"homepage": "https://github.com/Eliastik/snakeia-server#readme",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"body-parser": "^1.20.
|
|
21
|
+
"body-parser": "^1.20.3",
|
|
22
22
|
"config": "^3.3.12",
|
|
23
|
-
"cookie-parser": "^1.4.
|
|
24
|
-
"
|
|
25
|
-
"ejs": "^3.1.
|
|
26
|
-
"express": "^4.
|
|
27
|
-
"express-rate-limit": "^7.
|
|
23
|
+
"cookie-parser": "^1.4.7",
|
|
24
|
+
"csrf-csrf": "^3.1.0",
|
|
25
|
+
"ejs": "^3.1.10",
|
|
26
|
+
"express": "^4.21.2",
|
|
27
|
+
"express-rate-limit": "^7.5.0",
|
|
28
28
|
"html-entities": "^2.5.2",
|
|
29
29
|
"i18n": "^0.15.1",
|
|
30
30
|
"jsonwebtoken": "^9.0.2",
|
|
31
31
|
"node-fetch": "^3.3.2",
|
|
32
32
|
"seedrandom": "^3.0.5",
|
|
33
|
-
"snakeia": "
|
|
34
|
-
"socket.io": "^4.
|
|
33
|
+
"snakeia": "^2.2.0-0",
|
|
34
|
+
"socket.io": "^4.8.1",
|
|
35
35
|
"socket.io-cookie-parser": "^1.0.0",
|
|
36
|
-
"winston": "^3.
|
|
36
|
+
"winston": "^3.17.0"
|
|
37
37
|
}
|
|
38
38
|
}
|
package/server.js
CHANGED
|
@@ -36,7 +36,7 @@ const ioCookieParser = require("socket.io-cookie-parser");
|
|
|
36
36
|
const i18n = require("i18n");
|
|
37
37
|
const rateLimit = require("express-rate-limit");
|
|
38
38
|
const winston = require("winston");
|
|
39
|
-
const
|
|
39
|
+
const { doubleCsrf } = require("csrf-csrf");
|
|
40
40
|
const bodyParser = require("body-parser");
|
|
41
41
|
const node_config = require("config");
|
|
42
42
|
|
|
@@ -55,6 +55,8 @@ config.port = process.env.PORT || config.port;
|
|
|
55
55
|
const jsonWebTokenSecretKey = config.jsonWebTokenSecretKey && config.jsonWebTokenSecretKey.trim() != "" ? config.jsonWebTokenSecretKey : generateRandomJsonWebTokenSecretKey();
|
|
56
56
|
const jsonWebTokenSecretKeyAdmin = config.jsonWebTokenSecretKeyAdmin && config.jsonWebTokenSecretKeyAdmin.trim() != "" ? config.jsonWebTokenSecretKeyAdmin : generateRandomJsonWebTokenSecretKey(jsonWebTokenSecretKey);
|
|
57
57
|
|
|
58
|
+
const productionMode = process.env.NODE_ENV === "production";
|
|
59
|
+
|
|
58
60
|
// Update config to file
|
|
59
61
|
function updateConfigToFile() {
|
|
60
62
|
fs.writeFileSync(configFile, JSON.stringify({ "ServerConfig": config }, null, 4), "UTF-8");
|
|
@@ -73,14 +75,14 @@ const logger = winston.createLogger({
|
|
|
73
75
|
exceptionHandlers: config.enableLoggingFile ? [new winston.transports.File({ filename: config.errorLogFile })] : []
|
|
74
76
|
});
|
|
75
77
|
|
|
76
|
-
if(
|
|
78
|
+
if(!productionMode) {
|
|
77
79
|
logger.add(new winston.transports.Console({
|
|
78
80
|
format: winston.format.colorize()
|
|
79
81
|
}));
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
if(config.proxyMode) {
|
|
83
|
-
app.enable("trust proxy");
|
|
85
|
+
app.enable("trust proxy", config.numberOfProxies);
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
// Internationalization
|
|
@@ -1165,9 +1167,18 @@ function verifyFormAuthenticationAdmin(body) {
|
|
|
1165
1167
|
});
|
|
1166
1168
|
}
|
|
1167
1169
|
|
|
1168
|
-
const
|
|
1170
|
+
const csrfSecret = generateRandomJsonWebTokenSecretKey(jsonWebTokenSecretKeyAdmin);
|
|
1171
|
+
const { doubleCsrfProtection, generateToken } = doubleCsrf({
|
|
1172
|
+
getSecret: () => csrfSecret,
|
|
1173
|
+
cookieName: productionMode ? "__Host-snakeia-server.x-csrf-token" : "snakeia-server.x-csrf-token",
|
|
1174
|
+
cookieOptions: {
|
|
1175
|
+
sameSite: productionMode ? "strict" : "lax",
|
|
1176
|
+
path: "/",
|
|
1177
|
+
secure: productionMode
|
|
1178
|
+
}
|
|
1179
|
+
});
|
|
1169
1180
|
|
|
1170
|
-
app.get("/admin",
|
|
1181
|
+
app.get("/admin", doubleCsrfProtection, function(req, res) {
|
|
1171
1182
|
if(req.cookies) {
|
|
1172
1183
|
jwt.verify(req.cookies.tokenAdmin, jsonWebTokenSecretKeyAdmin, function(err, data) {
|
|
1173
1184
|
if(invalidatedAdminTokens.includes(req.cookies.tokenAdmin)) err = true;
|
|
@@ -1195,7 +1206,7 @@ app.get("/admin", csrfProtection, function(req, res) {
|
|
|
1195
1206
|
games: games,
|
|
1196
1207
|
io: io,
|
|
1197
1208
|
config: config,
|
|
1198
|
-
csrfToken: req
|
|
1209
|
+
csrfToken: generateToken(req, res, true),
|
|
1199
1210
|
serverLog: logFile,
|
|
1200
1211
|
errorLog: errorLogFile,
|
|
1201
1212
|
getIPSocketIO: getIPSocketIO
|
|
@@ -1288,14 +1299,14 @@ function adminAction(req, res, action) {
|
|
|
1288
1299
|
|
|
1289
1300
|
const jsonParser = bodyParser.json();
|
|
1290
1301
|
|
|
1291
|
-
app.post("/admin/:action", jsonParser,
|
|
1302
|
+
app.post("/admin/:action", jsonParser, doubleCsrfProtection, function(req, res) {
|
|
1292
1303
|
adminAction(req, res, req.params.action);
|
|
1293
1304
|
});
|
|
1294
1305
|
|
|
1295
1306
|
app.use(function (err, req, res, next) {
|
|
1296
1307
|
if(err.code !== "EBADCSRFTOKEN") return next(err);
|
|
1297
1308
|
res.status(403);
|
|
1298
|
-
res.send("Error");
|
|
1309
|
+
res.send("Error: invalid CSRF token");
|
|
1299
1310
|
});
|
|
1300
1311
|
|
|
1301
1312
|
const adminRateLimiter = rateLimit({
|
package/views/admin.html
CHANGED
|
@@ -251,13 +251,13 @@
|
|
|
251
251
|
</div>
|
|
252
252
|
<% if(authent && games) { %>
|
|
253
253
|
<script type="text/javascript">
|
|
254
|
-
|
|
254
|
+
const token = document.querySelector("meta[name='csrf-token']").getAttribute("content");
|
|
255
255
|
|
|
256
256
|
function requestAction(action, data, element) {
|
|
257
257
|
fetch("/admin/" + action, {
|
|
258
258
|
credentials: "same-origin",
|
|
259
259
|
headers: {
|
|
260
|
-
"
|
|
260
|
+
"x-csrf-token": token,
|
|
261
261
|
"Content-Type": "application/json",
|
|
262
262
|
},
|
|
263
263
|
method: "POST",
|
|
@@ -273,19 +273,19 @@
|
|
|
273
273
|
});
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
-
|
|
276
|
+
const elements = document.querySelectorAll("[data-action]");
|
|
277
277
|
|
|
278
278
|
elements.forEach(function(element) {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
279
|
+
const action = element.dataset.action;
|
|
280
|
+
const form = element.dataset.form;
|
|
281
|
+
const data = {};
|
|
282
|
+
const confirmAction = element.dataset.confirmAction;
|
|
283
283
|
|
|
284
284
|
if(form) {
|
|
285
285
|
form.split("&").forEach(function(element) {
|
|
286
286
|
if(element) {
|
|
287
|
-
|
|
288
|
-
|
|
287
|
+
const key = element.split("=")[0];
|
|
288
|
+
const value = element.split("=")[1];
|
|
289
289
|
data[key] = value;
|
|
290
290
|
}
|
|
291
291
|
});
|