rate limiting and api security enhancements

This commit is contained in:
2024-09-10 13:47:16 +02:00
parent 88991c9de0
commit 158a8ca0bb
4 changed files with 195 additions and 0 deletions

61
lib/rate-limiter.ts Normal file
View File

@@ -0,0 +1,61 @@
interface RateLimitData {
count: number
resetTime: number
}
const cache = new Map<string, RateLimitData>()
export interface RateLimitConfig {
windowMs: number
maxRequests: number
}
const defaultConfig: RateLimitConfig = {
windowMs: 60 * 1000, // 1 minute
maxRequests: 100
}
export function rateLimit(
identifier: string,
config: RateLimitConfig = defaultConfig
): { allowed: boolean; remaining: number; resetTime: number } {
const now = Date.now()
const windowStart = now - config.windowMs
// Clean expired entries
for (const [key, data] of cache.entries()) {
if (data.resetTime < now) {
cache.delete(key)
}
}
let data = cache.get(identifier)
if (!data || data.resetTime < now) {
data = {
count: 0,
resetTime: now + config.windowMs
}
}
data.count++
cache.set(identifier, data)
const allowed = data.count <= config.maxRequests
const remaining = Math.max(0, config.maxRequests - data.count)
return {
allowed,
remaining,
resetTime: data.resetTime
}
}
export function getRateLimitHeaders(result: ReturnType<typeof rateLimit>) {
return {
'X-RateLimit-Limit': '100',
'X-RateLimit-Remaining': result.remaining.toString(),
'X-RateLimit-Reset': new Date(result.resetTime).toISOString()
}
}