add rate limiting

This commit is contained in:
Alex Holliday
2025-07-28 12:00:09 -07:00
parent 051c17f454
commit ec99b5e9b4
5 changed files with 60 additions and 11 deletions

View File

@@ -13,11 +13,12 @@
"axios": "^1.7.2",
"bcryptjs": "3.0.2",
"bullmq": "5.41.2",
"compression": "1.8.0",
"compression": "1.8.1",
"cors": "^2.8.5",
"dockerode": "4.0.6",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"express-rate-limit": "8.0.1",
"handlebars": "^4.7.8",
"helmet": "^8.0.0",
"ioredis": "^5.4.2",
@@ -2022,16 +2023,16 @@
}
},
"node_modules/compression": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz",
"integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==",
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz",
"integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==",
"license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"compressible": "~2.0.18",
"debug": "2.6.9",
"negotiator": "~0.6.4",
"on-headers": "~1.0.2",
"on-headers": "~1.1.0",
"safe-buffer": "5.2.1",
"vary": "~1.1.2"
},
@@ -3159,6 +3160,24 @@
"url": "https://opencollective.com/express"
}
},
"node_modules/express-rate-limit": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.0.1.tgz",
"integrity": "sha512-aZVCnybn7TVmxO4BtlmnvX+nuz8qHW124KKJ8dumsBsmv5ZLxE0pYu7S2nwyRBGHHCAzdmnGyrc5U/rksSPO7Q==",
"license": "MIT",
"dependencies": {
"ip-address": "10.0.1"
},
"engines": {
"node": ">= 16"
},
"funding": {
"url": "https://github.com/sponsors/express-rate-limit"
},
"peerDependencies": {
"express": ">= 4.11"
}
},
"node_modules/express/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -3901,6 +3920,15 @@
"url": "https://opencollective.com/ioredis"
}
},
"node_modules/ip-address": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz",
"integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==",
"license": "MIT",
"engines": {
"node": ">= 12"
}
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -5705,9 +5733,9 @@
}
},
"node_modules/on-headers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
"integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
"license": "MIT",
"engines": {
"node": ">= 0.8"

View File

@@ -20,11 +20,12 @@
"axios": "^1.7.2",
"bcryptjs": "3.0.2",
"bullmq": "5.41.2",
"compression": "1.8.0",
"compression": "1.8.1",
"cors": "^2.8.5",
"dockerode": "4.0.6",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"express-rate-limit": "8.0.1",
"handlebars": "^4.7.8",
"helmet": "^8.0.0",
"ioredis": "^5.4.2",

View File

@@ -8,11 +8,13 @@ import languageMiddleware from "./middleware/languageMiddleware.js";
import swaggerUi from "swagger-ui-express";
import { handleErrors } from "./middleware/handleErrors.js";
import { setupRoutes } from "./config/routes.js";
import { generalApiLimiter } from "./middleware/rateLimiter.js";
export const createApp = ({ services, controllers, appSettings, frontendPath, openApiSpec }) => {
const allowedOrigin = appSettings.clientHost;
const app = express();
app.use(generalApiLimiter);
// Static files
app.use(express.static(frontendPath));

View File

@@ -1,4 +1,5 @@
import { verifyJWT } from "../middleware/verifyJWT.js";
import { authApiLimiter } from "../middleware/rateLimiter.js";
import AuthRoutes from "../routes/authRoute.js";
import InviteRoutes from "../routes/inviteRoute.js";
@@ -25,7 +26,7 @@ export const setupRoutes = (app, controllers) => {
const notificationRoutes = new NotificationRoutes(controllers.notificationController);
const diagnosticRoutes = new DiagnosticRoutes(controllers.diagnosticController);
app.use("/api/v1/auth", authRoutes.getRouter());
app.use("/api/v1/auth", authApiLimiter, authRoutes.getRouter());
app.use("/api/v1/monitors", verifyJWT, monitorRoutes.getRouter());
app.use("/api/v1/settings", verifyJWT, settingsRoutes.getRouter());
app.use("/api/v1/checks", verifyJWT, checkRoutes.getRouter());

View File

@@ -0,0 +1,17 @@
import rateLimit from "express-rate-limit";
export const generalApiLimiter = rateLimit({
window: 60 * 1000,
limit: 600,
standardHeaders: true,
legacyHeaders: false,
ipv6Subnet: 64,
});
export const authApiLimiter = rateLimit({
window: 60 * 1000,
limit: 5,
standardHeaders: true,
legacyHeaders: false,
ipv6Subnet: 64,
});