2024-04-15 17:01:47 -04:00
|
|
|
import { RateLimiterRedis } from "rate-limiter-flexible";
|
2024-04-20 14:02:22 -07:00
|
|
|
import { RateLimiterMode } from "../../src/types";
|
2024-07-16 22:41:13 -04:00
|
|
|
import Redis from "ioredis";
|
2024-04-15 17:01:47 -04:00
|
|
|
|
2024-05-30 14:31:36 -07:00
|
|
|
const RATE_LIMITS = {
|
|
|
|
|
crawl: {
|
2024-06-06 11:23:10 -07:00
|
|
|
default: 3,
|
2024-06-05 14:38:10 -07:00
|
|
|
free: 2,
|
2024-09-10 06:53:24 -03:00
|
|
|
starter: 10,
|
2024-05-30 14:31:36 -07:00
|
|
|
standard: 5,
|
2024-06-06 09:29:25 -07:00
|
|
|
standardOld: 40,
|
2024-07-24 16:56:19 -04:00
|
|
|
scale: 50,
|
2024-05-30 14:31:36 -07:00
|
|
|
hobby: 3,
|
|
|
|
|
standardNew: 10,
|
2024-06-23 18:59:08 -03:00
|
|
|
standardnew: 10,
|
2024-05-30 14:31:36 -07:00
|
|
|
growth: 50,
|
2024-08-15 18:37:19 -04:00
|
|
|
growthdouble: 50,
|
2024-10-29 21:01:43 -03:00
|
|
|
etier2c: 300,
|
2024-05-30 14:31:36 -07:00
|
|
|
},
|
|
|
|
|
scrape: {
|
2024-08-27 12:08:50 -03:00
|
|
|
default: 20,
|
|
|
|
|
free: 10,
|
2024-09-10 06:53:24 -03:00
|
|
|
starter: 100,
|
2024-08-27 12:08:50 -03:00
|
|
|
standard: 100,
|
2024-09-10 06:53:24 -03:00
|
|
|
standardOld: 100,
|
2024-08-27 12:08:50 -03:00
|
|
|
scale: 500,
|
|
|
|
|
hobby: 20,
|
|
|
|
|
standardNew: 100,
|
|
|
|
|
standardnew: 100,
|
|
|
|
|
growth: 1000,
|
|
|
|
|
growthdouble: 1000,
|
2024-10-29 21:01:43 -03:00
|
|
|
etier2c: 2500,
|
2024-08-27 12:08:50 -03:00
|
|
|
},
|
|
|
|
|
search: {
|
2024-06-06 11:23:10 -07:00
|
|
|
default: 20,
|
2024-05-30 14:31:36 -07:00
|
|
|
free: 5,
|
2024-09-10 06:53:24 -03:00
|
|
|
starter: 50,
|
|
|
|
|
standard: 50,
|
2024-05-30 14:31:36 -07:00
|
|
|
standardOld: 40,
|
2024-07-24 16:56:19 -04:00
|
|
|
scale: 500,
|
2024-05-30 14:31:36 -07:00
|
|
|
hobby: 10,
|
|
|
|
|
standardNew: 50,
|
2024-06-23 18:59:08 -03:00
|
|
|
standardnew: 50,
|
2024-05-30 14:31:36 -07:00
|
|
|
growth: 500,
|
2024-08-15 18:37:19 -04:00
|
|
|
growthdouble: 500,
|
2024-10-29 21:01:43 -03:00
|
|
|
etier2c: 2500,
|
2024-05-30 14:31:36 -07:00
|
|
|
},
|
2024-08-27 12:08:50 -03:00
|
|
|
map:{
|
2024-06-06 11:23:10 -07:00
|
|
|
default: 20,
|
2024-05-30 14:31:36 -07:00
|
|
|
free: 5,
|
2024-09-10 06:53:24 -03:00
|
|
|
starter: 50,
|
|
|
|
|
standard: 50,
|
|
|
|
|
standardOld: 50,
|
2024-07-24 16:56:19 -04:00
|
|
|
scale: 500,
|
2024-05-30 14:31:36 -07:00
|
|
|
hobby: 10,
|
|
|
|
|
standardNew: 50,
|
2024-06-23 18:59:08 -03:00
|
|
|
standardnew: 50,
|
2024-05-30 14:31:36 -07:00
|
|
|
growth: 500,
|
2024-08-15 18:37:19 -04:00
|
|
|
growthdouble: 500,
|
2024-10-29 21:01:43 -03:00
|
|
|
etier2c: 2500,
|
2024-05-30 14:31:36 -07:00
|
|
|
},
|
2024-06-06 11:23:10 -07:00
|
|
|
preview: {
|
2024-06-06 11:53:12 -07:00
|
|
|
free: 5,
|
2024-06-06 11:23:10 -07:00
|
|
|
default: 5,
|
|
|
|
|
},
|
|
|
|
|
account: {
|
2024-06-14 12:13:02 -07:00
|
|
|
free: 100,
|
|
|
|
|
default: 100,
|
2024-06-06 11:23:10 -07:00
|
|
|
},
|
|
|
|
|
crawlStatus: {
|
2024-06-06 11:53:12 -07:00
|
|
|
free: 150,
|
2024-08-28 14:17:59 -03:00
|
|
|
default: 250,
|
2024-06-06 11:23:10 -07:00
|
|
|
},
|
|
|
|
|
testSuite: {
|
2024-06-06 11:53:12 -07:00
|
|
|
free: 10000,
|
2024-06-06 11:23:10 -07:00
|
|
|
default: 10000,
|
|
|
|
|
},
|
2024-05-30 14:31:36 -07:00
|
|
|
};
|
2024-04-20 14:02:22 -07:00
|
|
|
|
2024-07-16 22:41:13 -04:00
|
|
|
export const redisRateLimitClient = new Redis(
|
|
|
|
|
process.env.REDIS_RATE_LIMIT_URL
|
|
|
|
|
)
|
2024-04-15 17:01:47 -04:00
|
|
|
|
2024-06-06 11:23:10 -07:00
|
|
|
const createRateLimiter = (keyPrefix, points) =>
|
|
|
|
|
new RateLimiterRedis({
|
2024-07-16 22:41:13 -04:00
|
|
|
storeClient: redisRateLimitClient,
|
2024-06-06 11:23:10 -07:00
|
|
|
keyPrefix,
|
|
|
|
|
points,
|
|
|
|
|
duration: 60, // Duration in seconds
|
|
|
|
|
});
|
2024-04-15 17:01:47 -04:00
|
|
|
|
2024-06-06 11:23:10 -07:00
|
|
|
export const serverRateLimiter = createRateLimiter(
|
|
|
|
|
"server",
|
2024-06-06 11:56:00 -07:00
|
|
|
RATE_LIMITS.account.default
|
2024-06-06 11:23:10 -07:00
|
|
|
);
|
2024-06-06 12:05:20 -07:00
|
|
|
|
2024-05-08 15:14:39 -07:00
|
|
|
export const testSuiteRateLimiter = new RateLimiterRedis({
|
2024-07-16 22:41:13 -04:00
|
|
|
storeClient: redisRateLimitClient,
|
2024-05-14 14:26:42 -07:00
|
|
|
keyPrefix: "test-suite",
|
2024-05-19 12:23:34 -07:00
|
|
|
points: 10000,
|
2024-05-08 15:14:39 -07:00
|
|
|
duration: 60, // Duration in seconds
|
|
|
|
|
});
|
2024-04-15 17:01:47 -04:00
|
|
|
|
2024-08-26 16:05:11 -03:00
|
|
|
export const devBRateLimiter = new RateLimiterRedis({
|
|
|
|
|
storeClient: redisRateLimitClient,
|
|
|
|
|
keyPrefix: "dev-b",
|
|
|
|
|
points: 1200,
|
|
|
|
|
duration: 60, // Duration in seconds
|
|
|
|
|
});
|
|
|
|
|
|
2024-09-13 18:09:59 -04:00
|
|
|
export const manualRateLimiter = new RateLimiterRedis({
|
|
|
|
|
storeClient: redisRateLimitClient,
|
|
|
|
|
keyPrefix: "manual",
|
|
|
|
|
points: 2000,
|
|
|
|
|
duration: 60, // Duration in seconds
|
|
|
|
|
});
|
|
|
|
|
|
2024-08-31 14:23:55 -03:00
|
|
|
|
|
|
|
|
export const scrapeStatusRateLimiter = new RateLimiterRedis({
|
|
|
|
|
storeClient: redisRateLimitClient,
|
|
|
|
|
keyPrefix: "scrape-status",
|
2024-08-31 14:26:16 -03:00
|
|
|
points: 400,
|
2024-08-31 14:23:55 -03:00
|
|
|
duration: 60, // Duration in seconds
|
|
|
|
|
});
|
|
|
|
|
|
2024-10-08 15:11:08 -03:00
|
|
|
const testSuiteTokens = [
|
|
|
|
|
"a01ccae",
|
|
|
|
|
"6254cf9",
|
|
|
|
|
"0f96e673",
|
|
|
|
|
"23befa1b",
|
|
|
|
|
"69141c4",
|
|
|
|
|
"48f9a97",
|
|
|
|
|
"5dc70ad",
|
|
|
|
|
"e5e60e5",
|
|
|
|
|
"65181ba",
|
|
|
|
|
"77c85b7",
|
|
|
|
|
"8567275",
|
|
|
|
|
"6c46abb",
|
|
|
|
|
"cb0ff78",
|
|
|
|
|
"fd769b2",
|
|
|
|
|
];
|
2024-09-11 14:03:34 -04:00
|
|
|
|
2024-09-13 18:09:59 -04:00
|
|
|
const manual = ["69be9e74-7624-4990-b20d-08e0acc70cf6"];
|
|
|
|
|
|
2024-09-28 00:19:46 +02:00
|
|
|
function makePlanKey(plan?: string) {
|
|
|
|
|
return plan ? plan.replace("-", "") : "default"; // "default"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getRateLimiterPoints(
|
2024-06-06 11:23:10 -07:00
|
|
|
mode: RateLimiterMode,
|
2024-09-28 00:19:46 +02:00
|
|
|
token?: string,
|
2024-08-26 16:05:11 -03:00
|
|
|
plan?: string,
|
|
|
|
|
teamId?: string
|
2024-10-01 16:04:39 -03:00
|
|
|
) : number {
|
|
|
|
|
const rateLimitConfig = RATE_LIMITS[mode]; // {default : 5}
|
|
|
|
|
|
|
|
|
|
if (!rateLimitConfig) return RATE_LIMITS.account.default;
|
2024-09-11 14:03:34 -04:00
|
|
|
|
2024-10-01 16:04:39 -03:00
|
|
|
const points : number =
|
|
|
|
|
rateLimitConfig[makePlanKey(plan)] || rateLimitConfig.default; // 5
|
|
|
|
|
return points;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getRateLimiter(
|
|
|
|
|
mode: RateLimiterMode,
|
|
|
|
|
token?: string,
|
|
|
|
|
plan?: string,
|
|
|
|
|
teamId?: string
|
|
|
|
|
) : RateLimiterRedis {
|
2024-09-28 00:19:46 +02:00
|
|
|
if (token && testSuiteTokens.some(testToken => token.includes(testToken))) {
|
2024-05-30 14:31:36 -07:00
|
|
|
return testSuiteRateLimiter;
|
|
|
|
|
}
|
2024-04-20 14:02:22 -07:00
|
|
|
|
2024-08-27 15:37:36 -03:00
|
|
|
if(teamId && teamId === process.env.DEV_B_TEAM_ID) {
|
2024-08-26 16:05:11 -03:00
|
|
|
return devBRateLimiter;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-13 18:09:59 -04:00
|
|
|
if(teamId && manual.includes(teamId)) {
|
|
|
|
|
return manualRateLimiter;
|
|
|
|
|
}
|
2024-10-01 16:04:39 -03:00
|
|
|
|
2024-09-28 00:19:46 +02:00
|
|
|
return createRateLimiter(`${mode}-${makePlanKey(plan)}`, getRateLimiterPoints(mode, token, plan, teamId));
|
2024-04-15 17:01:47 -04:00
|
|
|
}
|