Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 9 additions & 30 deletions src/frontend/src/components/AuthBroadcastListener/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,46 +71,25 @@ export function AuthBroadcastListener() {
console.debug("[AuthBroadcast] Clearing auth state...");
await logout();

// 5. For root path "/", stay on the page (just update auth state)
if (isOnRootPath) {
console.debug("[AuthBroadcast] On root path, staying at / (UI will update to show Login/Book Demo)");
// Sign out from Clerk in background (best effort, don't block)
// If this fails, the login page will detect and clean up stale session
if (IS_CLERK_AUTH && signOut) {
signOut().catch((error) => {
console.debug("[AuthBroadcast] Clerk signOut failed (will be cleaned up on next login):", error);
});
console.debug("[AuthBroadcast] Clerk signOut initiated (background)");
}
console.log("[AuthBroadcast] Cross-tab logout completed - staying at /");
return;
}
// 5. Always redirect tabs to the public landing page (/) for a consistent post-logout state
console.debug("[AuthBroadcast] Redirecting to / (public landing)...");
navigate("/", { replace: true });

// 6. For protected pages, redirect IMMEDIATELY (don't wait for Clerk)
// Sign out from Clerk in background (best effort, don't block)
// If this fails, the landing page will detect and clean up stale session
if (IS_CLERK_AUTH && signOut) {
console.debug("[AuthBroadcast] Redirecting to /login immediately...");
// Navigate first (instant)
navigate("/login", { replace: true });
// Then sign out from Clerk in background (best effort)
// If this fails, the login page will detect and clean up stale session
signOut().catch((error) => {
console.debug("[AuthBroadcast] Clerk signOut failed (will be cleaned up on next login):", error);
});
console.debug("[AuthBroadcast] Clerk signOut initiated (background)");
return;
}

// 7. Redirect to login (for non-Clerk auth)
console.debug("[AuthBroadcast] Redirecting to login...");
navigate("/login", { replace: true });

console.log("[AuthBroadcast] Cross-tab logout completed successfully");
console.log("[AuthBroadcast] Cross-tab logout completed - redirected to /");
return;
} catch (error) {
console.error("[AuthBroadcast] Error during cross-tab logout:", error);
// Force redirect even if cleanup fails (but not for root path)
if (!isOnRootPath) {
navigate("/login", { replace: true });
}
// Force redirect even if cleanup fails
navigate("/", { replace: true });
}
}, [location.pathname, queryClient, logout, navigate, signOut]);

Expand Down
4 changes: 2 additions & 2 deletions src/frontend/src/modals/IOModal/playground-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ export default function IOModal({
<Button
onClick={LangflowButtonClick}
variant="primary"
className="w-full !rounded-xl shadow-lg"
className="hidden w-full !rounded-xl shadow-lg"
>
<LangflowLogoColor />
<div className="text-sm">Built with Langflow</div>
Expand All @@ -444,7 +444,7 @@ export default function IOModal({
>
<Button
variant="primary"
className="h-12 w-12 !rounded-xl !p-4 shadow-lg"
className="hidden h-12 w-12 !rounded-xl !p-4 shadow-lg"
onClick={LangflowButtonClick}
>
<LangflowLogoColor className="h-[18px] w-[18px] scale-150" />
Expand Down
4 changes: 2 additions & 2 deletions src/new-landingpage/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="/src/new-assets/visualailogo.png" />
<link rel="icon" href="/visualaifavicon.png" />
<script src="https://cdn.tailwindcss.com"></script>
<title>Visual AI Agents Builder</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
</html>
45 changes: 44 additions & 1 deletion src/new-landingpage/src/LandingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,36 @@ import {
LANGFLOW_REFRESH_TOKEN,
} from "./session";

const API_BASE = (import.meta.env.VITE_LANGFLOW_API_BASE ?? "/api/v1/")
.replace(/\/?$/, "/");
const AUTH_CHANNEL_NAME = "langflow_auth_channel";

type AuthBroadcastMessage = {
type: "LOGOUT";
timestamp: number;
source?: string;
};

function broadcastLogoutEvent() {
if (typeof window === "undefined" || typeof BroadcastChannel === "undefined") {
return;
}

try {
const channel = new BroadcastChannel(AUTH_CHANNEL_NAME);
const message: AuthBroadcastMessage = {
type: "LOGOUT",
timestamp: Date.now(),
source: window.location.pathname,
};

channel.postMessage(message);
channel.close();
} catch (error) {
console.warn("[LandingPage] Failed to broadcast logout event", error);
}
}

/* -------------------- Icons -------------------- */

function CheckIcon(props: SVGProps<SVGSVGElement>) {
Expand Down Expand Up @@ -61,7 +91,20 @@ export default function LandingPage(): JSX.Element {
]);

const handleLogout = async () => {
await signOut();
try {
await signOut();
} catch (error) {
console.warn("[LandingPage] Clerk signOut failed", error);
}

try {
await fetch(`${API_BASE}logout`, { method: "POST" });
} catch (error) {
console.warn("[LandingPage] Backend logout request failed", error);
}

broadcastLogoutEvent();

removeCookie(LANGFLOW_ACCESS_TOKEN, { path: "/" });
removeCookie(LANGFLOW_REFRESH_TOKEN, { path: "/" });
clearStoredOrgSelection();
Expand Down
Loading