diff --git a/apps/x/apps/main/src/auth-server.ts b/apps/x/apps/main/src/auth-server.ts index b0b890c0..78e519d0 100644 --- a/apps/x/apps/main/src/auth-server.ts +++ b/apps/x/apps/main/src/auth-server.ts @@ -25,7 +25,7 @@ export interface AuthServerResult { */ export function createAuthServer( port: number = DEFAULT_PORT, - onCallback: (code: string, state: string) => void | Promise + onCallback: (params: Record) => void | Promise ): Promise { return new Promise((resolve, reject) => { const server = createServer((req, res) => { @@ -67,7 +67,7 @@ export function createAuthServer( // Handle callback - either traditional OAuth with code/state or Composio-style notification // Composio callbacks may not have code/state, just a notification that the flow completed - onCallback(code || '', state || ''); + onCallback(Object.fromEntries(url.searchParams.entries())); res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(` diff --git a/apps/x/apps/main/src/composio-handler.ts b/apps/x/apps/main/src/composio-handler.ts index 36470d3e..04b2ba41 100644 --- a/apps/x/apps/main/src/composio-handler.ts +++ b/apps/x/apps/main/src/composio-handler.ts @@ -147,7 +147,7 @@ export async function initiateConnection(toolkitSlug: string): Promise<{ // Set up callback server let cleanupTimeout: NodeJS.Timeout; let callbackHandled = false; - const { server } = await createAuthServer(8081, async (_code, _state) => { + const { server } = await createAuthServer(8081, async () => { // Guard against duplicate callbacks (browser may send multiple requests) if (callbackHandled) return; callbackHandled = true; diff --git a/apps/x/apps/main/src/oauth-handler.ts b/apps/x/apps/main/src/oauth-handler.ts index 99865d8e..dde2246d 100644 --- a/apps/x/apps/main/src/oauth-handler.ts +++ b/apps/x/apps/main/src/oauth-handler.ts @@ -187,12 +187,12 @@ export async function connectProvider(provider: string, clientId?: string): Prom // Create callback server let callbackHandled = false; - const { server } = await createAuthServer(8080, async (code, receivedState) => { + const { server } = await createAuthServer(8080, async (params: Record) => { // Guard against duplicate callbacks (browser may send multiple requests) if (callbackHandled) return; callbackHandled = true; // Validate state - if (receivedState !== state) { + if (params.state !== state) { throw new Error('Invalid state parameter - possible CSRF attack'); } @@ -203,7 +203,7 @@ export async function connectProvider(provider: string, clientId?: string): Prom try { // Build callback URL for token exchange - const callbackUrl = new URL(`${REDIRECT_URI}?code=${code}&state=${receivedState}`); + const callbackUrl = new URL(`${REDIRECT_URI}?${new URLSearchParams(params).toString()}`); // Exchange code for tokens console.log(`[OAuth] Exchanging authorization code for tokens (${provider})...`);