-
Notifications
You must be signed in to change notification settings - Fork 217
/
Copy pathrateLimiter.ts
58 lines (49 loc) · 1.87 KB
/
rateLimiter.ts
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
47
48
49
50
51
52
53
54
55
56
57
58
import rateLimit, { RateLimitRequestHandler } from 'express-rate-limit';
import { searchIP } from 'range_check';
import { RateLimiterConfig } from '../types';
export class RateLimiter {
PATH: string;
constructor(app: any, configs: RateLimiterConfig[]) {
this.PATH = configs[0].RATELIMIT.PATH || '/api/sendToken';
let rateLimiters: any = new Map()
configs.forEach((config: any) => {
const { RATELIMIT } = config;
let RL_CONFIG = {
MAX_LIMIT: RATELIMIT.MAX_LIMIT,
WINDOW_SIZE: RATELIMIT.WINDOW_SIZE,
SKIP_FAILED_REQUESTS: RATELIMIT.SKIP_FAILED_REQUESTS || true,
}
rateLimiters.set(config.ID, this.getLimiter(RL_CONFIG));
});
app.use(this.PATH, (req: any, res: any, next: any) => {
if(this.PATH == '/api/sendToken' && req.body.chain) {
return rateLimiters.get(req.body.chain)(req, res, next)
} else {
return rateLimiters.get(configs[0].ID)(req, res, next)
}
});
}
getLimiter(config: any): RateLimitRequestHandler {
const limiter = rateLimit({
windowMs: config.WINDOW_SIZE * 60 * 1000,
max: config.MAX_LIMIT,
standardHeaders: true,
legacyHeaders: false,
skipFailedRequests: config.SKIP_FAILED_REQUESTS,
message: {
message: `Too many requests. Please try again after ${config.WINDOW_SIZE} minutes`
},
keyGenerator: (req, res) => {
const ip = this.getIP(req);
if(ip != null) {
return ip + req.body?.chain;
}
}
});
return limiter;
}
getIP(req: any) {
const ip = req.headers['cf-connecting-ip'] || req.ip;
return searchIP(ip);
}
}