Skip to content

fix(auth): unify nonce implementations, add consume path, eviction, and bounded store - #1758

Merged
Baskarayelu merged 1 commit into
Remitwise-Org:mainfrom
CollinsKRO:main
Oct 22, 2026
Merged

Baskarayelu merged 1 commit into
Remitwise-Org:mainfrom
CollinsKRO:main

Conversation

@CollinsKRO

Copy link
Copy Markdown

Closes #1751

Summary

Consolidates three diverged nonce implementations into a single core in lib/auth/nonce.ts with a thin HTTP adapter in app/api/auth/nonce/route.ts.

Changes

  • Refactored lib/auth/nonce.ts to support per-address supersede, O(1) consume, lazy purge on access, and bounded store with LRU eviction
  • Rewrote app/api/auth/nonce/route.ts as a thin adapter over the core, preserving the public GET contract (validation codes, headers, response shape)
  • Deleted lib/auth-cache.ts (unused third implementation)
  • Deleted app/api/auth/nonce/route.test.ts (tested POST handler and resolveAddressFromRequest that never existed in the live route)
  • Added tests for all acceptance criteria: single-use, supersede, expiry, bounded store, TTL clamping

Three implementations resolved

  1. app/api/auth/nonce/route.ts (live GET route) → now thin adapter
  2. lib/auth/nonce.ts (failure boundary core) → now the single source of truth
  3. lib/auth-cache.ts (third store with sweeper) → deleted

Eviction policy

  • Lazy purge on access (get/findByNonce) removes expired/consumed entries
  • Background sweep every 60s (unref'd) for passive cleanup
  • LRU eviction when store exceeds NONCE_STORE_MAX (default 50,000)
  • TTL clamped to 30s–10min everywhere

Test expectations changed

  • route.test.ts deleted: tested non-existent POST/resolveAddressFromRequest
  • auth-nonce.test.ts: updated TTL tests to account for 30s minimum clamp
  • nonce.test.ts: added supersede, expiry, bounded store tests

…nd bounded store

Closes Remitwise-Org#1751

## Summary
Consolidates three diverged nonce implementations into a single core in lib/auth/nonce.ts with a thin HTTP adapter in app/api/auth/nonce/route.ts.

## Changes
- Refactored lib/auth/nonce.ts to support per-address supersede, O(1) consume, lazy purge on access, and bounded store with LRU eviction
- Rewrote app/api/auth/nonce/route.ts as a thin adapter over the core, preserving the public GET contract (validation codes, headers, response shape)
- Deleted lib/auth-cache.ts (unused third implementation)
- Deleted app/api/auth/nonce/route.test.ts (tested POST handler and resolveAddressFromRequest that never existed in the live route)
- Added tests for all acceptance criteria: single-use, supersede, expiry, bounded store, TTL clamping

## Three implementations resolved
1. app/api/auth/nonce/route.ts (live GET route) → now thin adapter
2. lib/auth/nonce.ts (failure boundary core) → now the single source of truth
3. lib/auth-cache.ts (third store with sweeper) → deleted

## Eviction policy
- Lazy purge on access (get/findByNonce) removes expired/consumed entries
- Background sweep every 60s (unref'd) for passive cleanup
- LRU eviction when store exceeds NONCE_STORE_MAX (default 50,000)
- TTL clamped to 30s–10min everywhere

## Test expectations changed
- route.test.ts deleted: tested non-existent POST/resolveAddressFromRequest
- auth-nonce.test.ts: updated TTL tests to account for 30s minimum clamp
- nonce.test.ts: added supersede, expiry, bounded store tests
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.

fix(auth): nonce issuance is split across three diverged implementations; nonces are never consumed and the live store never evicts

2 participants