68 lines
2.2 KiB
TypeScript
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();
|
|
}
|