diff --git a/frontend/src/pages/CallbackPage.tsx b/frontend/src/pages/CallbackPage.tsx index e95c69c..0e6c912 100644 --- a/frontend/src/pages/CallbackPage.tsx +++ b/frontend/src/pages/CallbackPage.tsx @@ -10,15 +10,20 @@ interface SessionResponse { 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 (state=error, error=access_denied, etc.) --- + // --- Erreur OAuth explicite --- const oauthError = params.get('error'); if (oauthError) { const desc = params.get('error_description') ?? oauthError; @@ -26,6 +31,21 @@ export default function CallbackPage() { 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) { @@ -38,7 +58,6 @@ export default function CallbackPage() { exchangeCode(code, verifier, redirectUri) .then((tokens) => { - // Pass tokens to backend to set httpOnly cookies + sync user return apiFetch('/auth/session', { method: 'POST', body: JSON.stringify({ @@ -55,7 +74,7 @@ export default function CallbackPage() { return; } - // --- Flow session (Step 2 — token JWT passé en query param) --- + // --- Flow session (token JWT en query param) --- const token = params.get('token'); if (token) { apiFetch('/auth/session', { @@ -74,6 +93,47 @@ export default function CallbackPage() { 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 (