UNPKG

secure-express-setup

Version:

Military-grade one-command security setup for Express.js applications

61 lines (53 loc) 2.15 kB
const rateLimit = require("express-rate-limit"); /** * Setup rate limiting middleware * @param {Object} options - Rate limit options * @param {String} redisUrl - Optional Redis URL for distributed rate limiting */ function setupRateLimit(options = {}, redisUrl) { const config = { windowMs: options.windowMs || 15 * 60 * 1000, // 15 minutes max: options.max || 100, // limit each IP to 100 requests per windowMs message: options.message || "Too many requests from this IP, please try again later.", standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers legacyHeaders: false, // Disable the `X-RateLimit-*` headers skipFailedRequests: options.skipFailedRequests || false, skipSuccessfulRequests: options.skipSuccessfulRequests || false, skip: (req, res) => { // Skip rate limiting for certain paths (like health checks) if (req.path === "/health" || req.path === "/api-docs") { return true; } // Skip if rate limit bypass is set (for testing) if (req.rateLimitBypass) { return true; } return false; } }; // If Redis URL is provided, try to use Redis store if (redisUrl && redisUrl !== "redis://localhost:6379") { try { // Try the new way first (rate-limit-redis v4+) const { RedisStore } = require("rate-limit-redis"); const { createClient } = require("redis"); const redisClient = createClient({ url: redisUrl }); redisClient.on("error", (err) => { console.warn("Redis connection error (rate limiting):", err.message); }); config.store = new RedisStore({ sendCommand: (...args) => redisClient.sendCommand(args), prefix: "rate-limit:" }); } catch (err) { console.warn("Redis store unavailable for rate limiting:", err.message); console.warn("Falling back to in-memory store"); // Continue with in-memory store } } // Return the rate limit middleware return rateLimit(config); } module.exports = setupRateLimit;