2023-06-19 10:01:06 +00:00
|
|
|
import { Ratelimit } from "@upstash/ratelimit";
|
|
|
|
import { Redis } from "@upstash/redis";
|
2022-08-30 19:58:35 +00:00
|
|
|
|
2023-06-19 10:01:06 +00:00
|
|
|
import { isIpInBanListString } from "./getIP";
|
|
|
|
import logger from "./logger";
|
2022-08-30 19:58:35 +00:00
|
|
|
|
2023-06-19 10:01:06 +00:00
|
|
|
const log = logger.getChildLogger({ prefix: ["RateLimit"] });
|
2022-08-30 19:58:35 +00:00
|
|
|
|
2023-06-19 10:01:06 +00:00
|
|
|
type RateLimitHelper = {
|
|
|
|
rateLimitingType?: "core" | "forcedSlowMode";
|
|
|
|
identifier: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
function rateLimiter() {
|
|
|
|
const UPSATCH_ENV_FOUND = process.env.UPSTASH_REDIS_REST_URL && process.env.UPSTASH_REDIS_REST_TOKEN;
|
2022-08-30 19:58:35 +00:00
|
|
|
|
2023-06-19 10:01:06 +00:00
|
|
|
if (!UPSATCH_ENV_FOUND) {
|
|
|
|
log.warn("Disabled due to not finding UPSTASH env variables");
|
|
|
|
return () => ({ success: true });
|
|
|
|
}
|
2022-08-30 19:58:35 +00:00
|
|
|
|
2023-06-19 10:01:06 +00:00
|
|
|
const redis = Redis.fromEnv();
|
|
|
|
const limiter = {
|
|
|
|
core: new Ratelimit({
|
|
|
|
redis,
|
|
|
|
analytics: true,
|
|
|
|
prefix: "ratelimit",
|
|
|
|
limiter: Ratelimit.fixedWindow(10, "60s"),
|
|
|
|
}),
|
|
|
|
forcedSlowMode: new Ratelimit({
|
|
|
|
redis,
|
|
|
|
analytics: true,
|
|
|
|
prefix: "ratelimit:slowmode",
|
|
|
|
limiter: Ratelimit.fixedWindow(1, "30s"),
|
|
|
|
}),
|
2022-08-30 19:58:35 +00:00
|
|
|
};
|
|
|
|
|
2023-06-19 10:01:06 +00:00
|
|
|
async function rateLimit({ rateLimitingType = "core", identifier }: RateLimitHelper) {
|
|
|
|
if (isIpInBanListString(identifier)) {
|
|
|
|
return await limiter.forcedSlowMode.limit(identifier);
|
|
|
|
}
|
|
|
|
|
|
|
|
return await limiter[rateLimitingType].limit(identifier);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rateLimit;
|
|
|
|
}
|
|
|
|
|
|
|
|
export default rateLimiter;
|