diff --git a/package-lock.json b/package-lock.json index d4c3d8e..085305f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,8 @@ "chalk": "^4.1.2", "compression": "^1.7.4", "express": "^4.18.2", + "express-rate-limit": "^7.1.5", + "express-slow-down": "^2.0.1", "express-validator": "^7.0.1", "helmet": "^7.1.0", "hpp": "^0.2.3", @@ -3423,6 +3425,34 @@ "node": ">= 0.10.0" } }, + "node_modules/express-rate-limit": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.1.5.tgz", + "integrity": "sha512-/iVogxu7ueadrepw1bS0X0kaRC/U0afwiYRSLg68Ts+p4Dc85Q5QKsOnPS/QUjPMHvOJQtBDrZgvkOzf8ejUYw==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": "4 || 5 || ^5.0.0-beta.1" + } + }, + "node_modules/express-slow-down": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/express-slow-down/-/express-slow-down-2.0.1.tgz", + "integrity": "sha512-zRogSZhNXJYKDBekhgFfFXGrOngH7Fub7Mx2g8OQ4RUBwSJP/3TVEKMgSGR/WlneT0mJ6NBUnidHhIELGVPe3w==", + "dependencies": { + "express-rate-limit": "7" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "express": ">= 4" + } + }, "node_modules/express-validator": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.0.1.tgz", diff --git a/package.json b/package.json index f78fb59..8b59750 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,8 @@ "chalk": "^4.1.2", "compression": "^1.7.4", "express": "^4.18.2", + "express-rate-limit": "^7.1.5", + "express-slow-down": "^2.0.1", "express-validator": "^7.0.1", "helmet": "^7.1.0", "hpp": "^0.2.3", diff --git a/src/app.ts b/src/app.ts index 9502854..6fa9452 100644 --- a/src/app.ts +++ b/src/app.ts @@ -2,6 +2,8 @@ require('module-alias/register'); import { config } from 'dotenv'; import express from 'express'; import toobusy from 'toobusy-js'; +// import { rateLimit } from 'express-rate-limit'; +// import { slowDown } from 'express-slow-down'; import compression from 'compression'; import helmet from 'helmet'; import hpp from 'hpp'; @@ -17,29 +19,37 @@ import logger from '@src/scripts/logger'; config(); // dotenv const app = express(); -app.use(helmet({ - contentSecurityPolicy: { - directives: { - "default-src": "'self'", - "img-src": "*" - } - } -})); + app.use((req, res, next) => { // monitor eventloop to block requests if busy if (toobusy()) { res.status(503).set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Retry-After': '60' }).send("I'm busy right now, sorry."); } else { next(); } }); + +// const slowDownLimiter = slowDown({ +// windowMs: 1 * 60 * 1000, +// delayAfter: 5, // Allow 5 requests per 15 minutes. +// delayMs: (used) => (used - 5) * 1000, // Add delay after delayAfter is reached +// }) + +// const rateLimiter = rateLimit({ +// windowMs: 1 * 60 * 1000, +// max: 10, // Limit each IP per `window` +// standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers +// legacyHeaders: false, // Disable the `X-RateLimit-*` headers +// }) + +app.use(helmet({ contentSecurityPolicy: { directives: { "default-src": "'self'", "img-src": "*" } } })); app.use(cache); app.use(compression()) app.use(hpp()); - app.use(function (req, res, next) { // limit request size limit when recieving data if (!['POST', 'PUT', 'DELETE'].includes(req.method)) { return next(); } - getRawBody(req, { length: req.headers['content-length'], limit: '1mb', encoding: true }, - function (err) { - if (err) { return next(err) } - next() - }) + getRawBody(req, { length: req.headers['content-length'], limit: '1mb', encoding: true }, + function (err) { + if (err) { return next(err) } + next() + } + ) }) // routes