rateLimiter.js•2.4 kB
/**
* Rate limiter middleware
* Limits the number of requests from a single IP address
*/
const rateLimit = require('express-rate-limit');
const { RateLimitError } = require('../utils/errorTypes');
const config = require('../config');
const logger = require('../utils/logger');
/**
* Parse rate limit window from string (e.g. '15m', '1h')
* @param {string} windowStr - Rate limit window string
* @returns {number} - Window in milliseconds
*/
const parseWindow = (windowStr) => {
const unit = windowStr.slice(-1);
const value = parseInt(windowStr.slice(0, -1));
switch (unit) {
case 's':
return value * 1000;
case 'm':
return value * 60 * 1000;
case 'h':
return value * 60 * 60 * 1000;
case 'd':
return value * 24 * 60 * 60 * 1000;
default:
return 15 * 60 * 1000; // Default: 15 minutes
}
};
/**
* Create a rate limiter middleware
* @param {Object} options - Rate limiter options
* @returns {Function} - Rate limiter middleware
*/
const createRateLimiter = (options = {}) => {
const windowMs = options.windowMs || parseWindow(config.RATE_LIMIT_WINDOW);
const max = options.max || parseInt(config.RATE_LIMIT_MAX);
return rateLimit({
windowMs,
max,
standardHeaders: true,
legacyHeaders: false,
skipSuccessfulRequests: options.skipSuccessfulRequests || false,
skip: options.skip || (() => false),
handler: (req, res, next) => {
const error = new RateLimitError(
`Too many requests from this IP, please try again after ${windowMs / 60000} minutes`,
Math.ceil(windowMs / 1000)
);
logger.warn(`Rate limit exceeded for IP: ${req.ip}`);
next(error);
}
});
};
/**
* Default API rate limiter
* Limits all API requests
*/
const apiLimiter = createRateLimiter();
/**
* Authentication rate limiter
* More strict limits for authentication endpoints
*/
const authLimiter = createRateLimiter({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 10, // 10 requests per 15 minutes
skipSuccessfulRequests: false
});
/**
* Facebook API rate limiter
* Limits requests to Facebook API endpoints
*/
const facebookApiLimiter = createRateLimiter({
windowMs: 60 * 1000, // 1 minute
max: 20, // 20 requests per minute
skipSuccessfulRequests: true
});
module.exports = {
createRateLimiter,
apiLimiter,
authLimiter,
facebookApiLimiter
};