ФУНКЦИИ - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: guest-доступ Operational Core

This commit is contained in:
DCCONSTRUCTIONS 2026-05-12 19:35:44 +03:00
parent b698741687
commit 6e47e12f2d
2 changed files with 29 additions and 1 deletions

View File

@ -1449,6 +1449,16 @@ app.post("/api/admin/access/user-service", requireLauncherAdmin, asyncRoute(asyn
return;
}
const snapshot = controlPlaneStore.getSnapshot(req.nodedcSession.user);
if (isPublicTaskManagerGuestServiceAssignment(snapshot.data, req.body)) {
res.status(400).json({
ok: false,
error: "task_manager_public_guest_not_assignable",
message: "Workspace Guest выдаётся только через настройки Operational Core.",
});
return;
}
const result = await controlPlaneStore.setUserServiceAccess(req.body, req.nodedcSession.user);
const syncResult = await syncUsersToAuthentik(result.data, [req.body?.userId], req.nodedcSession.user);
publishControlPlaneEvent("admin.access.user-service.updated", syncResult.userIds);
@ -2181,6 +2191,24 @@ function normalizeTaskManagerRole(value) {
return value === "guest" || value === "admin" || value === "member" ? value : null;
}
function isPublicTaskManagerGuestServiceAssignment(data, payload) {
if (payload?.value !== "viewer") return false;
const service = data.services.find((candidate) => candidate.id === payload?.serviceId);
if (!service || !isTaskManagerService(service)) return false;
return data.memberships.some(
(membership) =>
membership.userId === payload?.userId &&
membership.clientId === publicPoolClientId &&
membership.status === "active"
);
}
function isTaskManagerService(service) {
return service?.slug === "task-manager" || service?.authentikApplicationSlug === "task-manager";
}
function resolveTaskManagerRoleForMembership(role) {
return role === "client_owner" || role === "client_admin" ? "admin" : "member";
}

View File

@ -1347,7 +1347,7 @@ const accessAssignmentOptions: Array<NodeDcSelectOption<AccessAssignmentValue>>
const publicOperationalCoreAccessOptions: Array<NodeDcSelectOption<AccessAssignmentValue>> = [
{ value: "unset", label: "—", description: "Не назначен", hidden: true },
{ value: "viewer", label: "Workspace Guest", description: "Доступ к приглашённому workspace", tone: "green" },
{ value: "viewer", label: "Workspace Guest", description: "Выдаётся только через Tasker", tone: "green", hidden: true },
{ value: "member", label: "Workspace Member", description: "Доступ к приглашённому workspace", tone: "green" },
{ value: "admin", label: "Service Admin", description: "Self-service", tone: "green" },
{ value: "deny", label: "Заблокирован", description: "Запрет доступа", tone: "red" },