Sync BIM session logout with Hub
This commit is contained in:
parent
48400c7d8c
commit
66fc4960bf
|
|
@ -3220,20 +3220,28 @@ header {
|
||||||
}
|
}
|
||||||
|
|
||||||
body[data-viewer-mode="guest"] .tb-btn:not([data-action="measure"]):not([data-action="section"]):not([data-action="projection"]),
|
body[data-viewer-mode="guest"] .tb-btn:not([data-action="measure"]):not([data-action="section"]):not([data-action="projection"]),
|
||||||
html[data-share-startup="guest"] body:not([data-viewer-mode="standard"]) .tb-btn:not([data-action="measure"]):not([data-action="section"]):not([data-action="projection"]),
|
html[data-share-startup] body:not([data-viewer-mode="standard"]) .tb-btn:not([data-action="measure"]):not([data-action="section"]):not([data-action="projection"]),
|
||||||
body[data-viewer-mode="guest"] #settingsPanel,
|
body[data-viewer-mode="guest"] #settingsPanel,
|
||||||
html[data-share-startup="guest"] body:not([data-viewer-mode="standard"]) #settingsPanel,
|
html[data-share-startup] body:not([data-viewer-mode="standard"]) #settingsPanel,
|
||||||
body[data-viewer-mode="guest"] #templatesPanel,
|
body[data-viewer-mode="guest"] #templatesPanel,
|
||||||
html[data-share-startup="guest"] body:not([data-viewer-mode="standard"]) #templatesPanel,
|
html[data-share-startup] body:not([data-viewer-mode="standard"]) #templatesPanel,
|
||||||
body[data-viewer-mode="guest"] #projectNameSection,
|
body[data-viewer-mode="guest"] #projectNameSection,
|
||||||
html[data-share-startup="guest"] body:not([data-viewer-mode="standard"]) #projectNameSection,
|
html[data-share-startup] body:not([data-viewer-mode="standard"]) #projectNameSection,
|
||||||
body[data-viewer-mode="guest"] #saveProjectSection,
|
body[data-viewer-mode="guest"] #saveProjectSection,
|
||||||
html[data-share-startup="guest"] body:not([data-viewer-mode="standard"]) #saveProjectSection,
|
html[data-share-startup] body:not([data-viewer-mode="standard"]) #saveProjectSection,
|
||||||
body[data-viewer-mode="guest"] #modelVersionUploadButton,
|
body[data-viewer-mode="guest"] #modelVersionUploadButton,
|
||||||
html[data-share-startup="guest"] body:not([data-viewer-mode="standard"]) #modelVersionUploadButton {
|
html[data-share-startup] body:not([data-viewer-mode="standard"]) #modelVersionUploadButton {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html[data-share-startup="pending"] #dropZone {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-share-startup="pending"] #loader.hidden {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
.version-history-backdrop {
|
.version-history-backdrop {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,7 @@ const COMMENTS_API = "/api/comments";
|
||||||
const UPLOAD_VERSIONS_API = "/api/uploads/versions";
|
const UPLOAD_VERSIONS_API = "/api/uploads/versions";
|
||||||
const SHARE_AUTH_GUEST_PARAM = "ndc_bim_guest";
|
const SHARE_AUTH_GUEST_PARAM = "ndc_bim_guest";
|
||||||
const SHARE_PROMOTION_TIMEOUT_MS = 4500;
|
const SHARE_PROMOTION_TIMEOUT_MS = 4500;
|
||||||
|
const NODEDC_SESSION_EVENT_TYPE = "nodedc:session:logout";
|
||||||
|
|
||||||
const acceptByType = {
|
const acceptByType = {
|
||||||
xkt: ".xkt",
|
xkt: ".xkt",
|
||||||
|
|
@ -648,6 +649,101 @@ const clearShareGuestAuthMarker = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const clearShareStartupPending = () => {
|
||||||
|
if (document.documentElement?.dataset?.shareStartup === "pending") {
|
||||||
|
delete document.documentElement.dataset.shareStartup;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const isNodeDCSessionLogoutEvent = (value) => (
|
||||||
|
value &&
|
||||||
|
typeof value === "object" &&
|
||||||
|
value.type === NODEDC_SESSION_EVENT_TYPE &&
|
||||||
|
typeof value.id === "string"
|
||||||
|
);
|
||||||
|
|
||||||
|
let nodeDCSessionSyncCleanup = null;
|
||||||
|
let nodeDCLogoutHandling = false;
|
||||||
|
|
||||||
|
const handleNodeDCSessionLogout = async () => {
|
||||||
|
if (nodeDCLogoutHandling) return;
|
||||||
|
nodeDCLogoutHandling = true;
|
||||||
|
|
||||||
|
const logoutRequest = fetch("/logout", {
|
||||||
|
method: "GET",
|
||||||
|
credentials: "include",
|
||||||
|
keepalive: true,
|
||||||
|
cache: "no-store",
|
||||||
|
})
|
||||||
|
.catch(() => undefined);
|
||||||
|
|
||||||
|
runtimeSessionInfo = {
|
||||||
|
...runtimeSessionInfo,
|
||||||
|
authenticated: false,
|
||||||
|
canShare: false,
|
||||||
|
user: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (startupSharePayload) {
|
||||||
|
startupSharePayload = {
|
||||||
|
...startupSharePayload,
|
||||||
|
mode: "guest",
|
||||||
|
readonly: true,
|
||||||
|
authenticated: false,
|
||||||
|
canShare: false,
|
||||||
|
user: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getShareTokenFromPath()) {
|
||||||
|
viewerMode = "guest";
|
||||||
|
inspectorCollapsed = true;
|
||||||
|
applyRuntimeMode();
|
||||||
|
updatePanelsVisibility();
|
||||||
|
nodeDCLogoutHandling = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.race([
|
||||||
|
logoutRequest,
|
||||||
|
new Promise((resolve) => window.setTimeout(resolve, 500)),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const loginUrl = new URL("/auth/login", getLauncherUrl());
|
||||||
|
window.location.replace(loginUrl.toString());
|
||||||
|
};
|
||||||
|
|
||||||
|
const setupNodeDCSessionSync = () => {
|
||||||
|
if (nodeDCSessionSyncCleanup || typeof document === "undefined") return;
|
||||||
|
|
||||||
|
let launcherOrigin = "";
|
||||||
|
try {
|
||||||
|
launcherOrigin = new URL(getLauncherUrl()).origin;
|
||||||
|
} catch (_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const iframe = document.createElement("iframe");
|
||||||
|
iframe.src = new URL("/auth/session-sync", launcherOrigin).toString();
|
||||||
|
iframe.title = "NODE.DC session sync";
|
||||||
|
iframe.tabIndex = -1;
|
||||||
|
iframe.setAttribute("aria-hidden", "true");
|
||||||
|
iframe.style.cssText = "position:fixed;width:0;height:0;opacity:0;pointer-events:none;border:0;";
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
|
||||||
|
const handleMessage = (event) => {
|
||||||
|
if (event.origin !== launcherOrigin || !isNodeDCSessionLogoutEvent(event.data)) return;
|
||||||
|
void handleNodeDCSessionLogout();
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener("message", handleMessage);
|
||||||
|
nodeDCSessionSyncCleanup = () => {
|
||||||
|
window.removeEventListener("message", handleMessage);
|
||||||
|
iframe.remove();
|
||||||
|
nodeDCSessionSyncCleanup = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const scheduleShareSessionPromotion = (shareToken) => {
|
const scheduleShareSessionPromotion = (shareToken) => {
|
||||||
const silentPromoteUrl = startupSharePayload?.silentPromoteUrl;
|
const silentPromoteUrl = startupSharePayload?.silentPromoteUrl;
|
||||||
if (
|
if (
|
||||||
|
|
@ -5212,6 +5308,7 @@ const applyViewerState = (state) => {
|
||||||
|
|
||||||
const initViewer = async () => {
|
const initViewer = async () => {
|
||||||
await initializeRuntimeMode();
|
await initializeRuntimeMode();
|
||||||
|
setupNodeDCSessionSync();
|
||||||
|
|
||||||
const preloadHidden = document.getElementById("preload-hidden");
|
const preloadHidden = document.getElementById("preload-hidden");
|
||||||
if (preloadHidden) {
|
if (preloadHidden) {
|
||||||
|
|
@ -5842,6 +5939,8 @@ const initViewer = async () => {
|
||||||
});
|
});
|
||||||
if (!src) {
|
if (!src) {
|
||||||
reportViewerEvent("startup-no-src", { search: window.location.search }, "error");
|
reportViewerEvent("startup-no-src", { search: window.location.search }, "error");
|
||||||
|
clearShareStartupPending();
|
||||||
|
setLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5850,12 +5949,15 @@ const initViewer = async () => {
|
||||||
if (!type) {
|
if (!type) {
|
||||||
reportViewerEvent("startup-type-error", { src, name, typeParam: params.get("type") }, "error");
|
reportViewerEvent("startup-type-error", { src, name, typeParam: params.get("type") }, "error");
|
||||||
showError("Не удалось определить формат модели из URL");
|
showError("Не удалось определить формат модели из URL");
|
||||||
|
clearShareStartupPending();
|
||||||
|
setLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dropZone?.classList.add("hidden");
|
dropZone?.classList.add("hidden");
|
||||||
setStatus(`Подготовка: ${name}...`);
|
setStatus(`Подготовка: ${name}...`);
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
clearShareStartupPending();
|
||||||
|
|
||||||
let settingsSrc = sharedViewer?.settingsSrc || params.get("settingsSrc") || params.get("sourceSrc") || params.get("originalSrc") || src;
|
let settingsSrc = sharedViewer?.settingsSrc || params.get("settingsSrc") || params.get("sourceSrc") || params.get("originalSrc") || src;
|
||||||
const applyQueryViewerOverrides = () => {
|
const applyQueryViewerOverrides = () => {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
if (/^\/share\/[^/]+\/?$/.test(window.location.pathname || "")) {
|
if (/^\/share\/[^/]+\/?$/.test(window.location.pathname || "")) {
|
||||||
document.documentElement.dataset.shareStartup = "guest";
|
document.documentElement.dataset.shareStartup = "pending";
|
||||||
}
|
}
|
||||||
}());
|
}());
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1685,15 +1685,22 @@ const handleSharePromoted = (res, url) => {
|
||||||
</html>`);
|
</html>`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleLogout = (req, res) => {
|
const handleLogout = (req, res, {redirect = true} = {}) => {
|
||||||
const sessionId = parseCookies(req.headers.cookie || "")[BIM_SESSION_COOKIE];
|
const sessionId = parseCookies(req.headers.cookie || "")[BIM_SESSION_COOKIE];
|
||||||
if (sessionId) {
|
if (sessionId) {
|
||||||
bimSessions.delete(sessionId);
|
bimSessions.delete(sessionId);
|
||||||
}
|
}
|
||||||
clearBimSessionCookie(res);
|
clearBimSessionCookie(res);
|
||||||
|
res.setHeader("Cache-Control", "no-store");
|
||||||
|
if (redirect) {
|
||||||
res.statusCode = 302;
|
res.statusCode = 302;
|
||||||
res.setHeader("Location", "/");
|
res.setHeader("Location", "/");
|
||||||
res.end();
|
res.end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
res.statusCode = 200;
|
||||||
|
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
||||||
|
res.end("<!doctype html><html><head><meta charset='utf-8'></head><body>NODE.DC BIM session closed.</body></html>");
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCreateShare = async (req, res) => {
|
const handleCreateShare = async (req, res) => {
|
||||||
|
|
@ -3304,6 +3311,10 @@ const requestHandler = async (req, res) => {
|
||||||
return handleLogout(req, res);
|
return handleLogout(req, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req.method === "GET" && url.pathname === "/logout") {
|
||||||
|
return handleLogout(req, res, {redirect: false});
|
||||||
|
}
|
||||||
|
|
||||||
if (req.method === "GET" && /^\/api\/shares\/[^/]+\/?$/.test(url.pathname)) {
|
if (req.method === "GET" && /^\/api\/shares\/[^/]+\/?$/.test(url.pathname)) {
|
||||||
return handleGetShare(req, res, shareTokenFromPath(url.pathname));
|
return handleGetShare(req, res, shareTokenFromPath(url.pathname));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue