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) });
|
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) => {
|
app.get("/api/services/:serviceSlug/launch", requireSession, (req, res) => {
|
||||||
const serviceSlug = sanitizeServiceSlug(req.params.serviceSlug);
|
const serviceSlug = sanitizeServiceSlug(req.params.serviceSlug);
|
||||||
const runtimeContext = getRuntimeSessionContext(req.nodedcSession);
|
const runtimeContext = getRuntimeSessionContext(req.nodedcSession);
|
||||||
|
|
@ -415,53 +449,7 @@ app.get("/api/services/:serviceSlug/launch", requireSession, (req, res) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEngineServiceSlug(serviceSlug)) {
|
redirectToServiceLaunchTarget(res, serviceSlug, runtimeContext, app, req.query.next_path || req.query.returnTo || "/");
|
||||||
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());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post("/api/internal/handoff/consume", (req, res) => {
|
app.post("/api/internal/handoff/consume", (req, res) => {
|
||||||
|
|
@ -3126,6 +3114,88 @@ function getBimViewerBaseUrl(app = null) {
|
||||||
).replace(/\/$/, "");
|
).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() {
|
function getEnginePublicBaseUrl() {
|
||||||
return String(
|
return String(
|
||||||
process.env.NODEDC_ENGINE_PUBLIC_URL ||
|
process.env.NODEDC_ENGINE_PUBLIC_URL ||
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue