Promote shared BIM links through launcher
This commit is contained in:
+59
-1
@@ -805,15 +805,33 @@ const getRequestBaseUrl = (req) => {
|
||||
return `${proto}://${host}`.replace(/\/$/, "");
|
||||
};
|
||||
|
||||
const buildLauncherLoginUrl = (req, nextPath = "/") => {
|
||||
const buildLauncherLaunchUrl = (nextPath = "/") => {
|
||||
const launchPath = `/api/services/${encodeURIComponent(BIM_SERVICE_SLUG)}/launch`;
|
||||
const launchUrl = new URL(launchPath, LAUNCHER_BASE_URL);
|
||||
launchUrl.searchParams.set("returnTo", sanitizeReturnTo(nextPath));
|
||||
return launchUrl.toString();
|
||||
};
|
||||
|
||||
const buildLauncherLoginUrl = (req, nextPath = "/") => {
|
||||
const loginUrl = new URL("/auth/login", LAUNCHER_BASE_URL);
|
||||
const launchUrl = new URL(buildLauncherLaunchUrl(nextPath));
|
||||
loginUrl.searchParams.set("returnTo", `${launchUrl.pathname}${launchUrl.search}`);
|
||||
return loginUrl.toString();
|
||||
};
|
||||
|
||||
const buildSharePromotionUrls = (token) => {
|
||||
const safeToken = safeShareToken(token);
|
||||
if (!safeToken) {
|
||||
return {promoteUrl: null, silentPromoteUrl: null};
|
||||
}
|
||||
const sharePath = `/share/${encodeURIComponent(safeToken)}`;
|
||||
const bridgePath = `/auth/share-promoted?next=${encodeURIComponent(sharePath)}`;
|
||||
return {
|
||||
promoteUrl: buildLauncherLaunchUrl(sharePath),
|
||||
silentPromoteUrl: buildLauncherLaunchUrl(bridgePath)
|
||||
};
|
||||
};
|
||||
|
||||
const sendAuthRequired = (req, res, url) => {
|
||||
const nextPath = sanitizeReturnTo(`${url.pathname}${url.search || ""}`);
|
||||
if (!INTERNAL_ACCESS_TOKEN) {
|
||||
@@ -1596,6 +1614,37 @@ const handleLauncherHandoff = async (req, res, url) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleSharePromoted = (res, url) => {
|
||||
const nextPath = sanitizeReturnTo(url.searchParams.get("next") || "/");
|
||||
const nextPathJson = JSON.stringify(nextPath);
|
||||
res.statusCode = 200;
|
||||
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
||||
res.setHeader("Cache-Control", "no-store");
|
||||
res.setHeader("Content-Security-Policy", "default-src 'none'; script-src 'unsafe-inline'");
|
||||
res.end(`<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>BIM share auth</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
const nextPath = ${nextPathJson};
|
||||
const payload = {
|
||||
type: "nodedc:bim-share-promoted",
|
||||
nextPath,
|
||||
createdAt: Date.now()
|
||||
};
|
||||
if (window.parent && window.parent !== window) {
|
||||
window.parent.postMessage(payload, window.location.origin);
|
||||
} else {
|
||||
window.location.replace(nextPath);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>`);
|
||||
};
|
||||
|
||||
const handleLogout = (req, res) => {
|
||||
const sessionId = parseCookies(req.headers.cookie || "")[BIM_SESSION_COOKIE];
|
||||
if (sessionId) {
|
||||
@@ -1713,6 +1762,9 @@ const handleGetShare = async (req, res, token) => {
|
||||
}
|
||||
const session = getCurrentBimSession(req);
|
||||
const authenticated = !!session;
|
||||
const promotionUrls = BIM_AUTH_REQUIRED && !authenticated
|
||||
? buildSharePromotionUrls(safeToken)
|
||||
: {promoteUrl: null, silentPromoteUrl: null};
|
||||
const versionHistory = await getAssetVersionHistory(req, {
|
||||
projectId: share.projectId,
|
||||
assetId: share.assetId
|
||||
@@ -1723,6 +1775,8 @@ const handleGetShare = async (req, res, token) => {
|
||||
readonly: !authenticated,
|
||||
authenticated,
|
||||
canShare: !BIM_AUTH_REQUIRED || authenticated,
|
||||
promoteUrl: promotionUrls.promoteUrl,
|
||||
silentPromoteUrl: promotionUrls.silentPromoteUrl,
|
||||
user: session?.user || null,
|
||||
viewer: {
|
||||
src: publicUrlForUploadSrc(req, share.src),
|
||||
@@ -3201,6 +3255,10 @@ const requestHandler = async (req, res) => {
|
||||
return handleLauncherHandoff(req, res, url);
|
||||
}
|
||||
|
||||
if (req.method === "GET" && url.pathname === "/auth/share-promoted") {
|
||||
return handleSharePromoted(res, url);
|
||||
}
|
||||
|
||||
if (req.method === "GET" && url.pathname === "/auth/logout") {
|
||||
return handleLogout(req, res);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user