Skip to content
Closed
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
37 changes: 35 additions & 2 deletions apps/desktop/src/renderer/routes/_authenticated/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Outlet,
useNavigate,
} from "@tanstack/react-router";
import { useEffect, useRef } from "react";
import { DndProvider } from "react-dnd";
import { NewWorkspaceModal } from "renderer/components/NewWorkspaceModal";
import { Paywall } from "renderer/components/Paywall";
Expand All @@ -25,14 +26,25 @@ export const Route = createFileRoute("/_authenticated")({
});

function AuthenticatedLayout() {
const { data: session, isPending } = authClient.useSession();
const { data: session, isPending, error } = authClient.useSession();
const isSignedIn = env.SKIP_ENV_VALIDATION || !!session?.user;
const activeOrganizationId = env.SKIP_ENV_VALIDATION
? MOCK_ORG_ID
: session?.session?.activeOrganizationId;
const navigate = useNavigate();
const utils = electronTrpc.useUtils();

// Track if user was ever authenticated in this session.
// This prevents redirecting to sign-in on transient network errors.
const wasAuthenticatedRef = useRef(false);

// Update ref when we confirm user is authenticated
useEffect(() => {
if (isSignedIn) {
wasAuthenticatedRef.current = true;
}
}, [isSignedIn]);

// Global hooks and subscriptions (these don't need CollectionsProvider)
useAgentHookListener();
useUpdateListener();
Expand Down Expand Up @@ -66,11 +78,32 @@ function AuthenticatedLayout() {
},
});

// Still loading session - render nothing
if (isPending) {
return null;
}

if (!isSignedIn) {
// Check if error is a transient network error vs an auth error (401)
// Network errors typically have status 0 or undefined
// Auth errors (401) mean the session is actually invalid
const isNetworkError =
error && (error.status === 0 || error.status === undefined);
const isAuthError = error && error.status === 401;

// Transient network error while user was previously authenticated.
// Keep the authenticated UI instead of redirecting to sign-in.
// This prevents flashing the sign-in page on temporary connectivity issues.
if (isNetworkError && !isSignedIn && wasAuthenticatedRef.current) {
console.warn(
"[auth] Network error while fetching session, preserving authenticated state:",
error,
);
// Continue rendering the authenticated UI - the session will recover on next successful fetch
} else if (!isSignedIn || isAuthError) {
// Confirmed signed out: explicit 401, or no error + no session
if (isAuthError) {
console.log("[auth] Session invalid (401), redirecting to sign-in");
}
return <Navigate to="/sign-in" replace />;
}

Expand Down
Loading