import { trpc } from "@/lib/trpc"; import { UNAUTHED_ERR_MSG } from '@shared/const'; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { httpBatchLink, TRPCClientError } from "@trpc/client"; import { createRoot } from "react-dom/client"; import { useState } from "react"; import superjson from "superjson"; import App from "./App"; import { getLoginUrl } from "./const"; import { ENABLE_AUTH } from "@/lib/featureFlags"; import "./index.css"; // ── Domain detection ────────────────────────────────────────────────── // Clerk production keys are bound to marlowekeynes.org and its registered // satellite domains. On any other domain (dev, manus.space preview, etc.) // we skip Clerk entirely and fall back to legacy Manus OAuth. const CLERK_VALID_DOMAINS = [ "marlowekeynes.org", "mkdeepbrief.com", "www.mkdeepbrief.com", "steinbergstock.com", "www.steinbergstock.com", "mkdeepbrief.manus.space", "deepdiveanaly-mzjhetg8.manus.space", ]; const currentHost = typeof window !== "undefined" ? window.location.hostname : ""; const isClerkDomain = CLERK_VALID_DOMAINS.some( (d) => currentHost === d || currentHost.endsWith(`.${d}`) ); // Satellite domains are production domains that are NOT the primary domain const CLERK_PRIMARY_DOMAIN = "marlowekeynes.org"; const isSatelliteDomain = isClerkDomain && currentHost !== CLERK_PRIMARY_DOMAIN; const CLERK_SIGN_IN_URL = `https://${CLERK_PRIMARY_DOMAIN}/login`; // Map satellite hostnames to their Clerk CNAME (clerk.{base-domain}). // The Clerk JS SDK uses the `domain` prop to construct the sync URL: // `https://{domain}/v1/client/sync` // So `domain` must point to the Clerk CNAME, NOT the site hostname. const SATELLITE_CLERK_DOMAINS: Record = { "mkdeepbrief.com": "clerk.mkdeepbrief.com", "www.mkdeepbrief.com": "clerk.mkdeepbrief.com", "mkinitiation.com": "clerk.mkdeepbrief.com", "www.mkinitiation.com": "clerk.mkdeepbrief.com", "mkdeepbrief.manus.space": "clerk.mkdeepbrief.com", "deepdiveanaly-mzjhetg8.manus.space": "clerk.mkdeepbrief.com", }; const satelliteClerkDomain = SATELLITE_CLERK_DOMAINS[currentHost] || `clerk.${currentHost.replace(/^www\./, '')}`; // [OPT-091] Configure QueryClient defaults for performance const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 2 * 60 * 1000, gcTime: 10 * 60 * 1000, refetchOnWindowFocus: false, retry: 1, refetchOnReconnect: 'always', }, mutations: { retry: 0, }, }, }); const redirectToLoginIfUnauthorized = (error: unknown) => { if (!ENABLE_AUTH) return; // Auth disabled — never redirect to login if (!(error instanceof TRPCClientError)) return; if (typeof window === "undefined") return; const isUnauthorized = error.message === UNAUTHED_ERR_MSG; if (!isUnauthorized) return; if (isClerkDomain) { window.location.href = CLERK_SIGN_IN_URL; } else { window.location.href = getLoginUrl(); } }; queryClient.getQueryCache().subscribe(event => { if (event.type === "updated" && event.action.type === "error") { const error = event.query.state.error; redirectToLoginIfUnauthorized(error); console.error("[API Query Error]", error); } }); queryClient.getMutationCache().subscribe(event => { if (event.type === "updated" && event.action.type === "error") { const error = event.mutation.state.error; redirectToLoginIfUnauthorized(error); console.error("[API Mutation Error]", error); } }); // ── tRPC client wrapper (WITHOUT Clerk) ─────────────────────────────── // Used on dev/preview domains where Clerk is not available. function TrpcWithLegacyAuth({ children }: { children: React.ReactNode }) { const [trpcClient] = useState(() => trpc.createClient({ links: [ httpBatchLink({ url: "/api/trpc", transformer: superjson, fetch(input, init) { return globalThis.fetch(input, { ...(init ?? {}), credentials: "include", }); }, }), ], }) ); return ( {children} ); } // ── Conditional Clerk loading ───────────────────────────────────────── // Only import and use Clerk on domains where the production key is valid // AND when authentication is enabled. When ENABLE_AUTH is false, we skip // Clerk entirely to prevent forced sign-up/sign-in flows. if (isClerkDomain && ENABLE_AUTH) { // Dynamic import to avoid loading Clerk SDK on non-Clerk domains import("@clerk/clerk-react").then(({ ClerkProvider, useAuth: useClerkAuth }) => { const CLERK_PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY; /** * tRPC client wrapper with Clerk auth token injection. * Must be inside ClerkProvider to access useAuth(). */ function TrpcWithClerkAuth({ children }: { children: React.ReactNode }) { const { getToken } = useClerkAuth(); // Memoize the tRPC client so it's not recreated on every render. // getToken is stable from Clerk, so this is safe. const [trpcClient] = useState(() => trpc.createClient({ links: [ httpBatchLink({ url: "/api/trpc", transformer: superjson, async headers() { try { const token = await getToken(); return token ? { Authorization: `Bearer ${token}` } : {}; } catch { return {}; } }, fetch(input, init) { return globalThis.fetch(input, { ...(init ?? {}), credentials: "include", }); }, }), ], }) ); return ( {children} ); } // Build ClerkProvider props const clerkProps: Record = { publishableKey: CLERK_PUBLISHABLE_KEY, signInUrl: CLERK_SIGN_IN_URL, signUpUrl: `https://${CLERK_PRIMARY_DOMAIN}/login`, }; if (isSatelliteDomain) { clerkProps.isSatellite = true; clerkProps.domain = satelliteClerkDomain; } else { // Primary domain: allow redirects back to all satellite domains clerkProps.allowedRedirectOrigins = [ "https://mkdeepbrief.com", "https://www.mkdeepbrief.com", "https://mkinitiation.com", "https://www.mkinitiation.com", "https://mkdeepbrief.manus.space", "https://deepdiveanaly-mzjhetg8.manus.space", ]; } createRoot(document.getElementById("root")!).render( ); }); } else { // Non-Clerk domain: use legacy Manus OAuth (cookie-based auth) createRoot(document.getElementById("root")!).render( ); }