SEC - LAUNCHER: bind agent modules to Tasker workspace

This commit is contained in:
DCCONSTRUCTIONS 2026-05-15 00:47:59 +03:00
parent 17406d570f
commit 39843b7737
1 changed files with 40 additions and 25 deletions

View File

@ -424,7 +424,10 @@ app.post("/api/internal/access/check", (req, res) => {
const groups = resolveRequiredGroups(snapshot.data, user); const groups = resolveRequiredGroups(snapshot.data, user);
const app = getAppsForUser(groups).find((candidate) => candidate.slug === serviceSlug); const app = getAppsForUser(groups).find((candidate) => candidate.slug === serviceSlug);
const allowed = Boolean(app?.hasAccess); const allowed = Boolean(app?.hasAccess);
const serviceModules = resolveUserServiceModules(snapshot.data, user, serviceSlug, workspaceSlug); const serviceModules =
serviceSlug === "task-manager"
? resolveTaskManagerWorkspaceServiceModules(snapshot.data, user, serviceSlug, workspaceSlug)
: resolveUserServiceModules(snapshot.data, user, serviceSlug, null);
const workspacePolicy = const workspacePolicy =
serviceSlug === "task-manager" serviceSlug === "task-manager"
? resolveTaskManagerWorkspacePolicy(snapshot.data, groups, allowed, user, workspaceSlug, serviceModules) ? resolveTaskManagerWorkspacePolicy(snapshot.data, groups, allowed, user, workspaceSlug, serviceModules)
@ -2509,47 +2512,59 @@ function resolveTaskManagerWorkspacePolicy(data, groups, hasTaskManagerAccess, u
}; };
} }
function resolveUserServiceModules(data, user, serviceSlug, workspaceSlug = null) { function resolveTaskManagerWorkspaceServiceModules(data, user, serviceSlug, workspaceSlug) {
const normalizedWorkspaceSlug = normalizeOptionalText(workspaceSlug);
if (!normalizedWorkspaceSlug) {
return {};
}
const workspaces = resolveTaskManagerWorkspaceAssignments(data, user);
const workspaceAssignment = workspaces.find((workspace) => workspace.slug === normalizedWorkspaceSlug);
const boundClientId = resolveTaskManagerWorkspaceClientId(data, normalizedWorkspaceSlug);
const clientId =
workspaceAssignment?.clientId ??
(boundClientId ? null : isPublicPoolUser(data, user) ? publicPoolClientId : null);
return resolveUserServiceModules(data, user, serviceSlug, clientId);
}
function resolveTaskManagerWorkspaceClientId(data, workspaceSlug) {
const normalizedWorkspaceSlug = normalizeOptionalText(workspaceSlug);
if (!normalizedWorkspaceSlug) return null;
const client = data.clients.find((candidate) => resolveTaskManagerWorkspaceBinding(candidate, normalizedWorkspaceSlug));
return client?.id ?? null;
}
function isPublicPoolUser(data, user) {
return data.memberships.some(
(membership) => membership.userId === user?.id && membership.clientId === publicPoolClientId && membership.status === "active"
);
}
function resolveUserServiceModules(data, user, serviceSlug, clientId) {
if (!user?.id) return {}; if (!user?.id) return {};
const normalizedClientId = normalizeOptionalText(clientId);
if (!normalizedClientId) return {};
const service = data.services.find( const service = data.services.find(
(candidate) => candidate.slug === serviceSlug || candidate.authentikApplicationSlug === serviceSlug (candidate) => candidate.slug === serviceSlug || candidate.authentikApplicationSlug === serviceSlug
); );
if (!service?.id) return {}; if (!service?.id) return {};
const workspaceClientIds = resolveTaskManagerWorkspaceClientIds(data, user, workspaceSlug);
return Object.fromEntries( return Object.fromEntries(
(data.serviceModuleEntitlements ?? []) (data.serviceModuleEntitlements ?? [])
.filter( .filter(
(entitlement) => (entitlement) =>
entitlement.clientId === normalizedClientId &&
entitlement.userId === user.id && entitlement.userId === user.id &&
entitlement.serviceId === service.id && entitlement.serviceId === service.id &&
entitlement.enabled && entitlement.enabled
(!workspaceClientIds || workspaceClientIds.has(entitlement.clientId))
) )
.map((entitlement) => [entitlement.moduleId, true]) .map((entitlement) => [entitlement.moduleId, true])
); );
} }
function resolveTaskManagerWorkspaceClientIds(data, user, workspaceSlug) {
const normalizedWorkspaceSlug = normalizeOptionalText(workspaceSlug);
if (!normalizedWorkspaceSlug || !user?.id) return null;
const clientIds = new Set();
for (const membership of data.taskManagerMemberships ?? []) {
if (membership.userId === user.id && normalizeOptionalText(membership.workspaceSlug) === normalizedWorkspaceSlug) {
clientIds.add(membership.clientId);
}
}
for (const client of data.clients ?? []) {
if (resolveTaskManagerWorkspaceBinding(client, normalizedWorkspaceSlug)) {
clientIds.add(client.id);
}
}
return clientIds;
}
function getFrontchannelLogoutUrls() { function getFrontchannelLogoutUrls() {
const urls = [config.taskLogoutUrl]; const urls = [config.taskLogoutUrl];
const launcherData = readLauncherData(); const launcherData = readLauncherData();