mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-03-15 05:41:51 +00:00
feat: add rate limits to import/export
This commit is contained in:
parent
45941e47d6
commit
fc4f106afb
3 changed files with 32 additions and 2 deletions
|
@ -5,6 +5,8 @@ import { clientError, ok } from "../responses";
|
|||
import { GuildCases } from "../../data/GuildCases";
|
||||
import { z } from "zod";
|
||||
import { Case } from "../../data/entities/Case";
|
||||
import { rateLimit } from "../rateLimits";
|
||||
import { MINUTES } from "../../utils";
|
||||
|
||||
const caseHandlingModeSchema = z.union([
|
||||
z.literal("replace"),
|
||||
|
@ -62,6 +64,11 @@ export function initGuildsImportExportAPI(guildRouter: express.Router) {
|
|||
importExportRouter.post(
|
||||
"/:guildId/import",
|
||||
requireGuildPermission(ApiPermissions.ManageAccess),
|
||||
rateLimit(
|
||||
(req) => `import-${req.params.guildId}`,
|
||||
5 * MINUTES,
|
||||
"A single server can only import data once every 5 minutes",
|
||||
),
|
||||
async (req: Request, res: Response) => {
|
||||
let data: TImportExportData;
|
||||
try {
|
||||
|
@ -119,6 +126,11 @@ export function initGuildsImportExportAPI(guildRouter: express.Router) {
|
|||
importExportRouter.post(
|
||||
"/:guildId/export",
|
||||
requireGuildPermission(ApiPermissions.ManageAccess),
|
||||
rateLimit(
|
||||
(req) => `export-${req.params.guildId}`,
|
||||
5 * MINUTES,
|
||||
"A single server can only export data once every 5 minutes",
|
||||
),
|
||||
async (req: Request, res: Response) => {
|
||||
const guildCases = GuildCases.getGuildInstance(req.params.guildId);
|
||||
|
||||
|
|
18
backend/src/api/rateLimits.ts
Normal file
18
backend/src/api/rateLimits.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { Request, Response } from "express";
|
||||
import { error } from "./responses";
|
||||
|
||||
const lastRequestsByKey: Map<string, number> = new Map();
|
||||
|
||||
export function rateLimit(getKey: (req: Request) => string, limitMs: number, message = "Rate limited") {
|
||||
return async (req: Request, res: Response, next) => {
|
||||
const key = getKey(req);
|
||||
if (lastRequestsByKey.has(key)) {
|
||||
if (lastRequestsByKey.get(key)! > Date.now() - limitMs) {
|
||||
return error(res, message, 429);
|
||||
}
|
||||
}
|
||||
|
||||
lastRequestsByKey.set(key, Date.now());
|
||||
next();
|
||||
};
|
||||
}
|
|
@ -108,7 +108,7 @@ export default {
|
|||
caseHandlingMode: this.importCaseMode,
|
||||
});
|
||||
} catch (err) {
|
||||
this.importError = String(err);
|
||||
this.importError = err.body?.error ?? String(err);
|
||||
return;
|
||||
} finally {
|
||||
this.importing = false;
|
||||
|
@ -134,7 +134,7 @@ export default {
|
|||
guildId: this.$route.params.guildId,
|
||||
});
|
||||
} catch (err) {
|
||||
this.exportError = String(err);
|
||||
this.exportError = err.body?.error ?? String(err);
|
||||
return;
|
||||
} finally {
|
||||
this.exporting = false;
|
||||
|
|
Loading…
Add table
Reference in a new issue