From 358434fb740eb3f78b2f22eb14c11cf3e74dd6a0 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 7 Apr 2025 21:09:16 -0700 Subject: [PATCH] fix(oauth): added extra logging to token refresh and added client_id in token refresh for airtable --- sim/app/api/auth/oauth/utils.ts | 34 ++++++++++++++++---- sim/app/api/webhooks/trigger/[path]/route.ts | 8 ++++- sim/lib/oauth.ts | 7 ++-- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/sim/app/api/auth/oauth/utils.ts b/sim/app/api/auth/oauth/utils.ts index 1315ef61d6..73086cfd2f 100644 --- a/sim/app/api/auth/oauth/utils.ts +++ b/sim/app/api/auth/oauth/utils.ts @@ -47,7 +47,11 @@ export async function getOAuthToken(userId: string, providerId: string): Promise const refreshResult = await refreshOAuthToken(providerId, credential.refreshToken!) if (!refreshResult) { - logger.error(`Failed to refresh token for user ${userId}, provider ${providerId}`) + logger.error(`Failed to refresh token for user ${userId}, provider ${providerId}`, { + providerId, + userId, + hasRefreshToken: !!credential.refreshToken, + }) return null } @@ -66,7 +70,12 @@ export async function getOAuthToken(userId: string, providerId: string): Promise logger.info(`Successfully refreshed token for user ${userId}, provider ${providerId}`) return accessToken } catch (error) { - logger.error(`Error refreshing token for user ${userId}, provider ${providerId}`, error) + logger.error(`Error refreshing token for user ${userId}, provider ${providerId}`, { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + providerId, + userId, + }) return null } } @@ -116,7 +125,15 @@ export async function refreshAccessTokenIfNeeded( const refreshedToken = await refreshOAuthToken(credential.providerId, credential.refreshToken) if (!refreshedToken) { - logger.error(`[${requestId || ''}] Failed to refresh token for credential: ${credentialId}`) + logger.error( + `[${requestId || ''}] Failed to refresh token for credential: ${credentialId}`, + { + credentialId, + providerId: credential.providerId, + userId: credential.userId, + hasRefreshToken: !!credential.refreshToken, + } + ) return null } @@ -135,10 +152,13 @@ export async function refreshAccessTokenIfNeeded( ) return refreshedToken.accessToken } catch (error) { - logger.error( - `[${requestId || ''}] Error refreshing token for credential: ${credentialId}`, - error - ) + logger.error(`[${requestId || ''}] Error refreshing token for credential: ${credentialId}`, { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + providerId: credential.providerId, + credentialId, + userId: credential.userId, + }) return null } } else if (!accessToken) { diff --git a/sim/app/api/webhooks/trigger/[path]/route.ts b/sim/app/api/webhooks/trigger/[path]/route.ts index 0b05fc015a..2feb1c1086 100644 --- a/sim/app/api/webhooks/trigger/[path]/route.ts +++ b/sim/app/api/webhooks/trigger/[path]/route.ts @@ -469,10 +469,16 @@ async function fetchAndProcessAirtablePayloads( ) throw new Error('Airtable access token not found.') } + + logger.info(`[${requestId}] Successfully obtained Airtable access token`) } catch (tokenError: any) { logger.error( `[${requestId}] Failed to get Airtable OAuth token for user ${workflowData.userId}`, - tokenError + { + error: tokenError.message, + stack: tokenError.stack, + userId: workflowData.userId, + } ) await persistExecutionError( workflowData.id, diff --git a/sim/lib/oauth.ts b/sim/lib/oauth.ts index 8619a7ee39..79179c5802 100644 --- a/sim/lib/oauth.ts +++ b/sim/lib/oauth.ts @@ -409,8 +409,11 @@ export async function refreshOAuthToken( refresh_token: refreshToken, } - // Only add client_id and client_secret to body for non-Basic auth providers - if (!useBasicAuth) { + // For Airtable specifically, include client_id in body even with Basic auth + if (provider === 'airtable') { + bodyParams.client_id = clientId + } else if (!useBasicAuth) { + // For other non-Basic auth providers, include both credentials bodyParams.client_id = clientId bodyParams.client_secret = clientSecret }