mirror of
https://github.com/AlecM33/Werewolf.git
synced 2025-12-26 07:47:50 +01:00
rate limit socket connections
This commit is contained in:
@@ -34,9 +34,15 @@ const game = () => {
|
||||
UserUtility.validateAnonUserSignature(res.content)
|
||||
);
|
||||
});
|
||||
socket.on("connect_error", (err) => {
|
||||
toast('Connection error: ' + err, 'error', true, false);
|
||||
});
|
||||
socket.on('disconnect', () => {
|
||||
toast('Disconnected. Attempting reconnect...', 'error', true, false);
|
||||
});
|
||||
socket.emit('hey');
|
||||
socket.emit('hey');
|
||||
socket.emit('hey');
|
||||
setClientSocketHandlers(stateBucket, gameStateRenderer, socket, timerWorker, gameTimerManager);
|
||||
}).catch((res) => {
|
||||
toast(res.content, 'error', true);
|
||||
|
||||
@@ -68,6 +68,13 @@ img[src='../images/logo_cropped.gif'] {
|
||||
margin: 3em 0 1em 0;
|
||||
}
|
||||
|
||||
#logo-container {
|
||||
max-width: 400px;
|
||||
width: 63vw;
|
||||
min-width: 250px;
|
||||
margin: 3em 0 1em 0;
|
||||
}
|
||||
|
||||
form > div {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
<div id="mobile-menu-background-overlay"></div>
|
||||
<div id="navbar"></div>
|
||||
<div id="home-page-top-section">
|
||||
<img src="../images/logo_cropped.gif"/>
|
||||
<!-- <div id="logo-container">-->
|
||||
<img src="../images/logo_cropped.gif" alt="logo"/>
|
||||
<!-- </div>-->
|
||||
<h3>A tool to run werewolf when not in-person, or in any setting without a deck of cards.</h3>
|
||||
<a href="/create">
|
||||
<button id="home-create-button" class="app-button">Create A Game</button>
|
||||
|
||||
5
package-lock.json
generated
5
package-lock.json
generated
@@ -4227,6 +4227,11 @@
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
|
||||
},
|
||||
"rate-limiter-flexible": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/rate-limiter-flexible/-/rate-limiter-flexible-2.3.6.tgz",
|
||||
"integrity": "sha512-8DVFOe89rreyut/vzwBI7vgXJynyYoYnH5XogtAKs0F/neAbCTTglXxSJ7fZeZamcFXZDvMidCBvps4KM+1srw=="
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"jasmine": "^3.5.0",
|
||||
"karma-jasmine": "^4.0.1",
|
||||
"open": "^7.0.3",
|
||||
"rate-limiter-flexible": "^2.3.6",
|
||||
"socket.io": "^4.4.0",
|
||||
"socket.io-client": "^4.4.0",
|
||||
"webpack": "^5.65.0",
|
||||
|
||||
@@ -22,24 +22,23 @@ const main = ServerBootstrapper.createServerWithCorrectHTTPProtocol(app, args.us
|
||||
|
||||
app.set('port', args.port);
|
||||
|
||||
const inGameSocketServer = ServerBootstrapper.createSocketServer(main, app, args.port);
|
||||
const inGameSocketServer = ServerBootstrapper.createSocketServer(main, app, args.port, logger);
|
||||
const gameNamespace = ServerBootstrapper.createGameSocketNamespace(inGameSocketServer, logger);
|
||||
|
||||
let gameManager;
|
||||
|
||||
/* Instantiate the singleton game manager */
|
||||
if (process.env.NODE_ENV.trim() === 'development') {
|
||||
gameManager = new GameManager(logger, globals.ENVIRONMENT.LOCAL).getInstance();
|
||||
gameManager = new GameManager(logger, globals.ENVIRONMENT.LOCAL, gameNamespace).getInstance();
|
||||
} else {
|
||||
gameManager = new GameManager(logger, globals.ENVIRONMENT.PRODUCTION).getInstance();
|
||||
gameManager = new GameManager(logger, globals.ENVIRONMENT.PRODUCTION, gameNamespace).getInstance();
|
||||
}
|
||||
|
||||
gameManager.namespace = inGameSocketServer;
|
||||
|
||||
inGameSocketServer.on('connection', function (socket) {
|
||||
gameNamespace.on('connection', function (socket) {
|
||||
socket.on('disconnecting', (reason) => {
|
||||
logger.trace('client socket disconnecting because: ' + reason);
|
||||
});
|
||||
gameManager.addGameSocketHandlers(inGameSocketServer, socket);
|
||||
gameManager.addGameSocketHandlers(gameNamespace, socket);
|
||||
});
|
||||
|
||||
/* api endpoints */
|
||||
|
||||
@@ -6,11 +6,11 @@ const GameStateCurator = require('./GameStateCurator');
|
||||
const UsernameGenerator = require('./UsernameGenerator');
|
||||
|
||||
class GameManager {
|
||||
constructor (logger, environment) {
|
||||
constructor (logger, environment, namespace) {
|
||||
this.logger = logger;
|
||||
this.environment = environment;
|
||||
this.activeGameRunner = new ActiveGameRunner(logger).getInstance();
|
||||
this.namespace = null;
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
addGameSocketHandlers = (namespace, socket) => {
|
||||
@@ -477,10 +477,10 @@ function getGameSize (cards) {
|
||||
}
|
||||
|
||||
class Singleton {
|
||||
constructor (logger, environment) {
|
||||
constructor (logger, environment, namespace) {
|
||||
if (!Singleton.instance) {
|
||||
logger.info('CREATING SINGLETON GAME MANAGER');
|
||||
Singleton.instance = new GameManager(logger, environment);
|
||||
Singleton.instance = new GameManager(logger, environment, namespace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ const https = require('https');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const crypto = require('crypto');
|
||||
const { RateLimiterMemory } = require('rate-limiter-flexible');
|
||||
|
||||
const ServerBootstrapper = {
|
||||
processCLIArgs: () => {
|
||||
@@ -79,7 +80,7 @@ const ServerBootstrapper = {
|
||||
return main;
|
||||
},
|
||||
|
||||
createSocketServer: (main, app, port) => {
|
||||
createSocketServer: (main, app, port, logger) => {
|
||||
let io;
|
||||
if (process.env.NODE_ENV.trim() === 'development') {
|
||||
io = require('socket.io')(main, {
|
||||
@@ -91,8 +92,34 @@ const ServerBootstrapper = {
|
||||
});
|
||||
}
|
||||
|
||||
return io.of('/in-game');
|
||||
registerRateLimiter(io, logger);
|
||||
|
||||
return io;
|
||||
},
|
||||
|
||||
createGameSocketNamespace(server, logger) {
|
||||
const namespace = server.of('/in-game');
|
||||
registerRateLimiter(namespace, logger);
|
||||
return server.of('/in-game');
|
||||
}
|
||||
};
|
||||
|
||||
function registerRateLimiter(server, logger) {
|
||||
const rateLimiter = new RateLimiterMemory(
|
||||
{
|
||||
points: 10,
|
||||
duration: 1
|
||||
});
|
||||
|
||||
server.use(async (socket, next) => {
|
||||
try {
|
||||
await rateLimiter.consume(socket.handshake.address);
|
||||
logger.trace('consumed point from ' + socket.handshake.address);
|
||||
next();
|
||||
} catch(rejection) {
|
||||
next(new Error("Your connection has been blocked."));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = ServerBootstrapper;
|
||||
|
||||
Reference in New Issue
Block a user