Skip to content

fix(login): successful logins do not use up the IP's rate limit (1.3.1) - #11

Merged
BackStacked merged 1 commit into
mainfrom
claude/project-thread-dvfnaw
Oct 27, 2026
Merged

BackStacked merged 1 commit into
mainfrom
claude/project-thread-dvfnaw

Conversation

@BackStacked

Copy link
Copy Markdown
Contributor

Requested by Himanshu · project thread

Problem

login hits login:ip:<ip> (10 per 15 min in the api) before checking the password, and only the email key is reset on success. Successful logins therefore used up the IP's budget. In the local end-to-end test, 10 correct sign-ins from one IP were followed by RATE_LIMITED for 15 minutes. At a branch where all staff share one internet connection, the 11th person to sign in during a shift change gets locked out.

Fix

  • RateLimiter gets an optional undo(key) that takes back the latest hit. memoryRateLimiter pops it and redisRateLimiter uses ZPOPMAX.
  • After a successful login, login calls limiter.undo?.("login:ip:<ip>").
  • Every attempt is still counted before the password is checked, so a burst of parallel guesses is still blocked. A custom limiter without undo keeps the old behaviour.
  • The per-email limit and the reset limits are unchanged. The interface stays structural: the method is optional, and db-kit doesn't implement this interface.

Tests

New check, run on both the memory and the Redis (ioredis-mock) limiters, with a 3-per-window limit: 6 successful logins from one IP all succeed, and 3 failures from that IP still lead to RATE_LIMITED on the 4th. npm run typecheck passes and npm test gives 128 passed, 0 failed. Version 1.3.1; README, AGENTS.md and llms-full.txt updated.

After merge: tag v1.3.1, then the api moves to ^1.3.1.


Generated by Claude Code

10 logins per IP per 15 minutes counted successes too, so the 11th member
of staff on one office connection was locked out with RATE_LIMITED. Every
attempt is still counted before verification (bursts stay blocked); a
successful login now takes its IP hit back (RateLimiter.undo, optional;
memory and Redis limiters implement it). Per-email limits are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Bj7Tb5PweikTen79CdVH4
@BackStacked BackStacked self-assigned this Oct 27, 2026
@BackStacked
BackStacked merged commit ec56dea into main Oct 27, 2026
1 check passed
@BackStacked
BackStacked deleted the claude/project-thread-dvfnaw branch October 27, 2026 13:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants