"use client" import { useEffect, useState, Suspense } from "react" import { useRouter, useSearchParams } from "next/navigation" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Button } from "@/components/ui/button" import { Loader2, CheckCircle, XCircle, ArrowLeft } from "lucide-react" import { useAuth } from "@/contexts/auth-context" function AuthCallbackContent() { const router = useRouter() const searchParams = useSearchParams() const { refreshAuth } = useAuth() const [status, setStatus] = useState<"processing" | "success" | "error">("processing") const [error, setError] = useState(null) const [purpose, setPurpose] = useState("app_auth") useEffect(() => { const code = searchParams.get('code') const callbackKey = `callback_processed_${code}` // Prevent double execution across component remounts if (sessionStorage.getItem(callbackKey)) { return } sessionStorage.setItem(callbackKey, 'true') const handleCallback = async () => { try { // Get parameters from URL const state = searchParams.get('state') const errorParam = searchParams.get('error') // Get stored auth info const connectorId = localStorage.getItem('connecting_connector_id') const storedConnectorType = localStorage.getItem('connecting_connector_type') const authPurpose = localStorage.getItem('auth_purpose') // Determine purpose - default to app_auth for login, data_source for connectors const detectedPurpose = authPurpose || (storedConnectorType?.includes('drive') ? 'data_source' : 'app_auth') setPurpose(detectedPurpose) // Debug logging console.log('OAuth Callback Debug:', { urlParams: { code: !!code, state: !!state, error: errorParam }, localStorage: { connectorId, storedConnectorType, authPurpose }, detectedPurpose, fullUrl: window.location.href }) // Use state parameter as connection_id if localStorage is missing const finalConnectorId = connectorId || state if (errorParam) { throw new Error(`OAuth error: ${errorParam}`) } if (!code || !state || !finalConnectorId) { console.error('Missing OAuth callback parameters:', { code: !!code, state: !!state, finalConnectorId: !!finalConnectorId }) throw new Error('Missing required parameters for OAuth callback') } // Send callback data to backend const response = await fetch('/api/auth/callback', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ connection_id: finalConnectorId, authorization_code: code, state: state }), }) const result = await response.json() if (response.ok) { setStatus("success") if (result.purpose === 'app_auth' || detectedPurpose === 'app_auth') { // App authentication - refresh auth context and redirect to home/original page await refreshAuth() // Get redirect URL from login page const redirectTo = searchParams.get('redirect') || '/chat' // Clean up localStorage localStorage.removeItem('connecting_connector_id') localStorage.removeItem('connecting_connector_type') localStorage.removeItem('auth_purpose') // Redirect to the original page or home setTimeout(() => { router.push(redirectTo) }, 2000) } else { // Connector authentication - redirect to connectors page // Clean up localStorage localStorage.removeItem('connecting_connector_id') localStorage.removeItem('connecting_connector_type') localStorage.removeItem('auth_purpose') // Redirect to connectors page with success indicator setTimeout(() => { router.push('/connectors?oauth_success=true') }, 2000) } } else { throw new Error(result.error || 'Authentication failed') } } catch (err) { console.error('OAuth callback error:', err) setError(err instanceof Error ? err.message : 'Unknown error occurred') setStatus("error") // Clean up localStorage on error too localStorage.removeItem('connecting_connector_id') localStorage.removeItem('connecting_connector_type') localStorage.removeItem('auth_purpose') } } handleCallback() }, [searchParams, router, refreshAuth]) // Dynamic UI content based on purpose const isAppAuth = purpose === 'app_auth' const getTitle = () => { if (status === "processing") { return isAppAuth ? "Signing you in..." : "Connecting..." } if (status === "success") { return isAppAuth ? "Welcome to OpenRAG!" : "Connection Successful!" } if (status === "error") { return isAppAuth ? "Sign In Failed" : "Connection Failed" } } const getDescription = () => { if (status === "processing") { return isAppAuth ? "Please wait while we complete your sign in..." : "Please wait while we complete the connection..." } if (status === "success") { return "You will be redirected shortly." } if (status === "error") { return isAppAuth ? "There was an issue signing you in." : "There was an issue with the connection." } } return (
{status === "processing" && ( <> {getTitle()} )} {status === "success" && ( <> {getTitle()} )} {status === "error" && ( <> {getTitle()} )} {getDescription()} {status === "error" && (

{error}

)} {status === "success" && (

{isAppAuth ? 'Redirecting you to the app...' : 'Redirecting to connectors...'}

)}
) } export default function AuthCallbackPage() { return ( Loading... Please wait while we process your request... }> ) }