Files
MOPC-Portal/src/lib/rate-limit.ts

60 lines
1.4 KiB
TypeScript
Raw Normal View History

/**
* Simple in-memory rate limiter using fixed window approach.
* Tracks request counts per key (typically IP) within time windows.
*
* For production with multiple instances, replace with Redis-based solution.
*/
type RateLimitEntry = {
count: number
resetAt: number
}
const store = new Map<string, RateLimitEntry>()
export type RateLimitResult = {
success: boolean
remaining: number
resetAt: number
}
/**
* Check rate limit for a given key.
* @param key - Identifier (e.g., IP address)
* @param limit - Max requests per window
* @param windowMs - Window size in milliseconds
*/
export function checkRateLimit(
key: string,
limit: number,
windowMs: number
): RateLimitResult {
const now = Date.now()
const entry = store.get(key)
if (!entry || now > entry.resetAt) {
const resetAt = now + windowMs
store.set(key, { count: 1, resetAt })
return { success: true, remaining: limit - 1, resetAt }
}
if (entry.count >= limit) {
return { success: false, remaining: 0, resetAt: entry.resetAt }
}
entry.count++
return { success: true, remaining: limit - entry.count, resetAt: entry.resetAt }
}
// Clean up stale entries every 5 minutes to prevent memory leaks
if (typeof setInterval !== 'undefined') {
setInterval(() => {
const now = Date.now()
for (const [key, entry] of store) {
if (now > entry.resetAt) {
store.delete(key)
}
}
}, 5 * 60 * 1000).unref?.()
}