mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-07-01 20:01:35 +00:00
* 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>
202 lines
10 KiB
JSON
202 lines
10 KiB
JSON
{
|
|
"name": "LibreChat",
|
|
"version": "v0.8.7",
|
|
"description": "",
|
|
"packageManager": "npm@11.13.0",
|
|
"workspaces": [
|
|
"api",
|
|
"client",
|
|
"packages/*"
|
|
],
|
|
"scripts": {
|
|
"update": "node config/update.js",
|
|
"add-balance": "node config/add-balance.js",
|
|
"set-balance": "node config/set-balance.js",
|
|
"list-balances": "node config/list-balances.js",
|
|
"user-stats": "node config/user-stats.js",
|
|
"rebuild:package-lock": "node config/packages",
|
|
"reinstall": "node config/update.js -l -g",
|
|
"smart-reinstall": "node config/smart-reinstall.js",
|
|
"b:reinstall": "bun config/update.js -b -l -g",
|
|
"reinstall:docker": "node config/update.js -d -g",
|
|
"update:local": "node config/update.js -l",
|
|
"update:docker": "node config/update.js -d",
|
|
"update:single": "node config/update.js -s",
|
|
"update:sudo": "node config/update.js --sudo",
|
|
"update:deployed": "node config/deployed-update.js",
|
|
"rebase:deployed": "node config/deployed-update.js --rebase",
|
|
"start:deployed": "docker compose -f ./deploy-compose.yml up -d || docker-compose -f ./deploy-compose.yml up -d",
|
|
"stop:deployed": "docker compose -f ./deploy-compose.yml down || docker-compose -f ./deploy-compose.yml down",
|
|
"upgrade": "node config/upgrade.js",
|
|
"create-user": "node config/create-user.js",
|
|
"invite-user": "node config/invite-user.js",
|
|
"list-users": "node config/list-users.js",
|
|
"reset-password": "node config/reset-password.js",
|
|
"ban-user": "node config/ban-user.js",
|
|
"delete-user": "node config/delete-user.js",
|
|
"reset-meili-sync": "node config/reset-meili-sync.js",
|
|
"update-banner": "node config/update-banner.js",
|
|
"delete-banner": "node config/delete-banner.js",
|
|
"backend": "cross-env NODE_ENV=production node api/server/index.js",
|
|
"backend:inspect": "cross-env NODE_ENV=production node --inspect --expose-gc api/server/index.js",
|
|
"backend:dev": "cross-env NODE_ENV=development npx nodemon api/server/index.js",
|
|
"backend:experimental": "cross-env NODE_ENV=production node api/server/experimental.js",
|
|
"backend:stop": "node config/stop-backend.js",
|
|
"build:data-provider": "cd packages/data-provider && npm run build",
|
|
"build:api": "cd packages/api && npm run build",
|
|
"build:data-schemas": "cd packages/data-schemas && npm run build",
|
|
"build:client": "cd client && npm run build",
|
|
"build:client-package": "cd packages/client && npm run build",
|
|
"build:packages": "npm run build:data-provider && npm run build:data-schemas && npm run build:api && npm run build:client-package",
|
|
"build": "npx turbo run build",
|
|
"build:safe": "npx turbo run build --no-daemon",
|
|
"frontend": "npm run build:data-provider && npm run build:data-schemas && npm run build:api && npm run build:client-package && cd client && npm run build",
|
|
"frontend:ci": "npm run build:data-provider && npm run build:client-package && cd client && npm run build:ci",
|
|
"frontend:dev": "cd client && npm run dev",
|
|
"e2e:prepare": "npm run frontend",
|
|
"e2e": "npm run e2e:prepare && playwright test --config=e2e/playwright.config.local.ts",
|
|
"e2e:headed": "npm run e2e:prepare && playwright test --config=e2e/playwright.config.local.ts --headed",
|
|
"e2e:a11y": "npm run e2e:prepare && playwright test --config=e2e/playwright.config.a11y.ts --headed",
|
|
"e2e:ci": "npm run e2e:prepare && playwright test --config=e2e/playwright.config.ts",
|
|
"e2e:mock": "npm run e2e:prepare && playwright test --config=e2e/playwright.config.mock.ts",
|
|
"e2e:mock:enforce": "npm run e2e:prepare && cross-env E2E_MODEL_SPECS_ENFORCE=true playwright test --config=e2e/playwright.config.mock.ts enforced-model-specs.spec.ts",
|
|
"e2e:mock:ci": "npm run e2e:prepare && playwright test --config=e2e/playwright.config.mock.ts",
|
|
"e2e:debug": "npm run e2e:prepare && cross-env PWDEBUG=1 playwright test --config=e2e/playwright.config.local.ts",
|
|
"e2e:record": "npm run e2e:prepare && cross-env E2E_BASE_URL=http://localhost:3333 node e2e/setup/record.js",
|
|
"e2e:record:local": "npm run e2e:prepare && node e2e/setup/record.js --profile=local",
|
|
"e2e:codegen": "npx playwright codegen --target=playwright-test --test-id-attribute=data-testid --load-storage=e2e/storageState.json http://localhost:3080/c/new",
|
|
"e2e:login": "npx playwright codegen --save-storage=e2e/storageState.json http://localhost:3080/login",
|
|
"e2e:github": "act -W .github/workflows/playwright.yml --secret-file my.secrets",
|
|
"test:client": "cd client && npm run test:ci",
|
|
"test:api": "cd api && npm run test:ci",
|
|
"test:packages:api": "cd packages/api && npm run test:ci",
|
|
"test:packages:data-provider": "cd packages/data-provider && npm run test:ci",
|
|
"test:packages:data-schemas": "cd packages/data-schemas && npm run test:ci",
|
|
"test:config": "jest --config config/jest.config.js",
|
|
"test:all": "npm run test:client && npm run test:api && npm run test:packages:api && npm run test:packages:data-provider && npm run test:packages:data-schemas",
|
|
"e2e:update": "npm run e2e:prepare && playwright test --config=e2e/playwright.config.local.ts --update-snapshots",
|
|
"e2e:report": "npx playwright show-report e2e/playwright-report",
|
|
"lint:fix": "eslint --fix \"{,!(node_modules|venv)/**/}*.{js,jsx,ts,tsx}\"",
|
|
"lint": "eslint \"{,!(node_modules|venv)/**/}*.{js,jsx,ts,tsx}\"",
|
|
"sort-imports": "node scripts/sort-imports.mts",
|
|
"sort-imports:check": "node scripts/sort-imports.mts --check",
|
|
"format": "npx prettier --write \"{,!(node_modules|venv)/**/}*.{js,jsx,ts,tsx}\"",
|
|
"b:api": "NODE_ENV=production bun run api/server/index.js",
|
|
"b:api-inspect": "NODE_ENV=production bun --inspect run api/server/index.js",
|
|
"b:api:dev": "NODE_ENV=production bun run --watch api/server/index.js",
|
|
"b:data": "cd packages/data-provider && bun run b:build",
|
|
"b:build:client-package": "cd packages/client && bun run b:build",
|
|
"b:data-schemas": "cd packages/data-schemas && bun run b:build",
|
|
"b:build:api": "cd packages/api && bun run b:build",
|
|
"b:build:client": "cd client && bun --bun run b:build",
|
|
"b:client": "bun --bun run b:data && bun --bun run b:data-schemas && bun --bun run b:build:api && bun --bun run b:build:client-package && bun --bun run b:build:client",
|
|
"b:client:dev": "cd client && bun run b:dev",
|
|
"b:test:client": "cd client && bun run b:test",
|
|
"b:test:api": "cd api && bun run b:test",
|
|
"b:balance": "bun config/add-balance.js",
|
|
"b:list-balances": "bun config/list-balances.js",
|
|
"reset-terms": "node config/reset-terms.js",
|
|
"migrate:terms-timestamp": "node config/migrate-terms-timestamp.js",
|
|
"flush-cache": "node config/flush-cache.js",
|
|
"migrate:agent-permissions:dry-run": "node config/migrate-agent-permissions.js --dry-run",
|
|
"migrate:agent-permissions": "node config/migrate-agent-permissions.js",
|
|
"migrate:agent-permissions:batch": "node config/migrate-agent-permissions.js --batch-size=50",
|
|
"migrate:prompt-permissions:dry-run": "node config/migrate-prompt-permissions.js --dry-run",
|
|
"migrate:prompt-permissions": "node config/migrate-prompt-permissions.js",
|
|
"migrate:prompt-permissions:batch": "node config/migrate-prompt-permissions.js --batch-size=50",
|
|
"migrate:shared-link-permissions:dry-run": "node config/migrate-shared-link-permissions.js --dry-run",
|
|
"migrate:shared-link-permissions": "node config/migrate-shared-link-permissions.js",
|
|
"migrate:shared-link-permissions:batch": "node config/migrate-shared-link-permissions.js --batch-size=50",
|
|
"migrate:orphaned-agent-files:dry-run": "node config/migrate-orphaned-agent-files.js --dry-run",
|
|
"migrate:orphaned-agent-files": "node config/migrate-orphaned-agent-files.js",
|
|
"migrate:orphaned-agent-files:batch": "node config/migrate-orphaned-agent-files.js --batch-size=50"
|
|
},
|
|
"repository": {
|
|
"type": "git",
|
|
"url": "git+https://github.com/danny-avila/LibreChat.git"
|
|
},
|
|
"author": "",
|
|
"license": "ISC",
|
|
"bugs": {
|
|
"url": "https://github.com/danny-avila/LibreChat/issues"
|
|
},
|
|
"homepage": "https://librechat.ai/",
|
|
"devDependencies": {
|
|
"@axe-core/playwright": "^4.10.1",
|
|
"@eslint/compat": "^1.2.6",
|
|
"@eslint/eslintrc": "^3.3.4",
|
|
"@eslint/js": "^9.20.0",
|
|
"@playwright/test": "^1.56.1",
|
|
"@types/react-virtualized": "^9.22.0",
|
|
"caniuse-lite": "^1.0.30001741",
|
|
"cross-env": "^7.0.3",
|
|
"elliptic": "^6.6.1",
|
|
"eslint": "^9.39.1",
|
|
"eslint-config-prettier": "^10.0.1",
|
|
"eslint-import-resolver-typescript": "^3.7.0",
|
|
"eslint-plugin-i18next": "^6.1.1",
|
|
"eslint-plugin-import": "^2.31.0",
|
|
"eslint-plugin-jest": "^29.1.0",
|
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
"eslint-plugin-prettier": "^5.2.3",
|
|
"eslint-plugin-react": "^7.37.4",
|
|
"eslint-plugin-react-hooks": "^5.1.0",
|
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
"globals": "^15.14.0",
|
|
"husky": "^9.1.7",
|
|
"jest": "^30.2.0",
|
|
"lint-staged": "^15.4.3",
|
|
"prettier": "^3.5.0",
|
|
"prettier-plugin-tailwindcss": "^0.6.11",
|
|
"turbo": "^2.9.17",
|
|
"typescript-eslint": "^8.60.1"
|
|
},
|
|
"overrides": {
|
|
"@xmldom/xmldom": "^0.8.13",
|
|
"elliptic": "^6.6.1",
|
|
"form-data": "^4.0.6",
|
|
"langsmith": "^0.6.0",
|
|
"postcss": "^8.5.13",
|
|
"tslib": "^2.8.1",
|
|
"@anthropic-ai/sdk": "^0.92.0",
|
|
"fast-xml-parser": "5.7.2",
|
|
"serialize-javascript": "7.0.5",
|
|
"mdast-util-gfm-autolink-literal": "2.0.0",
|
|
"remark-gfm": {
|
|
"mdast-util-gfm-autolink-literal": "2.0.0"
|
|
},
|
|
"mdast-util-gfm": {
|
|
"mdast-util-gfm-autolink-literal": "2.0.0"
|
|
},
|
|
"katex": "^0.16.21",
|
|
"rehype-katex": {
|
|
"katex": "^0.16.21"
|
|
},
|
|
"remark-math": {
|
|
"micromark-extension-math": {
|
|
"katex": "^0.16.21"
|
|
}
|
|
},
|
|
"eslint": {
|
|
"ajv": "6.14.0"
|
|
},
|
|
"underscore": "1.13.8",
|
|
"hono": "^4.12.25",
|
|
"@hono/node-server": "^1.19.10",
|
|
"monaco-editor": {
|
|
"dompurify": "3.4.0"
|
|
},
|
|
"svgo": "^2.8.2",
|
|
"js-yaml": "^4.2.0",
|
|
"ws": "^8.21.0"
|
|
},
|
|
"nodemonConfig": {
|
|
"ignore": [
|
|
"api/data/",
|
|
"data/",
|
|
"client/",
|
|
"admin/",
|
|
"packages/"
|
|
]
|
|
}
|
|
}
|