Skip to content

Commit 7662b9d

Browse files
fixed google OAuth issues in Tauri wrapper, updated docs with google OAuth config info
1 parent 267ffca commit 7662b9d

File tree

18 files changed

+672
-25
lines changed

18 files changed

+672
-25
lines changed

client/bun.lock

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"@google-cloud/local-auth": "^3.0.1",
1010
"@mui/lab": "^7.0.0-beta.13",
1111
"@mui/material": "^7.1.0",
12+
"@tauri-apps/api": "^2.9.0",
1213
"@xyflow/react": "^12.6.4",
1314
"ace-builds": "^1.42.0",
1415
"ajv": "^8.17.1",
@@ -338,6 +339,8 @@
338339

339340
"@svgr/plugin-jsx": ["@svgr/[email protected]", "", { "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", "@svgr/hast-util-to-babel-ast": "8.0.0", "svg-parser": "^2.0.4" }, "peerDependencies": { "@svgr/core": "*" } }, "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA=="],
340341

342+
"@tauri-apps/api": ["@tauri-apps/[email protected]", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="],
343+
341344
"@types/babel__core": ["@types/[email protected]", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
342345

343346
"@types/babel__generator": ["@types/[email protected]", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="],

client/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"@google-cloud/local-auth": "^3.0.1",
1616
"@mui/lab": "^7.0.0-beta.13",
1717
"@mui/material": "^7.1.0",
18+
"@tauri-apps/api": "^2.9.0",
1819
"@xyflow/react": "^12.6.4",
1920
"ace-builds": "^1.42.0",
2021
"ajv": "^8.17.1",

client/src/components/nodes/ToolNode/UserConfigFields.tsx

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@ import {Box, Typography, Button, Chip} from "@mui/material";
88
import {PROVIDER_SCOPES, PROVIDERS} from "../../../constants";
99
import {FieldsetGroup} from "../../FieldsetGroup";
1010
import {DebouncedTextField} from "../../DebouncedTextField";
11+
import {isTauri} from "../../../utils";
1112

12-
declare global {
13-
interface Window {
14-
google?: any;
13+
14+
const AUTHENTICATION_CANCELED = 'Authentication cancelled';
15+
16+
const showTauriError = (error: unknown) => {
17+
const errorMessage = error instanceof Error ? error.message : String(error);
18+
19+
if (!errorMessage.includes(AUTHENTICATION_CANCELED)) {
20+
alert(`OAuth failed: ${errorMessage}`);
1521
}
16-
}
22+
};
1723

1824
type UserConfigSchema = {
1925
[key: string]: {
@@ -49,25 +55,47 @@ export function UserConfigFields ({userConfigSchema, userConfig, onConfigChange}
4955
return;
5056
}
5157

52-
if (!window.google) {
53-
alert('Google Identity Services not loaded. Please refresh the page.');
58+
const isTauriEnv = isTauri();
5459

55-
return;
56-
}
60+
if (isTauriEnv) {
61+
try {
62+
const scope = PROVIDER_SCOPES[provider];
63+
const {invoke} = await import('@tauri-apps/api/core');
64+
const result = await invoke<{accessToken: string}>('start_oauth_flow', {
65+
clientId: googleClientId,
66+
scope: scope
67+
});
5768

58-
const tokenClient = window.google.accounts.oauth2.initTokenClient({
59-
client_id: googleClientId,
60-
scope: PROVIDER_SCOPES[provider],
61-
callback: (response: { access_token: string; }) => {
62-
if (response.access_token) {
63-
onConfigChange('accessToken', response.access_token);
69+
if (result && result.accessToken) {
70+
onConfigChange('accessToken', result.accessToken);
6471
} else {
65-
alert('OAuth authentication failed');
72+
alert('OAuth failed: No access token received');
6673
}
74+
} catch (error) {
75+
showTauriError(error);
6776
}
68-
});
77+
} else {
78+
// Web environment - use Google's popup
79+
if (!window.google) {
80+
alert('Google Identity Services not loaded. Please refresh the page.');
6981

70-
tokenClient.requestAccessToken();
82+
return;
83+
}
84+
85+
const tokenClient = window.google.accounts.oauth2.initTokenClient({
86+
client_id: googleClientId,
87+
scope: PROVIDER_SCOPES[provider],
88+
callback: (response: { access_token: string; error?: string }) => {
89+
if (response.access_token) {
90+
onConfigChange('accessToken', response.access_token);
91+
} else {
92+
alert(`OAuth authentication failed: ${response.error || 'Unknown error'}`);
93+
}
94+
}
95+
});
96+
97+
tokenClient.requestAccessToken();
98+
}
7199
}
72100
} catch (error) {
73101
alert(`OAuth failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
@@ -97,7 +125,9 @@ export function UserConfigFields ({userConfigSchema, userConfig, onConfigChange}
97125
<Button
98126
variant={isConnected ? "outlined" : "contained"}
99127
color={isConnected ? "success" : "primary"}
100-
onClick={() => handleOAuthLogin(schema.provider || 'gmail')}
128+
onClick={() => {
129+
handleOAuthLogin(schema.provider || 'gmail');
130+
}}
101131
size="small"
102132
>
103133
{isConnected ? 'Reconnect' : 'Connect'} {schema.provider || 'Account'}

client/src/types/custom.d.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,13 @@ declare module "*.svg" {
33
import React from "react";
44
const content: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
55
export default content;
6-
}
6+
}
7+
8+
declare global {
9+
interface Window {
10+
google?: any;
11+
__TAURI_INTERNALS__?: any;
12+
}
13+
}
14+
15+
export {};

client/src/utils/utils.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,12 @@ export const parseUrl = (initialUrl: string): string => {
8484
}
8585

8686
return url;
87-
}
87+
}
88+
89+
export const isTauri = (): boolean => {
90+
return typeof window !== 'undefined' && (
91+
window.__TAURI_INTERNALS__ !== undefined ||
92+
window.location.protocol === 'tauri:' ||
93+
window.location.hostname === 'tauri.localhost'
94+
);
95+
};
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Google OAuth2 Client Setup
2+
3+
To use Google services (Gmail, Drive, Calendar) in Agentic Signal, you need to create an OAuth2 client in Google Cloud Console.
4+
5+
## Step-by-Step Guide
6+
7+
1. **Go to [Google Cloud Console](https://console.cloud.google.com/apis/credentials).**
8+
2. **Create a new project** (or select an existing one).
9+
3. **Enable APIs** for your project:
10+
- Gmail API
11+
- Google Drive API
12+
- Google Calendar API
13+
4. **Configure the OAuth consent screen**:
14+
- Go to [OAuth consent screen setup](https://console.cloud.google.com/auth/overview/create).
15+
- Fill in required fields (app name, support email, etc.).
16+
- Add scopes for the APIs you want to use.
17+
5. **Create OAuth2 Client ID**:
18+
- Go to [OAuth2 Client ID creation](https://console.cloud.google.com/auth/clients/create).
19+
- Choose **Web application** as the application type.
20+
- **Authorized JavaScript origins:**
21+
- `http://localhost:3000`
22+
- `http://localhost:5173`
23+
- **Authorized redirect URIs:**
24+
- `http://localhost:3000`
25+
- `http://localhost:5173`
26+
- `http://localhost:8080`
27+
- `http://localhost:8080/callback`
28+
- Click **Save** to create the client.
29+
6. **Copy your Client ID** and use it in Agentic Signal’s configuration (`Google OAuth2 Client ID (from Google Cloud Console)` field).
30+
31+
32+
> For more details, see [Google's official documentation](https://developers.google.com/identity/protocols/oauth2).
33+
34+
---
35+
36+
## Troubleshooting
37+
38+
- Make sure the APIs are enabled for your project.
39+
- The OAuth consent screen must be published (for external users).
40+
- Redirect URIs must match exactly.

docs/docs/getting-started/windows-app/quick-start.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ If you **do not want to develop or build from source**, you can simply:
1717
See [Ollama and App Configuration](../configuration) for instructions on:
1818
- Setting up Ollama CORS for the Windows app
1919
- Configuring the Ollama Host and Chrome Executable Path in the app settings
20+
5. *(Optional)* **Set up Google OAuth2 Client for Google integrations:**
21+
If you want to use Gmail, Google Drive, or Google Calendar nodes, follow the [Google OAuth2 Client Setup](../google-oauth-client) guide to create your credentials in Google Cloud Console.
2022

2123
You are now ready to use `Agentic Signal` with local AI and browser automation!
2224

docs/docs/nodes/ai/tools/gcalendar-fetch-events.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import TabItem from '@theme/TabItem';
1717
- `timeMin` ¹ (string, optional): Lower bound (inclusive) for event start time (RFC3339 timestamp).
1818
- `timeMax` ¹ (string, optional): Upper bound (exclusive) for event end time (RFC3339 timestamp).
1919
- `googleClientId` (string, user config): Google OAuth2 Client ID.
20-
You must [create an OAuth2 client in Google Cloud Console](https://console.cloud.google.com/auth/clients) before using this tool.
20+
You must [create an OAuth2 client in Google Cloud Console](../../../getting-started/google-oauth-client) before using this tool.
2121
- `accessToken` (OAuth, user config): Google Calendar Authentication.
2222
This field will be auto-filled if you use the **CONNECT CALENDAR** button.
2323
- `maxResults` (integer, user config): Maximum number of events to fetch (default: 10, min: 1, max: 100)

docs/docs/nodes/ai/tools/gdrive-fetch-files.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import TabItem from '@theme/TabItem';
1515
<TabItem value="inputs" label="Inputs" default>
1616
- `query` ¹ (string): Google Drive search query using Google Drive search operators (e.g., `"name contains \"report\""`).
1717
- `googleClientId` (string, user config): Google OAuth2 Client ID.
18-
You must [create an OAuth2 client in Google Cloud Console](https://console.cloud.google.com/auth/clients) before using this tool.
18+
You must [create an OAuth2 client in Google Cloud Console](../../../getting-started/google-oauth-client) before using this tool.
1919
- `accessToken` (OAuth, user config): Google Drive Authentication.
2020
This field will be auto-filled if you use the **CONNECT DRIVE** button.
2121
- `maxResults` (integer, user config): Maximum number of files to fetch (default: 5, min: 1, max: 50)

docs/docs/nodes/ai/tools/gmail-fetch-emails.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import TabItem from '@theme/TabItem';
1515
<TabItem value="inputs" label="Inputs" default>
1616
- `query` ¹ (string): Gmail search query using Gmail search operators (e.g., `"in:inbox newer_than:7d"`).
1717
- `googleClientId` (string, user config): Google OAuth2 Client ID.
18-
You must [create an OAuth2 client in Google Cloud Console](https://console.cloud.google.com/auth/clients) before using this tool.
18+
You must [create an OAuth2 client in Google Cloud Console](../../../getting-started/google-oauth-client) before using this tool.
1919
- `accessToken` (OAuth, user config): Gmail Authentication.
2020
This field will be auto-filled if you use the **CONNECT GMAIL** button.
2121
- `maxResults` (integer, user config): Maximum number of emails to fetch (default: 5, min: 1, max: 50)

0 commit comments

Comments
 (0)