LibreChat/client
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
..
public
scripts
src 🔒 fix: Bound /files/usage TTL Hold Instead of Clearing It 2026-07-27 19:09:10 -04:00
sw 🛟 fix: Auto-Recover from Stale Service Worker Assets After Deploys (#13686) 2026-06-11 11:57:06 -04:00
test 🧰 feat: Redesign Agent Builder with Unified Tools Marketplace, Skills & Orchestration (#13952) 2026-07-05 11:30:12 -04:00
.node_modules-101IklEQ 🔒 fix: Bound /files/usage TTL Hold Instead of Clearing It 2026-07-27 19:09:10 -04:00
babel.config.cjs
check_updates.sh
index.html 📡 feat: add rum browser page-load diagnostics (#14106) 2026-07-05 11:32:53 -04:00
jest.config.cjs ⬆️ chore: Migrate off deprecated @ariakit/react-core to @ariakit/react-components (#13940) 2026-06-24 23:13:57 -04:00
jest.resolver.cjs ⬆️ chore: Migrate off deprecated @ariakit/react-core to @ariakit/react-components (#13940) 2026-06-24 23:13:57 -04:00
nginx.conf 🐳 feat: Bundle Admin Panel in Docker Compose Stacks (#13876) 2026-06-22 16:59:08 -04:00
package.json 🗺️ chore: Bump PostCSS to 8.5.18 to Patch Source Map Traversal (#14463) 2026-07-27 12:45:55 -04:00
postcss.config.cjs
tailwind.config.cjs ⌨️ feat: Keyboard Shortcuts (#12425) 2026-06-22 17:02:46 -04:00
tsconfig.json 👷 ci: Type-check the Client Workspace (#13560) 2026-06-06 18:40:31 -04:00
vite.config.ts 🧩 chore: Prebundle Node Polyfills for Buffer, Process, and Global in Vite optimizeDeps (#14354) 2026-07-20 21:18:27 -04:00