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
8 changes: 7 additions & 1 deletion src/components/AppShell.deeplink.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ vi.mock("./app-shell/useOnboardingFlow", () => ({
}),
}));

import { AppShell } from "./AppShell";
import { AppShell, buildAuthStartPath } from "./AppShell";

const waitForCondition = async (check: () => boolean, timeoutMs = 2500): Promise<void> => {
const started = Date.now();
Expand Down Expand Up @@ -284,6 +284,12 @@ describe("AppShell deeplink cold-load flow", () => {
window.history.replaceState(null, "", "/H%C3%B8gevarde-hyttefelt/Fyrisj%C3%B8vegen");
});

it("builds direct auth-start navigation for explicit sign-in clicks", () => {
expect(buildAuthStartPath({ pathname: "/sim/site", search: "?mode=demo", hash: "#panel" })).toBe(
"/api/auth-start?returnTo=%2Fsim%2Fsite%3Fmode%3Ddemo%23panel",
);
});

it("loads the resolved simulation id and does not emit unavailable", async () => {
const view = await renderAppShell();

Expand Down
22 changes: 6 additions & 16 deletions src/components/AppShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ const ACCESS_CHECKING_NOTICE_ID = "access-checking";
const AUTH_DEGRADED_NOTICE_ID = "auth-degraded";
const OFFLINE_SYNC_NOTICE_ID = "offline-sync";
const BLANK_SIM_NOTICE_ID = "blank-simulation-guidance";

export const buildAuthStartPath = (location: Pick<Location, "pathname" | "search" | "hash">): string => {
const returnTo = `${location.pathname}${location.search}${location.hash}`;
return `/api/auth-start?returnTo=${encodeURIComponent(returnTo || "/")}`;
};
// Shell vocabulary mapping for cleanup work:
// - navigator => LeftSidePanel
// - inspector => RightSidePanel (legacy term retained in code for stability)
Expand Down Expand Up @@ -275,7 +280,6 @@ export function AppShell() {
const authRetryQuickAttemptRef = useRef(0);
const authRetryTimerRef = useRef<number | null>(null);
const authCheckGenerationRef = useRef(0);
const userInitiatedSignInRef = useRef(false);
const runAccessCheckRef = useRef<(reason: "initial" | "retry" | "online") => void>(() => {});
const setShowWelcomeModalRef = useRef<(show: boolean) => void>(() => {});
const isInitializingRef = useRef(isInitializing);
Expand Down Expand Up @@ -559,9 +563,8 @@ export function AppShell() {
}, []);

const handleUserSignInRequested = useCallback(() => {
userInitiatedSignInRef.current = true;
clearAuthRetryTimer();
runAccessCheckRef.current("retry");
window.location.href = buildAuthStartPath(window.location);
}, [clearAuthRetryTimer]);

const scheduleAuthRecoveryRetry = useCallback(
Expand Down Expand Up @@ -611,7 +614,6 @@ export function AppShell() {
authRecoveryActiveRef.current = false;
authRecoveryDisabledRef.current = false;
authRetryQuickAttemptRef.current = 0;
userInitiatedSignInRef.current = false;
setAccessDiagnosticMessage(null);
setCurrentUser(profile);
setAuthState("signed_in");
Expand Down Expand Up @@ -686,12 +688,6 @@ export function AppShell() {
online: typeof navigator === "undefined" ? true : navigator.onLine,
isInitializing: isInitializingRef.current,
});
if (userInitiatedSignInRef.current) {
userInitiatedSignInRef.current = false;
const returnTo = `${window.location.pathname}${window.location.search}${window.location.hash}`;
window.location.href = `/api/auth-start?returnTo=${encodeURIComponent(returnTo || "/")}`;
return;
}
setAuthDegraded(
"Cloud save is unavailable. Your changes may not be saved. The sign-in check timed out; LinkSim is retrying automatically.",
"timeout",
Expand Down Expand Up @@ -799,12 +795,6 @@ export function AppShell() {
setAccessState("readonly");
return;
}
if (userInitiatedSignInRef.current) {
userInitiatedSignInRef.current = false;
const returnTo = `${window.location.pathname}${window.location.search}${window.location.hash}`;
window.location.href = `/api/auth-start?returnTo=${encodeURIComponent(returnTo || "/")}`;
return;
}
setAuthDegraded(
isServerTimeout
? "Cloud save is unavailable. Your changes may not be saved. The sign-in service timed out; LinkSim is retrying automatically."
Expand Down
3 changes: 1 addition & 2 deletions src/components/UserAdminPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ type UserAdminPanelProps = {
*/
onOpenSettings?: () => void;
/**
* When provided, clicking "Sign in" triggers a silent auth check first;
* only if that fails does it redirect to the CF Access login page.
* When provided, clicking "Sign in" delegates sign-in handling to the shell.
*/
onSignInRequested?: () => void;
};
Expand Down
Loading