Files
turnosxpress/server/src/middleware/ratelimiter.ts
T

68 lines
2.2 KiB
TypeScript

import { Request, Response, NextFunction } from "express";
import { ApiValidationError } from "../Models/Server.Error.model";
const ipLastRequest = new Map<string, number>();
const ratingIpRequests = new Map<string, number[]>();
const RATING_RATE_LIMIT_WINDOW_MS = 60000;
const RATING_RATE_LIMIT_MAX_REQUESTS = 20;
// Limpia las IPs cada hora
setInterval(() => {
const now = Date.now();
const timeLimit = process.env.WAP_TIME_LIMIT ? parseInt(process.env.WAP_TIME_LIMIT) : 5000;
ipLastRequest.forEach((time, ip) => {
if (now - time > timeLimit) ipLastRequest.delete(ip);
});
ratingIpRequests.forEach((times, ip) => {
const recentTimes = times.filter((time) => now - time <= RATING_RATE_LIMIT_WINDOW_MS);
if (recentTimes.length === 0) {
ratingIpRequests.delete(ip);
return;
}
ratingIpRequests.set(ip, recentTimes);
});
}, 3600000);
export async function rateLimiter(
request: Request,
response: Response,
next: NextFunction
): Promise<void | Response | ApiValidationError> {
const ip = request.ip;
const timeLimit = process.env.WAP_TIME_LIMIT ? parseInt(process.env.WAP_TIME_LIMIT) : 5000;
const currentTime = Date.now();
const lastRequestTime = ipLastRequest.get(ip) || 0;
if (currentTime - lastRequestTime < timeLimit) {
response
.status(429)
.json(new ApiValidationError(429, "Demasiadas solicitudes. Por favor espere!"));
return;
}
ipLastRequest.set(ip, currentTime);
next();
}
export async function ratingRateLimiter(
request: Request,
response: Response,
next: NextFunction
): Promise<void | Response | ApiValidationError> {
const ip = request.ip;
const currentTime = Date.now();
const windowStart = currentTime - RATING_RATE_LIMIT_WINDOW_MS;
const recentRequests = (ratingIpRequests.get(ip) || []).filter((time) => time > windowStart);
if (recentRequests.length >= RATING_RATE_LIMIT_MAX_REQUESTS) {
response
.status(429)
.json(new ApiValidationError(429, "Demasiadas solicitudes. Por favor espere!"));
return;
}
recentRequests.push(currentTime);
ratingIpRequests.set(ip, recentRequests);
next();
}