diff --git a/package-lock.json b/package-lock.json index 87dbee5f..010807a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "dompurify": "^3.1.6", "dotenv": "^16.4.5", "express": "^4.19.2", + "express-rate-limit": "^7.4.0", "lucide-react": "^0.439.0", "mermaid": "^11.1.1", "openai": "^4.58.1", @@ -9060,6 +9061,20 @@ "node": ">= 0.10.0" } }, + "node_modules/express-rate-limit": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.4.0.tgz", + "integrity": "sha512-v1204w3cXu5gCDmAvgvzI6qjzZzoMWKnyVDk3ACgfswTQLYiGen+r8w0VnXnGMmzEN/g8fwIQ4JrFFd4ZP6ssg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": "4 || 5 || ^5.0.0-beta.1" + } + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", diff --git a/package.json b/package.json index 122072a0..5ea9b329 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "dompurify": "^3.1.6", "dotenv": "^16.4.5", "express": "^4.19.2", + "express-rate-limit": "^7.4.0", "lucide-react": "^0.439.0", "mermaid": "^11.1.1", "openai": "^4.58.1", diff --git a/server.js b/server.js index c3c8d7cf..75d10a35 100644 --- a/server.js +++ b/server.js @@ -10,6 +10,7 @@ const { exec } = require("child_process"); const path = require("path"); const swaggerUi = require("swagger-ui-express"); const swaggerJsdoc = require("swagger-jsdoc"); +const rateLimit = require('express-rate-limit'); const USER_PREFERENCES_FILE = path.join(__dirname, "user_preferences.json"); @@ -126,6 +127,19 @@ async function initializeApiClients() { } const app = express(); + app.set('trust proxy', 1); // Adjust this based on your environment + + const apiLimiter = rateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + max: 100, // limit each IP to 100 requests per windowMs + standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers + legacyHeaders: false, // Disable the `X-RateLimit-*` headers + skipFailedRequests: true, // Skip limiting if request fails + keyGenerator: (req, res) => req.ip, // Use the request IP as key + }); + + app.use(apiLimiter); + app.use(express.json()); const artifactManager = new ArtifactManager();