Skip to main content
Glama
zqushair
by zqushair
rateLimiting.ts4.15 kB
import { Request, Response, NextFunction } from 'express'; import rateLimit from 'express-rate-limit'; import { config } from '../config/index.js'; import logger from '../utils/logger.js'; /** * Rate Limiting Middleware * This middleware limits the number of requests a client can make in a given time window */ export class RateLimitingMiddleware { /** * Create a rate limiter middleware * @param options Rate limiting options * @returns A rate limiter middleware */ public static createRateLimiter(options?: { windowMs?: number; max?: number; message?: string; statusCode?: number; keyGenerator?: (req: Request) => string; skip?: (req: Request, res: Response) => boolean; }) { // Get rate limiting configuration from environment variables or use defaults const windowMs = options?.windowMs || config.security.rateLimiting.windowMs || 60 * 1000; // 1 minute const max = options?.max || config.security.rateLimiting.max || 100; // 100 requests per minute const message = options?.message || 'Too many requests, please try again later.'; const statusCode = options?.statusCode || 429; // Too Many Requests // Create a rate limiter const limiter = rateLimit({ windowMs, max, message, statusCode, standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers legacyHeaders: false, // Disable the `X-RateLimit-*` headers keyGenerator: options?.keyGenerator || ((req) => { // Use IP address as the default key return req.ip || 'unknown'; }), skip: options?.skip, handler: (req: Request, res: Response, next: NextFunction, options: any) => { // Log rate limit exceeded logger.warn('Rate limit exceeded', { ip: req.ip, path: req.path, method: req.method, windowMs, max, }); // Send rate limit exceeded response res.status(options.statusCode).send(options.message); }, }); return limiter; } /** * Create a rate limiter middleware for API endpoints * @returns A rate limiter middleware for API endpoints */ public static createApiRateLimiter() { return RateLimitingMiddleware.createRateLimiter({ windowMs: config.security.rateLimiting.api?.windowMs || 60 * 1000, // 1 minute max: config.security.rateLimiting.api?.max || 100, // 100 requests per minute message: 'Too many API requests, please try again later.', }); } /** * Create a rate limiter middleware for authentication endpoints * @returns A rate limiter middleware for authentication endpoints */ public static createAuthRateLimiter() { return RateLimitingMiddleware.createRateLimiter({ windowMs: config.security.rateLimiting.auth?.windowMs || 15 * 60 * 1000, // 15 minutes max: config.security.rateLimiting.auth?.max || 5, // 5 requests per 15 minutes message: 'Too many authentication attempts, please try again later.', }); } /** * Create a rate limiter middleware for webhook endpoints * @returns A rate limiter middleware for webhook endpoints */ public static createWebhookRateLimiter() { return RateLimitingMiddleware.createRateLimiter({ windowMs: config.security.rateLimiting.webhook?.windowMs || 60 * 1000, // 1 minute max: config.security.rateLimiting.webhook?.max || 200, // 200 requests per minute message: 'Too many webhook requests, please try again later.', }); } /** * Create a rate limiter middleware for a specific IP address * @param ip The IP address to limit * @param options Rate limiting options * @returns A rate limiter middleware for the specified IP address */ public static createIpRateLimiter( ip: string, options?: { windowMs?: number; max?: number; message?: string; statusCode?: number; } ) { return RateLimitingMiddleware.createRateLimiter({ ...options, keyGenerator: () => ip, skip: (req) => req.ip !== ip, }); } } // Export the middleware export default RateLimitingMiddleware;

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zqushair/Frontapp-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server