0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-14 12:52:42 +00:00

"Added express-rate-limit package and implemented rate limiting for admin API login attempts"

This commit is contained in:
Víctor Losada Hernández
2024-05-24 20:42:25 +02:00
parent dcd34ccdaf
commit 748c25aae4
3 changed files with 15196 additions and 15162 deletions

23
package-lock.json generated
View File

@@ -25,6 +25,7 @@
"expr-eval": "^2.0.2", "expr-eval": "^2.0.2",
"express": "^4.19.2", "express": "^4.19.2",
"express-async-handler": "^1.2.0", "express-async-handler": "^1.2.0",
"express-rate-limit": "^7.2.0",
"express-static-gzip": "2.1.7", "express-static-gzip": "2.1.7",
"fs-extra": "11.2.0", "fs-extra": "11.2.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
@@ -6202,6 +6203,20 @@
"resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz", "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz",
"integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w=="
}, },
"node_modules/express-rate-limit": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.2.0.tgz",
"integrity": "sha512-T7nul1t4TNyfZMJ7pKRKkdeVJWa2CqB8NA1P8BwYaoDI5QSBZARv5oMS43J7b7I5P+4asjVXjb7ONuwDKucahg==",
"engines": {
"node": ">= 16"
},
"funding": {
"url": "https://github.com/sponsors/express-rate-limit"
},
"peerDependencies": {
"express": "4 || 5 || ^5.0.0-beta.1"
}
},
"node_modules/express-static-gzip": { "node_modules/express-static-gzip": {
"version": "2.1.7", "version": "2.1.7",
"resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.1.7.tgz", "resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.1.7.tgz",
@@ -7240,6 +7255,14 @@
"node": ">=10.17.0" "node": ">=10.17.0"
} }
}, },
"node_modules/i": {
"version": "0.3.7",
"resolved": "https://registry.npmjs.org/i/-/i-0.3.7.tgz",
"integrity": "sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q==",
"engines": {
"node": ">=0.4"
}
},
"node_modules/iconv-lite": { "node_modules/iconv-lite": {
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",

View File

@@ -97,6 +97,7 @@
"expr-eval": "^2.0.2", "expr-eval": "^2.0.2",
"express": "^4.19.2", "express": "^4.19.2",
"express-async-handler": "^1.2.0", "express-async-handler": "^1.2.0",
"express-rate-limit": "^7.2.0",
"express-static-gzip": "2.1.7", "express-static-gzip": "2.1.7",
"fs-extra": "11.2.0", "fs-extra": "11.2.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",

View File

@@ -1,29 +1,39 @@
const HomebrewModel = require('./homebrew.model.js').model; const HomebrewModel = require('./homebrew.model.js').model;
const router = require('express').Router(); const router = require('express').Router();
const Moment = require('moment'); const Moment = require('moment');
//const render = require('vitreum/steps/render');
const templateFn = require('../client/template.js'); const templateFn = require('../client/template.js');
const zlib = require('zlib'); const zlib = require('zlib');
const rateLimit = require('express-rate-limit');
// Define rate limiter options
const loginLimiter = rateLimit({
windowMs: 24 * 60 * 60 * 1000, // 24 hours window
max: 10, // limit each IP to 10 requests per windowMs
message: "Too many login attempts from this IP, please try again later"
});
process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin'; process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin';
process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password3'; process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password3';
const mw = { const mw = {
adminOnly : (req, res, next)=>{ adminOnly: [
if(!req.get('authorization')){ loginLimiter,
return res (req, res, next) => {
.set('WWW-Authenticate', 'Basic realm="Authorization Required"') if (!req.get('authorization')) {
.status(401) return res
.send('Authorization Required'); .set('WWW-Authenticate', 'Basic realm="Authorization Required"')
} .status(401)
const [username, password] = Buffer.from(req.get('authorization').split(' ').pop(), 'base64') .send('Authorization Required');
.toString('ascii') }
.split(':'); const [username, password] = Buffer.from(req.get('authorization').split(' ').pop(), 'base64')
if(process.env.ADMIN_USER === username && process.env.ADMIN_PASS === password){ .toString('ascii')
return next(); .split(':');
} if (process.env.ADMIN_USER === username && process.env.ADMIN_PASS === password) {
return res.status(401).send('Access denied'); return next();
} }
return res.status(401).send('Access denied');
}
]
}; };
const junkBrewPipeline = [ const junkBrewPipeline = [