Impliment basic rate limiting
This commit is contained in:
parent
2b306d60b7
commit
9470ded1e8
5
index.js
5
index.js
|
@ -77,6 +77,9 @@ app.use((req, res, next) => {
|
||||||
next()
|
next()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Rate Limit middleware from scratch
|
||||||
|
const rateLimit = require('./rateLimit.js');
|
||||||
|
|
||||||
// The very very few direct routes
|
// The very very few direct routes
|
||||||
app.get("/", (req, res) => {
|
app.get("/", (req, res) => {
|
||||||
const readmePath = path.join(__dirname, 'README.md');
|
const readmePath = path.join(__dirname, 'README.md');
|
||||||
|
@ -98,7 +101,7 @@ app.get("/", (req, res) => {
|
||||||
|
|
||||||
var cached_invite = { code: "", expires: 0 }
|
var cached_invite = { code: "", expires: 0 }
|
||||||
|
|
||||||
app.get('/discord', async (req, res) => {
|
app.get('/discord', rateLimit.middleware, async (req, res) => {
|
||||||
if (cached_invite.expires > Date.now()) {
|
if (cached_invite.expires > Date.now()) {
|
||||||
return res.redirect(`https://discord.gg/${cached_invite.code}`)
|
return res.redirect(`https://discord.gg/${cached_invite.code}`)
|
||||||
} else {
|
} else {
|
||||||
|
|
40
rateLimit.js
Normal file
40
rateLimit.js
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
const { message } = require("noblox.js");
|
||||||
|
|
||||||
|
if (!global.rateLimitList) {
|
||||||
|
global.rateLimitList = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const middleware = (req, res, next) => {
|
||||||
|
console.log(global.rateLimitList)
|
||||||
|
// X requests per Y seconds per IP address
|
||||||
|
const maxRequests = process.env.RATE_LIMIT_MAX || 30;
|
||||||
|
const timeWindow = process.env.RATE_LIMIT_TIME || 60;
|
||||||
|
|
||||||
|
var requestIp = req.ip;
|
||||||
|
if (process.env.TRUST_PROXY && (req.ip == `::ffff:${process.env.PROXY_IP}` || req.ip == process.env.PROXY_IP)) {
|
||||||
|
requestIp = req.headers["x-forwarded-for"];
|
||||||
|
}
|
||||||
|
if (!global.rateLimitList[requestIp]) {
|
||||||
|
global.rateLimitList[requestIp] = { requests: 0, lastRequest: Date.now() };
|
||||||
|
}
|
||||||
|
if (global.rateLimitList[requestIp].lastRequest + timeWindow * 1000 < Date.now()) {
|
||||||
|
global.rateLimitList[requestIp] = { requests: 0, lastRequest: Date.now() };
|
||||||
|
} else {
|
||||||
|
if (global.rateLimitList[requestIp].requests >= maxRequests) {
|
||||||
|
return res.status(429).json({ completed: false, success: false, error: "Rate limit exceeded", message: "You have been rate limited. Please try again later.", expires: global.rateLimitList[requestIp].lastRequest + timeWindow * 1000 });
|
||||||
|
} else {
|
||||||
|
global.rateLimitList[requestIp].lastRequest = Date.now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
global.rateLimitList[requestIp].requests++;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
const getRateLimit = () => {
|
||||||
|
return global.global.rateLimitList;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
middleware,
|
||||||
|
getRateLimit
|
||||||
|
}
|
|
@ -235,7 +235,9 @@ router.get('/login', (req, res) => {
|
||||||
res.render('admin/login', { env: process.env });
|
res.render('admin/login', { env: process.env });
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post('/login', async (req, res) => {
|
const rateLimit = require('../rateLimit.js');
|
||||||
|
|
||||||
|
router.post('/login', rateLimit.middleware, async (req, res) => {
|
||||||
const conn = await pool.getConnection();
|
const conn = await pool.getConnection();
|
||||||
const username = req.body.username;
|
const username = req.body.username;
|
||||||
const password = req.body.password;
|
const password = req.body.password;
|
||||||
|
|
|
@ -7,6 +7,9 @@ const { execSync } = require('child_process');
|
||||||
// Create a MariaDB connection pool
|
// Create a MariaDB connection pool
|
||||||
const pool = global.db_pool
|
const pool = global.db_pool
|
||||||
|
|
||||||
|
const rateLimit = require('../rateLimit.js');
|
||||||
|
router.use(rateLimit.middleware);
|
||||||
|
|
||||||
router.get("/health", async (req,res) => {
|
router.get("/health", async (req,res) => {
|
||||||
try {
|
try {
|
||||||
// Get a connection from the pool
|
// Get a connection from the pool
|
||||||
|
|
Loading…
Reference in a new issue