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

Function AuthGate

apps/cloud/src/routes/__root.tsx:186–328  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

184}
185
186function AuthGate() {
187 const auth = useAuth();
188 const location = useLocation();
189 const navigate = useNavigate();
190 const isOnboardingRoute = ONBOARDING_PATHS.has(location.pathname);
191 const isPublicRoute = PUBLIC_PATHS.has(location.pathname);
192 // The org the URL names (the `{-$orgSlug}` segment), if any. `/account/me`
193 // is scoped to it, so `auth.organization` IS this org when the caller is a
194 // member — and `null` when the URL names an org they can't access.
195 const urlOrgSlug = (useParams({ strict: false }) as { orgSlug?: string }).orgSlug;
196 // The same slug derived from the PATHNAME instead of the route params: the
197 // params resolve asynchronously (a fresh load renders once with no orgSlug,
198 // then again with it), and anything keyed on them remounts on that flap.
199 // The pathname is synchronously correct on the very first render, and it is
200 // exactly what the request header derives from (getActiveOrgSlug), so the
201 // registry scope below can never disagree with the header scope.
202 const firstSegment = location.pathname.split("/")[1] ?? "";
203 const pathnameOrgSlug = isValidOrgSlug(firstSegment) ? firstSegment : null;
204
205 // The SSR gate already bounced fresh org-less document requests to
206 // /create-org; this catches the MID-SESSION transitions (org deleted,
207 // membership revoked → /account/me now reports no org). Only for BARE paths:
208 // an org-less result on a slugged URL is a wrong address (404 below), not a
209 // reason to send the user to onboarding.
210 const needsOrgRedirect =
211 auth.status === "authenticated" &&
212 auth.organization == null &&
213 !urlOrgSlug &&
214 !isOnboardingRoute &&
215 !isPublicRoute;
216
217 React.useEffect(() => {
218 if (needsOrgRedirect) {
219 void navigate({ to: "/create-org", replace: true });
220 }
221 }, [needsOrgRedirect, navigate]);
222
223 // The signed-out safety net behind the SSR gate: if a session dies while
224 // the SPA is already loaded (logout elsewhere, expiry), go to /login the
225 // same way a fresh document request would — keeping where they were.
226 const needsLoginRedirect = auth.status === "unauthenticated" && !isPublicRoute;
227 React.useEffect(() => {
228 if (needsLoginRedirect) {
229 window.location.assign(loginPath(`${location.pathname}${location.searchStr}`));
230 }
231 }, [needsLoginRedirect, location.pathname, location.searchStr]);
232
233 if (isPublicRoute) {
234 return <Outlet />;
235 }
236
237 // Every state that isn't "authenticated with an org, on a page that wants
238 // the shell" is a moment between redirects, or the one frame between mount
239 // and the hint cookie seeding (SPA mode reads it in an effect). Neutral
240 // blank — the one placeholder that's correct whatever happens next. The
241 // app-shell skeleton this file used to render here is exactly the
242 // wrong-UI flash the document gate + hint exist to prevent.
243 if (auth.status === "loading" || auth.status === "unauthenticated") {

Callers

nothing calls this directly

Calls 3

useAuthFunction · 0.90
isValidOrgSlugFunction · 0.90
loginPathFunction · 0.90

Tested by

no test coverage detected