LibreChat/api/server/middleware
Danny Avila b6879220aa 🔒 fix: Bound /files/usage TTL Hold Instead of Clearing It
`POST /files/usage` marks queued attachments so the 1-hour upload-window
TTL cannot reap them before the client queue drains. It did this by
calling `updateFilesUsage`, which unsets `expiresAt` outright, turning
every touched upload into a permanently retained file.

The client queue is ephemeral browser state, so this also leaks in normal
use: a closed tab or cleared queue leaves nothing referencing the files,
but their TTL is already gone. The same mechanism let an authenticated
user pin arbitrary owned uploads indefinitely, and the route was excluded
from the file limiters, so the touch was entirely unmetered.

Make the operation match its intent, a renewable hold rather than a
release:

- Add `extendFilesTTL`, which pushes `expiresAt` forward by a bounded
  window in a single owner-scoped `updateMany`. Two filter guards keep it
  safe under client-supplied ids: `$exists: true` so an already-released
  file never has a TTL re-added (that would schedule a live file for
  deletion), and `$lt` so a hold only ever moves the deadline later.
  The owner scope is a required argument, so an unscoped call is a no-op
  rather than a cross-user update.
- `handleFilesUsageRequest` now holds for 24h instead of clearing, and no
  longer increments `usage`, since a queue touch is not a send. The real
  release still happens at drain, where `updateFilesUsage` marks the
  files used against an actual message.
- Give `/usage` its own per-user limiter. Keeping it off the upload quota
  was intentional, leaving it unmetered was not.

Abandoned queues are now reaped on schedule, and a replayed touch can only
ever re-assert the same bounded window.
2026-07-27 19:09:10 -04:00
..
__tests__ 🔍 refactor: Surface primary OpenID JWT failure reason in auth failure log (#14346) 2026-07-20 21:05:20 -04:00
accessResources 🧷 fix: Align Agent File Attachment Ownership (#14149) 2026-07-07 16:23:48 -04:00
assistants ⚗️ feat: Agent Context Compaction/Summarization (#12287) 2026-03-21 14:28:56 -04:00
config ⚙️ perf: reduce first-load MongoDB round trips (#14101) 2026-07-06 09:36:34 -04:00
limiters 🔒 fix: Bound /files/usage TTL Hold Instead of Clearing It 2026-07-27 19:09:10 -04:00
roles ⚗️ feat: Agent Context Compaction/Summarization (#12287) 2026-03-21 14:28:56 -04:00
spec
validate 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
abortMiddleware.js 🛑 refactor: Demote User Abort Logs (#13904) 2026-06-23 09:55:21 -04:00
abortMiddleware.spec.js 🛑 refactor: Demote User Abort Logs (#13904) 2026-06-23 09:55:21 -04:00
abortRun.js 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
buildEndpointOption.js 🧾 fix: Harden Historical File Authorization (#13918) 2026-06-23 15:49:57 -04:00
buildEndpointOption.spec.js 🧾 fix: Harden Historical File Authorization (#13918) 2026-06-23 15:49:57 -04:00
canAccessSharedLink.js 🔗 feat: Add Granular Access Control to Shared Links via ACL System (#13051) 2026-06-03 14:17:17 -04:00
canDeleteAccount.js 📜 feat: Implement System Grants for Capability-Based Authorization (#11896) 2026-03-21 14:28:54 -04:00
canDeleteAccount.spec.js 📜 feat: Implement System Grants for Capability-Based Authorization (#11896) 2026-03-21 14:28:54 -04:00
checkBan.js ♾️ fix: Permanent Ban Cache and Expired Ban Cleanup Defects (#12324) 2026-03-20 12:47:51 -04:00
checkDomainAllowed.js ⚙️ perf: reduce first-load MongoDB round trips (#14101) 2026-07-06 09:36:34 -04:00
checkInviteUser.js 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
checkPeoplePickerAccess.js 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
checkPeoplePickerAccess.spec.js 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
checkSharePublicAccess.js 🗝️ fix: Enforce Skill Share Role Permission (#13062) 2026-05-11 09:39:58 -04:00
checkSharePublicAccess.spec.js 🗝️ fix: Enforce Skill Share Role Permission (#13062) 2026-05-11 09:39:58 -04:00
denyRequest.js 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
error.js 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
index.js 💂 fix: Enforce ALLOW_EMAIL_LOGIN on the Backend Login Route (#14180) 2026-07-09 09:55:36 -04:00
logHeaders.js
messageValidation.js ⚙️ perf: reduce first-load MongoDB round trips (#14101) 2026-07-06 09:36:34 -04:00
moderateText.js 🪝 feat: Human-in-the-Loop Runtime - Tool Approval + Ask-User-Question (Slice B) (#13942) 2026-06-29 16:56:41 -04:00
noIndex.js
optionalJwtAuth.js 🔐 feat: Mint Code API Auth Tokens (#13028) 2026-05-09 16:09:10 -04:00
optionalShareFileAuth.js 🍪 fix: Validate Shared-File Cookie Auth Against the Live Refresh Session (#13908) 2026-06-23 08:32:28 -04:00
optionalShareFileAuth.spec.js 🍪 fix: Validate Shared-File Cookie Auth Against the Live Refresh Session (#13908) 2026-06-23 08:32:28 -04:00
requireJwtAuth.js 🔍 refactor: Surface primary OpenID JWT failure reason in auth failure log (#14346) 2026-07-20 21:05:20 -04:00
requireLdapAuth.js
requireLocalAuth.js
setHeaders.js
setTwoFactorTempUser.js 🚦 fix: Guard Auth Continuation with Dedicated Limiter (#13555) 2026-06-06 14:21:28 -04:00
uaParser.js
validateEmailLogin.js 💂 fix: Enforce ALLOW_EMAIL_LOGIN on the Backend Login Route (#14180) 2026-07-09 09:55:36 -04:00
validateImageRequest.js
validateMessageReq.js ⚙️ perf: reduce first-load MongoDB round trips (#14101) 2026-07-06 09:36:34 -04:00
validateModel.js 🏗️ refactor: Remove Redundant Caching, Migrate Config Services to TypeScript (#12466) 2026-03-30 16:49:48 -04:00
validatePasswordReset.js
validateRegistration.js