import { AuthDebuggerState, OAuthStep } from "@/lib/auth-types"; import { CheckCircle2, Circle, ExternalLink } from "lucide-react"; import { Button } from "./ui/button"; import { DebugInspectorOAuthClientProvider } from "@/lib/auth"; interface OAuthStepProps { label: string; isComplete: boolean; isCurrent: boolean; error?: Error | null; children?: React.ReactNode; } const OAuthStepDetails = ({ label, isComplete, isCurrent, error, children, }: OAuthStepProps) => { return (
{isComplete ? ( ) : ( )} {label}
{/* Show children if current step or complete and children exist */} {(isCurrent || isComplete) && children && (
{children}
)} {/* Display error if current step and an error exists */} {isCurrent && error && (

Error:

{error.message}

)}
); }; interface OAuthFlowProgressProps { serverUrl: string; authState: AuthDebuggerState; updateAuthState: (updates: Partial) => void; proceedToNextStep: () => Promise; } export const OAuthFlowProgress = ({ serverUrl, authState, updateAuthState, proceedToNextStep, }: OAuthFlowProgressProps) => { const provider = new DebugInspectorOAuthClientProvider(serverUrl); const steps: Array = [ "metadata_discovery", "client_registration", "authorization_redirect", "authorization_code", "token_request", "complete", ]; const currentStepIdx = steps.findIndex((s) => s === authState.oauthStep); // Helper to get step props const getStepProps = (stepName: OAuthStep) => ({ isComplete: currentStepIdx > steps.indexOf(stepName) || currentStepIdx === steps.length - 1, // last step is "complete" isCurrent: authState.oauthStep === stepName, error: authState.oauthStep === stepName ? authState.latestError : null, }); return (

OAuth Flow Progress

Follow these steps to complete OAuth authentication with the server.

{provider.getServerMetadata() && (
Retrieved OAuth Metadata from {serverUrl} /.well-known/oauth-authorization-server
                {JSON.stringify(provider.getServerMetadata(), null, 2)}
              
)}
{authState.oauthClientInfo && (
Registered Client Information
                {JSON.stringify(authState.oauthClientInfo, null, 2)}
              
)}
{authState.authorizationUrl && (

Authorization URL:

{authState.authorizationUrl}

Click the link to authorize in your browser. After authorization, you'll be redirected back to continue the flow.

)}
{ updateAuthState({ authorizationCode: e.target.value, validationError: null, }); }} placeholder="Enter the code from the authorization server" className={`flex h-9 w-full rounded-md border bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${ authState.validationError ? "border-red-500" : "border-input" }`} />
{authState.validationError && (

{authState.validationError}

)}

Once you've completed authorization in the link, paste the code here.

{authState.oauthMetadata && (
Token Request Details

Token Endpoint:

{authState.oauthMetadata.token_endpoint}
)}
{authState.oauthTokens && (
Access Tokens

Authentication successful! You can now use the authenticated connection. These tokens will be used automatically for server requests.

                {JSON.stringify(authState.oauthTokens, null, 2)}
              
)}
{authState.oauthStep !== "complete" && ( <> )} {authState.oauthStep === "authorization_redirect" && authState.authorizationUrl && ( )}
); };