MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / AuthGate

Function AuthGate

apps/cloud/src/routes/__root.tsx:207–315  ·  view source on GitHub ↗
({ ssrOrigin }: { ssrOrigin: string | null })

Source from the content-addressed store, hash-verified

205}
206
207function AuthGate({ ssrOrigin }: { ssrOrigin: string | null }) {
208 const auth = useAuth();
209 const location = useLocation();
210 const navigate = useNavigate();
211 const isOnboardingRoute = ONBOARDING_PATHS.has(location.pathname);
212 const isPublicRoute = PUBLIC_PATHS.has(location.pathname);
213 // The org the URL names (the `{-$orgSlug}` segment), if any. `/account/me`
214 // is scoped to it, so `auth.organization` IS this org when the caller is a
215 // member — and `null` when the URL names an org they can't access.
216 const urlOrgSlug = (useParams({ strict: false }) as { orgSlug?: string }).orgSlug;
217
218 // The SSR gate already bounced fresh org-less document requests to
219 // /create-org; this catches the MID-SESSION transitions (org deleted,
220 // membership revoked → /account/me now reports no org). Only for BARE paths:
221 // an org-less result on a slugged URL is a wrong address (404 below), not a
222 // reason to send the user to onboarding.
223 const needsOrgRedirect =
224 auth.status === "authenticated" &&
225 auth.organization == null &&
226 !urlOrgSlug &&
227 !isOnboardingRoute &&
228 !isPublicRoute;
229
230 React.useEffect(() => {
231 if (needsOrgRedirect) {
232 void navigate({ to: "/create-org", replace: true });
233 }
234 }, [needsOrgRedirect, navigate]);
235
236 // The signed-out safety net behind the SSR gate: if a session dies while
237 // the SPA is already loaded (logout elsewhere, expiry), go to /login the
238 // same way a fresh document request would — keeping where they were.
239 const needsLoginRedirect = auth.status === "unauthenticated" && !isPublicRoute;
240 React.useEffect(() => {
241 if (needsLoginRedirect) {
242 window.location.assign(loginPath(`${location.pathname}${location.searchStr}`));
243 }
244 }, [needsLoginRedirect, location.pathname, location.searchStr]);
245
246 if (isPublicRoute) {
247 return <Outlet />;
248 }
249
250 // Every state that isn't "authenticated with an org, on a page that wants
251 // the shell" is a moment between redirects or an edge the gates make
252 // near-impossible (a verified user whose hint hasn't seeded yet). Neutral
253 // blank — the one placeholder that's correct whatever happens next. The
254 // app-shell skeleton this file used to render here is exactly the
255 // wrong-UI flash the SSR gate + hint exist to prevent.
256 if (auth.status === "loading" || auth.status === "unauthenticated") {
257 return <BlankScreen />;
258 }
259
260 if (isOnboardingRoute) {
261 return <Outlet />;
262 }
263
264 if (auth.organization == null) {

Callers

nothing calls this directly

Calls 2

useAuthFunction · 0.90
loginPathFunction · 0.90

Tested by

no test coverage detected