Skip to content

Commit

Permalink
refactor: change fastify rate limiting config
Browse files Browse the repository at this point in the history
  • Loading branch information
favna committed Oct 14, 2024
1 parent ae3573f commit c8c0a0d
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 7 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@
"extends": "@sapphire"
},
"packageManager": "[email protected]"
}
}
2 changes: 1 addition & 1 deletion src/backend/lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const config: Config = {

rateLimits: {
max: envParseInteger('RATE_LIMIT_MAX', 500),
timeWindow: envParseString('RATE_LIMIT_TIME_WINDOW', '1 minute')
timeWindow: envParseInteger('RATE_LIMIT_TIME_WINDOW', 1000 * 60)
},

storage: {
Expand Down
19 changes: 15 additions & 4 deletions src/backend/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,21 @@ export interface Config {

/** The rate limit configuration */
interface RateLimitsConfig {
/** The maximum amount of requests within the timespan {@link RateLimitsConfig.timeWindow timeWindow} */
/**
* Maximum number of requests a single client can perform inside a {@link RateLimitsConfig.timeWindow timeWindow}.
*
* It can be an async function with the signature `async (request, key) => {}` where `request` is the
* Fastify request object and `key` is the value generated by the `keyGenerator`. The function **must** return a number.
*/
max: number;
/** The time window in which the requests count, in the {@linkplain https://github.com/zeit/ms ms} string format */
timeWindow: string;
/**
* The duration of the time window.
*
* It can be expressed in milliseconds, as a string (in the [`ms`](https://github.com/zeit/ms) format), or as an
* async function with the signature `async (request, key) => {}` where `request` is the Fastify request object and
* `key` is the value generated by the `keyGenerator`. The function **must** return a number.
*/
timeWindow: number;
}

/** The storage options */
Expand Down Expand Up @@ -80,7 +91,7 @@ declare module '@skyra/env-utilities' {
KEY_LENGTH: IntegerString;
MAX_LENGTH: IntegerString;
RATE_LIMIT_MAX: IntegerString;
RATE_LIMIT_TIME_WINDOW: string;
RATE_LIMIT_TIME_WINDOW: IntegerString;
STORAGE_TYPE: 'file' | 'redis';
STORAGE_HOST: string;
STORAGE_PORT: IntegerString;
Expand Down
18 changes: 17 additions & 1 deletion src/backend/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,23 @@ fastify.setErrorHandler((error, _, reply) => {
// Register the rate limit handler
await fastify.register(import('@fastify/rate-limit'), {
max: config.rateLimits.max,
timeWindow: config.rateLimits.timeWindow
timeWindow: config.rateLimits.timeWindow,
keyGenerator: (request) => {
console.log(request.headers);
const xRealIp = request.headers['x-real-ip'];
if (typeof xRealIp === 'string') return xRealIp;
return request.ip;
},
errorResponseBuilder: (_, context) => {
return {
statusCode: 429,
error: 'Too Many Requests',
message: `Rate limit exceeded. Only ${context.max} requests per ${context.after} to this service are allowed. Retry in ${context.after}ms.`,
date: Date.now(),
expiresIn: context.ttl
};
},
allowList: []
});

// Register Fastify Sensible for sending errors
Expand Down

0 comments on commit c8c0a0d

Please sign in to comment.