Import source: app/backend/src/lib/rate-limit

Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
arsam
2026-09-18 23:19:34 +03:30
parent c88280d9f4
commit 59039e7f28
+43
View File
@@ -0,0 +1,43 @@
import { redis } from '../redis.js';
export interface RateLimitResult {
limited: boolean;
retryAfter: number;
}
export async function checkRateLimit(
ip: string,
action: string,
max: number,
windowSeconds: number,
): Promise<RateLimitResult> {
const key = `rl:${action}:${ip}`;
const hits = await redis.incr(key);
if (hits === 1) await redis.expire(key, windowSeconds);
if (hits > max) {
const ttl = await redis.ttl(key);
return { limited: true, retryAfter: Math.max(ttl, 1) };
}
return { limited: false, retryAfter: 0 };
}
export async function checkRateLimitBySubject(
subject: string,
action: string,
max: number,
windowSeconds: number,
): Promise<RateLimitResult> {
const key = `rl:${action}:${subject}`;
const hits = await redis.incr(key);
if (hits === 1) await redis.expire(key, windowSeconds);
if (hits > max) {
const ttl = await redis.ttl(key);
return { limited: true, retryAfter: Math.max(ttl, 1) };
}
return { limited: false, retryAfter: 0 };
}
export function rateLimitResponse(reply: import('fastify').FastifyReply, retryAfter: number) {
reply.header('Retry-After', String(retryAfter));
return reply.code(429).send({ error: 'rate_limited', retryAfter });
}