summaryrefslogtreecommitdiff
path: root/rateLimiter.ts
blob: 239ef8854dc15ebdb8e63ef3d4111946c6d380c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import { config } from "./config.ts";
import { logger } from "./logger.ts";

interface RateLimitEntry {
  count: number;
  resetTime: number;
}

class RateLimiter {
  private storage = new Map<string, RateLimitEntry>();

  isRateLimited(ip: string): boolean {
    const now = Date.now();
    const entry = this.storage.get(ip);

    if (!entry || now > entry.resetTime) {
      this.storage.set(ip, {
        count: 1,
        resetTime: now + config.rateLimit.windowMs,
      });
      return false;
    }

    if (entry.count >= config.rateLimit.maxUploads) {
      logger.security("WARN", "Rate limit exceeded", { ip, count: entry.count });
      return true;
    }

    entry.count++;
    return false;
  }

  cleanup() {
    const now = Date.now();
    for (const [ip, entry] of this.storage.entries()) {
      if (now > entry.resetTime) {
        this.storage.delete(ip);
      }
    }
  }
}

export const rateLimiter = new RateLimiter();

// Cleanup expired entries every 5 minutes
setInterval(() => rateLimiter.cleanup(), 5 * 60 * 1000);