Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion copilot/copilot.appName.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -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=

Expand Down
10 changes: 9 additions & 1 deletion packages/components/nodes/documentloaders/Gmail/Gmail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,18 @@ 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,
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
Expand Down
54 changes: 47 additions & 7 deletions packages/docs/docs/developers/authorization/google-oauth.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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**
Expand All @@ -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
Expand Down Expand Up @@ -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"**

Expand Down
13 changes: 12 additions & 1 deletion packages/server/src/config/passport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,24 @@ 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.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)'
)
}

passport.use(
`google`,
new GoogleStrategy(
{
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) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
9 changes: 8 additions & 1 deletion packages/server/src/utils/refreshGoogleAccessToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@ 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,
process.env.GOOGLE_CALLBACK_URL
`${process.env.API_HOST}/api/v1/google-auth/callback`
)

this.oauth2Client.setCredentials({
Expand Down
Loading