LibreChat/config
Marco Beretta b84e26671e
🕒 feat: Track Terms Acceptance Timestamp (#10810)
* feat: add terms acceptance timestamp tracking and migration script

* feat: update migration script to use countUsers method for user count

* Update config/migrate-terms-timestamp.js

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* feat: enhance terms acceptance response to include acceptance timestamp

* fix: make terms acceptance idempotent and fail migration on partial errors

Preserve the original termsAcceptedAt on repeat accepts within a terms
cycle so retried or duplicate requests no longer overwrite the first
acceptance time. Exit the migration script with a non-zero status when
any per-user update fails so partial failures are not reported as
successful.

* style: fix import ordering in data-provider mutations

* refactor: record terms acceptance atomically to preserve first-accept time

Replace the read-then-write in acceptTermsController with a single
atomic acceptTerms method that conditionally stamps termsAcceptedAt via
an $ifNull aggregation update. This removes the TOCTOU window where two
concurrent first-time accepts could overwrite the earlier acceptance
timestamp, while still preserving an existing timestamp and backfilling
legacy accepted users.

* fix: run terms timestamp migration under system tenant context

Wrap the count, cursor scan, and per-user updates in runAsSystem so the
tenant isolation plugin does not throw under TENANT_ISOLATION_STRICT or
scope the cross-tenant migration to a non-existent tenant, matching the
other maintenance migrations.

* fix: guard terms backfill against concurrent acceptances

Add the missing-timestamp predicate to the per-user updateOne filter so
a user who accepts through the API between the cursor read and the write
keeps their real acceptance time instead of being overwritten with
createdAt. Track modified vs skipped so the summary reflects skips.

* fix: scope terms backfill to still-accepted users

Add termsAccepted: true to the per-user updateOne filter so a reset that
clears acceptance between the cursor read and the write is not re-stamped
with createdAt, which would otherwise poison the next acceptance cycle
through the $ifNull preserve in acceptTerms.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-06-24 16:26:42 -04:00
..
__tests__ 🔗 feat: Add Granular Access Control to Shared Links via ACL System (#13051) 2026-06-03 14:17:17 -04:00
translations 📦 chore: npm audit fixes and Mongoose 8.23 TypeScript follow-ups (#12996) 2026-05-07 09:47:40 -04:00
add-balance.js 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
ban-user.js 🐍 fix: Use Standard Mongoose Module Resolution in Config Scripts (#9143) 2025-08-19 11:15:09 -04:00
connect.js 🏗️ refactor: Extract DB layers to data-schemas for shared use (#7650) 2025-05-30 22:18:13 -04:00
create-user.js 🪪 fix: Preserve Trusted Registration Provider Overrides (#13307) 2026-05-30 10:04:50 -04:00
delete-banner.js 🐍 fix: Use Standard Mongoose Module Resolution in Config Scripts (#9143) 2025-08-19 11:15:09 -04:00
delete-user.js 🐘 feat: FerretDB Compatibility (#11769) 2026-03-21 14:28:49 -04:00
deployed-update.js 🏷️ chore: Remove Docker Images by Named Tag in deployed-update.js (#12138) 2026-03-08 21:48:22 -04:00
flush-cache.js 🪂 refactor: MCP Server Init Fallback (#10608) 2025-11-20 16:47:00 -05:00
helpers.js 🚀 feat: Banner (#3952) 2024-09-11 09:34:25 -04:00
invite-user.js 🛜 refactor: Streamline App Config Usage (#9234) 2025-08-26 12:10:18 -04:00
jest.config.js 🔗 feat: Add Granular Access Control to Shared Links via ACL System (#13051) 2026-06-03 14:17:17 -04:00
list-balances.js 🐍 fix: Use Standard Mongoose Module Resolution in Config Scripts (#9143) 2025-08-19 11:15:09 -04:00
list-users.js 🕒 feat: Track Terms Acceptance Timestamp (#10810) 2026-06-24 16:26:42 -04:00
migrate-agent-permissions.js 🗑️ chore: Remove Deprecated Project Model and Associated Fields (#11773) 2026-03-21 14:28:53 -04:00
migrate-orphaned-agent-files.js 🧹 fix: Clean Up Orphaned Agent File Stubs After Deletion (#12781) 2026-04-22 11:35:48 -07:00
migrate-prompt-permissions.js 🗑️ chore: Remove Deprecated Project Model and Associated Fields (#11773) 2026-03-21 14:28:53 -04:00
migrate-shared-link-permissions.js 🔗 feat: Add Granular Access Control to Shared Links via ACL System (#13051) 2026-06-03 14:17:17 -04:00
migrate-terms-timestamp.js 🕒 feat: Track Terms Acceptance Timestamp (#10810) 2026-06-24 16:26:42 -04:00
packages.js 🧠 feat: User Memories for Conversational Context (#7760) 2025-06-07 18:52:22 -04:00
prepare.js feat(prepare.js): add script to install husky only if NODE_ENV is not 'CI' (#512) 2023-06-13 11:36:54 -04:00
reset-meili-sync.js 🔧 refactor: batching documents on meili index reset (#11165) 2026-01-02 10:50:06 -05:00
reset-password.js 🐍 fix: Use Standard Mongoose Module Resolution in Config Scripts (#9143) 2025-08-19 11:15:09 -04:00
reset-terms.js 🕒 feat: Track Terms Acceptance Timestamp (#10810) 2026-06-24 16:26:42 -04:00
set-balance.js 🔧 chore: Drop duplicate getAppConfig import in set-balance.js (#13417) 2026-05-30 09:12:58 -07:00
smart-reinstall.js 📝 docs: Add AGENTS.md for Project Structure and Coding Standards (#11866) 2026-02-19 16:33:43 -05:00
stop-backend.js 🔄 refactor: Consolidate Ask/Edit Controllers (#1365) 2023-12-15 15:47:40 -05:00
test-subdirectory-setup.sh 🧭 fix: Subdirectory Deployment Auth Redirect Path Doubling (#12077) 2026-03-05 01:38:44 -05:00
update-banner.js 📌 feat: Add Support for Persistable (Non-Dismissible) Banners (#10730) 2025-12-11 16:37:22 -05:00
update.js 📦 feat: Move Shared Components to @librechat/client (#8685) 2025-07-27 12:19:01 -04:00
user-stats.js 🐍 fix: Use Standard Mongoose Module Resolution in Config Scripts (#9143) 2025-08-19 11:15:09 -04:00