LFM2-WebGPU / src /components /OAuthCallback.tsx
shreyask's picture
add mcp support
c211e0e verified
raw
history blame
3.63 kB
import { useEffect, useState } from "react";
import { exchangeCodeForToken } from "../services/oauth";
import { secureStorage } from "../utils/storage";
import type { MCPServerConfig } from "../types/mcp";
import { STORAGE_KEYS, DEFAULTS } from "../config/constants";
interface OAuthTokens {
access_token: string;
refresh_token?: string;
expires_in?: number;
token_type?: string;
[key: string]: string | number | undefined;
}
interface OAuthCallbackProps {
serverUrl: string;
onSuccess?: (tokens: OAuthTokens) => void;
onError?: (error: Error) => void;
}
const OAuthCallback: React.FC<OAuthCallbackProps> = ({
serverUrl,
onSuccess,
onError,
}) => {
const [status, setStatus] = useState<string>("Authorizing...");
useEffect(() => {
const params = new URLSearchParams(window.location.search);
const code = params.get("code");
// Always persist MCP server URL for robustness
localStorage.setItem(STORAGE_KEYS.OAUTH_MCP_SERVER_URL, serverUrl);
if (code) {
exchangeCodeForToken({
serverUrl,
code,
redirectUri: window.location.origin + DEFAULTS.OAUTH_REDIRECT_PATH,
})
.then(async (tokens) => {
await secureStorage.setItem(STORAGE_KEYS.OAUTH_ACCESS_TOKEN, tokens.access_token);
// Add MCP server to MCPClientService for UI
const mcpServerUrl = localStorage.getItem(STORAGE_KEYS.OAUTH_MCP_SERVER_URL);
if (mcpServerUrl) {
// Use persisted name and transport from initial add
const serverName =
localStorage.getItem(STORAGE_KEYS.MCP_SERVER_NAME) || mcpServerUrl;
const serverTransport =
(localStorage.getItem(STORAGE_KEYS.MCP_SERVER_TRANSPORT) as MCPServerConfig['transport']) || DEFAULTS.MCP_TRANSPORT;
// Build config and add to mcp-servers
const serverConfig = {
id: `server_${Date.now()}`,
name: serverName,
url: mcpServerUrl,
enabled: true,
transport: serverTransport,
auth: {
type: "bearer" as const,
token: tokens.access_token,
},
};
// Load existing servers
let servers: MCPServerConfig[] = [];
try {
const stored = localStorage.getItem(STORAGE_KEYS.MCP_SERVERS);
if (stored) servers = JSON.parse(stored);
} catch {}
// Add or update
const exists = servers.some((s: MCPServerConfig) => s.url === mcpServerUrl);
if (!exists) {
servers.push(serverConfig);
localStorage.setItem(STORAGE_KEYS.MCP_SERVERS, JSON.stringify(servers));
}
// Clear temp values from localStorage for clean slate
localStorage.removeItem(STORAGE_KEYS.MCP_SERVER_NAME);
localStorage.removeItem(STORAGE_KEYS.MCP_SERVER_TRANSPORT);
localStorage.removeItem(STORAGE_KEYS.OAUTH_MCP_SERVER_URL);
}
setStatus("Authorization successful! Redirecting...");
if (onSuccess) onSuccess(tokens);
// Redirect to main app page after short delay
setTimeout(() => {
window.location.replace("/");
}, 1000);
})
.catch((err) => {
setStatus("OAuth token exchange failed: " + err.message);
if (onError) onError(err);
});
} else {
setStatus("Missing authorization code in callback URL.");
}
}, [serverUrl, onSuccess, onError]);
return <div>{status}</div>;
};
export default OAuthCallback;