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-11-04 18:14:38 -05:00
|
|
|
etier1a: 1000,
|
2024-11-05 13:08:01 -05:00
|
|
|
etier2a: 300,
|
2024-12-11 19:46:11 -03:00
|
|
|
etierscale1: 150
|
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-11-04 18:14:38 -05:00
|
|
|
etier1a: 1000,
|
2024-11-05 13:08:01 -05:00
|
|
|
etier2a: 2500,
|
2024-12-11 19:46:11 -03:00
|
|
|
etierscale1: 1500
|
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-11-04 18:14:38 -05:00
|
|
|
etier1a: 1000,
|
2024-11-05 13:08:01 -05:00
|
|
|
etier2a: 2500,
|
2024-12-11 19:46:11 -03:00
|
|
|
etierscale1: 1500
|
2024-05-30 14:31:36 -07:00
|
|
|
},
|
2024-12-11 19:46:11 -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-11-04 18:14:38 -05:00
|
|
|
etier1a: 1000,
|
2024-11-05 13:08:01 -05:00
|
|
|
etier2a: 2500,
|
2024-12-11 19:46:11 -03:00
|
|
|
etierscale1: 1500
|
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-12-11 19:46:11 -03:00
|
|
|
default: 5
|
2024-06-06 11:23:10 -07:00
|
|
|
},
|
|
|
|
|
account: {
|
2024-06-14 12:13:02 -07:00
|
|
|
free: 100,
|
2024-12-11 19:46:11 -03:00
|
|
|
default: 100
|
2024-06-06 11:23:10 -07:00
|
|
|
},
|
|
|
|
|
crawlStatus: {
|
2024-11-27 12:47:11 -03:00
|
|
|
free: 300,
|
2024-12-11 19:46:11 -03:00
|
|
|
default: 500
|
2024-06-06 11:23:10 -07:00
|
|
|
},
|
|
|
|
|
testSuite: {
|
2024-06-06 11:53:12 -07:00
|
|
|
free: 10000,
|
2024-12-11 19:46:11 -03: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(
|
2024-11-07 20:57:33 +01:00
|
|
|
process.env.REDIS_RATE_LIMIT_URL!
|
2024-12-11 19:46:11 -03:00
|
|
|
);
|
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,
|
2024-12-11 19:46:11 -03:00
|
|
|
duration: 60 // Duration in seconds
|
2024-06-06 11:23:10 -07:00
|
|
|
});
|
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-12-11 19:46:11 -03:00
|
|
|
duration: 60 // Duration in seconds
|
2024-05-08 15:14:39 -07:00
|
|
|
});
|
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,
|
2024-12-11 19:46:11 -03:00
|
|
|
duration: 60 // Duration in seconds
|
2024-08-26 16:05:11 -03:00
|
|
|
});
|
|
|
|
|
|
2024-09-13 18:09:59 -04:00
|
|
|
export const manualRateLimiter = new RateLimiterRedis({
|
|
|
|
|
storeClient: redisRateLimitClient,
|
|
|
|
|
keyPrefix: "manual",
|
|
|
|
|
points: 2000,
|
2024-12-11 19:46:11 -03:00
|
|
|
duration: 60 // Duration in seconds
|
2024-09-13 18:09:59 -04:00
|
|
|
});
|
|
|
|
|
|
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-12-11 19:46:11 -03:00
|
|
|
duration: 60 // Duration in seconds
|
2024-08-31 14:23:55 -03:00
|
|
|
});
|
|
|
|
|
|
2024-11-04 18:14:38 -05:00
|
|
|
export const etier1aRateLimiter = new RateLimiterRedis({
|
|
|
|
|
storeClient: redisRateLimitClient,
|
|
|
|
|
keyPrefix: "etier1a",
|
|
|
|
|
points: 10000,
|
2024-12-11 19:46:11 -03:00
|
|
|
duration: 60 // Duration in seconds
|
2024-11-04 18:14:38 -05:00
|
|
|
});
|
|
|
|
|
|
2024-11-05 13:08:01 -05:00
|
|
|
export const etier2aRateLimiter = new RateLimiterRedis({
|
|
|
|
|
storeClient: redisRateLimitClient,
|
|
|
|
|
keyPrefix: "etier2a",
|
|
|
|
|
points: 2500,
|
2024-12-11 19:46:11 -03:00
|
|
|
duration: 60 // Duration in seconds
|
2024-11-05 13:08:01 -05:00
|
|
|
});
|
|
|
|
|
|
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-11-19 17:51:31 -08:00
|
|
|
"4c2638d",
|
2024-10-30 17:19:37 -03:00
|
|
|
"cbb3462", // don't remove (s-ai)
|
|
|
|
|
"824abcd" // don't remove (s-ai)
|
2024-10-08 15:11:08 -03:00
|
|
|
];
|
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-12-11 19:46:11 -03:00
|
|
|
): number {
|
2024-10-01 16:04:39 -03:00
|
|
|
const rateLimitConfig = RATE_LIMITS[mode]; // {default : 5}
|
|
|
|
|
|
|
|
|
|
if (!rateLimitConfig) return RATE_LIMITS.account.default;
|
2024-12-11 19:46:11 -03:00
|
|
|
|
|
|
|
|
const points: number =
|
2024-10-01 16:04:39 -03:00
|
|
|
rateLimitConfig[makePlanKey(plan)] || rateLimitConfig.default; // 5
|
|
|
|
|
return points;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getRateLimiter(
|
|
|
|
|
mode: RateLimiterMode,
|
|
|
|
|
token?: string,
|
|
|
|
|
plan?: string,
|
|
|
|
|
teamId?: string
|
2024-12-11 19:46:11 -03:00
|
|
|
): RateLimiterRedis {
|
|
|
|
|
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-12-11 19:46:11 -03:00
|
|
|
if (teamId && teamId === process.env.DEV_B_TEAM_ID) {
|
2024-08-26 16:05:11 -03:00
|
|
|
return devBRateLimiter;
|
|
|
|
|
}
|
2024-12-11 19:46:11 -03:00
|
|
|
|
|
|
|
|
if (teamId && teamId === process.env.ETIER1A_TEAM_ID) {
|
2024-11-04 18:14:38 -05:00
|
|
|
return etier1aRateLimiter;
|
|
|
|
|
}
|
2024-08-26 16:05:11 -03:00
|
|
|
|
2024-12-11 19:46:11 -03:00
|
|
|
if (teamId && teamId === process.env.ETIER2A_TEAM_ID) {
|
2024-11-05 13:08:01 -05:00
|
|
|
return etier2aRateLimiter;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-11 19:46:11 -03:00
|
|
|
if (teamId && teamId === process.env.ETIER2D_TEAM_ID) {
|
2024-11-21 13:45:30 -03:00
|
|
|
return etier2aRateLimiter;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-11 19:46:11 -03:00
|
|
|
if (teamId && manual.includes(teamId)) {
|
2024-09-13 18:09:59 -04:00
|
|
|
return manualRateLimiter;
|
|
|
|
|
}
|
2024-12-11 19:46:11 -03:00
|
|
|
|
|
|
|
|
return createRateLimiter(
|
|
|
|
|
`${mode}-${makePlanKey(plan)}`,
|
|
|
|
|
getRateLimiterPoints(mode, token, plan, teamId)
|
|
|
|
|
);
|
2024-04-15 17:01:47 -04:00
|
|
|
}
|