Repository navigation
🧹 fix: Run the Full Erasure Cascade When an Admin Deletes a User #17050
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4f30f39
bccc2e4
a68a7ce
feb0fa2
5388abb
429663c
6cb7d89
bf50f1e
912506f
8223c5b
4600f30
fb560c1
5965bbe
30de716
4cdf30c
3d78be3
076beb3
9dc6298
9bbd434
717e202
5118d04
294e04d
f085493
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,14 @@ | ||
| const express = require('express'); | ||
| const mongoose = require('mongoose'); | ||
| const { createAdminUsersHandlers, revokeUserCodeEnvironmentWorkers } = require('@librechat/api'); | ||
| const { SystemCapabilities } = require('@librechat/data-schemas'); | ||
| const { | ||
| GenerationJobManager, | ||
| openCheckpointDeletion, | ||
| deleteAllSharedLinksWithCleanup, | ||
| createErasureResolver, | ||
| createAdminUsersHandlers, | ||
| revokeUserCodeEnvironmentWorkers, | ||
| } = require('@librechat/api'); | ||
| const { SystemCapabilities, runAsSystem, tenantStorage } = require('@librechat/data-schemas'); | ||
| const { requireCapability } = require('~/server/middleware/roles/capabilities'); | ||
| const { requireJwtAuth } = require('~/server/middleware'); | ||
| const { | ||
|
|
@@ -10,11 +17,37 @@ const { | |
| cancelAgentTriggerUserPurge, | ||
| purgeAgentTriggerDeliveriesForUser, | ||
| } = require('~/server/services/Agents/triggers'); | ||
| const { processDeleteRequest } = require('~/server/services/Files/process'); | ||
| const { invalidateCachedTools } = require('~/server/services/Config/getCachedTools'); | ||
| const { getMCPManager, getMCPServersRegistry } = require('~/config'); | ||
| const { maybeUninstallOAuthMCP } = require('~/server/services/MCP/oauthCleanup'); | ||
| const subagentThreadTaskStore = require('~/server/services/Endpoints/agents/subagentThreadStore'); | ||
| const { | ||
| quiesceUserSchedules, | ||
| restoreUserSchedulesFromDeletion, | ||
| } = require('~/server/services/Schedules'); | ||
| const db = require('~/models'); | ||
| const { getAppConfig, invalidateCodeEnvironmentConfigCache } = require('~/server/services/Config'); | ||
|
|
||
| const router = express.Router(); | ||
|
|
||
| const resolveErasure = createErasureResolver({ | ||
| withTenant: (tenantId, operation) => | ||
| tenantId ? tenantStorage.run({ tenantId }, operation) : runAsSystem(operation), | ||
| db, | ||
| getAppConfig, | ||
| getMCPManager, | ||
| processDeleteRequest, | ||
| invalidateCachedTools, | ||
| mcpOAuth: { | ||
| getRegistry: getMCPServersRegistry, | ||
| getUserPrincipals: db.getUserPrincipals, | ||
| uninstallOAuthMCP: maybeUninstallOAuthMCP, | ||
| }, | ||
| openCheckpointDeletion, | ||
| deleteSharedLinks: (userId) => deleteAllSharedLinksWithCleanup(userId, { awaitCleanup: true }), | ||
| }); | ||
|
|
||
| const requireAdminAccess = requireCapability(SystemCapabilities.ACCESS_ADMIN); | ||
| const requireReadUsers = requireCapability(SystemCapabilities.READ_USERS); | ||
| // const requireManageUsers = requireCapability(SystemCapabilities.MANAGE_USERS); | ||
|
|
@@ -40,7 +73,12 @@ const handlers = createAdminUsersHandlers({ | |
| deleteConfig: db.deleteConfig, | ||
| deleteAclEntries: db.deleteAclEntries, | ||
| deletePasskeysByUser: db.deletePasskeysByUser, | ||
| deleteTokens: db.deleteTokens, | ||
| resolveErasure, | ||
| cancelSubagentTasks: (userId, tenantId) => | ||
| subagentThreadTaskStore.cancelAndDrainForOwner(userId, tenantId), | ||
| quiesceUserSchedules, | ||
| restoreUserSchedulesFromDeletion, | ||
| generationJobs: GenerationJobManager, | ||
|
Comment on lines
+76
to
+81
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This adds the full admin-erasure dependency graph, but the repository-wide search finds its only HTTP binding still commented out at AGENTS.md reference: AGENTS.md:L50-L53 Useful? React with 👍 / 👎.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Accepted: mounting the admin DELETE route is a recorded non-goal; it stays commented out on dev. |
||
| }); | ||
|
|
||
| router.use(requireJwtAuth, requireAdminAccess); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the app is launched via
npm run backend:experimental,api/server/experimental.js:366-372initializesGenerationJobManagerbut never callssetAdmissionGuard. Because this patch also removes the controller-levelisAgentTriggerPrincipalActivecheck, a generation authenticated before self-deletion can commit after that worker's deletion drain and start without ever observing the deletion fence, allowing it to recreate user data after erasure. Configure the same guard in every server entrypoint or retain a shared request-level barrier.Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in fb444cc: experimental.js installs the same admission guard.