diff --git a/.github/workflows/security.yaml b/.github/workflows/security.yaml index adab787f..943b1006 100644 --- a/.github/workflows/security.yaml +++ b/.github/workflows/security.yaml @@ -1,6 +1,7 @@ name: Bearer -on: [pull_request] +on: #[pull_request] + workflow_dispatch: permissions: contents: read diff --git a/src/package.json b/src/package.json index e772ad12..c51b4a11 100644 --- a/src/package.json +++ b/src/package.json @@ -35,7 +35,8 @@ "express-session": "^1.17.3", "mongodb": "^4.9.1", "morgan": "~1.10.0", - "redis": "^4.3.1" + "redis": "^4.3.1", + "express-rate-limit": "^8.0.1" }, "devDependencies": { "eslint": "^8.23.1", diff --git a/src/todo/routes.mjs b/src/todo/routes.mjs index 44cf1a4f..081e8060 100644 --- a/src/todo/routes.mjs +++ b/src/todo/routes.mjs @@ -9,6 +9,14 @@ import express from 'express' const router = express.Router() import { MongoClient, ObjectId } from 'mongodb' import appInsights from 'applicationinsights' +import rateLimit from 'express-rate-limit' + +// Configure rate limiter: maximum of 100 requests per 15 minutes +const apiLimiter = rateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + max: 100, // limit each IP to 100 requests per windowMs + message: { error: 'Too many requests, please try again later.' }, // Custom error message +}) const DBNAME = process.env.TODO_MONGO_DB || 'todoDb' const COLLECTION = 'todos' @@ -99,7 +107,7 @@ router.put('/api/todo/:id', async function (req, res, next) { // // Todo API: DELETE - remove a todo from DB // -router.delete('/api/todo/:id', async function (req, res, next) { +router.delete('/api/todo/:id', apiLimiter, async function (req, res, next) { try { const result = await db.collection(COLLECTION).deleteOne({ _id: ObjectId(req.params.id) }) if (result && result.deletedCount) {