This commit is contained in:
411
packages/contracts/src/rate-limit/index.ts
Normal file
411
packages/contracts/src/rate-limit/index.ts
Normal file
@@ -0,0 +1,411 @@
|
||||
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,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user