Skip to content

Commit 0a341f0

Browse files
authored
fix(rate-limiter): prevent TTL reset on every request in sliding window (JhaSourav07#1236)
## Description The TTL was being reset on every request inside `check()` and `checkWithResult()`, meaning aggressive IPs could extend their window indefinitely. Fixed by only setting the TTL on the first request (count === 0) and incrementing without refreshing expiry on subsequent calls. Window is now fixed from the first request as intended. Fixes JhaSourav07#1210 ## Pillar - [ ] 🎨 Pillar 1 — New Theme Design - [ ] 📐 Pillar 2 — Geometric SVG Improvement - [ ] 🕐 Pillar 3 — Timezone Logic Optimization - [x] 🛠️ Other (Bug fix, refactoring, docs) ## Visual Preview N/A — internal logic fix, no visual output. ## Checklist before requesting a review: - [x] I have read the `CONTRIBUTING.md` file. - [x] I have tested these changes locally (`localhost:3000/api/streak?user=YOUR_USERNAME`). - [x] I have run `npm run format` and `npm run lint` locally and resolved all errors (CI will fail otherwise). - [x] My commits follow the Conventional Commits format (e.g., `fix(rate-limiter): ...`). - [ ] I have updated `README.md` if I added a new theme or URL parameter. - [x] I have starred the repo. - [x] I have made sure that I have only one commit to merge in this PR. - [ ] The SVG output matches the CommitPulse "premium quality" aesthetic standard (no raw elements, smooth animations, correct fonts). - [ ] (Recommended) I joined the CommitPulse Discord community for contributor discussions, mentorship, and faster PR support.
2 parents 1c75955 + 854dc35 commit 0a341f0

1 file changed

Lines changed: 13 additions & 7 deletions

File tree

lib/rate-limit.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,15 @@ export class RateLimiter {
4848
* }
4949
*/
5050
check(ip: string): boolean {
51-
if (this.allowlist.has(ip)) return true; // for check()
52-
if (this.blocklist.has(ip)) return false; // for check()
53-
const current = this.cache.get(ip) || 0;
54-
if (current >= this.limit) {
55-
return false;
51+
if (this.allowlist.has(ip)) return true;
52+
if (this.blocklist.has(ip)) return false;
53+
const current = this.cache.get(ip) ?? 0;
54+
if (current >= this.limit) return false;
55+
if (current === 0) {
56+
this.cache.set(ip, 1, this.windowMs);
57+
} else {
58+
this.cache.set(ip, current + 1, this.windowMs);
5659
}
57-
this.cache.set(ip, current + 1, this.windowMs);
5860
return true;
5961
}
6062
checkWithResult(ip: string): RateLimitResult {
@@ -79,7 +81,11 @@ export class RateLimiter {
7981
};
8082
}
8183

82-
this.cache.set(ip, current + 1, this.windowMs);
84+
if (current === 0) {
85+
this.cache.set(ip, 1, this.windowMs);
86+
} else {
87+
this.cache.set(ip, current + 1, this.windowMs);
88+
}
8389
return {
8490
success: true,
8591
limit: this.limit,

0 commit comments

Comments
 (0)