@firela/billclaw-openclaw 0.1.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/oauth/gmail.d.ts +21 -9
- package/dist/oauth/gmail.d.ts.map +1 -1
- package/dist/oauth/gmail.js +88 -145
- package/dist/oauth/gmail.js.map +1 -1
- package/dist/oauth/plaid.d.ts +10 -8
- package/dist/oauth/plaid.d.ts.map +1 -1
- package/dist/oauth/plaid.js +55 -60
- package/dist/oauth/plaid.js.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +3 -0
- package/dist/plugin.js.map +1 -1
- package/dist/services/webhook-handler.d.ts +15 -8
- package/dist/services/webhook-handler.d.ts.map +1 -1
- package/dist/services/webhook-handler.js +255 -75
- package/dist/services/webhook-handler.js.map +1 -1
- package/dist/tools/index.d.ts +3 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +110 -20
- package/dist/tools/index.js.map +1 -1
- package/package.json +14 -14
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 fire-la
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/oauth/gmail.d.ts
CHANGED
|
@@ -1,31 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Gmail OAuth handler -
|
|
2
|
+
* Gmail OAuth handler - OpenClaw adapter
|
|
3
3
|
*
|
|
4
|
-
* This
|
|
4
|
+
* This is an adapter layer that calls the framework-agnostic OAuth implementation
|
|
5
|
+
* from @firela/billclaw-core and adds OpenClaw-specific functionality (config management).
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
-
* 1. Generate authorization URL (with PKCE) - Returns { url, state }
|
|
8
|
-
* 2. Handle callback - Receives authorization code
|
|
9
|
-
* 3. Exchange code for access token - Returns { accessToken, refreshToken }
|
|
7
|
+
* @packageDocumentation
|
|
10
8
|
*/
|
|
11
9
|
import type { OpenClawPluginApi } from "../types/openclaw-plugin.js";
|
|
12
10
|
/**
|
|
13
11
|
* Handle Gmail OAuth flow
|
|
14
12
|
*
|
|
15
|
-
* This
|
|
13
|
+
* This is an OpenClaw adapter that calls the framework-agnostic OAuth handler
|
|
14
|
+
* from @firela/billclaw-core and adds OpenClaw-specific functionality.
|
|
16
15
|
*
|
|
17
16
|
* Flow:
|
|
18
17
|
* 1. Initialize OAuth (no params) - Returns { url, state }
|
|
19
|
-
* 2. Handle callback (code + state) - Returns { accessToken, refreshToken }
|
|
18
|
+
* 2. Handle callback (code + state + accountId) - Returns { accessToken, refreshToken }
|
|
19
|
+
* - Tokens are automatically saved to account config if accountId is provided
|
|
20
20
|
*
|
|
21
21
|
* @param api - OpenClaw plugin API
|
|
22
|
-
* @param context - OAuth context with optional code
|
|
22
|
+
* @param context - OAuth context with optional code, state, redirectUri, and accountId
|
|
23
23
|
* @returns OAuthResult with URL and/or token
|
|
24
24
|
*/
|
|
25
25
|
export declare function gmailOAuthHandler(api: OpenClawPluginApi, context?: {
|
|
26
26
|
code?: string;
|
|
27
27
|
state?: string;
|
|
28
28
|
redirectUri?: string;
|
|
29
|
+
accountId?: string;
|
|
29
30
|
}): Promise<{
|
|
30
31
|
url: string;
|
|
31
32
|
state?: string;
|
|
@@ -33,4 +34,15 @@ export declare function gmailOAuthHandler(api: OpenClawPluginApi, context?: {
|
|
|
33
34
|
refreshToken?: string;
|
|
34
35
|
expiresIn?: number;
|
|
35
36
|
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Refresh Gmail access token using refresh token
|
|
39
|
+
*
|
|
40
|
+
* @param api - OpenClaw plugin API
|
|
41
|
+
* @param accountId - Account ID to refresh token for
|
|
42
|
+
* @returns New access token and expiry info, or null if refresh failed
|
|
43
|
+
*/
|
|
44
|
+
export declare function refreshGmailToken(api: OpenClawPluginApi, accountId: string): Promise<{
|
|
45
|
+
accessToken: string;
|
|
46
|
+
expiresIn: number;
|
|
47
|
+
} | null>;
|
|
36
48
|
//# sourceMappingURL=gmail.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gmail.d.ts","sourceRoot":"","sources":["../../src/oauth/gmail.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"gmail.d.ts","sourceRoot":"","sources":["../../src/oauth/gmail.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AA8FpE;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,iBAAiB,EACtB,OAAO,CAAC,EAAE;IACR,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GACA,OAAO,CAAC;IACT,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAC,CA4BD;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,iBAAiB,EACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA4C5D"}
|
package/dist/oauth/gmail.js
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Gmail OAuth handler -
|
|
2
|
+
* Gmail OAuth handler - OpenClaw adapter
|
|
3
3
|
*
|
|
4
|
-
* This
|
|
4
|
+
* This is an adapter layer that calls the framework-agnostic OAuth implementation
|
|
5
|
+
* from @firela/billclaw-core and adds OpenClaw-specific functionality (config management).
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
import { gmailOAuthHandler as coreGmailOAuthHandler, refreshGmailToken as coreRefreshGmailToken, } from "@firela/billclaw-core";
|
|
10
|
+
/**
|
|
11
|
+
* Get a logger from OpenClaw API, or provide a no-op logger
|
|
10
12
|
*/
|
|
13
|
+
function getLogger(api) {
|
|
14
|
+
return {
|
|
15
|
+
info: api.logger?.info || (() => { }),
|
|
16
|
+
error: api.logger?.error || (() => { }),
|
|
17
|
+
warn: api.logger?.warn || (() => { }),
|
|
18
|
+
debug: api.logger?.debug || (() => { }),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
11
21
|
/**
|
|
12
22
|
* Get Gmail configuration from OpenClaw config
|
|
13
23
|
*/
|
|
@@ -25,166 +35,99 @@ function getGmailConfig(api) {
|
|
|
25
35
|
};
|
|
26
36
|
}
|
|
27
37
|
/**
|
|
28
|
-
*
|
|
29
|
-
*/
|
|
30
|
-
function generateCodeVerifier() {
|
|
31
|
-
const array = new Uint8Array(32);
|
|
32
|
-
crypto.getRandomValues(array);
|
|
33
|
-
return base64UrlEncode(array);
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Generate code challenge from verifier for PKCE
|
|
37
|
-
*/
|
|
38
|
-
async function generateCodeChallenge(verifier) {
|
|
39
|
-
const encoder = new TextEncoder();
|
|
40
|
-
const data = encoder.encode(verifier);
|
|
41
|
-
const hash = await crypto.subtle.digest("SHA-256", data);
|
|
42
|
-
return base64UrlEncode(new Uint8Array(hash));
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Base64URL encode a byte array
|
|
46
|
-
*/
|
|
47
|
-
function base64UrlEncode(bytes) {
|
|
48
|
-
const binString = Array.from(bytes, (byte) => String.fromCharCode(byte));
|
|
49
|
-
const base64 = btoa(binString.join(""));
|
|
50
|
-
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* State parameter storage (in-memory for security)
|
|
54
|
-
* In production, this should be stored in a secure session
|
|
55
|
-
*/
|
|
56
|
-
const oauthStateStore = new Map();
|
|
57
|
-
/**
|
|
58
|
-
* Clean up expired states (older than 10 minutes)
|
|
59
|
-
*/
|
|
60
|
-
function cleanupExpiredStates() {
|
|
61
|
-
const now = Date.now();
|
|
62
|
-
const maxAge = 10 * 60 * 1000; // 10 minutes
|
|
63
|
-
for (const [key, value] of oauthStateStore.entries()) {
|
|
64
|
-
if (now - value.timestamp > maxAge) {
|
|
65
|
-
oauthStateStore.delete(key);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Generate Gmail OAuth authorization URL
|
|
71
|
-
*
|
|
72
|
-
* Uses PKCE for security without requiring client secret.
|
|
73
|
-
*/
|
|
74
|
-
async function generateAuthorizationUrl(api, redirectUri = "http://localhost:3000/callback") {
|
|
75
|
-
cleanupExpiredStates();
|
|
76
|
-
const gmailConfig = getGmailConfig(api);
|
|
77
|
-
// Generate PKCE verifier and challenge
|
|
78
|
-
const codeVerifier = generateCodeVerifier();
|
|
79
|
-
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
80
|
-
// Generate state parameter for CSRF protection
|
|
81
|
-
const state = Array.from(crypto.getRandomValues(new Uint8Array(16)))
|
|
82
|
-
.map((b) => b.toString(16).padStart(2, "0"))
|
|
83
|
-
.join("");
|
|
84
|
-
// Store state and verifier
|
|
85
|
-
oauthStateStore.set(state, {
|
|
86
|
-
codeVerifier,
|
|
87
|
-
timestamp: Date.now(),
|
|
88
|
-
});
|
|
89
|
-
// Build authorization URL
|
|
90
|
-
const params = new URLSearchParams();
|
|
91
|
-
params.set("client_id", gmailConfig.clientId);
|
|
92
|
-
params.set("redirect_uri", redirectUri);
|
|
93
|
-
params.set("response_type", "code");
|
|
94
|
-
params.set("scope", "https://www.googleapis.com/auth/gmail.readonly");
|
|
95
|
-
params.set("state", state);
|
|
96
|
-
params.set("code_challenge", codeChallenge);
|
|
97
|
-
params.set("code_challenge_method", "S256");
|
|
98
|
-
params.set("access_type", "offline"); // Allow refresh token
|
|
99
|
-
params.set("prompt", "consent"); // Force consent to get refresh token
|
|
100
|
-
const url = `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;
|
|
101
|
-
api.logger.info?.("Gmail authorization URL generated");
|
|
102
|
-
return { url, state };
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Exchange authorization code for access token
|
|
38
|
+
* Save Gmail OAuth tokens to account configuration
|
|
106
39
|
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
40
|
+
* NOTE: This requires the OpenClaw runtime to support config updates.
|
|
41
|
+
* The actual persistence depends on the OpenClawConfigProvider implementation.
|
|
109
42
|
*/
|
|
110
|
-
async function
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
params.set("client_id", gmailConfig.clientId);
|
|
124
|
-
if (gmailConfig.clientSecret) {
|
|
125
|
-
params.set("client_secret", gmailConfig.clientSecret);
|
|
43
|
+
async function saveGmailTokensToAccount(api, accountId, accessToken, refreshToken, expiresIn) {
|
|
44
|
+
const logger = getLogger(api);
|
|
45
|
+
// Calculate token expiry timestamp
|
|
46
|
+
const expiresAt = expiresIn
|
|
47
|
+
? new Date(Date.now() + expiresIn * 1000).toISOString()
|
|
48
|
+
: undefined;
|
|
49
|
+
// Get config from OpenClaw
|
|
50
|
+
const config = api.pluginConfig;
|
|
51
|
+
// Find and update the account
|
|
52
|
+
const accountIndex = config.accounts?.findIndex((a) => a.id === accountId && a.type === "gmail");
|
|
53
|
+
if (accountIndex === -1 || accountIndex === undefined) {
|
|
54
|
+
logger.warn(`Gmail account ${accountId} not found in config. Tokens not saved.`);
|
|
55
|
+
return;
|
|
126
56
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
},
|
|
135
|
-
body: params.toString(),
|
|
136
|
-
});
|
|
137
|
-
if (!response.ok) {
|
|
138
|
-
const errorText = await response.text();
|
|
139
|
-
throw new Error(`Failed to exchange token: ${response.status} ${errorText}`);
|
|
140
|
-
}
|
|
141
|
-
const data = (await response.json());
|
|
142
|
-
api.logger.info?.("Gmail access token obtained successfully");
|
|
143
|
-
return {
|
|
144
|
-
accessToken: data.access_token,
|
|
145
|
-
refreshToken: data.refresh_token,
|
|
146
|
-
expiresIn: data.expires_in,
|
|
57
|
+
// Update account with tokens
|
|
58
|
+
config.accounts[accountIndex] = {
|
|
59
|
+
...config.accounts[accountIndex],
|
|
60
|
+
gmailAccessToken: accessToken,
|
|
61
|
+
gmailRefreshToken: refreshToken,
|
|
62
|
+
gmailTokenExpiry: expiresAt,
|
|
63
|
+
enabled: true, // Auto-enable account after successful OAuth
|
|
147
64
|
};
|
|
65
|
+
// Note: The actual persistence to disk depends on OpenClaw's config management
|
|
66
|
+
// The updated config is in memory but OpenClaw needs to handle persistence
|
|
67
|
+
logger.info(`Gmail tokens updated in memory for account ${accountId}. Persistence depends on OpenClaw config management.`);
|
|
148
68
|
}
|
|
149
69
|
/**
|
|
150
70
|
* Handle Gmail OAuth flow
|
|
151
71
|
*
|
|
152
|
-
* This
|
|
72
|
+
* This is an OpenClaw adapter that calls the framework-agnostic OAuth handler
|
|
73
|
+
* from @firela/billclaw-core and adds OpenClaw-specific functionality.
|
|
153
74
|
*
|
|
154
75
|
* Flow:
|
|
155
76
|
* 1. Initialize OAuth (no params) - Returns { url, state }
|
|
156
|
-
* 2. Handle callback (code + state) - Returns { accessToken, refreshToken }
|
|
77
|
+
* 2. Handle callback (code + state + accountId) - Returns { accessToken, refreshToken }
|
|
78
|
+
* - Tokens are automatically saved to account config if accountId is provided
|
|
157
79
|
*
|
|
158
80
|
* @param api - OpenClaw plugin API
|
|
159
|
-
* @param context - OAuth context with optional code
|
|
81
|
+
* @param context - OAuth context with optional code, state, redirectUri, and accountId
|
|
160
82
|
* @returns OAuthResult with URL and/or token
|
|
161
83
|
*/
|
|
162
84
|
export async function gmailOAuthHandler(api, context) {
|
|
163
85
|
try {
|
|
164
|
-
const { code, state, redirectUri } = context || {};
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
86
|
+
const { code, state, redirectUri, accountId } = context || {};
|
|
87
|
+
const config = getGmailConfig(api);
|
|
88
|
+
const logger = getLogger(api);
|
|
89
|
+
// Call the framework-agnostic OAuth handler from core
|
|
90
|
+
const result = await coreGmailOAuthHandler(config, { code, state, redirectUri }, logger);
|
|
91
|
+
// Save tokens to account config if accountId is provided and we have accessToken
|
|
92
|
+
if (accountId && result.accessToken && code) {
|
|
93
|
+
await saveGmailTokensToAccount(api, accountId, result.accessToken, result.refreshToken, result.expiresIn);
|
|
94
|
+
logger.info(`Gmail tokens saved for account ${accountId} (expires in ${result.expiresIn}s)`);
|
|
172
95
|
}
|
|
173
|
-
|
|
174
|
-
if (!state) {
|
|
175
|
-
throw new Error("State parameter is required for code exchange");
|
|
176
|
-
}
|
|
177
|
-
const { accessToken, refreshToken, expiresIn } = await exchangeCodeForToken(api, code, state, redirectUri);
|
|
178
|
-
return {
|
|
179
|
-
url: "",
|
|
180
|
-
accessToken,
|
|
181
|
-
refreshToken,
|
|
182
|
-
expiresIn,
|
|
183
|
-
};
|
|
96
|
+
return result;
|
|
184
97
|
}
|
|
185
98
|
catch (error) {
|
|
186
|
-
api.
|
|
99
|
+
getLogger(api).error("Gmail OAuth error:", error);
|
|
187
100
|
throw error;
|
|
188
101
|
}
|
|
189
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Refresh Gmail access token using refresh token
|
|
105
|
+
*
|
|
106
|
+
* @param api - OpenClaw plugin API
|
|
107
|
+
* @param accountId - Account ID to refresh token for
|
|
108
|
+
* @returns New access token and expiry info, or null if refresh failed
|
|
109
|
+
*/
|
|
110
|
+
export async function refreshGmailToken(api, accountId) {
|
|
111
|
+
const config = api.pluginConfig;
|
|
112
|
+
const logger = getLogger(api);
|
|
113
|
+
// Find the account
|
|
114
|
+
const account = config.accounts?.find((a) => a.id === accountId && a.type === "gmail");
|
|
115
|
+
if (!account) {
|
|
116
|
+
logger.error(`Gmail account ${accountId} not found`);
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
const gmailConfig = getGmailConfig(api);
|
|
120
|
+
if (!account.gmailRefreshToken) {
|
|
121
|
+
logger.error(`No refresh token available for Gmail account ${accountId}. User must re-authenticate.`);
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
// Call the framework-agnostic refresh handler from core
|
|
125
|
+
const result = await coreRefreshGmailToken(gmailConfig, account.gmailRefreshToken, logger);
|
|
126
|
+
if (!result) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
// Save new tokens to account config
|
|
130
|
+
await saveGmailTokensToAccount(api, accountId, result.accessToken, account.gmailRefreshToken, result.expiresIn);
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
190
133
|
//# sourceMappingURL=gmail.js.map
|
package/dist/oauth/gmail.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gmail.js","sourceRoot":"","sources":["../../src/oauth/gmail.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"gmail.js","sourceRoot":"","sources":["../../src/oauth/gmail.ts"],"names":[],"mappings":"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"}
|
package/dist/oauth/plaid.d.ts
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Plaid OAuth handler -
|
|
2
|
+
* Plaid OAuth handler - OpenClaw adapter
|
|
3
3
|
*
|
|
4
|
-
* This
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* This is an adapter layer that calls the framework-agnostic OAuth implementation
|
|
5
|
+
* from @firela/billclaw-core and adds OpenClaw-specific functionality (config management).
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
8
|
*/
|
|
9
9
|
import type { OpenClawPluginApi } from "../types/openclaw-plugin.js";
|
|
10
10
|
/**
|
|
11
11
|
* Handle Plaid Link OAuth flow
|
|
12
12
|
*
|
|
13
|
-
* This
|
|
14
|
-
*
|
|
13
|
+
* This is an OpenClaw adapter that calls the framework-agnostic OAuth handler
|
|
14
|
+
* from @firela/billclaw-core and adds OpenClaw-specific functionality.
|
|
15
15
|
*
|
|
16
16
|
* Flow:
|
|
17
17
|
* 1. Create Link token (no params) - Returns { url, token: linkToken }
|
|
18
18
|
* 2. Handle Link success callback - Receives publicToken
|
|
19
19
|
* 3. Exchange public_token for access_token - Returns { url: "", token: accessToken, itemId }
|
|
20
|
+
* - If accountId is provided, tokens are automatically saved to account config
|
|
20
21
|
*
|
|
21
22
|
* @param api - OpenClaw plugin API
|
|
22
23
|
* @param publicToken - Optional public token from Plaid Link callback
|
|
24
|
+
* @param accountId - Optional account ID to save tokens to
|
|
23
25
|
* @returns OAuthResult with URL and token
|
|
24
26
|
*/
|
|
25
|
-
export declare function plaidOAuthHandler(api: OpenClawPluginApi, publicToken?: string): Promise<{
|
|
27
|
+
export declare function plaidOAuthHandler(api: OpenClawPluginApi, publicToken?: string, accountId?: string): Promise<{
|
|
26
28
|
url: string;
|
|
27
29
|
token?: string;
|
|
28
30
|
itemId?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plaid.d.ts","sourceRoot":"","sources":["../../src/oauth/plaid.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;
|
|
1
|
+
{"version":3,"file":"plaid.d.ts","sourceRoot":"","sources":["../../src/oauth/plaid.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAyFpE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,iBAAiB,EACtB,WAAW,CAAC,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;IACT,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAC,CA6BD"}
|
package/dist/oauth/plaid.js
CHANGED
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Plaid OAuth handler -
|
|
2
|
+
* Plaid OAuth handler - OpenClaw adapter
|
|
3
3
|
*
|
|
4
|
-
* This
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* This is an adapter layer that calls the framework-agnostic OAuth implementation
|
|
5
|
+
* from @firela/billclaw-core and adds OpenClaw-specific functionality (config management).
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
9
|
+
import { plaidOAuthHandler as corePlaidOAuthHandler, } from "@firela/billclaw-core";
|
|
10
|
+
/**
|
|
11
|
+
* Get a logger from OpenClaw API, or provide a no-op logger
|
|
12
|
+
*/
|
|
13
|
+
function getLogger(api) {
|
|
14
|
+
return {
|
|
15
|
+
info: api.logger?.info || (() => { }),
|
|
16
|
+
error: api.logger?.error || (() => { }),
|
|
17
|
+
warn: api.logger?.warn || (() => { }),
|
|
18
|
+
debug: api.logger?.debug || (() => { }),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
10
21
|
/**
|
|
11
22
|
* Get Plaid configuration from OpenClaw config
|
|
12
23
|
*
|
|
@@ -28,80 +39,64 @@ function getPlaidConfig(api) {
|
|
|
28
39
|
};
|
|
29
40
|
}
|
|
30
41
|
/**
|
|
31
|
-
*
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const plaidClient = createPlaidClient(plaidConfig);
|
|
36
|
-
const request = {
|
|
37
|
-
user: {
|
|
38
|
-
client_user_id: accountId || `user_${Date.now()}`,
|
|
39
|
-
},
|
|
40
|
-
client_name: "BillClaw",
|
|
41
|
-
products: ["transactions"],
|
|
42
|
-
country_codes: ["US"],
|
|
43
|
-
language: "en",
|
|
44
|
-
};
|
|
45
|
-
const axiosResponse = await plaidClient.linkTokenCreate(request);
|
|
46
|
-
const response = axiosResponse.data;
|
|
47
|
-
api.logger.info?.("Plaid Link token created successfully");
|
|
48
|
-
return { linkToken: response.link_token };
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Exchange Plaid public token for access token
|
|
42
|
+
* Save Plaid OAuth tokens to account configuration
|
|
43
|
+
*
|
|
44
|
+
* NOTE: This requires the OpenClaw runtime to support config updates.
|
|
45
|
+
* The actual persistence depends on the OpenClawConfigProvider implementation.
|
|
52
46
|
*/
|
|
53
|
-
async function
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
47
|
+
async function savePlaidTokensToAccount(api, accountId, accessToken, itemId) {
|
|
48
|
+
const logger = getLogger(api);
|
|
49
|
+
// Get config from OpenClaw
|
|
50
|
+
const config = api.pluginConfig;
|
|
51
|
+
// Find and update the account
|
|
52
|
+
const accountIndex = config.accounts?.findIndex((a) => a.id === accountId && a.type === "plaid");
|
|
53
|
+
if (accountIndex === -1 || accountIndex === undefined) {
|
|
54
|
+
logger.warn(`Plaid account ${accountId} not found in config. Tokens not saved.`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Update account with tokens
|
|
58
|
+
config.accounts[accountIndex] = {
|
|
59
|
+
...config.accounts[accountIndex],
|
|
60
|
+
plaidAccessToken: accessToken,
|
|
61
|
+
plaidItemId: itemId,
|
|
62
|
+
enabled: true, // Auto-enable account after successful OAuth
|
|
65
63
|
};
|
|
64
|
+
// Note: The actual persistence to disk depends on OpenClaw's config management
|
|
65
|
+
// The updated config is in memory but OpenClaw needs to handle persistence
|
|
66
|
+
logger.info(`Plaid tokens updated in memory for account ${accountId}. Persistence depends on OpenClaw config management.`);
|
|
66
67
|
}
|
|
67
68
|
/**
|
|
68
69
|
* Handle Plaid Link OAuth flow
|
|
69
70
|
*
|
|
70
|
-
* This
|
|
71
|
-
*
|
|
71
|
+
* This is an OpenClaw adapter that calls the framework-agnostic OAuth handler
|
|
72
|
+
* from @firela/billclaw-core and adds OpenClaw-specific functionality.
|
|
72
73
|
*
|
|
73
74
|
* Flow:
|
|
74
75
|
* 1. Create Link token (no params) - Returns { url, token: linkToken }
|
|
75
76
|
* 2. Handle Link success callback - Receives publicToken
|
|
76
77
|
* 3. Exchange public_token for access_token - Returns { url: "", token: accessToken, itemId }
|
|
78
|
+
* - If accountId is provided, tokens are automatically saved to account config
|
|
77
79
|
*
|
|
78
80
|
* @param api - OpenClaw plugin API
|
|
79
81
|
* @param publicToken - Optional public token from Plaid Link callback
|
|
82
|
+
* @param accountId - Optional account ID to save tokens to
|
|
80
83
|
* @returns OAuthResult with URL and token
|
|
81
84
|
*/
|
|
82
|
-
export async function plaidOAuthHandler(api, publicToken) {
|
|
85
|
+
export async function plaidOAuthHandler(api, publicToken, accountId) {
|
|
83
86
|
try {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
};
|
|
87
|
+
const config = getPlaidConfig(api);
|
|
88
|
+
const logger = getLogger(api);
|
|
89
|
+
// Call the framework-agnostic OAuth handler from core
|
|
90
|
+
const result = await corePlaidOAuthHandler(config, publicToken, accountId, logger);
|
|
91
|
+
// Save tokens to account config if accountId is provided and we have accessToken
|
|
92
|
+
if (accountId && result.accessToken && publicToken) {
|
|
93
|
+
await savePlaidTokensToAccount(api, accountId, result.accessToken, result.itemId || "");
|
|
94
|
+
logger.info(`Plaid tokens saved for account ${accountId}`);
|
|
92
95
|
}
|
|
93
|
-
|
|
94
|
-
const { accessToken, itemId } = await exchangePublicToken(api, publicToken);
|
|
95
|
-
// Return the access token and item ID for storage
|
|
96
|
-
return {
|
|
97
|
-
url: "",
|
|
98
|
-
token: accessToken,
|
|
99
|
-
itemId,
|
|
100
|
-
accessToken,
|
|
101
|
-
};
|
|
96
|
+
return result;
|
|
102
97
|
}
|
|
103
98
|
catch (error) {
|
|
104
|
-
api.
|
|
99
|
+
getLogger(api).error("Plaid OAuth error:", error);
|
|
105
100
|
throw error;
|
|
106
101
|
}
|
|
107
102
|
}
|
package/dist/oauth/plaid.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plaid.js","sourceRoot":"","sources":["../../src/oauth/plaid.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,
|
|
1
|
+
{"version":3,"file":"plaid.js","sourceRoot":"","sources":["../../src/oauth/plaid.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAYnE;;GAEG;;;;;;kBAQa,iBAAiB;;AAPjC,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAYnE;;GAEG;;;;;;kBAQa,iBAAiB;;AAPjC,wBA6NC"}
|
package/dist/plugin.js
CHANGED
|
@@ -176,9 +176,12 @@ export default {
|
|
|
176
176
|
// ========================================================================
|
|
177
177
|
const cfg = api.pluginConfig;
|
|
178
178
|
const plaidSecret = cfg.plaid?.webhookSecret || process.env.PLAID_WEBHOOK_SECRET;
|
|
179
|
+
// Webhook registration is now async (initializes Core components)
|
|
179
180
|
registerWebhookHandlers({
|
|
180
181
|
api,
|
|
181
182
|
plaidWebhookSecret: plaidSecret,
|
|
183
|
+
}).catch((error) => {
|
|
184
|
+
api.logger.error?.("Failed to register webhook handlers:", error);
|
|
182
185
|
});
|
|
183
186
|
// ========================================================================
|
|
184
187
|
// Background Services
|