SECURITY - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: очистка доступа Tasker

This commit is contained in:
DCCONSTRUCTIONS 2026-05-12 22:26:48 +03:00
parent 6e47e12f2d
commit 0ba6dc7115
1 changed files with 21 additions and 7 deletions

View File

@ -1108,12 +1108,22 @@ app.patch("/api/admin/users/:userId/profile", requireLauncherAdmin, asyncRoute(a
return;
}
const beforeSnapshot = controlPlaneStore.getSnapshot(req.nodedcSession.user);
const beforeUser = beforeSnapshot.data.users.find((candidate) => candidate.id === req.params.userId) ?? null;
const result = await controlPlaneStore.updateUserProfile(req.params.userId, req.body, req.nodedcSession.user);
const syncResult = await syncUsersToAuthentik(result.data, [req.params.userId], req.nodedcSession.user);
const updatedUser = syncResult.data.users.find((candidate) => candidate.id === req.params.userId);
const taskManagerProfile = await syncTaskManagerUserProfile(updatedUser);
const taskManagerCleanup =
beforeUser?.globalStatus === "active" && updatedUser?.globalStatus === "blocked"
? await cleanupTaskManagerUserAccess(updatedUser, {
source: "launcher-user-blocked",
revokeIdentityLinks: false,
revokeTaskerAccess: true,
})
: null;
publishControlPlaneEvent("admin.user.updated", syncResult.userIds);
res.json({ ...scopeAdminMutationResult(req, { ...result, data: syncResult.data }), taskManagerProfile });
res.json({ ...scopeAdminMutationResult(req, { ...result, data: syncResult.data }), taskManagerProfile, taskManagerCleanup });
}));
app.delete("/api/admin/users/:userId", requireLauncherAdmin, requireRootLauncherAdmin, asyncRoute(async (req, res) => {
@ -1131,7 +1141,11 @@ app.delete("/api/admin/users/:userId", requireLauncherAdmin, requireRootLauncher
authentik = await authentikSyncClient.deleteUser({ data: snapshot.data, userId: req.params.userId });
}
const taskManagerCleanup = await cleanupTaskManagerUserAccess(user);
const taskManagerCleanup = await cleanupTaskManagerUserAccess(user, {
source: "launcher-user-hard-delete",
revokeIdentityLinks: true,
revokeTaskerAccess: true,
});
const result = await controlPlaneStore.deleteUser(req.params.userId, req.nodedcSession.user);
publishControlPlaneEvent("admin.user.deleted", [req.params.userId]);
res.json({ ...scopeAdminMutationResult(req, result), authentik, taskManagerCleanup });
@ -2152,7 +2166,7 @@ async function syncTaskManagerUserProfile(user) {
}
}
async function cleanupTaskManagerUserAccess(user) {
async function cleanupTaskManagerUserAccess(user, options = {}) {
if (!user?.email || !config.internalAccessToken) {
return null;
}
@ -2161,11 +2175,11 @@ async function cleanupTaskManagerUserAccess(user) {
return await requestTaskManagerInternalJson("/api/internal/nodedc/logout/", {
method: "POST",
body: {
source: "launcher-user-hard-delete",
source: normalizeOptionalText(options.source) ?? "launcher-user-access-revoked",
subject: user.authentikUserId ?? undefined,
email: user.email,
revokeIdentityLinks: true,
revokeTaskerAccess: true,
revokeIdentityLinks: options.revokeIdentityLinks === true,
revokeTaskerAccess: options.revokeTaskerAccess !== false,
},
});
} catch (error) {
@ -2369,7 +2383,7 @@ function resolveTaskManagerWorkspacePolicy(data, groups, hasTaskManagerAccess, u
};
}
if (hasLauncherManagedWorkspace && !isSuperAdmin) {
if (hasLauncherManagedWorkspace && !isSuperAdmin && !isTaskManagerAdmin) {
if (workspaceAssignment?.managedBy === "launcher") {
return {
mode,