ФУНКЦИИ - 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 type { Route } from "./+types/root";
|
||||||
import designConfig from "../design.config.json";
|
import designConfig from "../design.config.json";
|
||||||
// components
|
// components
|
||||||
|
import { NodeDCSessionSync } from "@/components/auth-screens/nodedc-session-sync";
|
||||||
// local
|
// local
|
||||||
import { CustomErrorComponent } from "./error";
|
import { CustomErrorComponent } from "./error";
|
||||||
import { AppProvider } from "./provider";
|
import { AppProvider } from "./provider";
|
||||||
|
|
@ -181,6 +182,7 @@ export const meta: Route.MetaFunction = () => [
|
||||||
export default function Root() {
|
export default function Root() {
|
||||||
return (
|
return (
|
||||||
<AppProvider>
|
<AppProvider>
|
||||||
|
<NodeDCSessionSync />
|
||||||
<div className={cn("relative flex h-screen w-full flex-col overflow-hidden bg-canvas", "desktop-app-container")}>
|
<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">
|
<main className="relative h-full w-full overflow-hidden">
|
||||||
<Outlet />
|
<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