72 lines
2.0 KiB
JavaScript
72 lines
2.0 KiB
JavaScript
import { useEffect, useRef } from 'react'
|
|
import { useNavigate, useSearchParams, Link } from 'react-router-dom'
|
|
import { useAuth } from '../context/AuthContext'
|
|
import { homeFor } from '../config/roles'
|
|
|
|
// Point d'arrivée après un aller-retour OAuth : le backend nous renvoie ici
|
|
// avec le JWT et le profil encodés dans l'URL.
|
|
export default function AuthCallback() {
|
|
const navigate = useNavigate()
|
|
const [searchParams] = useSearchParams()
|
|
const { login } = useAuth()
|
|
const handled = useRef(false)
|
|
|
|
const errorParam = searchParams.get('error')
|
|
const token = searchParams.get('token')
|
|
const encodedUser = searchParams.get('user')
|
|
|
|
let error = ''
|
|
let user = null
|
|
|
|
if (errorParam) {
|
|
error = errorParam
|
|
} else if (!token || !encodedUser) {
|
|
error = 'Réponse de connexion incomplète.'
|
|
} else {
|
|
try {
|
|
// atob renvoie des octets : on les relit en UTF-8.
|
|
const bytes = Uint8Array.from(
|
|
atob(encodedUser),
|
|
(c) => c.charCodeAt(0)
|
|
)
|
|
user = JSON.parse(new TextDecoder().decode(bytes))
|
|
} catch {
|
|
error = 'Réponse de connexion illisible.'
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (handled.current || !user) return
|
|
|
|
handled.current = true
|
|
|
|
login(user, token)
|
|
navigate(homeFor(user), { replace: true })
|
|
}, [user, token, login, navigate])
|
|
|
|
if (error) {
|
|
return (
|
|
<div className="min-h-screen bg-white flex flex-col justify-center items-center px-8 max-w-sm mx-auto text-center">
|
|
<div className="mb-4 px-4 py-3 rounded-lg bg-red-50 border border-red-200 text-red-600 text-sm">
|
|
{error}
|
|
</div>
|
|
|
|
<Link
|
|
to="/connexion"
|
|
className="text-sm text-[#006B6B] font-medium hover:underline"
|
|
>
|
|
Retour à la connexion
|
|
</Link>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div className="min-h-screen bg-white flex flex-col justify-center items-center px-8 max-w-sm mx-auto text-center">
|
|
<p className="text-gray-500 text-sm">
|
|
Connexion en cours…
|
|
</p>
|
|
</div>
|
|
)
|
|
}
|