Files
test/packages/contracts/src/rate-limit/index.ts
Benjamin Falch 2bc741fb78
Some checks failed
Mark Stale PRs / stale (push) Has been cancelled
adding monkeytype
2026-04-23 13:53:44 +02:00

412 lines
5.7 KiB
TypeScript

export type Window = "second" | "minute" | "hour" | "day" | number;
export type RateLimitOptions = {
/** Timeframe or time in milliseconds */
window: Window;
/** Max request within the given window */
max: number;
};
export const limits = {
defaultApeRateLimit: {
window: "minute",
max: 30,
},
adminLimit: {
window: 5000,
max: 1,
},
// Config Routing
configUpdate: {
window: "hour",
max: 500,
},
configGet: {
window: "hour",
max: 120,
},
configDelete: {
window: "hour",
max: 120,
},
// Leaderboards Routing
leaderboardsGet: {
window: "hour",
max: 500,
},
// New Quotes Routing
newQuotesGet: {
window: "hour",
max: 500,
},
newQuotesIsSubmissionEnabled: {
window: "minute",
max: 60,
},
newQuotesAdd: {
window: "hour",
max: 60,
},
newQuotesAction: {
window: "hour",
max: 500,
},
// Quote Ratings Routing
quoteRatingsGet: {
window: "hour",
max: 500,
},
quoteRatingsSubmit: {
window: "hour",
max: 500,
},
// Quote reporting
quoteReportSubmit: {
window: 30 * 60 * 1000, // 30 min
max: 50,
},
// Quote favorites
quoteFavoriteGet: {
window: 30 * 60 * 1000, // 30 min
max: 50,
},
quoteFavoritePost: {
window: 30 * 60 * 1000, // 30 min
max: 50,
},
quoteFavoriteDelete: {
window: 30 * 60 * 1000, // 30 min
max: 50,
},
// Presets Routing
presetsGet: {
window: "hour",
max: 60,
},
presetsAdd: {
window: "hour",
max: 60,
},
presetsRemove: {
window: "hour",
max: 60,
},
presetsEdit: {
window: "hour",
max: 60,
},
// PSA (Public Service Announcement) Routing
psaGet: {
window: "minute",
max: 60,
},
// get public speed stats
publicStatsGet: {
window: "minute",
max: 60,
},
// Results Routing
resultsGet: {
window: "hour",
max: 60,
},
// Results Routing
resultsGetApe: {
window: "day",
max: 30,
},
// Result by id
resultByIdGet: {
window: "hour",
max: 300,
},
// Result by id
resultByIdGetApe: {
window: "hour",
max: 60,
},
resultsAdd: {
window: "hour",
max: 300,
},
resultsTagsUpdate: {
window: "hour",
max: 100,
},
resultsDeleteAll: {
window: "hour",
max: 10,
},
resultsLeaderboardGet: {
window: "hour",
max: 60,
},
resultsLeaderboardQualificationGet: {
window: "hour",
max: 60,
},
// Users Routing
userGet: {
window: "hour",
max: 60,
},
setStreakHourOffset: {
window: "hour",
max: 5,
},
userSignup: {
window: "day",
max: 2,
},
userDelete: {
window: "day",
max: 3,
},
userReset: {
window: "day",
max: 3,
},
userCheckName: {
window: "minute",
max: 60,
},
userUpdateName: {
window: "day",
max: 3,
},
userUpdateLBMemory: {
window: "minute",
max: 60,
},
userUpdateEmail: {
window: "hour",
max: 60,
},
userClearPB: {
window: "hour",
max: 60,
},
userOptOutOfLeaderboards: {
window: "hour",
max: 10,
},
userCustomFilterAdd: {
window: "hour",
max: 60,
},
userCustomFilterRemove: {
window: "hour",
max: 60,
},
userTagsGet: {
window: "hour",
max: 60,
},
userTagsRemove: {
window: "hour",
max: 30,
},
userTagsClearPB: {
window: "hour",
max: 60,
},
userTagsEdit: {
window: "hour",
max: 30,
},
userTagsAdd: {
window: "hour",
max: 30,
},
userCustomThemeGet: {
window: "hour",
max: 30,
},
userCustomThemeAdd: {
window: "hour",
max: 30,
},
userCustomThemeRemove: {
window: "hour",
max: 30,
},
userCustomThemeEdit: {
window: "hour",
max: 30,
},
userDiscordLink: {
window: "hour",
max: 15,
},
userDiscordUnlink: {
window: "hour",
max: 15,
},
userRequestVerificationEmail: {
window: 15 * 60 * 1000, //15 minutes
max: 1,
},
userForgotPasswordEmail: {
window: "minute",
max: 1,
},
userRevokeAllTokens: {
window: "hour",
max: 10,
},
userProfileGet: {
window: "hour",
max: 100,
},
userProfileUpdate: {
window: "hour",
max: 60,
},
userMailGet: {
window: "hour",
max: 60,
},
userMailUpdate: {
window: "hour",
max: 60,
},
userTestActivity: {
window: "hour",
max: 60,
},
userCurrentTestActivity: {
window: "hour",
max: 60,
},
userStreak: {
window: "hour",
max: 60,
},
userFriendGet: {
window: "hour",
max: 60,
},
// ApeKeys Routing
apeKeysGet: {
window: "hour",
max: 120,
},
apeKeysGenerate: {
window: "hour",
max: 15,
},
webhookLimit: {
window: "second",
max: 1,
},
connectionGet: {
window: "hour",
max: 60,
},
connectionCreate: {
window: "hour",
max: 60,
},
connectionDelete: {
window: "hour",
max: 60,
},
connectionUpdate: {
window: "hour",
max: 60,
},
} satisfies Record<string, RateLimitOptions>;
export type RateLimiterId = keyof typeof limits;
export type RateLimitIds = {
/** rate limiter options for non-apeKey requests */
normal: RateLimiterId;
/** Rate limiter options for apeKey requests */
apeKey: RateLimiterId;
};
export function getLimits(limit: RateLimiterId | RateLimitIds): {
limiter: RateLimitOptions;
apeKeyLimiter?: RateLimitOptions;
} {
const isApeKeyLimiter = typeof limit === "object";
const limiter = isApeKeyLimiter ? limit.normal : limit;
const apeLimiter = isApeKeyLimiter ? limit.apeKey : undefined;
return {
limiter: limits[limiter],
apeKeyLimiter: apeLimiter !== undefined ? limits[apeLimiter] : undefined,
};
}