From ce34ecdd4d35dcabcd706fd1740f95bac4794757 Mon Sep 17 00:00:00 2001 From: CODEX Date: Tue, 23 Jun 2026 18:57:36 +0300 Subject: [PATCH] Promote BIM share on Launcher login event --- frontend/dcViewer.js | 48 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/frontend/dcViewer.js b/frontend/dcViewer.js index 02d3ca6..37acfe3 100644 --- a/frontend/dcViewer.js +++ b/frontend/dcViewer.js @@ -188,7 +188,8 @@ const SHARE_AUTH_GUEST_PARAM = "ndc_bim_guest"; const SHARE_PROMOTION_TIMEOUT_MS = 4500; const SHARE_PROMOTION_RETRY_MS = 15000; const SESSION_STATUS_WATCH_INTERVAL_MS = 2500; -const NODEDC_SESSION_EVENT_TYPE = "nodedc:session:logout"; +const NODEDC_SESSION_LOGOUT_EVENT_TYPE = "nodedc:session:logout"; +const NODEDC_SESSION_LOGIN_EVENT_TYPE = "nodedc:session:login"; const acceptByType = { xkt: ".xkt", @@ -632,6 +633,13 @@ const getShareTopLevelPromotionUrl = () => { return typeof promoteUrl === "string" && promoteUrl.trim() ? promoteUrl : ""; }; +const buildLauncherOptionalServiceUrl = (nextPath = getCurrentReturnPath(), fallbackPath = nextPath) => { + const launchUrl = new URL("/api/services/bim-viewer/optional-launch", getLauncherUrl()); + launchUrl.searchParams.set("returnTo", nextPath); + launchUrl.searchParams.set("fallbackTo", fallbackPath); + return launchUrl.toString(); +}; + const hasShareGuestAuthMarker = () => { try { return new URLSearchParams(window.location.search || "").get(SHARE_AUTH_GUEST_PARAM) === "1"; @@ -660,12 +668,20 @@ const clearShareStartupPending = () => { const isNodeDCSessionLogoutEvent = (value) => ( value && typeof value === "object" && - value.type === NODEDC_SESSION_EVENT_TYPE && + value.type === NODEDC_SESSION_LOGOUT_EVENT_TYPE && + typeof value.id === "string" +); + +const isNodeDCSessionLoginEvent = (value) => ( + value && + typeof value === "object" && + value.type === NODEDC_SESSION_LOGIN_EVENT_TYPE && typeof value.id === "string" ); let nodeDCSessionSyncCleanup = null; let nodeDCLogoutHandling = false; +let nodeDCLoginHandling = false; let nodeDCSessionWatchTimer = null; let nodeDCSessionWatchInFlight = false; @@ -717,6 +733,24 @@ const handleNodeDCSessionLogout = async () => { window.location.replace(loginUrl.toString()); }; +const handleNodeDCSessionLogin = () => { + if (nodeDCLoginHandling || runtimeSessionInfo.authenticated === true) return; + nodeDCLoginHandling = true; + + const shareToken = getShareTokenFromPath(); + if (shareToken) { + const promotionUrl = getShareTopLevelPromotionUrl() || + buildLauncherOptionalServiceUrl( + `/share/${encodeURIComponent(shareToken)}`, + `/share/${encodeURIComponent(shareToken)}?${SHARE_AUTH_GUEST_PARAM}=1` + ); + window.location.assign(promotionUrl); + return; + } + + window.location.assign(buildLauncherOptionalServiceUrl()); +}; + const setupNodeDCSessionSync = () => { if (nodeDCSessionSyncCleanup || typeof document === "undefined") return; @@ -736,8 +770,14 @@ const setupNodeDCSessionSync = () => { document.body.appendChild(iframe); const handleMessage = (event) => { - if (event.origin !== launcherOrigin || !isNodeDCSessionLogoutEvent(event.data)) return; - void handleNodeDCSessionLogout(); + if (event.origin !== launcherOrigin) return; + if (isNodeDCSessionLogoutEvent(event.data)) { + void handleNodeDCSessionLogout(); + return; + } + if (isNodeDCSessionLoginEvent(event.data)) { + handleNodeDCSessionLogin(); + } }; window.addEventListener("message", handleMessage);