Add optional BIM share launch handoff
This commit is contained in:
parent
4edca8c7cc
commit
754142b2ca
|
|
@ -405,6 +405,40 @@ app.get("/api/apps", (req, res) => {
|
|||
res.json({ apps: getAppsForUser(sessionAccess.runtimeContext.groups) });
|
||||
});
|
||||
|
||||
app.get("/api/services/:serviceSlug/optional-launch", (req, res) => {
|
||||
const serviceSlug = sanitizeServiceSlug(req.params.serviceSlug);
|
||||
const fallbackPath = req.query.fallbackTo || req.query.returnTo || "/";
|
||||
const fallbackUrl = buildOptionalServiceFallbackUrl(serviceSlug, null, fallbackPath);
|
||||
const session = getCurrentSession(req);
|
||||
|
||||
if (!session) {
|
||||
setNoStore(res);
|
||||
res.redirect(fallbackUrl);
|
||||
return;
|
||||
}
|
||||
|
||||
const sessionAccess = getSessionAccessState(session);
|
||||
|
||||
if (!sessionAccess.ok) {
|
||||
expireSession(res, session);
|
||||
setNoStore(res);
|
||||
res.redirect(fallbackUrl);
|
||||
return;
|
||||
}
|
||||
|
||||
const runtimeContext = sessionAccess.runtimeContext;
|
||||
const app = getAppsForUser(runtimeContext.groups).find((candidate) => candidate.slug === serviceSlug);
|
||||
const appFallbackUrl = buildOptionalServiceFallbackUrl(serviceSlug, app, fallbackPath);
|
||||
|
||||
if (!app || !app.hasAccess || app.status !== "active") {
|
||||
setNoStore(res);
|
||||
res.redirect(appFallbackUrl);
|
||||
return;
|
||||
}
|
||||
|
||||
redirectToServiceLaunchTarget(res, serviceSlug, runtimeContext, app, req.query.next_path || req.query.returnTo || "/");
|
||||
});
|
||||
|
||||
app.get("/api/services/:serviceSlug/launch", requireSession, (req, res) => {
|
||||
const serviceSlug = sanitizeServiceSlug(req.params.serviceSlug);
|
||||
const runtimeContext = getRuntimeSessionContext(req.nodedcSession);
|
||||
|
|
@ -415,53 +449,7 @@ 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 (isBimViewerServiceSlug(serviceSlug)) {
|
||||
const handoffToken = createServiceHandoff(serviceSlug, runtimeContext.user);
|
||||
const targetUrl = new URL("/auth/nodedc/handoff", getBimViewerBaseUrl(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;
|
||||
}
|
||||
|
||||
const handoffToken = createServiceHandoff(serviceSlug, runtimeContext.user);
|
||||
const taskBaseUrl = getTaskBaseUrl();
|
||||
const targetUrl = new URL("/auth/nodedc/handoff/", taskBaseUrl);
|
||||
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());
|
||||
redirectToServiceLaunchTarget(res, serviceSlug, runtimeContext, app, req.query.next_path || req.query.returnTo || "/");
|
||||
});
|
||||
|
||||
app.post("/api/internal/handoff/consume", (req, res) => {
|
||||
|
|
@ -3126,6 +3114,88 @@ function getBimViewerBaseUrl(app = null) {
|
|||
).replace(/\/$/, "");
|
||||
}
|
||||
|
||||
function findServiceCatalogAppBySlug(serviceSlug) {
|
||||
const slug = sanitizeServiceSlug(serviceSlug);
|
||||
|
||||
try {
|
||||
const snapshot = controlPlaneStore.getSnapshot({ name: "NODE.DC optional service fallback" });
|
||||
return snapshot.data.services.find((candidate) => sanitizeServiceSlug(candidate.slug) === slug) || null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function buildOptionalServiceFallbackUrl(serviceSlug, app, fallbackPath) {
|
||||
const path = sanitizeReturnTo(fallbackPath || "/");
|
||||
const serviceApp = app || findServiceCatalogAppBySlug(serviceSlug);
|
||||
let baseUrl = config.appBaseUrl;
|
||||
|
||||
if (isBimViewerServiceSlug(serviceSlug)) {
|
||||
baseUrl = getBimViewerBaseUrl(serviceApp);
|
||||
} else if (isEngineServiceSlug(serviceSlug)) {
|
||||
baseUrl = getEngineLaunchTargetUrl(serviceApp);
|
||||
} else if (serviceSlug === "task-manager") {
|
||||
baseUrl = getTaskBaseUrl();
|
||||
} else if (serviceApp?.openUrl || serviceApp?.url) {
|
||||
baseUrl = serviceApp.openUrl || serviceApp.url;
|
||||
}
|
||||
|
||||
try {
|
||||
return new URL(path, String(baseUrl || config.appBaseUrl).replace(/\/$/, "")).toString();
|
||||
} catch {
|
||||
return new URL("/", config.appBaseUrl).toString();
|
||||
}
|
||||
}
|
||||
|
||||
function redirectToServiceLaunchTarget(res, serviceSlug, runtimeContext, app, returnTo = "/") {
|
||||
if (isEngineServiceSlug(serviceSlug)) {
|
||||
const handoffToken = createServiceHandoff("nodedc", runtimeContext.user);
|
||||
const targetUrl = new URL("/auth/nodedc/handoff/", getEngineLaunchTargetUrl(app));
|
||||
const nextPath = sanitizeReturnTo(returnTo);
|
||||
|
||||
targetUrl.searchParams.set("token", handoffToken);
|
||||
|
||||
if (nextPath && nextPath !== "/") {
|
||||
targetUrl.searchParams.set("next_path", nextPath);
|
||||
}
|
||||
|
||||
res.redirect(targetUrl.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBimViewerServiceSlug(serviceSlug)) {
|
||||
const handoffToken = createServiceHandoff(serviceSlug, runtimeContext.user);
|
||||
const targetUrl = new URL("/auth/nodedc/handoff", getBimViewerBaseUrl(app));
|
||||
const nextPath = sanitizeReturnTo(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;
|
||||
}
|
||||
|
||||
const handoffToken = createServiceHandoff(serviceSlug, runtimeContext.user);
|
||||
const targetUrl = new URL("/auth/nodedc/handoff/", getTaskBaseUrl());
|
||||
const nextPath = sanitizeReturnTo(returnTo);
|
||||
|
||||
targetUrl.searchParams.set("token", handoffToken);
|
||||
|
||||
if (nextPath && nextPath !== "/") {
|
||||
targetUrl.searchParams.set("next_path", nextPath);
|
||||
}
|
||||
|
||||
res.redirect(targetUrl.toString());
|
||||
}
|
||||
|
||||
function getEnginePublicBaseUrl() {
|
||||
return String(
|
||||
process.env.NODEDC_ENGINE_PUBLIC_URL ||
|
||||
|
|
|
|||
Loading…
Reference in New Issue