From 6e2bcff8e44892b495cab35befe60b942f44167e Mon Sep 17 00:00:00 2001 From: Diego Costa Date: Thu, 22 Jan 2026 13:09:24 -0300 Subject: [PATCH 1/3] fix(AGENT-559): use API_HOST for Google OAuth callback URL - Update passport.ts to construct callback URL from API_HOST like Salesforce/Atlassian - Update Gmail.ts and refreshGoogleAccessToken.ts to use API_HOST pattern - Remove GOOGLE_CALLBACK_URL from .env.template and copilot template - Fix documentation to show correct callback paths - Add documentation section explaining both OAuth callback URLs: - /api/v1/google-auth/callback (user auth, port 3000) - /api/v1/oauth2-credential/callback (Flowise credentials, port 4000) - Add troubleshooting section for redirect_uri_mismatch error Co-Authored-By: Claude Opus 4.5 --- .env.template | 3 +- copilot/copilot.appName.env.template | 3 +- .../nodes/documentloaders/Gmail/Gmail.ts | 2 +- .../developers/authorization/google-oauth.md | 54 ++++++++++++++++--- packages/server/src/config/passport.ts | 2 +- packages/server/src/utils/constants.ts | 2 +- .../src/utils/refreshGoogleAccessToken.ts | 2 +- 7 files changed, 55 insertions(+), 13 deletions(-) diff --git a/.env.template b/.env.template index 61b6ed847b6..bf5e8c51ac9 100644 --- a/.env.template +++ b/.env.template @@ -125,7 +125,8 @@ LANGCHAIN_HANDLER=langchain # Main Google Client ID GOOGLE_CLIENT_ID=your_google_client_id GOOGLE_CLIENT_SECRET=your_google_client_secret -GOOGLE_CALLBACK_URL=/api/v1/google-auth/callback +# Note: Google OAuth callback URL is automatically derived from API_HOST +# Callback URL: ${API_HOST}/api/v1/google-auth/callback # Public Google Configuration (for client-side) NEXT_PUBLIC_GOOGLE_DEVELOPER_KEY=your_google_developer_key diff --git a/copilot/copilot.appName.env.template b/copilot/copilot.appName.env.template index 0dbb3ebff6e..2181e025003 100644 --- a/copilot/copilot.appName.env.template +++ b/copilot/copilot.appName.env.template @@ -187,7 +187,8 @@ AAI_DEFAULT_OPENAI_API_KEY= # # ================================================== # # GOOGLE OAUTH & API CONFIGURATION # # ================================================== -# GOOGLE_CALLBACK_URL=/api/v1/google-auth/callback +# # Note: Google OAuth callback URL is automatically derived from API_HOST +# # Callback URL: ${API_HOST}/api/v1/google-auth/callback # GOOGLE_CLIENT_ID= # GOOGLE_CLIENT_SECRET= diff --git a/packages/components/nodes/documentloaders/Gmail/Gmail.ts b/packages/components/nodes/documentloaders/Gmail/Gmail.ts index 4a4286372c8..69d2e1c9151 100644 --- a/packages/components/nodes/documentloaders/Gmail/Gmail.ts +++ b/packages/components/nodes/documentloaders/Gmail/Gmail.ts @@ -123,7 +123,7 @@ class Gmail implements INode { const credentials = { clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, - redirectUrl: process.env.GOOGLE_CALLBACK_URL, + redirectUrl: `${process.env.API_HOST}/api/v1/google-auth/callback`, accessToken: credentialData.googleAccessToken, refreshToken: credentialData.googleRefreshToken, expiresAt: credentialData.expiresAt diff --git a/packages/docs/docs/developers/authorization/google-oauth.md b/packages/docs/docs/developers/authorization/google-oauth.md index 5728b9a53b5..f0570e0d018 100644 --- a/packages/docs/docs/developers/authorization/google-oauth.md +++ b/packages/docs/docs/developers/authorization/google-oauth.md @@ -8,6 +8,38 @@ description: Complete guide to setting up Google OAuth for AnswerAgentAI integra Google OAuth 2.0 is required for integrating Google services with AnswerAgentAI, including Gmail, Google Drive, and Google Calendar. This guide covers the complete setup process from creating a Google Cloud Console project to configuring OAuth in your AnswerAgentAI instance. +## Two Types of OAuth Callbacks + +AnswerAgentAI uses two different OAuth callback URLs depending on the use case. **You need to add BOTH to your Google Cloud Console if using both features.** + +### 1. User Authentication Callback + +**URL Pattern:** `${API_HOST}/api/v1/google-auth/callback` + +Used for TheAnswer user authentication via Google. This is automatically derived from your `API_HOST` environment variable. + +| Environment | Callback URL | +|-------------|--------------| +| Local | `http://localhost:3000/api/v1/google-auth/callback` | +| Staging | `https://staging.theanswer.ai/api/v1/google-auth/callback` | +| Production | `https://app.theanswer.ai/api/v1/google-auth/callback` | + +### 2. Flowise Credential Callback + +**URL Pattern:** `${FLOWISE_HOST}/api/v1/oauth2-credential/callback` + +Used for Google Drive, Gmail, and Calendar document loaders/tools within Flowise chatflows. The exact URL is displayed in the credential configuration dialog. + +| Environment | Callback URL | +|-------------|--------------| +| Local | `http://localhost:4000/api/v1/oauth2-credential/callback` | +| Staging | `https://staging.theanswer.ai/api/v1/oauth2-credential/callback` | +| Production | `https://app.theanswer.ai/api/v1/oauth2-credential/callback` | + +:::tip +When configuring Google Cloud Console, add all the callback URLs for the environments you'll be using. Check the "OAUTH REDIRECT URL" field in the Flowise credential dialog to see the exact URL to use. +::: + ## Prerequisites - A Google account @@ -132,13 +164,13 @@ For each API: **For Local Development:** ``` - http://localhost:3000/api/v1/callback/googleoauth + http://localhost:3000/api/v1/google-auth/callback ``` **For Production:** ``` - https://yourdomain.com/api/v1/callback/googleoauth + https://yourdomain.com/api/v1/google-auth/callback ``` 5. **Create and Download** @@ -154,10 +186,12 @@ Add the following environment variables to your AnswerAgentAI instance: # Google OAuth Configuration GOOGLE_CLIENT_ID=your_client_id_here GOOGLE_CLIENT_SECRET=your_client_secret_here -GOOGLE_CALLBACK_URL=http://localhost:3000/api/v1/callback/googleoauth -# For production, use your domain: -# GOOGLE_CALLBACK_URL=https://yourdomain.com/api/v1/callback/googleoauth +# Note: The callback URL is automatically derived from API_HOST +# Make sure API_HOST is set correctly in your environment: +# - Local: API_HOST=http://localhost:3000 +# - Production: API_HOST=https://yourdomain.com +# The callback URL will be: ${API_HOST}/api/v1/google-auth/callback ``` ## Step 7: Credential Configuration in AnswerAgentAI @@ -227,8 +261,14 @@ Once developers have set up the Google OAuth application, end users can connect 1. **"Error 400: redirect_uri_mismatch"** - - Ensure the redirect URI in Google Console matches your AnswerAgentAI instance URL - - Check that GOOGLE_CALLBACK_URL environment variable is correct + - The callback URL is automatically derived from `API_HOST`: + - If `API_HOST=http://localhost:3000`, callback is `http://localhost:3000/api/v1/google-auth/callback` + - If `API_HOST=https://app.example.com`, callback is `https://app.example.com/api/v1/google-auth/callback` + - Add the exact callback URL to Google Cloud Console: + - Go to APIs & Services → Credentials + - Edit your OAuth 2.0 Client ID + - Under "Authorized redirect URIs", add your callback URL + - Ensure the URL matches **exactly** (including http vs https, no trailing slashes) 2. **"Access Blocked: This app's request is invalid"** diff --git a/packages/server/src/config/passport.ts b/packages/server/src/config/passport.ts index 66d60ea9fc9..681c5a0d321 100644 --- a/packages/server/src/config/passport.ts +++ b/packages/server/src/config/passport.ts @@ -14,7 +14,7 @@ export default function (passport: any) { { clientID: process.env.GOOGLE_CLIENT_ID ?? '', clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? '', - callbackURL: process.env.GOOGLE_CALLBACK_URL ?? '', + callbackURL: `${process.env.API_HOST}/api/v1/google-auth/callback`, proxy: true }, async (accessToken, refreshToken, profile, done) => { diff --git a/packages/server/src/utils/constants.ts b/packages/server/src/utils/constants.ts index f2950f0d7b4..5ac9b25377f 100644 --- a/packages/server/src/utils/constants.ts +++ b/packages/server/src/utils/constants.ts @@ -59,7 +59,7 @@ export const WHITELIST_URLS = [ // AAI '/api/v1/google-auth', - process.env.GOOGLE_CALLBACK_URL ?? '/api/v1/google-auth/callback', + '/api/v1/google-auth/callback', '/api/v1/salesforce-auth', '/api/v1/salesforce-auth/callback', '/api/v1/atlassian-auth', diff --git a/packages/server/src/utils/refreshGoogleAccessToken.ts b/packages/server/src/utils/refreshGoogleAccessToken.ts index 96f59987294..c734bbd9695 100644 --- a/packages/server/src/utils/refreshGoogleAccessToken.ts +++ b/packages/server/src/utils/refreshGoogleAccessToken.ts @@ -15,7 +15,7 @@ export class GoogleOauth2Client { this.oauth2Client = new google.auth.OAuth2( process.env.GOOGLE_CLIENT_ID, process.env.GOOGLE_CLIENT_SECRET, - process.env.GOOGLE_CALLBACK_URL + `${process.env.API_HOST}/api/v1/google-auth/callback` ) this.oauth2Client.setCredentials({ From 66addc953b3fb55d967aa837d898be41a8fa71d8 Mon Sep 17 00:00:00 2001 From: Diego Costa Date: Thu, 22 Jan 2026 13:17:06 -0300 Subject: [PATCH 2/3] fix(AGENT-559): add API_HOST validation for Google OAuth Add runtime validation to warn when API_HOST is missing, preventing silent failures where callback URL becomes undefined/api/v1/... Co-Authored-By: Claude Opus 4.5 --- packages/server/src/config/passport.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/server/src/config/passport.ts b/packages/server/src/config/passport.ts index 681c5a0d321..fc6a8b6f42b 100644 --- a/packages/server/src/config/passport.ts +++ b/packages/server/src/config/passport.ts @@ -8,6 +8,15 @@ export default function (passport: any) { // Configure Auth0 SSO strategy for browser login flow configureAuth0Strategy() if (process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET) { + // Validate API_HOST is set for Google OAuth callback + if (!process.env.API_HOST) { + console.warn( + '⚠️ WARNING: API_HOST environment variable is not set.\n' + + ' Google OAuth callback URL will be invalid.\n' + + ' Please set API_HOST in your .env file (e.g., http://localhost:3000)' + ) + } + passport.use( `google`, new GoogleStrategy( From 91f96f5d7c63c8a99d91c8d795a06e9a8b42bb13 Mon Sep 17 00:00:00 2001 From: Diego Costa Date: Thu, 22 Jan 2026 13:24:22 -0300 Subject: [PATCH 3/3] fix(AGENT-559): add API_HOST validation across all Google OAuth files Address review feedback: - Add API_HOST validation to Gmail.ts (throws error if missing) - Improve passport.ts message: use console.error with actionable fix instructions - Add API_HOST validation to refreshGoogleAccessToken.ts This ensures early failure with clear error messages when API_HOST is not configured, preventing silent failures with invalid callback URLs. Co-Authored-By: Claude Opus 4.5 --- .../components/nodes/documentloaders/Gmail/Gmail.ts | 8 ++++++++ packages/server/src/config/passport.ts | 10 ++++++---- packages/server/src/utils/refreshGoogleAccessToken.ts | 7 +++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/components/nodes/documentloaders/Gmail/Gmail.ts b/packages/components/nodes/documentloaders/Gmail/Gmail.ts index 69d2e1c9151..a656f68c4e1 100644 --- a/packages/components/nodes/documentloaders/Gmail/Gmail.ts +++ b/packages/components/nodes/documentloaders/Gmail/Gmail.ts @@ -120,6 +120,14 @@ class Gmail implements INode { throw new Error('Credentials not found') } + // Validate API_HOST is set for OAuth redirect + if (!process.env.API_HOST) { + throw new Error( + 'API_HOST environment variable is not set. ' + + 'Please set API_HOST in your .env file (e.g., http://localhost:3000)' + ) + } + const credentials = { clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, diff --git a/packages/server/src/config/passport.ts b/packages/server/src/config/passport.ts index fc6a8b6f42b..8fb0a998ee7 100644 --- a/packages/server/src/config/passport.ts +++ b/packages/server/src/config/passport.ts @@ -10,10 +10,12 @@ export default function (passport: any) { if (process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET) { // Validate API_HOST is set for Google OAuth callback if (!process.env.API_HOST) { - console.warn( - '⚠️ WARNING: API_HOST environment variable is not set.\n' + - ' Google OAuth callback URL will be invalid.\n' + - ' Please set API_HOST in your .env file (e.g., http://localhost:3000)' + console.error( + '❌ ERROR: API_HOST environment variable is not set.\n' + + ' Google OAuth will fail with redirect_uri_mismatch error.\n' + + ' Fix: Add API_HOST to your .env file:\n' + + ' API_HOST=http://localhost:3000 (for local development)\n' + + ' API_HOST=https://yourdomain.com (for production)' ) } diff --git a/packages/server/src/utils/refreshGoogleAccessToken.ts b/packages/server/src/utils/refreshGoogleAccessToken.ts index c734bbd9695..1d971f1aab4 100644 --- a/packages/server/src/utils/refreshGoogleAccessToken.ts +++ b/packages/server/src/utils/refreshGoogleAccessToken.ts @@ -12,6 +12,13 @@ export class GoogleOauth2Client { throw new Error('Refresh token is required') } + if (!process.env.API_HOST) { + throw new Error( + 'API_HOST environment variable is not set. ' + + 'Please set API_HOST in your .env file (e.g., http://localhost:3000)' + ) + } + this.oauth2Client = new google.auth.OAuth2( process.env.GOOGLE_CLIENT_ID, process.env.GOOGLE_CLIENT_SECRET,