snakeia-server 1.1.3-7 → 1.1.4-2
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 +12 -12
- 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.2 (6/18/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.2", // 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.2 (6/18/2025):
|
|
124
|
+
- Updated dependencies
|
|
125
|
+
|
|
126
|
+
* Version 1.1.4.1 (1/1/2025):
|
|
127
|
+
- Updated dependencies
|
|
128
|
+
|
|
129
|
+
* Version 1.1.4 (11/23/2024):
|
|
130
|
+
- Switched to csrf-csrf library instead of csurf (no longer maintained) for CSRF protection
|
|
131
|
+
- Added "numberOfProxies" parameter (default 1) to server configuration file
|
|
132
|
+
- Updated dependencies
|
|
133
|
+
|
|
134
|
+
* Version 1.1.3.8 (9/29/2024) :
|
|
135
|
+
- Updated dependencies
|
|
136
|
+
|
|
122
137
|
* Version 1.1.3.7 (9/19/2024) :
|
|
123
138
|
- Updated dependencies
|
|
124
139
|
|
|
@@ -170,7 +185,7 @@ Un serveur pour mon jeu [SnakeIA](https://github.com/Eliastik/snakeia), écrit e
|
|
|
170
185
|
|
|
171
186
|
## À propos de ce serveur
|
|
172
187
|
|
|
173
|
-
* Version 1.1.
|
|
188
|
+
* Version 1.1.4.2 (18/06/2025)
|
|
174
189
|
* Made in France by Eliastik - [eliastiksofts.com](http://eliastiksofts.com) - Contact : [eliastiksofts.com/contact](http://eliastiksofts.com/contact)
|
|
175
190
|
* Licence : GNU GPLv3 (voir le fichier LICENCE.txt)
|
|
176
191
|
|
|
@@ -236,9 +251,10 @@ Vous pouvez créer un fichier de configuration **local.json** dans le dossier **
|
|
|
236
251
|
````
|
|
237
252
|
{
|
|
238
253
|
"ServerConfig": {
|
|
239
|
-
"version": "1.1.
|
|
254
|
+
"version": "1.1.4.2", // La version du serveur
|
|
240
255
|
"port": 3000, // Le port sur lequel lancer le server
|
|
241
256
|
"proxyMode": false, // Mettez à true si votre serveur est derrière un proxy - par défaut false
|
|
257
|
+
"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
|
|
242
258
|
"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
|
|
243
259
|
"maxPlayers": 20, // Le nombre maximal d'utilisateurs par salle
|
|
244
260
|
"maxRooms": 20, // Le nombre maximal de salles
|
|
@@ -281,6 +297,20 @@ Vous pouvez créer un fichier de configuration **local.json** dans le dossier **
|
|
|
281
297
|
|
|
282
298
|
## Journal des changements
|
|
283
299
|
|
|
300
|
+
* Version 1.1.4.2 (18/06/2025) :
|
|
301
|
+
- Mise à jour des dépendences
|
|
302
|
+
|
|
303
|
+
* Version 1.1.4.1 (1/1/2025) :
|
|
304
|
+
- Mise à jour des dépendences
|
|
305
|
+
|
|
306
|
+
* Version 1.1.4 (23/11/2024) :
|
|
307
|
+
- Passage à la bibliothèque logicielle csrf-csrf au lieu de csurf (qui n'était plus maintenue) pour la protection CSRF
|
|
308
|
+
- Ajout du paramètre "numberOfProxies" (par défaut à 1) dans le fichier de configuration du serveur
|
|
309
|
+
- Mise à jour des dépendences
|
|
310
|
+
|
|
311
|
+
* Version 1.1.3.8 (29/09/2024) :
|
|
312
|
+
- Mise à jour des dépendences
|
|
313
|
+
|
|
284
314
|
* Version 1.1.3.7 (19/09/2024) :
|
|
285
315
|
- Mise à jour des dépendences
|
|
286
316
|
|
|
@@ -335,7 +365,7 @@ Vous pouvez créer un fichier de configuration **local.json** dans le dossier **
|
|
|
335
365
|
|
|
336
366
|
## Déclaration de licence
|
|
337
367
|
|
|
338
|
-
Copyright (C) 2020-
|
|
368
|
+
Copyright (C) 2020-2025 Eliastik (eliastiksofts.com)
|
|
339
369
|
|
|
340
370
|
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.
|
|
341
371
|
|
|
@@ -345,7 +375,7 @@ Vous devez avoir reçu une copie de la GNU General Public License en même temps
|
|
|
345
375
|
|
|
346
376
|
----
|
|
347
377
|
|
|
348
|
-
Copyright (C) 2020-
|
|
378
|
+
Copyright (C) 2020-2025 Eliastik (eliastiksofts.com)
|
|
349
379
|
|
|
350
380
|
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.
|
|
351
381
|
|
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-2",
|
|
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": "^
|
|
22
|
-
"config": "^
|
|
23
|
-
"cookie-parser": "^1.4.
|
|
24
|
-
"
|
|
25
|
-
"ejs": "^3.1.
|
|
26
|
-
"express": "^
|
|
27
|
-
"express-rate-limit": "^7.
|
|
28
|
-
"html-entities": "^2.
|
|
21
|
+
"body-parser": "^2.2.0",
|
|
22
|
+
"config": "^4.0.0",
|
|
23
|
+
"cookie-parser": "^1.4.7",
|
|
24
|
+
"csrf-csrf": "^4.0.3",
|
|
25
|
+
"ejs": "^3.1.10",
|
|
26
|
+
"express": "^5.1.0",
|
|
27
|
+
"express-rate-limit": "^7.5.0",
|
|
28
|
+
"html-entities": "^2.6.0",
|
|
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
|
});
|