diff --git a/backend/api/routes/config.js b/backend/api/routes/config.js index 905364ba4..b21cbc514 100644 --- a/backend/api/routes/config.js +++ b/backend/api/routes/config.js @@ -1,11 +1,22 @@ const { authenticateRequest } = require("../../middlewares/auth"); const { Router } = require("express"); const ConfigController = require("../controllers/config"); +const RateLimit = require("../../middlewares/rate-limit"); const router = Router(); -router.get("/", authenticateRequest, ConfigController.getConfig); +router.get( + "/", + RateLimit.limit60perhour, + authenticateRequest, + ConfigController.getConfig +); -router.post("/save", authenticateRequest, ConfigController.saveConfig); +router.post( + "/save", + RateLimit.limit500perhour, + authenticateRequest, + ConfigController.saveConfig +); module.exports = router; diff --git a/backend/api/routes/preset.js b/backend/api/routes/preset.js index 9c246fad8..c4ef25551 100644 --- a/backend/api/routes/preset.js +++ b/backend/api/routes/preset.js @@ -1,16 +1,37 @@ const { authenticateRequest } = require("../../middlewares/auth"); const PresetController = require("../controllers/preset"); +const RateLimit = require("../../middlewares/rate-limit"); const { Router } = require("express"); const router = Router(); -router.get("/", authenticateRequest, PresetController.getPresets); +router.get( + "/", + RateLimit.limit60perhour, + authenticateRequest, + PresetController.getPresets +); -router.post("/add", authenticateRequest, PresetController.addPreset); +router.post( + "/add", + RateLimit.limit60perhour, + authenticateRequest, + PresetController.addPreset +); -router.post("/edit", authenticateRequest, PresetController.editPreset); +router.post( + "/edit", + RateLimit.limit60perhour, + authenticateRequest, + PresetController.editPreset +); -router.post("/remove", authenticateRequest, PresetController.removePreset); +router.post( + "/remove", + RateLimit.limit60perhour, + authenticateRequest, + PresetController.removePreset +); module.exports = router; diff --git a/backend/api/routes/quote-ratings.js b/backend/api/routes/quote-ratings.js index 37f4329db..a31f35839 100644 --- a/backend/api/routes/quote-ratings.js +++ b/backend/api/routes/quote-ratings.js @@ -1,13 +1,20 @@ const { authenticateRequest } = require("../../middlewares/auth"); const { Router } = require("express"); const QuoteRatingsController = require("../controllers/quote-ratings"); +const RateLimit = require("../../middlewares/rate-limit"); const router = Router(); -router.get("/get", authenticateRequest, QuoteRatingsController.getRating); +router.get( + "/get", + RateLimit.limit500perhour, + authenticateRequest, + QuoteRatingsController.getRating +); router.post( "/submit", + RateLimit.limit500perhour, authenticateRequest, QuoteRatingsController.submitRating ); diff --git a/backend/api/routes/result.js b/backend/api/routes/result.js index 7ad23bdd9..14e6a8969 100644 --- a/backend/api/routes/result.js +++ b/backend/api/routes/result.js @@ -1,24 +1,47 @@ const { authenticateRequest } = require("../../middlewares/auth"); const { Router } = require("express"); const ResultController = require("../controllers/result"); +const RateLimit = require("../../middlewares/rate-limit"); const router = Router(); -router.get("/", authenticateRequest, ResultController.getResults); +router.get( + "/", + RateLimit.limit60perhour, + authenticateRequest, + ResultController.getResults +); -router.post("/add", authenticateRequest, ResultController.addResult); +router.post( + "/add", + RateLimit.limit500perhour, + authenticateRequest, + ResultController.addResult +); -router.post("/updateTags", authenticateRequest, ResultController.updateTags); +router.post( + "/updateTags", + RateLimit.limit60perhour, + authenticateRequest, + ResultController.updateTags +); -router.post("/deleteAll", authenticateRequest, ResultController.deleteAll); +router.post( + "/deleteAll", + RateLimit.limit60perhour, + authenticateRequest, + ResultController.deleteAll +); router.get( "/getLeaderboard/:type/:mode/:mode2", + RateLimit.limit60perhour, ResultController.getLeaderboard ); router.post( "/checkLeaderboardQualification", + RateLimit.limit60perhour, authenticateRequest, ResultController.checkLeaderboardQualification ); diff --git a/backend/api/routes/user.js b/backend/api/routes/user.js index 3a2b07ccf..a3f62a8b0 100644 --- a/backend/api/routes/user.js +++ b/backend/api/routes/user.js @@ -1,37 +1,99 @@ const { authenticateRequest } = require("../../middlewares/auth"); const { Router } = require("express"); const UserController = require("../controllers/user"); +const RateLimit = require("../../middlewares/rate-limit"); const router = Router(); -router.get("/", authenticateRequest, UserController.getUser); +router.get( + "/", + RateLimit.limit60perhour, + authenticateRequest, + UserController.getUser +); -router.post("/signup", authenticateRequest, UserController.createNewUser); +router.post( + "/signup", + RateLimit.limit3perday, + authenticateRequest, + UserController.createNewUser +); -router.post("/checkName", UserController.checkName); +router.post("/checkName", RateLimit.limit60perhour, UserController.checkName); -router.post("/delete", authenticateRequest, UserController.deleteUser); +router.post( + "/delete", + RateLimit.limit3perday, + authenticateRequest, + UserController.deleteUser +); -router.post("/updateName", authenticateRequest, UserController.updateName); +router.post( + "/updateName", + RateLimit.limit3perday, + authenticateRequest, + UserController.updateName +); -router.post("/updateEmail", authenticateRequest, UserController.updateEmail); +router.post( + "/updateEmail", + RateLimit.limit60perhour, + authenticateRequest, + UserController.updateEmail +); -router.post("/clearPb", authenticateRequest, UserController.clearPb); +router.post( + "/clearPb", + RateLimit.limit60perhour, + authenticateRequest, + UserController.clearPb +); -router.post("/tags/add", authenticateRequest, UserController.addTag); +router.post( + "/tags/add", + RateLimit.limit60perhour, + authenticateRequest, + UserController.addTag +); -router.get("/tags", authenticateRequest, UserController.getTags); +router.get( + "/tags", + RateLimit.limit60perhour, + authenticateRequest, + UserController.getTags +); -router.post("/tags/clearPb", authenticateRequest, UserController.clearTagPb); +router.post( + "/tags/clearPb", + RateLimit.limit60perhour, + authenticateRequest, + UserController.clearTagPb +); -router.post("/tags/remove", authenticateRequest, UserController.removeTag); +router.post( + "/tags/remove", + RateLimit.limit60perhour, + authenticateRequest, + UserController.removeTag +); -router.post("/tags/edit", authenticateRequest, UserController.editTag); +router.post( + "/tags/edit", + RateLimit.limit60perhour, + authenticateRequest, + UserController.editTag +); -router.post("/discord/link", authenticateRequest, UserController.linkDiscord); +router.post( + "/discord/link", + RateLimit.limit60perhour, + authenticateRequest, + UserController.linkDiscord +); router.post( "/discord/unlink", + RateLimit.limit60perhour, authenticateRequest, UserController.unlinkDiscord ); diff --git a/backend/middlewares/rate-limit.js b/backend/middlewares/rate-limit.js new file mode 100644 index 000000000..833027aec --- /dev/null +++ b/backend/middlewares/rate-limit.js @@ -0,0 +1,33 @@ +const rateLimit = require("express-rate-limit"); + +exports.limit60perhour = rateLimit({ + windowMs: 60 * 60 * 1000, // 60 min + max: 60, + message: { + message: "Too many requests, please try again later", + }, +}); + +exports.limit3perday = rateLimit({ + windowMs: 24 * 60 * 60 * 1000, // 1 day + max: 3, + message: { + message: "Too many requests, please try again later", + }, +}); + +exports.limit1persec = rateLimit({ + windowMs: 60 * 1000, + max: 60, + message: { + message: "Too many requests, please try again later", + }, +}); + +exports.limit500perhour = rateLimit({ + windowMs: 60 * 60 * 1000, + max: 500, + message: { + message: "Too many requests, please try again later", + }, +}); diff --git a/package-lock.json b/package-lock.json index 5b2e38e2c..dbe211d22 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "dom-to-image": "^2.6.0", "dotenv": "^10.0.0", "express": "^4.17.1", + "express-rate-limit": "^5.3.0", "firebase-admin": "^9.11.0", "helmet": "^4.6.0", "howler": "^2.2.1", @@ -5652,6 +5653,11 @@ "node": ">= 0.10.0" } }, + "node_modules/express-rate-limit": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.3.0.tgz", + "integrity": "sha512-qJhfEgCnmteSeZAeuOKQ2WEIFTX5ajrzE0xS6gCOBCoRQcU+xEzQmgYQQTpzCcqUAAzTEtu4YEih4pnLfvNtew==" + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -18899,6 +18905,11 @@ } } }, + "express-rate-limit": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.3.0.tgz", + "integrity": "sha512-qJhfEgCnmteSeZAeuOKQ2WEIFTX5ajrzE0xS6gCOBCoRQcU+xEzQmgYQQTpzCcqUAAzTEtu4YEih4pnLfvNtew==" + }, "ext": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", diff --git a/package.json b/package.json index 9a12bb18b..f6871a87a 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "dom-to-image": "^2.6.0", "dotenv": "^10.0.0", "express": "^4.17.1", + "express-rate-limit": "^5.3.0", "firebase-admin": "^9.11.0", "helmet": "^4.6.0", "howler": "^2.2.1",