mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2024-09-20 23:36:37 +08:00
fix: endpoints share the same rate limit (#2136) by CameronCT
* fix: cleaned rate limiter * chore: separated ratelimits per request * fix: bug where leaderboards would crash
This commit is contained in:
parent
8ae20c5626
commit
e56d534f33
|
@ -7,14 +7,14 @@ const router = Router();
|
|||
|
||||
router.get(
|
||||
"/",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.configGet,
|
||||
authenticateRequest,
|
||||
ConfigController.getConfig
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/save",
|
||||
RateLimit.limit500perhour,
|
||||
RateLimit.configUpdate,
|
||||
authenticateRequest,
|
||||
ConfigController.saveConfig
|
||||
);
|
||||
|
|
|
@ -6,20 +6,13 @@ const { Router } = require("express");
|
|||
|
||||
const router = Router();
|
||||
|
||||
router.get("/", RateLimit.limit1persec, LeaderboardsController.get);
|
||||
router.get("/", RateLimit.leaderboardsGet, LeaderboardsController.get);
|
||||
|
||||
router.get(
|
||||
"/rank",
|
||||
RateLimit.limit1persec,
|
||||
RateLimit.leaderboardsGet,
|
||||
authenticateRequest,
|
||||
LeaderboardsController.getRank
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/update",
|
||||
RateLimit.limit60perhour,
|
||||
authenticateRequest,
|
||||
LeaderboardsController.update
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
@ -7,28 +7,28 @@ const router = Router();
|
|||
|
||||
router.get(
|
||||
"/get",
|
||||
RateLimit.limit500perhour,
|
||||
RateLimit.newQuotesGet,
|
||||
authenticateRequest,
|
||||
NewQuotesController.getQuotes
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/add",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.newQuotesAdd,
|
||||
authenticateRequest,
|
||||
NewQuotesController.addQuote
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/approve",
|
||||
RateLimit.limit500perhour,
|
||||
RateLimit.newQuotesAction,
|
||||
authenticateRequest,
|
||||
NewQuotesController.approve
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/refuse",
|
||||
RateLimit.limit500perhour,
|
||||
RateLimit.newQuotesAction,
|
||||
authenticateRequest,
|
||||
NewQuotesController.refuse
|
||||
);
|
||||
|
|
|
@ -8,28 +8,28 @@ const router = Router();
|
|||
|
||||
router.get(
|
||||
"/",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.presetsGet,
|
||||
authenticateRequest,
|
||||
PresetController.getPresets
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/add",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.presetsAdd,
|
||||
authenticateRequest,
|
||||
PresetController.addPreset
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/edit",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.presetsEdit,
|
||||
authenticateRequest,
|
||||
PresetController.editPreset
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/remove",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.presetsRemove,
|
||||
authenticateRequest,
|
||||
PresetController.removePreset
|
||||
);
|
||||
|
|
|
@ -6,6 +6,6 @@ const { Router } = require("express");
|
|||
|
||||
const router = Router();
|
||||
|
||||
router.get("/", RateLimit.limit1persec, PsaController.get);
|
||||
router.get("/", RateLimit.psaGet, PsaController.get);
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
@ -7,14 +7,14 @@ const router = Router();
|
|||
|
||||
router.get(
|
||||
"/get",
|
||||
RateLimit.limit500perhour,
|
||||
RateLimit.quoteRatingsGet,
|
||||
authenticateRequest,
|
||||
QuoteRatingsController.getRating
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/submit",
|
||||
RateLimit.limit500perhour,
|
||||
RateLimit.quoteRatingsSubmit,
|
||||
authenticateRequest,
|
||||
QuoteRatingsController.submitRating
|
||||
);
|
||||
|
|
|
@ -7,41 +7,41 @@ const router = Router();
|
|||
|
||||
router.get(
|
||||
"/",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.resultsGet,
|
||||
authenticateRequest,
|
||||
ResultController.getResults
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/add",
|
||||
RateLimit.limit500perhour,
|
||||
RateLimit.resultsAdd,
|
||||
authenticateRequest,
|
||||
ResultController.addResult
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/updateTags",
|
||||
RateLimit.limit500perhour,
|
||||
RateLimit.resultsTagsUpdate,
|
||||
authenticateRequest,
|
||||
ResultController.updateTags
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/deleteAll",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.resultsDeleteAll,
|
||||
authenticateRequest,
|
||||
ResultController.deleteAll
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/getLeaderboard/:type/:mode/:mode2",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.resultsLeaderboardGet,
|
||||
ResultController.getLeaderboard
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/checkLeaderboardQualification",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.resultsLeaderboardQualificationGet,
|
||||
authenticateRequest,
|
||||
ResultController.checkLeaderboardQualification
|
||||
);
|
||||
|
|
|
@ -7,100 +7,100 @@ const router = Router();
|
|||
|
||||
router.get(
|
||||
"/",
|
||||
RateLimit.limit120perhour,
|
||||
RateLimit.userGet,
|
||||
authenticateRequest,
|
||||
UserController.getUser
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/signup",
|
||||
RateLimit.limit3perday,
|
||||
RateLimit.userSignup,
|
||||
authenticateRequest,
|
||||
UserController.createNewUser
|
||||
);
|
||||
|
||||
router.post("/checkName", RateLimit.limit1persec, UserController.checkName);
|
||||
router.post("/checkName", RateLimit.userCheckName, UserController.checkName);
|
||||
|
||||
router.post(
|
||||
"/delete",
|
||||
RateLimit.limit3perday,
|
||||
RateLimit.userDelete,
|
||||
authenticateRequest,
|
||||
UserController.deleteUser
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/updateName",
|
||||
RateLimit.limit3perday,
|
||||
RateLimit.userUpdateName,
|
||||
authenticateRequest,
|
||||
UserController.updateName
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/updateLbMemory",
|
||||
RateLimit.limit1persec,
|
||||
RateLimit.userUpdateLBMemory,
|
||||
authenticateRequest,
|
||||
UserController.updateLbMemory
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/updateEmail",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.userUpdateEmail,
|
||||
authenticateRequest,
|
||||
UserController.updateEmail
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/clearPb",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.userClearPB,
|
||||
authenticateRequest,
|
||||
UserController.clearPb
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/tags/add",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.userTagsAdd,
|
||||
authenticateRequest,
|
||||
UserController.addTag
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/tags",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.userTagsGet,
|
||||
authenticateRequest,
|
||||
UserController.getTags
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/tags/clearPb",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.userTagsClearPB,
|
||||
authenticateRequest,
|
||||
UserController.clearTagPb
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/tags/remove",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.userTagsRemove,
|
||||
authenticateRequest,
|
||||
UserController.removeTag
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/tags/edit",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.userTagsEdit,
|
||||
authenticateRequest,
|
||||
UserController.editTag
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/discord/link",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.userDiscordLink,
|
||||
authenticateRequest,
|
||||
UserController.linkDiscord
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/discord/unlink",
|
||||
RateLimit.limit60perhour,
|
||||
RateLimit.userDiscordUnlink,
|
||||
authenticateRequest,
|
||||
UserController.unlinkDiscord
|
||||
);
|
||||
|
|
|
@ -90,9 +90,10 @@ class LeaderboardsDAO {
|
|||
.collection(`leaderboards.${language}.${mode}.${mode2}`)
|
||||
.drop();
|
||||
} catch (e) {}
|
||||
await mongoDB()
|
||||
.collection(`leaderboards.${language}.${mode}.${mode2}`)
|
||||
.insertMany(lb);
|
||||
if (lb && lb.length !== 0)
|
||||
await mongoDB()
|
||||
.collection(`leaderboards.${language}.${mode}.${mode2}`)
|
||||
.insertMany(lb);
|
||||
let end3 = performance.now();
|
||||
|
||||
let start4 = performance.now();
|
||||
|
|
|
@ -1,83 +1,251 @@
|
|||
const rateLimit = require("express-rate-limit");
|
||||
|
||||
let multiplier = process.env.MODE === "dev" ? 100 : 1;
|
||||
const getAddress = (req) => req.headers["cf-connecting-ip"] || req.headers["x-forwarded-for"] || req.ip || "255.255.255.255";
|
||||
const message = "Too many requests, please try again later";
|
||||
const multiplier = process.env.MODE === "dev" ? 100 : 1;
|
||||
|
||||
exports.limit60perhour = rateLimit({
|
||||
// Config Routing
|
||||
exports.configUpdate = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 60 * multiplier,
|
||||
message: {
|
||||
message: "Too many requests, please try again later",
|
||||
},
|
||||
keyGenerator: (req) => {
|
||||
return `${
|
||||
req.headers["cf-connecting-ip"] ||
|
||||
req.headers["x-forwarded-for"] ||
|
||||
req.ip ||
|
||||
"255.255.255.255"
|
||||
}`;
|
||||
},
|
||||
max: 500 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.limit120perhour = rateLimit({
|
||||
exports.configGet = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 120 * multiplier,
|
||||
message: {
|
||||
message: "Too many requests, please try again later",
|
||||
},
|
||||
keyGenerator: (req) => {
|
||||
return `${
|
||||
req.headers["cf-connecting-ip"] ||
|
||||
req.headers["x-forwarded-for"] ||
|
||||
req.ip ||
|
||||
"255.255.255.255"
|
||||
}`;
|
||||
},
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.limit3perday = rateLimit({
|
||||
windowMs: 24 * 60 * 60 * 1000, // 1 day
|
||||
max: 3 * multiplier,
|
||||
message: {
|
||||
message: "Too many requests, please try again later",
|
||||
},
|
||||
keyGenerator: (req) => {
|
||||
return `${
|
||||
req.headers["cf-connecting-ip"] ||
|
||||
req.headers["x-forwarded-for"] ||
|
||||
req.ip ||
|
||||
"255.255.255.255"
|
||||
}`;
|
||||
},
|
||||
});
|
||||
|
||||
exports.limit1persec = rateLimit({
|
||||
windowMs: 60 * 1000,
|
||||
// Leaderboards Routing
|
||||
exports.leaderboardsGet = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 60 * multiplier,
|
||||
message: {
|
||||
message: "Too many requests, please try again later",
|
||||
},
|
||||
keyGenerator: (req) => {
|
||||
return `${
|
||||
req.headers["cf-connecting-ip"] ||
|
||||
req.headers["x-forwarded-for"] ||
|
||||
req.ip ||
|
||||
"255.255.255.255"
|
||||
}`;
|
||||
},
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.limit500perhour = rateLimit({
|
||||
// New Quotes Routing
|
||||
exports.newQuotesGet = rateLimit({
|
||||
windowMs: 60 * 60 * 1000,
|
||||
max: 500 * multiplier,
|
||||
message: {
|
||||
message: "Too many requests, please try again later",
|
||||
},
|
||||
keyGenerator: (req) => {
|
||||
return `${
|
||||
req.headers["cf-connecting-ip"] ||
|
||||
req.headers["x-forwarded-for"] ||
|
||||
req.ip ||
|
||||
"255.255.255.255"
|
||||
}`;
|
||||
},
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.newQuotesAdd = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.newQuotesAction = rateLimit({
|
||||
windowMs: 60 * 60 * 1000,
|
||||
max: 500 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
// Quote Ratings Routing
|
||||
exports.quoteRatingsGet = rateLimit({
|
||||
windowMs: 60 * 60 * 1000,
|
||||
max: 500 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.quoteRatingsSubmit = rateLimit({
|
||||
windowMs: 60 * 60 * 1000,
|
||||
max: 500 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
// Presets Routing
|
||||
exports.presetsGet = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.presetsAdd = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.presetsRemove = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.presetsEdit = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
// PSA (Public Service Announcement) Routing
|
||||
exports.psaGet = rateLimit({
|
||||
windowMs: 60 * 1000,
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
// Results Routing
|
||||
exports.resultsGet = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.resultsAdd = rateLimit({
|
||||
windowMs: 60 * 60 * 1000,
|
||||
max: 500 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.resultsTagsUpdate = rateLimit({
|
||||
windowMs: 60 * 60 * 1000,
|
||||
max: 30 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.resultsDeleteAll = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 10 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.resultsLeaderboardGet = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.resultsLeaderboardQualificationGet = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
// Users Routing
|
||||
exports.userGet = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 1 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.userSignup = rateLimit({
|
||||
windowMs: 24 * 60 * 60 * 1000, // 1 day
|
||||
max: 3 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.userDelete = rateLimit({
|
||||
windowMs: 24 * 60 * 60 * 1000, // 1 day
|
||||
max: 3 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.userCheckName = rateLimit({
|
||||
windowMs: 60 * 1000,
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.userUpdateName = rateLimit({
|
||||
windowMs: 24 * 60 * 60 * 1000, // 1 day
|
||||
max: 3 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.userUpdateLBMemory = rateLimit({
|
||||
windowMs: 60 * 1000,
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.userUpdateEmail = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.userClearPB = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.userTagsGet = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.userTagsRemove = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 30 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.userTagsClearPB = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 60 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.userTagsEdit = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 30 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.userTagsAdd = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 30 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.userDiscordLink = exports.usersTagsEdit = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 15 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
||||
|
||||
exports.userDiscordUnlink = exports.usersTagsEdit = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 60 min
|
||||
max: 15 * multiplier,
|
||||
message,
|
||||
keyGenerator: getAddress
|
||||
});
|
Loading…
Reference in a new issue