Skip to content

Commit b6ca706

Browse files
committed
feat(rate-limiter): add IP allowlist and blocklist support
1 parent 5790627 commit b6ca706

1 file changed

Lines changed: 31 additions & 0 deletions

File tree

lib/rate-limit.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export class RateLimiter {
1818
private cache: TTLCache<number>;
1919
private limit: number;
2020
private windowMs: number;
21+
private allowlist = new Set<string>();
22+
private blocklist = new Set<string>();
2123

2224
/**
2325
* Creates a new RateLimiter instance.
@@ -46,6 +48,8 @@ export class RateLimiter {
4648
* }
4749
*/
4850
check(ip: string): boolean {
51+
if (this.allowlist.has(ip)) return true; // for check()
52+
if (this.blocklist.has(ip)) return false; // for check()
4953
const current = this.cache.get(ip) || 0;
5054
if (current >= this.limit) {
5155
return false;
@@ -54,6 +58,15 @@ export class RateLimiter {
5458
return true;
5559
}
5660
checkWithResult(ip: string): RateLimitResult {
61+
if (this.allowlist.has(ip))
62+
return {
63+
success: true,
64+
limit: this.limit,
65+
remaining: this.limit,
66+
reset: Date.now() + this.windowMs,
67+
};
68+
if (this.blocklist.has(ip))
69+
return { success: false, limit: this.limit, remaining: 0, reset: Date.now() + this.windowMs };
5770
const now = Date.now();
5871
const current = this.cache.get(ip) ?? 0;
5972

@@ -88,6 +101,24 @@ export class RateLimiter {
88101
reset(ip: string): void {
89102
this.cache.delete(ip);
90103
}
104+
105+
allow(ip: string): void {
106+
this.allowlist.add(ip);
107+
this.blocklist.delete(ip);
108+
}
109+
110+
block(ip: string): void {
111+
this.blocklist.add(ip);
112+
this.allowlist.delete(ip);
113+
}
114+
115+
unallow(ip: string): void {
116+
this.allowlist.delete(ip);
117+
}
118+
119+
unblock(ip: string): void {
120+
this.blocklist.delete(ip);
121+
}
91122
}
92123

93124
// Global instance for track-user endpoint (5 requests per IP per minute)

0 commit comments

Comments
 (0)