sanket3280/code-execution
0
1 2const rateLimit = require('express-rate-limit');3const { ipKeyGenerator } = require('express-rate-limit');4 5// Strict rate limiter for authentication endpoints6const authLimiter = rateLimit({7 windowMs: 15 * 60 * 1000, // 15 minutes8 max: 10000, // 8 requests per window9 standardHeaders: true,10 legacyHeaders: false,11 skipSuccessfulRequests: false, // Count all requests12 handler: (req, res) => {13 res.status(429).json({14 error: 'Too many login attempts',15 message: 'Too many login attempts! Please wait 15 minutes before trying again. ๐',16 retryAfter: 900,17 tip: 'For security, we limit login attempts. Take a break and try again later! โ'18 });19 }20});21 22// Moderate rate limiter for password reset23const passwordResetLimiter = rateLimit({24 windowMs: 60 * 60 * 1000, // 1 hour25 max: 3, // 3 requests per hour26 standardHeaders: true,27 legacyHeaders: false,28 handler: (req, res) => {29 res.status(429).json({30 error: 'Too many password reset attempts',31 message: 'Too many password reset requests! Please wait 1 hour before trying again. ๐',32 retryAfter: 3600,33 tip: 'Check your email for previous reset links or contact support if you need help! ๐ง'34 });35 }36});37 38// Lenient rate limiter for general API39const apiLimiter = rateLimit({40 windowMs: 1 * 60 * 1000, // 1 minute41 max: 100000, // 100 requests per window42 message: {43 error: 'Rate limit exceeded',44 message: 'Whoa! Slow down there! ๐ข You\'ve made too many requests. Please wait 1 minute and try again.',45 retryAfter: 6046 },47 standardHeaders: true,48 legacyHeaders: false,49 handler: (req, res) => {50 res.status(429).json({51 error: 'Rate limit exceeded',52 message: 'Too many requests! Please wait 1 minute before trying again. โฐ',53 retryAfter: 60,54 tip: 'Take a quick break and come back in a minute! โ'55 });56 }57});58 59// User-specific rate limiter for code execution endpoints60const codeExecutionLimiter = rateLimit({61 windowMs: 60 * 1000, // 1 minute62 max: 10, // 10 requests per minute per user63 keyGenerator: (req) => {64 // Use user ID if authenticated, otherwise use default IP handling65 if (req.user?.id) {66 return `user:${req.user.id}`;67 }68 // Return undefined to use default IP-based key generation with IPv6 support69 return undefined;70 },71 standardHeaders: true,72 legacyHeaders: false,73 handler: (req, res) => {74 res.status(429).json({75 error: 'Rate limit exceeded',76 message: 'Too many code execution requests! Please wait 1 minute before trying again. โฐ',77 retryAfter: 60,78 tip: 'Code execution is resource-intensive. Please wait before submitting again! ๐ป'79 });80 }81});82 83// Very strict for OTP verification84const otpVerifyLimiter = rateLimit({85 windowMs: 15 * 60 * 1000, // 15 minutes86 max: 300, // 10 attempts per 15 minutes87 standardHeaders: true,88 legacyHeaders: false,89 handler: (req, res) => {90 res.status(429).json({91 error: 'Too many OTP attempts',92 message: 'Too many OTP verification attempts! Please wait 15 minutes. ๐ข',93 retryAfter: 900,94 tip: 'Request a new OTP after the wait time or check if you entered the correct code! โ๏ธ'95 });96 }97});98 99// Strict rate limiter for challenge join attempts (prevent password brute force)100const challengeJoinLimiter = rateLimit({101 windowMs: 15 * 60 * 1000, // 15 minutes102 max: 10, // 10 join attempts per 15 minutes per user103 keyGenerator: (req) => {104 // Use combination of user/IP and challenge ID for rate limiting105 const userKey = req.user?.id ? `user:${req.user.id}` : ipKeyGenerator(req);106 return `${userKey}_challenge:${req.params.id}`;107 },108 standardHeaders: true,109 legacyHeaders: false,110 skipSuccessfulRequests: true, // Only count failed attempts111 handler: (req, res) => {112 res.status(429).json({113 error: 'Too many join attempts',114 message: 'Too many join attempts for this challenge! Please wait 15 minutes before trying again. ๐',115 retryAfter: 900,116 tip: 'Make sure you have the correct password. Contact the challenge creator if you need help! ๐ง'117 });118 }119});120 121module.exports = {122 authLimiter,123 passwordResetLimiter,124 apiLimiter,125 otpVerifyLimiter,126 codeExecutionLimiter,127 challengeJoinLimiter,128};129 