* handle the authentication code received from the oauth redirect
(authorizationCode: string, state?: string)
| 274 | * handle the authentication code received from the oauth redirect |
| 275 | */ |
| 276 | async function handleMCPOauthCode(authorizationCode: string, state?: string) { |
| 277 | let serverUrl: string | undefined; |
| 278 | let context: MCPOauthContext | undefined; |
| 279 | |
| 280 | if (state) { |
| 281 | // Use state parameter to find the correct server |
| 282 | serverUrl = stateToServerUrl.get(state); |
| 283 | if (serverUrl) { |
| 284 | context = authenticatingContexts.get(serverUrl); |
| 285 | } |
| 286 | } else { |
| 287 | // Fallback: if no state or single context, use the first one |
| 288 | const contexts = Array.from(authenticatingContexts.entries()); |
| 289 | if (contexts.length === 1) { |
| 290 | [serverUrl, context] = contexts[0]; |
| 291 | } |
| 292 | } |
| 293 | |
| 294 | if (!context || !serverUrl) { |
| 295 | console.error("No matching authenticating context found for state:", state); |
| 296 | return; |
| 297 | } |
| 298 | |
| 299 | const { ide, serverId } = context; |
| 300 | |
| 301 | try { |
| 302 | if (!serverUrl) { |
| 303 | throw new Error("No MCP server url found for authentication"); |
| 304 | } |
| 305 | if (!authorizationCode) { |
| 306 | throw new Error(`No MCP authorization code found for ${serverUrl}`); |
| 307 | } |
| 308 | |
| 309 | // Close the server before processing auth |
| 310 | if (serverInstance) { |
| 311 | await new Promise<void>((resolve) => { |
| 312 | serverInstance!.close(() => { |
| 313 | console.debug("Server for MCP Oauth process was closed"); |
| 314 | serverInstance = null; |
| 315 | resolve(); |
| 316 | }); |
| 317 | }); |
| 318 | } |
| 319 | |
| 320 | const authProvider = new MCPConnectionOauthProvider(serverUrl, ide); |
| 321 | await authProvider.ensureRedirectUrl(); |
| 322 | const authStatus = await auth(authProvider, { |
| 323 | serverUrl, |
| 324 | authorizationCode, |
| 325 | }); |
| 326 | |
| 327 | if (authStatus === "AUTHORIZED") { |
| 328 | const { MCPManagerSingleton } = await import("./MCPManagerSingleton"); // put dynamic import to avoid cyclic imports |
| 329 | await MCPManagerSingleton.getInstance().refreshConnection(serverId); |
| 330 | } |
| 331 | } catch (error) { |
| 332 | const errorMessage = error instanceof Error ? error.message : String(error); |
| 333 | console.error("OAuth authorization failed:", errorMessage); |
no test coverage detected