Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 7x 24x 7x 7x 5x 5x 3x 3x 3x 3x 3x 2x 7x 2x 5x 2x 2x 2x 2x | import { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { useAuthStore } from './authStore'
export function CallbackPage() {
const navigate = useNavigate()
const setAuth = useAuthStore((s) => s.setAuth)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
fetch('/api/auth/session')
.then((res) => {
if (!res.ok) throw new Error('Session fetch failed')
return res.json()
})
.then((data) => {
setAuth(
{
sub: data.sub ?? '',
preferred_username: data.preferred_username ?? data.sub ?? '',
email: data.email ?? '',
groups: data.groups ?? [],
},
data.expiresAt,
data.idleExpiresAt,
)
const returnUrl = sessionStorage.getItem('returnUrl')
sessionStorage.removeItem('returnUrl')
navigate(returnUrl ?? '/', { replace: true })
})
.catch(() => {
setError('Failed to complete authentication. Please try again.')
})
}, [navigate, setAuth])
if (error) {
return <CallbackError error={error} navigate={navigate} />
}
return (
<div className="flex min-h-screen items-center justify-center">
<p className="text-muted-foreground">Signing in...</p>
</div>
)
}
function CallbackError({ error, navigate }: { error: string; navigate: (path: string, opts?: { replace?: boolean }) => void }) {
useEffect(() => {
const timer = setTimeout(() => navigate('/login', { replace: true }), 3000)
return () => clearTimeout(timer)
}, [navigate])
return (
<div className="flex min-h-screen flex-col items-center justify-center gap-4">
<p className="text-destructive">{error}</p>
<p className="text-sm text-muted-foreground">Redirecting to login...</p>
</div>
)
}
|