forked from hippoz/brainlet
add a simple rate limiter
This commit is contained in:
parent
7bebf6d471
commit
3bc1fdbde7
3 changed files with 45 additions and 1 deletions
|
@ -2,6 +2,7 @@ const User = require('../../../models/User');
|
||||||
const secret = require('../../../secret');
|
const secret = require('../../../secret');
|
||||||
const config = require('../../../config');
|
const config = require('../../../config');
|
||||||
const Category = require('../../../models/Category');
|
const Category = require('../../../models/Category');
|
||||||
|
const RateLimiter = require('./ratelimiter');
|
||||||
|
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
const siolib = require('socket.io');
|
const siolib = require('socket.io');
|
||||||
|
@ -11,6 +12,11 @@ class GatewayServer {
|
||||||
constructor(httpServer) {
|
constructor(httpServer) {
|
||||||
this._io = siolib(httpServer);
|
this._io = siolib(httpServer);
|
||||||
this._gateway = this._io.of('/gateway');
|
this._gateway = this._io.of('/gateway');
|
||||||
|
this.rateLimiter = new RateLimiter({
|
||||||
|
points: 5,
|
||||||
|
time: 1000,
|
||||||
|
minPoints: 0
|
||||||
|
});
|
||||||
this.eventSetup();
|
this.eventSetup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,6 +100,11 @@ GatewayServer.prototype.eventSetup = function() {
|
||||||
if (!category || !content || !socket.joinedCategories || !socket.isConnected || !socket.user || !(typeof content === 'string') || !(typeof category._id === 'string')) return;
|
if (!category || !content || !socket.joinedCategories || !socket.isConnected || !socket.user || !(typeof content === 'string') || !(typeof category._id === 'string')) return;
|
||||||
content = content.trim();
|
content = content.trim();
|
||||||
if (!content || content === '' || content === ' ' || content.length >= 2000) return;
|
if (!content || content === '' || content === ' ' || content.length >= 2000) return;
|
||||||
|
if (!this.rateLimiter.consoom(socket.user.token)) { // TODO: maybe user ip instead of token?
|
||||||
|
console.log(`[E] [gateway] Rate limiting ${socket.user.username}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: When/if category permissions are added, check if the user has permissions for that category
|
// TODO: When/if category permissions are added, check if the user has permissions for that category
|
||||||
const categoryTitle = socket.joinedCategories[category._id];
|
const categoryTitle = socket.joinedCategories[category._id];
|
||||||
|
|
33
api/v1/gateway/ratelimiter.js
Normal file
33
api/v1/gateway/ratelimiter.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// This is "inspired" by rate-limiter-flexible
|
||||||
|
|
||||||
|
class RateLimiter {
|
||||||
|
constructor({ points=5, time=1000, minPoints=0 }) {
|
||||||
|
this.points = points;
|
||||||
|
this.minPoints = minPoints;
|
||||||
|
this.time = time;
|
||||||
|
|
||||||
|
this._flooding = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RateLimiter.prototype.consoom = function(discriminator) {
|
||||||
|
if (!this._flooding[discriminator]) this._flooding[discriminator] = { points: this.points, lastReset: Date.now() };
|
||||||
|
|
||||||
|
if (Math.abs(new Date() - this._flooding[discriminator].lastReset) >= this.time) {
|
||||||
|
this._flooding[discriminator] = { points: this.points, lastReset: Date.now() };
|
||||||
|
}
|
||||||
|
|
||||||
|
this._flooding[discriminator].points--;
|
||||||
|
|
||||||
|
if (this._flooding[discriminator].points <= this.minPoints) {
|
||||||
|
this._flooding[discriminator].flooding = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._flooding[discriminator].flooding === true) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = RateLimiter;
|
|
@ -3,7 +3,7 @@ module.exports = {
|
||||||
mainServerPort: 3000,
|
mainServerPort: 3000,
|
||||||
},
|
},
|
||||||
address: 'localhost',
|
address: 'localhost',
|
||||||
mongoUrl: 'mongodb://localhost:27017/app',
|
mongoUrl: 'mongodb://192.168.0.105:27017/app',
|
||||||
bcryptRounds: 10,
|
bcryptRounds: 10,
|
||||||
roleMap: {
|
roleMap: {
|
||||||
'BANNED': 0,
|
'BANNED': 0,
|
||||||
|
|
Loading…
Reference in a new issue