import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { apiFetch } from '../lib/api'; import { exchangeCode, loadVerifier } from '../lib/oauth'; import { useAuthContext } from '../context/AuthContext'; import type { User } from '../context/AuthContext'; interface SessionResponse { success: boolean; data: { user: User }; } type PendingState = | { kind: 'verification_pending'; email: string } | { kind: 'merge_pending'; email: string; provider: string }; export default function CallbackPage() { const navigate = useNavigate(); const { setUser } = useAuthContext(); const [error, setError] = useState(null); const [pending, setPending] = useState(null); useEffect(() => { const params = new URLSearchParams(window.location.search); // --- Erreur OAuth explicite --- const oauthError = params.get('error'); if (oauthError) { const desc = params.get('error_description') ?? oauthError; setError(`Erreur OAuth : ${desc}`); return; } // --- Pending states (verification / merge) --- const status = params.get('status'); if (status === 'verification_pending') { setPending({ kind: 'verification_pending', email: params.get('email') ?? '' }); return; } if (status === 'merge_pending') { setPending({ kind: 'merge_pending', email: params.get('email') ?? '', provider: params.get('provider') ?? '', }); return; } // --- Flow PKCE : ?code= présent --- const code = params.get('code'); if (code) { const verifier = loadVerifier(); if (!verifier) { setError('Session PKCE expirée. Recommence la connexion.'); return; } const redirectUri = `${window.location.origin}/callback`; exchangeCode(code, verifier, redirectUri) .then((tokens) => { return apiFetch('/auth/session', { method: 'POST', body: JSON.stringify({ token: tokens.access_token, refreshToken: tokens.refresh_token, }), }); }) .then((res) => { setUser(res.data.user); navigate('/', { replace: true }); }) .catch(() => setError("Échec de l'échange de code OAuth. Réessaie.")); return; } // --- Flow session (token JWT en query param) --- const token = params.get('token'); if (token) { apiFetch('/auth/session', { method: 'POST', body: JSON.stringify({ token }), }) .then((res) => { setUser(res.data.user); navigate('/', { replace: true }); }) .catch(() => setError("Échec de l'authentification. Réessaie.")); return; } // Aucun paramètre reconnu → retour accueil navigate('/', { replace: true }); }, [navigate, setUser]); // --- Pending UI --- if (pending) { return (
{pending.kind === 'verification_pending' ? ( <>
📧

Vérifie ton email

Un email de vérification a été envoyé à{' '} {pending.email}.
Clique sur le lien pour activer ton compte.

) : ( <>
🔗

Fusion de compte

Un compte existe déjà avec l'email{' '} {pending.email}.
Un email a été envoyé pour fusionner ton compte{' '} {pending.provider}.
Clique sur le lien dans l'email pour confirmer.

)} ← Retour à la connexion
); } // --- Error UI --- if (error) { return (

{error}

← Retour à l'accueil
); } return (

Connexion en cours…

); }