Fix Launcher Engine access role handling
This commit is contained in:
@@ -1212,6 +1212,7 @@ export function createControlPlaneStore({ projectRoot }) {
|
||||
}
|
||||
|
||||
const targetUser = findById(data.users, request.targetUserId, "user");
|
||||
const membership = ensureEngineWorkflowPublicPoolMembership(data, targetUser, request, actor, now);
|
||||
const grant = ensureEngineWorkflowServiceAccess(data, targetUser, request.role, now);
|
||||
|
||||
request.status = "approved";
|
||||
@@ -1230,7 +1231,7 @@ export function createControlPlaneStore({ projectRoot }) {
|
||||
});
|
||||
|
||||
await writeData(data);
|
||||
return { engineWorkflowAccessRequest: request, grant, targetUser, data };
|
||||
return { engineWorkflowAccessRequest: request, grant, membership, targetUser, data };
|
||||
}
|
||||
|
||||
async function rejectEngineWorkflowAccessRequest(engineWorkflowAccessRequestId, payload, identity) {
|
||||
@@ -1647,6 +1648,11 @@ export function createControlPlaneStore({ projectRoot }) {
|
||||
const value = requireString(payload?.value, "value");
|
||||
const user = findById(data.users, userId, "user");
|
||||
const service = findById(data.services, serviceId, "service");
|
||||
const engineService = isEngineService(service);
|
||||
|
||||
if (engineService && (value === "admin" || value === "owner")) {
|
||||
throw new Error("Для Engine доступны только роли guest, member или блокировка");
|
||||
}
|
||||
|
||||
const directGrant = data.grants.find(
|
||||
(grant) => grant.serviceId === serviceId && grant.targetType === "user" && grant.targetId === userId
|
||||
@@ -1677,6 +1683,9 @@ export function createControlPlaneStore({ projectRoot }) {
|
||||
createdAt: directGrant?.createdAt ?? now,
|
||||
updatedAt: now,
|
||||
});
|
||||
if (engineService) {
|
||||
ensurePublicPoolMembershipActiveForServiceAccess(data, user, actor, now);
|
||||
}
|
||||
} else if (value !== "unset") {
|
||||
throw new Error(`Unsupported access value: ${value}`);
|
||||
}
|
||||
@@ -2662,13 +2671,78 @@ function ensureEngineWorkflowServiceAccess(data, user, workflowRole, now) {
|
||||
return grant;
|
||||
}
|
||||
|
||||
function ensureEngineWorkflowPublicPoolMembership(data, user, request, actor, now) {
|
||||
const invitedByUserId = request.requesterUserId || actor?.id || null;
|
||||
let membership = data.memberships.find(
|
||||
(candidate) => candidate.clientId === publicPoolClientId && candidate.userId === user.id
|
||||
);
|
||||
|
||||
if (membership) {
|
||||
const wasActive = membership.status === "active";
|
||||
membership.status = "active";
|
||||
if (!wasActive) {
|
||||
membership.role = "member";
|
||||
membership.source = "engine_workflow_access_request";
|
||||
membership.sourceEngineWorkflowAccessRequestId = request.id;
|
||||
} else {
|
||||
membership.sourceEngineWorkflowAccessRequestId =
|
||||
membership.sourceEngineWorkflowAccessRequestId ?? request.id;
|
||||
}
|
||||
membership.invitedByUserId = membership.invitedByUserId ?? invitedByUserId;
|
||||
membership.updatedAt = now;
|
||||
markPendingSync(data, user, "user", user.email);
|
||||
return membership;
|
||||
}
|
||||
|
||||
membership = {
|
||||
id: uniqueId(data.memberships, "mem", `${publicPoolClientId}-${user.email}`),
|
||||
clientId: publicPoolClientId,
|
||||
userId: user.id,
|
||||
role: "member",
|
||||
status: "active",
|
||||
invitedByUserId,
|
||||
inviteId: null,
|
||||
source: "engine_workflow_access_request",
|
||||
sourceTaskerInviteRequestId: null,
|
||||
sourceEngineWorkflowAccessRequestId: request.id,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
data.memberships.push(membership);
|
||||
markPendingSync(data, user, "user", user.email);
|
||||
return membership;
|
||||
}
|
||||
|
||||
function ensurePublicPoolMembershipActiveForServiceAccess(data, user, actor, now) {
|
||||
const membership = data.memberships.find(
|
||||
(candidate) => candidate.clientId === publicPoolClientId && candidate.userId === user.id
|
||||
);
|
||||
if (!membership || membership.status === "active") {
|
||||
return null;
|
||||
}
|
||||
|
||||
membership.role = "member";
|
||||
membership.status = "active";
|
||||
membership.invitedByUserId = membership.invitedByUserId ?? actor?.id ?? null;
|
||||
membership.source = membership.source ?? "launcher";
|
||||
membership.updatedAt = now;
|
||||
markPendingSync(data, user, "user", user.email);
|
||||
return membership;
|
||||
}
|
||||
|
||||
function findEngineService(data) {
|
||||
return data.services.find(
|
||||
(candidate) =>
|
||||
candidate.id === "service_nodedc" ||
|
||||
candidate.slug === "nodedc" ||
|
||||
candidate.slug === "engine" ||
|
||||
candidate.authentikApplicationSlug === "nodedc-engine"
|
||||
return data.services.find(isEngineService);
|
||||
}
|
||||
|
||||
function isEngineService(candidate) {
|
||||
return Boolean(
|
||||
candidate &&
|
||||
(
|
||||
candidate.id === "service_nodedc" ||
|
||||
candidate.slug === "nodedc" ||
|
||||
candidate.slug === "engine" ||
|
||||
candidate.authentikApplicationSlug === "nodedc-engine"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user