From 34cb44cfa8412c10c627c951673e175c49e132e7 Mon Sep 17 00:00:00 2001 From: tanweer919 Date: Mon, 13 Jul 2026 03:22:04 +0530 Subject: [PATCH] feat(auth): gate Google sign-in on an existing CRM profile Google is sign-IN only: after OAuth, check crm.account.registrationStatus; if the account has no CRM profile, sign back out and show an error on the login screen instead of admitting a profile-less user. (Onboarding to collect the profile comes later.) --- src/components/portal/login-flow.tsx | 34 ++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/components/portal/login-flow.tsx b/src/components/portal/login-flow.tsx index 955d238..600274d 100644 --- a/src/components/portal/login-flow.tsx +++ b/src/components/portal/login-flow.tsx @@ -24,8 +24,8 @@ const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; export function LoginFlow() { const router = useRouter(); - const { login, loginWithOAuth, completeOAuthLogin } = useAuth(); - const { ready } = useAppShell(); + const { login, loginWithOAuth, completeOAuthLogin, logout } = useAuth(); + const { ready, sdk } = useAppShell(); const [step, setStep] = useState("identify"); const [email, setEmail] = useState(""); const [account, setAccount] = useState(null); @@ -76,20 +76,29 @@ export function LoginFlow() { if (!ready) { setStep("connecting"); return; } setStep("connecting"); completeOAuthLogin(code) - .then((ace) => { - if (ace) { - // Clear the ?code=… from the URL, then enter the app. - window.history.replaceState({}, "", "/portal/login"); - router.replace("/dashboard"); - } else { + .then(async (ace) => { + if (!ace) { replace("identify"); return; } + // Google is sign-IN only: require an existing CRM profile. If the account + // has none, sign back out and show an error rather than silently admitting it. + let registered = false; + try { + const st = await sdk.query<{ registered: boolean }>("crm.account.registrationStatus"); + registered = !!st?.registered; + } catch { registered = false; } + window.history.replaceState({}, "", "/portal/login"); + if (!registered) { + try { await logout(); } catch { /* ignore */ } + setFlash("No account is registered for this Google email. Please register first."); replace("identify"); + return; } + router.replace("/dashboard"); }) .catch(() => { setFlash("Google sign-in didn't complete. Please try again."); replace("identify"); }); - }, [ready, completeOAuthLogin, router]); + }, [ready, completeOAuthLogin, router, sdk, logout]); /* ---- auth resolution ---- */ function afterAuth(factor: "password" | "passkey" | "otp" | "totp" | "push" | "social") { @@ -144,7 +153,12 @@ export function LoginFlow() { /* =================================================================== */ return (
- {step === "identify" && router.push("/portal/register")} />} + {step === "identify" && ( + <> + {flash &&
{flash}
} + router.push("/portal/register")} /> + + )} {step === "connecting" && (
-- 2.52.0