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 e5b25d1a..452a76e3 100644 --- a/apps/x/apps/main/src/composio-handler.ts +++ b/apps/x/apps/main/src/composio-handler.ts @@ -143,7 +143,7 @@ export async function initiateConnection(toolkitSlug: string): Promise<{ // Set up callback server let cleanupTimeout: NodeJS.Timeout; - const { server } = await createAuthServer(8081, async (_code, _state) => { + const { server } = await createAuthServer(8081, async () => { // OAuth callback received - sync the account status try { const accountStatus = await composioClient.getConnectedAccount(connectedAccountId); diff --git a/apps/x/apps/main/src/oauth-handler.ts b/apps/x/apps/main/src/oauth-handler.ts index 2efc77c2..bf9c77ff 100644 --- a/apps/x/apps/main/src/oauth-handler.ts +++ b/apps/x/apps/main/src/oauth-handler.ts @@ -186,9 +186,9 @@ export async function connectProvider(provider: string, clientId?: string): Prom }); // Create callback server - const { server } = await createAuthServer(8080, async (code, receivedState) => { + const { server } = await createAuthServer(8080, async (params: Record) => { // Validate state - if (receivedState !== state) { + if (params.state !== state) { throw new Error('Invalid state parameter - possible CSRF attack'); } @@ -199,7 +199,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})...`);