Milestone v1.0: FamilySync MVP #1
@@ -93,10 +93,22 @@ export function CalendarShell() {
|
|||||||
staleTime: 5 * 60 * 1000,
|
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({
|
const eventsQuery = useQuery({
|
||||||
queryKey: ['events', start, end],
|
queryKey: ['events', start, end],
|
||||||
queryFn: () => fetchEvents(start, end),
|
queryFn: () => fetchEvents(start, end),
|
||||||
|
enabled: meQuery.isSuccess,
|
||||||
retry: 2,
|
retry: 2,
|
||||||
staleTime: 5 * 60 * 1000,
|
staleTime: 5 * 60 * 1000,
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user