| import { db } from '@/lib/db'; |
|
|
| export async function rateLimit( |
| key: string, |
| maxRequests: number, |
| windowMs: number |
| ): Promise<{ allowed: boolean; retryAfterMs: number }> { |
| const now = new Date(); |
|
|
| try { |
| const record = await db.rateLimit.findUnique({ |
| where: { key }, |
| }); |
|
|
| if (!record) { |
| await db.rateLimit.create({ |
| data: { |
| key, |
| count: 1, |
| resetAt: new Date(now.getTime() + windowMs), |
| }, |
| }); |
| return { allowed: true, retryAfterMs: 0 }; |
| } |
|
|
| if (now >= record.resetAt) { |
| |
| const updated = await db.rateLimit.update({ |
| where: { key }, |
| data: { |
| count: 1, |
| resetAt: new Date(now.getTime() + windowMs), |
| }, |
| }); |
| return { allowed: true, retryAfterMs: 0 }; |
| } |
|
|
| if (record.count >= maxRequests) { |
| const retryAfterMs = record.resetAt.getTime() - now.getTime(); |
| return { allowed: false, retryAfterMs }; |
| } |
|
|
| await db.rateLimit.update({ |
| where: { key }, |
| data: { count: { increment: 1 } }, |
| }); |
|
|
| return { allowed: true, retryAfterMs: 0 }; |
| } catch { |
| |
| return { allowed: true, retryAfterMs: 0 }; |
| } |
| } |
|
|
| |
| export const authRateLimit = (key: string) => |
| rateLimit(key, 5, 60_000); |
|
|
| export const uploadRateLimit = (key: string) => |
| rateLimit(key, 20, 60_000); |
|
|
| export const chatRateLimit = (key: string) => |
| rateLimit(key, 20, 60_000); |
|
|
| export const generalRateLimit = (key: string) => |
| rateLimit(key, 60, 60_000); |