Route engine launches through NODE.DC handoff

This commit is contained in:
DCCONSTRUCTIONS 2026-05-26 20:32:41 +03:00
parent dae87bb9b8
commit 3b006303a2
1 changed files with 43 additions and 1 deletions

View File

@ -407,6 +407,21 @@ app.get("/api/services/:serviceSlug/launch", requireSession, (req, res) => {
return;
}
if (isEngineServiceSlug(serviceSlug)) {
const handoffToken = createServiceHandoff("nodedc", runtimeContext.user);
const targetUrl = new URL("/auth/nodedc/handoff/", getEngineLaunchTargetUrl(app));
const nextPath = sanitizeReturnTo(req.query.next_path || req.query.returnTo || "/");
targetUrl.searchParams.set("token", handoffToken);
if (nextPath && nextPath !== "/") {
targetUrl.searchParams.set("next_path", nextPath);
}
res.redirect(targetUrl.toString());
return;
}
if (serviceSlug !== "task-manager") {
res.redirect(app.openUrl || app.url || "/");
return;
@ -2828,6 +2843,7 @@ function getAppCatalog() {
description: service.description,
url: getServiceUrl(service),
openUrl: getServiceUrl(service),
launchTargetUrl: getServiceLaunchTargetUrl(service),
status: service.status ?? "disabled",
provider: "authentik",
requiredGroups,
@ -2861,6 +2877,11 @@ const engineRequiredGroups = [
"nodedc_viewer",
];
function isEngineServiceSlug(serviceSlug) {
const slug = sanitizeServiceSlug(serviceSlug);
return slug === "nodedc" || slug === "engine" || slug === "nodedc-engine";
}
function specialRequiredGroups(serviceOrSlug) {
const slug = typeof serviceOrSlug === "string" ? serviceOrSlug : serviceOrSlug?.slug;
const applicationSlug = typeof serviceOrSlug === "string" ? null : serviceOrSlug?.authentikApplicationSlug;
@ -2876,22 +2897,43 @@ function specialRequiredGroups(serviceOrSlug) {
}
function getServiceUrl(service) {
if (service.slug === "task-manager") {
if (service.slug === "task-manager" || isEngineServiceSlug(service.slug)) {
return `/api/services/${encodeURIComponent(service.slug)}/launch`;
}
return service.launchUrl || service.url || "#";
}
function getServiceLaunchTargetUrl(service) {
if (isEngineServiceSlug(service?.slug)) {
return service.launchUrl || service.url || getEnginePublicBaseUrl();
}
return service?.launchUrl || service?.url || "#";
}
function getTaskBaseUrl() {
const taskBaseUrl = process.env.TASK_BASE_URL ?? `http://${process.env.TASK_DOMAIN ?? "task.local.nodedc"}`;
return taskBaseUrl.replace(/\/$/, "");
}
function getEnginePublicBaseUrl() {
return String(
process.env.NODEDC_ENGINE_PUBLIC_URL ||
process.env.NODEDC_ENGINE_BASE_URL ||
process.env.ENGINE_BASE_URL ||
"https://engine.nodedc.ru"
).replace(/\/$/, "");
}
function getEngineBaseUrl() {
return String(config.engineBaseUrl || "https://engine.nodedc.ru").replace(/\/$/, "");
}
function getEngineLaunchTargetUrl(service) {
return String(service?.launchTargetUrl || getEnginePublicBaseUrl()).replace(/\/$/, "");
}
async function requestTaskManagerInternalJson(pathname, init = {}) {
if (!config.internalAccessToken) {
throw new Error("NODE.DC internal access token is not configured");