ФУНКЦИИ - NODEDC TASK: listen for platform logout
This commit is contained in:
parent
424e262a91
commit
f02865512f
|
|
@ -24,6 +24,7 @@ import globalStyles from "@/styles/globals.css?url";
|
|||
import type { Route } from "./+types/root";
|
||||
import designConfig from "../design.config.json";
|
||||
// components
|
||||
import { NodeDCSessionSync } from "@/components/auth-screens/nodedc-session-sync";
|
||||
// local
|
||||
import { CustomErrorComponent } from "./error";
|
||||
import { AppProvider } from "./provider";
|
||||
|
|
@ -181,6 +182,7 @@ export const meta: Route.MetaFunction = () => [
|
|||
export default function Root() {
|
||||
return (
|
||||
<AppProvider>
|
||||
<NodeDCSessionSync />
|
||||
<div className={cn("relative flex h-screen w-full flex-col overflow-hidden bg-canvas", "desktop-app-container")}>
|
||||
<main className="relative h-full w-full overflow-hidden">
|
||||
<Outlet />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
|
||||
import { buildNodeDCLauncherUrl, shouldUseNodeDCOIDC } from "@/helpers/nodedc-auth";
|
||||
|
||||
const NODEDC_SESSION_EVENT_TYPE = "nodedc:session:logout";
|
||||
|
||||
interface NodeDCSessionEvent {
|
||||
type: typeof NODEDC_SESSION_EVENT_TYPE;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export function NodeDCSessionSync() {
|
||||
useEffect(() => {
|
||||
if (!shouldUseNodeDCOIDC()) return;
|
||||
|
||||
const launcherOrigin = new URL(buildNodeDCLauncherUrl()).origin;
|
||||
const syncUrl = new URL("/auth/session-sync", launcherOrigin).toString();
|
||||
const loginUrl = new URL("/auth/login?prompt=login", launcherOrigin).toString();
|
||||
let isRedirecting = false;
|
||||
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src = syncUrl;
|
||||
iframe.title = "NODE.DC session sync";
|
||||
iframe.tabIndex = -1;
|
||||
iframe.setAttribute("aria-hidden", "true");
|
||||
iframe.style.position = "fixed";
|
||||
iframe.style.width = "0";
|
||||
iframe.style.height = "0";
|
||||
iframe.style.opacity = "0";
|
||||
iframe.style.pointerEvents = "none";
|
||||
iframe.style.border = "0";
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
const handleLogout = () => {
|
||||
if (isRedirecting) return;
|
||||
|
||||
isRedirecting = true;
|
||||
const redirectToLogin = () => window.location.replace(loginUrl);
|
||||
const fallbackTimer = window.setTimeout(redirectToLogin, 500);
|
||||
|
||||
fetch("/logout", { method: "GET", credentials: "include", keepalive: true })
|
||||
.catch(() => undefined)
|
||||
.finally(() => {
|
||||
window.clearTimeout(fallbackTimer);
|
||||
redirectToLogin();
|
||||
});
|
||||
};
|
||||
|
||||
const handleMessage = (event: MessageEvent) => {
|
||||
if (event.origin !== launcherOrigin || !isNodeDCSessionEvent(event.data)) return;
|
||||
handleLogout();
|
||||
};
|
||||
|
||||
window.addEventListener("message", handleMessage);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("message", handleMessage);
|
||||
iframe.remove();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function isNodeDCSessionEvent(value: unknown): value is NodeDCSessionEvent {
|
||||
if (!value || typeof value !== "object") return false;
|
||||
|
||||
const event = value as Partial<NodeDCSessionEvent>;
|
||||
return event.type === NODEDC_SESSION_EVENT_TYPE && typeof event.id === "string";
|
||||
}
|
||||
Loading…
Reference in New Issue