LibreChat/api/server
JooyoungChoi14 54fc9c2c99
♾️ fix: Permanent Ban Cache and Expired Ban Cleanup Defects (#12324)
* fix: preserve ban data object in checkBan to prevent permanent cache

The !! operator on line 108 coerces the ban data object to a boolean,
losing the expiresAt property. This causes:

1. Number(true.expiresAt) = NaN → expired bans never cleaned from banLogs
2. banCache.set(key, true, NaN) → Keyv stores with expires: null (permanent)
3. IP-based cache entries persist indefinitely, blocking unrelated users

Fix: replace isBanned (boolean) with banData (original object) so that
expiresAt is accessible for TTL calculation and proper cache expiry.

* fix: address checkBan cleanup defects exposed by ban data fix

The prior commit correctly replaced boolean coercion with the ban data
object, but activated previously-dead cleanup code with several defects:

- IP-only expired bans fell through cleanup without returning next(),
  re-caching with negative TTL (permanent entry) and blocking the user
- Redis deployments used cache-prefixed keys for banLogs.delete(),
  silently failing since bans are stored at raw keys
- banCache.set() calls were fire-and-forget, silently dropping errors
- No guard for missing/invalid expiresAt reproduced the NaN TTL bug
  on legacy ban records

Consolidate expired-ban cleanup into a single block that always returns
next(), use raw keys (req.ip, userId) for banLogs.delete(), add an
expiresAt validity guard, await cache writes with error logging, and
parallelize independent I/O with Promise.all.

Add 25 tests covering all checkBan code paths including the specific
regressions for IP-only cleanup, Redis key mismatch, missing expiresAt,
and cache write failures.

---------

Co-authored-by: Danny Avila <danny@librechat.ai>
2026-03-20 12:47:51 -04:00
..
controllers 🪂 fix: Automatic logout_hint Fallback for Oversized OpenID Token URLs (#12326) 2026-03-20 12:46:57 -04:00
middleware ♾️ fix: Permanent Ban Cache and Expired Ban Cleanup Defects (#12324) 2026-03-20 12:47:51 -04:00
routes 🪢 fix: Action Domain Encoding Collision for HTTPS URLs (#12271) 2026-03-17 01:38:51 -04:00
services 🪦 fix: ACL-Safe User Account Deletion for Agents, Prompts, and MCP Servers (#12314) 2026-03-19 17:46:14 -04:00
utils 🚦 fix: ERR_ERL_INVALID_IP_ADDRESS and IPv6 Key Collisions in IP Rate Limiters (#12319) 2026-03-19 21:48:03 -04:00
cleanup.js 🪣 fix: Prevent Memory Retention from AsyncLocalStorage Context Propagation (#11942) 2026-02-25 17:41:23 -05:00
experimental.js 🚦 fix: 404 JSON Responses for Unmatched API Routes (#11976) 2026-02-27 22:49:54 -05:00
index.js 🚦 fix: 404 JSON Responses for Unmatched API Routes (#11976) 2026-02-27 22:49:54 -05:00
index.spec.js 🚦 fix: 404 JSON Responses for Unmatched API Routes (#11976) 2026-02-27 22:49:54 -05:00
socialLogins.js 🔒 fix: Secure Cookie Localhost Bypass and OpenID Token Selection in AuthService (#11782) 2026-02-13 10:35:51 -05:00