T.ME/BIBIL_0DAY
CasperSecurity


Server : Apache/2
System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User : gositeme ( 1004)
PHP Version : 8.2.29
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Directory :  /home/gositeme/domains/lavocat.ca/public_html/src/lib/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/lavocat.ca/public_html/src/lib/rate-limit.ts
import { NextApiRequest, NextApiResponse } from 'next';

// Simple in-memory rate limiter (for production, use Redis)
const rateLimitMap = new Map<string, { count: number; resetTime: number }>();

interface RateLimitOptions {
  interval: number; // Time window in milliseconds
  uniqueTokenPerInterval: number; // Max requests per interval
}

export function rateLimit(options: RateLimitOptions) {
  return async (req: NextApiRequest, res: NextApiResponse, next: () => void) => {
    // Get client identifier (IP + User-Agent for better uniqueness)
    const identifier = `${req.headers['x-forwarded-for'] || req.connection.remoteAddress || 'unknown'}-${req.headers['user-agent'] || 'unknown'}`;
    
    const now = Date.now();
    const windowStart = now - options.interval;
    
    // Get or create rate limit data for this identifier
    const rateLimitData = rateLimitMap.get(identifier) || { count: 0, resetTime: now + options.interval };
    
    // Reset if window has passed
    if (now > rateLimitData.resetTime) {
      rateLimitData.count = 0;
      rateLimitData.resetTime = now + options.interval;
    }
    
    // Check if limit exceeded
    if (rateLimitData.count >= options.uniqueTokenPerInterval) {
      const resetIn = Math.ceil((rateLimitData.resetTime - now) / 1000);
      
      console.log('🚫 Rate limit exceeded for:', identifier, 'count:', rateLimitData.count);
      
      res.status(429).json({
        error: 'Too many requests',
        message: `Rate limit exceeded. Try again in ${resetIn} seconds.`,
        resetIn
      });
      return;
    }
    
    // Increment counter
    rateLimitData.count++;
    rateLimitMap.set(identifier, rateLimitData);
    
    // Clean up old entries periodically
    if (Math.random() < 0.01) { // 1% chance to clean up
      cleanupOldEntries();
    }
    
    // Set rate limit headers
    res.setHeader('X-RateLimit-Limit', options.uniqueTokenPerInterval);
    res.setHeader('X-RateLimit-Remaining', Math.max(0, options.uniqueTokenPerInterval - rateLimitData.count));
    res.setHeader('X-RateLimit-Reset', Math.ceil(rateLimitData.resetTime / 1000));
    
    next();
  };
}

function cleanupOldEntries() {
  const now = Date.now();
  rateLimitMap.forEach((data, key) => {
    if (now > data.resetTime) {
      rateLimitMap.delete(key);
    }
  });
}

// Common rate limit configurations
export const rateLimits = {
  // Strict rate limit for sensitive operations
  strict: { interval: 15 * 60 * 1000, uniqueTokenPerInterval: 5 }, // 5 requests per 15 minutes
  
  // Moderate rate limit for admin operations
  moderate: { interval: 5 * 60 * 1000, uniqueTokenPerInterval: 20 }, // 20 requests per 5 minutes
  
  // Standard rate limit for API endpoints
  standard: { interval: 60 * 1000, uniqueTokenPerInterval: 100 }, // 100 requests per minute
  
  // Lenient rate limit for general use
  lenient: { interval: 60 * 1000, uniqueTokenPerInterval: 300 }, // 300 requests per minute
}; 

CasperSecurity Mini