Wait for config to load before evaluating route access

Fix race condition where custom role users are temporarily denied access after login while config is still loading. Defer route rendering in DefaultAppView until config is available so the complete role list is known before ProtectedRoute evaluates permissions
This commit is contained in:
Josh Hawkins 2025-12-15 12:38:52 -06:00
parent f543d0ab31
commit 0f36422b35

View File

@ -14,6 +14,7 @@ import ProtectedRoute from "@/components/auth/ProtectedRoute";
import { AuthProvider } from "@/context/auth-context"; import { AuthProvider } from "@/context/auth-context";
import useSWR from "swr"; import useSWR from "swr";
import { FrigateConfig } from "./types/frigateConfig"; import { FrigateConfig } from "./types/frigateConfig";
import ActivityIndicator from "@/components/indicators/activity-indicator";
const Live = lazy(() => import("@/pages/Live")); const Live = lazy(() => import("@/pages/Live"));
const Events = lazy(() => import("@/pages/Events")); const Events = lazy(() => import("@/pages/Events"));
@ -50,6 +51,13 @@ function DefaultAppView() {
const { data: config } = useSWR<FrigateConfig>("config", { const { data: config } = useSWR<FrigateConfig>("config", {
revalidateOnFocus: false, revalidateOnFocus: false,
}); });
// Compute required roles for main routes, ensuring we have config first
// to prevent race condition where custom roles are temporarily unavailable
const mainRouteRoles = config?.auth?.roles
? Object.keys(config.auth.roles)
: undefined;
return ( return (
<div className="size-full overflow-hidden"> <div className="size-full overflow-hidden">
{isDesktop && <Sidebar />} {isDesktop && <Sidebar />}
@ -68,13 +76,11 @@ function DefaultAppView() {
<Routes> <Routes>
<Route <Route
element={ element={
<ProtectedRoute mainRouteRoles ? (
requiredRoles={ <ProtectedRoute requiredRoles={mainRouteRoles} />
config?.auth.roles ) : (
? Object.keys(config.auth.roles) <ActivityIndicator className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2" />
: ["admin", "viewer"] )
}
/>
} }
> >
<Route index element={<Live />} /> <Route index element={<Live />} />