Skip to content

refactor: extract auth rate-limit storage adapter to dedicated module#307

Merged
kodiakhq[bot] merged 4 commits into
mainfrom
claude/better-auth-rate-limiting-bbg1tx
Jul 22, 2026
Merged

refactor: extract auth rate-limit storage adapter to dedicated module#307
kodiakhq[bot] merged 4 commits into
mainfrom
claude/better-auth-rate-limiting-bbg1tx

Conversation

@RedStar071

@RedStar071 RedStar071 commented Jul 20, 2026

Copy link
Copy Markdown
Member

🔗 Linked issue

N/A

🧭 Context

The auth rate-limit storage adapter in server/auth.config.ts was a simple inline implementation. This change extracts it into a dedicated module (server/utils/auth-rate-limit-storage.ts) to improve maintainability and enable comprehensive testing of the rate-limiting logic.

📚 Description

Changes:

  1. New module: server/utils/auth-rate-limit-storage.ts

    • Exports createAuthSecondaryStorage() function that adapts a Nitro/unstorage mount to better-auth's SecondaryStorage interface
    • Implements an atomic-ish increment() method using an in-process keyed mutex (AsyncQueue) to serialize read-modify-write cycles per storage key
    • Implements a fixed-window counter where the window's expiry is set at creation and never extended by later increments
    • Includes detailed comments explaining the design and limitations (cross-instance races remain possible with HTTP-based storage backends like Cloudflare KV)
  2. Updated server/auth.config.ts

    • Replaced inline storage adapter with a call to createAuthSecondaryStorage()
    • Simplified from ~10 lines of inline code to a single function call
    • Updated comment to reflect the extraction
  3. New test file: test/unit/server/utils/auth-rate-limit-storage.spec.ts

    • Comprehensive unit tests covering all invariants:
      • Fresh window starts at count 1
      • Counts increment within the same window
      • Window expiry is fixed and never extended
      • Count resets when window expires
      • Concurrent increments are serialized (no lost updates)
      • Different keys maintain independent counters
      • Standard get/set/delete operations still work

The increment() method is critical for better-auth's rate limiter to use its single-step consume path instead of falling back to a non-atomic get-then-set operation that logs a warning.

Test Plan:

Added unit tests covering all rate-limiting invariants. Tests pass with the new implementation.

https://claude.ai/code/session_01L3DbZF2CQPuxRnBFWHjVxS


View with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is enabled.

Confidence Score: 5/5

Safe to merge with low risk.

The change is a focused refactor with unit tests for the new storage behavior, and the auth configuration continues to match the documented better-auth rate-limit setup.

No files require special attention.

T-Rex T-Rex Logs

What T-Rex did

  • Executed the contract-validation run and confirmed the test suite reported 51 test files passed and 1019 tests passed, with an EXIT_CODE of 0 and ELAPSED_SECONDS of 15.
  • Reviewed the auth-rate-limit-storage-unit.log artifact to validate the reported test results and exit status.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (3): Last reviewed commit: "Merge branch 'main' into claude/better-a..." | Re-trigger Greptile

claude added 2 commits July 19, 2026 22:19
better-auth logs "Rate limiting is best-effort" and falls back to a
non-atomic get-then-set check whenever its secondaryStorage lacks an
increment(key, ttl) method. Add createAuthSecondaryStorage(), which
wraps the Cloudflare KV / fsLite-backed wolfstar:auth-ratelimiter
mount with a fixed-window increment guarded by an in-process keyed
mutex (same pattern as server/utils/wrappedEventHandler.ts), so
better-auth uses its atomic consume path instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3DbZF2CQPuxRnBFWHjVxS
Adds dotenv, dotenvx, and vite-plus entries picked up by `skilld prepare`
during `pnpm install`.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3DbZF2CQPuxRnBFWHjVxS
@codspeed-hq

codspeed-hq Bot commented Jul 20, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 44 untouched benchmarks


Comparing claude/better-auth-rate-limiting-bbg1tx (d9e6ef9) with main (88743ca)

Open in CodSpeed

@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.95238% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.59%. Comparing base (8babfde) to head (d9e8506).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
server/utils/auth-rate-limit-storage.ts 80.95% 0 Missing and 4 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #307      +/-   ##
==========================================
+ Coverage   71.53%   71.59%   +0.05%     
==========================================
  Files         167      168       +1     
  Lines        3302     3323      +21     
  Branches      702      706       +4     
==========================================
+ Hits         2362     2379      +17     
  Misses        447      447              
- Partials      493      497       +4     
Flag Coverage Δ
component 66.09% <ø> (ø)
unit 67.86% <80.95%> (+0.19%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
server/utils/auth-rate-limit-storage.ts 80.95% <80.95%> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread .claude/skills/dotenv Outdated
The skilld lockfile sync committed absolute symlinks (dotenv, dotenvx,
vite-plus) pointing at /home/user/.../node_modules paths that only exist
on the author's machine, so they resolve to broken skills in any fresh
checkout or CI workspace. Remove the symlinks and their shipped lock
entries.

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
@RedStar071
RedStar071 requested a review from lorypelli July 22, 2026 07:52

@lorypelli lorypelli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@kodiakhq
kodiakhq Bot merged commit 6194ef0 into main Jul 22, 2026
21 of 23 checks passed
@kodiakhq
kodiakhq Bot deleted the claude/better-auth-rate-limiting-bbg1tx branch July 22, 2026 11: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.

3 participants