Files
lidify/backend/src/middleware/rateLimiter.ts
T
2025-12-25 18:58:06 -06:00

59 lines
2.4 KiB
TypeScript

import rateLimit from "express-rate-limit";
// General API rate limiter (5000 req/minute per IP)
// This is for a single-user self-hosted app, so limits should be VERY high
// Only exists to prevent infinite loops or bugs from DOS'ing the server
export const apiLimiter = rateLimit({
windowMs: 1 * 60 * 1000, // 1 minute
max: 5000, // Very high limit - personal app, not a public API
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
skip: (req) => {
// Never rate limit streaming or status polling endpoints
return req.path.includes("/stream") ||
req.path.includes("/status") ||
req.path.includes("/health");
},
});
// Auth limiter for login endpoints (20 attempts/15min per IP)
// More lenient for self-hosted apps where users may have password manager issues
export const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 20, // Increased from 5 for self-hosted environments
skipSuccessfulRequests: true, // Don't count successful requests
message: "Too many login attempts, please try again in 15 minutes.",
standardHeaders: true,
legacyHeaders: false,
});
// Media streaming limiter (higher limit: 200 streams/minute)
export const streamLimiter = rateLimit({
windowMs: 1 * 60 * 1000, // 1 minute
max: 200, // Allow 200 stream requests per minute
message: "Too many streaming requests, please slow down.",
standardHeaders: true,
legacyHeaders: false,
});
// Image/Cover art limiter (very high limit: 500 req/minute)
// This is for image proxying - not a security risk, just bandwidth
export const imageLimiter = rateLimit({
windowMs: 1 * 60 * 1000, // 1 minute
max: 500, // Allow 500 image requests per minute (high volume pages need this)
message: "Too many image requests, please slow down.",
standardHeaders: true,
legacyHeaders: false,
});
// Download limiter (100 req/minute)
// Users might download entire discographies, so this needs to be reasonable
export const downloadLimiter = rateLimit({
windowMs: 1 * 60 * 1000, // 1 minute
max: 100,
message: "Too many download requests, please try again later.",
standardHeaders: true,
legacyHeaders: false,
});