Milestone v1.0: FamilySync MVP #1
@@ -93,10 +93,22 @@ export function CalendarShell() {
|
||||
staleTime: 5 * 60 * 1000,
|
||||
})
|
||||
|
||||
// Fetch windowed occurrences — key includes start/end so navigation refetches
|
||||
// Fetch windowed occurrences — key includes start/end so navigation refetches.
|
||||
//
|
||||
// enabled: meQuery.isSuccess is load-bearing for the OIDC login flow, not just
|
||||
// an optimization. When unauthenticated, every /api/* request hits the OIDC
|
||||
// guard, which 302-redirects to Authelia AND sets a fresh state cookie. If this
|
||||
// query ran concurrently with fetchMe (and retried), each /api/events redirect
|
||||
// would overwrite the OIDC state cookie mid-login — so the state returned to
|
||||
// /callback no longer matched the cookie, producing OAUTH_INVALID_RESPONSE
|
||||
// ("unexpected state parameter") and an Internal Server Error after Authelia.
|
||||
// Gating on a successful /api/me means only fetchMe (redirect:'manual',
|
||||
// retry:false) touches a guarded endpoint while unauthenticated, so the single
|
||||
// top-level /api/login navigation owns the state cookie uncontested.
|
||||
const eventsQuery = useQuery({
|
||||
queryKey: ['events', start, end],
|
||||
queryFn: () => fetchEvents(start, end),
|
||||
enabled: meQuery.isSuccess,
|
||||
retry: 2,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user