@firela/billclaw-openclaw 0.1.4 → 0.2.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 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.
@@ -1,31 +1,32 @@
1
1
  /**
2
- * Gmail OAuth handler - implements Gmail OAuth 2.0 flow
2
+ * Gmail OAuth handler - OpenClaw adapter
3
3
  *
4
- * This module handles Gmail OAuth 2.0 authorization using PKCE (Proof Key for Code Exchange).
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
- * Flow:
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 integrates Gmail OAuth 2.0 with PKCE for secure authorization.
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 and state from callback
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;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAiMpE;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,iBAAiB,EACtB,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAChE,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,CAsCD"}
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"}
@@ -1,13 +1,23 @@
1
1
  /**
2
- * Gmail OAuth handler - implements Gmail OAuth 2.0 flow
2
+ * Gmail OAuth handler - OpenClaw adapter
3
3
  *
4
- * This module handles Gmail OAuth 2.0 authorization using PKCE (Proof Key for Code Exchange).
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
- * Flow:
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
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
- * Generate random code verifier for PKCE
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
- * Completes the OAuth flow by exchanging the authorization code
108
- * for an access token (and optionally refresh token).
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 exchangeCodeForToken(api, code, state, redirectUri = "http://localhost:3000/callback") {
111
- // Retrieve stored state
112
- const storedState = oauthStateStore.get(state);
113
- if (!storedState) {
114
- throw new Error("Invalid or expired OAuth state. Please try again.");
115
- }
116
- // Clean up state
117
- oauthStateStore.delete(state);
118
- const gmailConfig = getGmailConfig(api);
119
- // Exchange code for token
120
- const tokenUrl = "https://oauth2.googleapis.com/token";
121
- const params = new URLSearchParams();
122
- params.set("code", code);
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
- params.set("redirect_uri", redirectUri);
128
- params.set("grant_type", "authorization_code");
129
- params.set("code_verifier", storedState.codeVerifier);
130
- const response = await fetch(tokenUrl, {
131
- method: "POST",
132
- headers: {
133
- "Content-Type": "application/x-www-form-urlencoded",
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 integrates Gmail OAuth 2.0 with PKCE for secure authorization.
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 and state from callback
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
- // Phase 1: Generate authorization URL
166
- if (!code) {
167
- const { url: authUrl, state: newState } = await generateAuthorizationUrl(api, redirectUri);
168
- return {
169
- url: authUrl,
170
- state: newState,
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
- // Phase 2: Exchange authorization code for access token
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.logger.error?.("Gmail OAuth error:", error);
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
@@ -1 +1 @@
1
- {"version":3,"file":"gmail.js","sourceRoot":"","sources":["../../src/oauth/gmail.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gmail.js","sourceRoot":"","sources":["../../src/oauth/gmail.ts"],"names":[],"mappings":"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"}
@@ -1,28 +1,30 @@
1
1
  /**
2
- * Plaid OAuth handler - implements Plaid Link flow
2
+ * Plaid OAuth handler - OpenClaw adapter
3
3
  *
4
- * This module handles the Plaid Link OAuth flow for connecting bank accounts.
5
- * It supports two modes:
6
- * 1. Link token creation (for initializing Plaid Link frontend)
7
- * 2. Public token exchange (for completing the connection)
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 integrates Plaid Link (https://plaid.com/docs/link/)
14
- * for secure bank account connection.
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;AAwFpE;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,iBAAiB,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB,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,CA2BD"}
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"}
@@ -1,12 +1,23 @@
1
1
  /**
2
- * Plaid OAuth handler - implements Plaid Link flow
2
+ * Plaid OAuth handler - OpenClaw adapter
3
3
  *
4
- * This module handles the Plaid Link OAuth flow for connecting bank accounts.
5
- * It supports two modes:
6
- * 1. Link token creation (for initializing Plaid Link frontend)
7
- * 2. Public token exchange (for completing the connection)
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 { createPlaidClient } from "@firela/billclaw-core";
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
- * Create Plaid Link token for initializing Link frontend
32
- */
33
- async function createLinkToken(api, accountId) {
34
- const plaidConfig = getPlaidConfig(api);
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 exchangePublicToken(api, publicToken) {
54
- const plaidConfig = getPlaidConfig(api);
55
- const plaidClient = createPlaidClient(plaidConfig);
56
- const request = {
57
- public_token: publicToken,
58
- };
59
- const axiosResponse = await plaidClient.itemPublicTokenExchange(request);
60
- const response = axiosResponse.data;
61
- api.logger.info?.("Plaid public token exchanged successfully");
62
- return {
63
- accessToken: response.access_token,
64
- itemId: response.item_id,
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 integrates Plaid Link (https://plaid.com/docs/link/)
71
- * for secure bank account connection.
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
- if (!publicToken) {
85
- // No public token provided - create Link token for initializing Link
86
- const { linkToken } = await createLinkToken(api);
87
- // Return Plaid Link URL and the link token
88
- return {
89
- url: "https://cdn.plaid.com/link/v2/stable/link.html",
90
- token: linkToken,
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
- // Public token provided - exchange for access token
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.logger.error?.("Plaid OAuth error:", error);
99
+ getLogger(api).error("Plaid OAuth error:", error);
105
100
  throw error;
106
101
  }
107
102
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plaid.js","sourceRoot":"","sources":["../../src/oauth/plaid.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plaid.js","sourceRoot":"","sources":["../../src/oauth/plaid.ts"],"names":[],"mappings":"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"}
@@ -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,wBA0NC"}
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
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,16 @@
2
2
  * Webhook handlers for BillClaw OpenClaw plugin
3
3
  *
4
4
  * This module provides HTTP route handlers for receiving webhooks from
5
- * external services (Plaid, GoCardless, etc.) and forwarding them to
6
- * configured external webhook endpoints.
5
+ * external services (Plaid, GoCardless, etc.) using the Core webhook layer.
6
+ *
7
+ * P0 Security Features:
8
+ * - Replay attack protection (timestamp + nonce validation)
9
+ * - Rate limiting (per-IP fixed-window)
10
+ * - Signature verification
11
+ *
12
+ * P1 Error Handling:
13
+ * - Sync failures emit sync.failed event
14
+ * - Retry logic with exponential backoff (3 retries)
7
15
  */
8
16
  import type { OpenClawPluginApi } from "../types/openclaw-plugin.js";
9
17
  /**
@@ -15,12 +23,11 @@ interface WebhookHandlerDependencies {
15
23
  }
16
24
  /**
17
25
  * Register webhook handlers with OpenClaw HTTP routes
18
- *
19
- * This function registers HTTP routes for:
20
- * - /webhook/plaid - Plaid webhook handler
21
- * - /webhook/gocardless - GoCardless webhook handler
22
- * - /webhook/test - Test webhook endpoint
23
26
  */
24
- export declare function registerWebhookHandlers(dependencies: WebhookHandlerDependencies): void;
27
+ export declare function registerWebhookHandlers(dependencies: WebhookHandlerDependencies): Promise<void>;
28
+ /**
29
+ * Cleanup rate limit entries (call periodically)
30
+ */
31
+ export declare function cleanupRateLimits(): void;
25
32
  export {};
26
33
  //# sourceMappingURL=webhook-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-handler.d.ts","sourceRoot":"","sources":["../../src/services/webhook-handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAIpE;;GAEG;AACH,UAAU,0BAA0B;IAClC,GAAG,EAAE,iBAAiB,CAAA;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAgCD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,0BAA0B,GACvC,IAAI,CA+BN"}
1
+ {"version":3,"file":"webhook-handler.d.ts","sourceRoot":"","sources":["../../src/services/webhook-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAYpE;;GAEG;AACH,UAAU,0BAA0B;IAClC,GAAG,EAAE,iBAAiB,CAAA;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAG5B;AAiFD;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,YAAY,EAAE,0BAA0B,GACvC,OAAO,CAAC,IAAI,CAAC,CA8Hf;AAkND;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAOxC"}
@@ -2,19 +2,39 @@
2
2
  * Webhook handlers for BillClaw OpenClaw plugin
3
3
  *
4
4
  * This module provides HTTP route handlers for receiving webhooks from
5
- * external services (Plaid, GoCardless, etc.) and forwarding them to
6
- * configured external webhook endpoints.
5
+ * external services (Plaid, GoCardless, etc.) using the Core webhook layer.
6
+ *
7
+ * P0 Security Features:
8
+ * - Replay attack protection (timestamp + nonce validation)
9
+ * - Rate limiting (per-IP fixed-window)
10
+ * - Signature verification
11
+ *
12
+ * P1 Error Handling:
13
+ * - Sync failures emit sync.failed event
14
+ * - Retry logic with exponential backoff (3 retries)
7
15
  */
8
- import { emitEvent, verifySignature } from "@firela/billclaw-core";
9
- // Global API reference for webhook handlers
16
+ import { WebhookProcessor, createWebhookSecurity, createWebhookDeduplication, createSyncRateLimiter, PlaidWebhookHandler, GoCardlessWebhookHandler, } from "@firela/billclaw-core";
17
+ import { emitEvent, emitSyncFailed } from "@firela/billclaw-core";
18
+ // Global state
10
19
  let api = null;
11
20
  let configWebhooks = [];
12
21
  let plaidWebhookSecret;
22
+ // gocardlessWebhookSecret reserved for future use
23
+ // let gocardlessWebhookSecret: string | undefined
24
+ // Core components
25
+ let processor = null;
26
+ let rateLimiter = null;
27
+ const rateLimitMap = new Map();
28
+ // Rate limit configuration
29
+ const RATE_LIMITS = {
30
+ plaid: { requests: 100, window: 60_000 }, // 100/min
31
+ gocardless: { requests: 50, window: 60_000 }, // 50/min
32
+ test: { requests: 30, window: 60_000 }, // 30/min
33
+ };
13
34
  /**
14
35
  * Convert OpenClaw logger to BillClaw Logger interface
15
36
  */
16
37
  function toLogger(logger) {
17
- // Ensure all methods are defined and callable
18
38
  const log = logger?.info || (() => { });
19
39
  const logError = logger?.error || (() => { });
20
40
  const logWarn = logger?.warn || (() => console.warn);
@@ -26,22 +46,112 @@ function toLogger(logger) {
26
46
  debug: logDebug,
27
47
  };
28
48
  }
49
+ /**
50
+ * Check rate limit for a source and IP
51
+ */
52
+ function checkRateLimit(source, ip) {
53
+ const now = Date.now();
54
+ const key = `${source}:${ip}`;
55
+ const limit = RATE_LIMITS[source];
56
+ let entry = rateLimitMap.get(key);
57
+ // Reset if window expired
58
+ if (!entry || now > entry.resetTime) {
59
+ entry = { count: 0, resetTime: now + limit.window };
60
+ rateLimitMap.set(key, entry);
61
+ }
62
+ // Check if exceeded
63
+ if (entry.count >= limit.requests) {
64
+ const retryAfter = Math.ceil((entry.resetTime - now) / 1000);
65
+ return { allowed: false, retryAfter };
66
+ }
67
+ // Increment counter
68
+ entry.count++;
69
+ return { allowed: true };
70
+ }
29
71
  /**
30
72
  * Register webhook handlers with OpenClaw HTTP routes
31
- *
32
- * This function registers HTTP routes for:
33
- * - /webhook/plaid - Plaid webhook handler
34
- * - /webhook/gocardless - GoCardless webhook handler
35
- * - /webhook/test - Test webhook endpoint
36
73
  */
37
- export function registerWebhookHandlers(dependencies) {
74
+ export async function registerWebhookHandlers(dependencies) {
38
75
  api = dependencies.api;
39
76
  plaidWebhookSecret = dependencies.plaidWebhookSecret;
77
+ // gocardlessWebhookSecret reserved for future use
78
+ // gocardlessWebhookSecret = dependencies.gocardlessWebhookSecret
40
79
  // Get webhooks from config
41
80
  const pluginConfig = api.pluginConfig;
42
81
  configWebhooks = pluginConfig?.webhooks || [];
43
- api.logger.info?.("billclaw webhook handler registered");
82
+ const logger = toLogger(api.logger);
83
+ // Initialize Core components
84
+ const storageBase = pluginConfig?.storage?.path || "~/.billclaw";
85
+ const basePath = storageBase.startsWith("~")
86
+ ? storageBase.replace("~", process.env.HOME || "")
87
+ : storageBase;
88
+ // Create deduplication cache
89
+ const deduplication = await createWebhookDeduplication({
90
+ basePath,
91
+ logger,
92
+ });
93
+ // Create security layer
94
+ const security = createWebhookSecurity(deduplication, logger);
95
+ // Create rate limiter
96
+ rateLimiter = createSyncRateLimiter(logger);
97
+ // Create processor
98
+ processor = new WebhookProcessor({
99
+ logger,
100
+ webhookSecret: plaidWebhookSecret,
101
+ security,
102
+ });
103
+ // Register handlers
104
+ processor.registerHandler("plaid", new PlaidWebhookHandler({
105
+ logger,
106
+ findAccountByItemId: async (itemId) => {
107
+ const accounts = pluginConfig?.accounts || [];
108
+ return accounts.find((acc) => acc.type === "plaid" && acc.plaidItemId === itemId && acc.enabled);
109
+ },
110
+ triggerSync: async (accountId) => {
111
+ const { plaidSyncTool } = await import("../tools/index.js");
112
+ // P1: Retry logic with exponential backoff
113
+ let lastError = null;
114
+ for (let attempt = 0; attempt < 3; attempt++) {
115
+ try {
116
+ await plaidSyncTool.execute(api, { accountId });
117
+ return;
118
+ }
119
+ catch (error) {
120
+ lastError = error;
121
+ if (attempt < 2) {
122
+ // Exponential backoff: 1s, 2s, 4s
123
+ const delay = 2 ** attempt * 1000;
124
+ await new Promise((resolve) => setTimeout(resolve, delay));
125
+ }
126
+ }
127
+ }
128
+ // All retries failed - emit sync.failed event (P1)
129
+ logger.error?.(`Webhook-triggered sync failed for ${accountId}:`, lastError);
130
+ await emitSyncFailed(logger, configWebhooks, accountId, `webhook_${Date.now()}`, lastError?.message || "Unknown error").catch((err) => logger.debug?.(`Event emission failed:`, err));
131
+ throw lastError;
132
+ },
133
+ emitEvent: async (eventType, data) => {
134
+ await emitEvent(logger, configWebhooks, eventType, data);
135
+ },
136
+ webhooks: configWebhooks,
137
+ rateLimiter: {
138
+ isWebhookSyncAllowed: (accountId) => {
139
+ if (!rateLimiter)
140
+ return true;
141
+ return rateLimiter.isWebhookSyncAllowed(accountId);
142
+ },
143
+ recordWebhookSync: (accountId) => {
144
+ if (!rateLimiter)
145
+ return;
146
+ rateLimiter.recordWebhookSync(accountId);
147
+ },
148
+ },
149
+ }));
150
+ processor.registerHandler("gocardless", new GoCardlessWebhookHandler({
151
+ logger,
152
+ }));
44
153
  // Register HTTP routes
154
+ api.logger.info?.("billclaw webhook handler registered with Core layer");
45
155
  api.http?.register({
46
156
  path: "/webhook/plaid",
47
157
  method: "POST",
@@ -61,67 +171,75 @@ export function registerWebhookHandlers(dependencies) {
61
171
  handler: handleTestWebhook,
62
172
  });
63
173
  }
174
+ /**
175
+ * Get client IP from request
176
+ */
177
+ function getClientIp(request) {
178
+ // Check for forwarded IP (proxy/load balancer)
179
+ const forwarded = request.headers["x-forwarded-for"];
180
+ if (forwarded) {
181
+ return forwarded.split(",")[0].trim();
182
+ }
183
+ // Check for real IP header
184
+ const realIp = request.headers["x-real-ip"];
185
+ if (realIp) {
186
+ return realIp;
187
+ }
188
+ // Fallback to query param or default
189
+ return request.query.ip || "unknown";
190
+ }
64
191
  /**
65
192
  * Handle Plaid webhook
66
193
  *
67
- * Processes webhooks from Plaid:
68
- * - TRANSACTIONS/SYNC_UPDATES_AVAILABLE: Trigger sync for the item
69
- * - ITEM/ERROR: Emit account.error event
70
- * - ITEM/LOGIN_REQUIRED: Notify user to re-authenticate
194
+ * Applies rate limiting and delegates to Core processor.
71
195
  */
72
196
  async function handlePlaidWebhook(request) {
73
197
  try {
74
- const body = request.body;
75
- const webhookType = body.webhook_type;
76
- const webhookCode = body.webhook_code;
77
- const itemId = body.item_id;
78
- api?.logger.info?.(`Received Plaid webhook: ${webhookType}.${webhookCode} for item ${itemId}`);
79
- // Verify signature if configured
80
- const signature = request.headers["plaid-verification"];
81
- const timestamp = request.headers["plaid-timestamp"];
82
- if (plaidWebhookSecret && signature && timestamp) {
83
- const payload = JSON.stringify(body);
84
- if (!verifySignature(payload, signature, plaidWebhookSecret)) {
85
- return {
86
- status: 401,
87
- body: { received: false, error: "Invalid signature" },
88
- };
89
- }
198
+ const ip = getClientIp(request);
199
+ // P0: Rate limiting check
200
+ const rateLimit = checkRateLimit("plaid", ip);
201
+ if (!rateLimit.allowed) {
202
+ api?.logger.warn?.(`Rate limit exceeded for Plaid webhook from ${ip}`);
203
+ return {
204
+ status: 429,
205
+ body: {
206
+ received: false,
207
+ error: `Rate limit exceeded. Retry after ${rateLimit.retryAfter} seconds`,
208
+ },
209
+ };
90
210
  }
91
- // Handle webhook events
92
- switch (webhookType) {
93
- case "TRANSACTIONS":
94
- if (webhookCode === "SYNC_UPDATES_AVAILABLE") {
95
- // Find the account associated with this item
96
- const pluginConfig = api?.pluginConfig;
97
- const account = pluginConfig?.accounts?.find((acc) => acc.type === "plaid" && acc.plaidItemId === itemId && acc.enabled);
98
- if (account && api) {
99
- // Trigger async sync (don't wait for completion)
100
- const { plaidSyncTool } = await import("../tools/index.js");
101
- plaidSyncTool
102
- .execute(api, { accountId: account.id })
103
- .catch((error) => {
104
- api?.logger.error?.(`Webhook-triggered sync failed:`, error);
105
- });
106
- }
107
- }
108
- break;
109
- case "ITEM":
110
- if (webhookCode === "ERROR" || webhookCode === "LOGIN_REQUIRED") {
111
- const error = body.error ?? {
112
- error_code: webhookCode,
113
- error_message: "Item login required",
114
- };
115
- // Emit account error event
116
- await emitEvent(toLogger(api.logger), configWebhooks, "account.error", {
117
- accountId: itemId,
118
- accountType: "plaid",
119
- error: JSON.stringify(error),
120
- }).catch((err) => api?.logger.debug?.(`Event emission failed:`, err));
121
- }
122
- break;
211
+ if (!processor) {
212
+ return {
213
+ status: 500,
214
+ body: { received: false, error: "Webhook processor not initialized" },
215
+ };
123
216
  }
124
- return { status: 200, body: { received: true } };
217
+ // Normalize request to Core format
218
+ const webhookRequest = {
219
+ body: request.body,
220
+ headers: request.headers,
221
+ query: request.query,
222
+ source: "plaid",
223
+ timestamp: request.headers["plaid-timestamp"]
224
+ ? parseInt(request.headers["plaid-timestamp"], 10)
225
+ : undefined,
226
+ nonce: request.body.webhook_id
227
+ ? `${request.body.webhook_id}_${request.body.webhook_code}`
228
+ : undefined,
229
+ signature: request.headers["plaid-verification"],
230
+ };
231
+ // Process with Core
232
+ const response = await processor.process(webhookRequest);
233
+ // Convert Core response to OpenClaw format
234
+ return {
235
+ status: response.status,
236
+ body: {
237
+ received: response.body.received,
238
+ error: typeof response.body.error === "string"
239
+ ? response.body.error
240
+ : response.body.error?.message || response.body.error?.code,
241
+ },
242
+ };
125
243
  }
126
244
  catch (error) {
127
245
  api?.logger.error?.(`Error handling Plaid webhook:`, error);
@@ -134,29 +252,80 @@ async function handlePlaidWebhook(request) {
134
252
  /**
135
253
  * Handle GoCardless webhook
136
254
  *
137
- * Processes webhooks from GoCardless (placeholder implementation)
255
+ * Applies rate limiting and delegates to Core processor.
138
256
  */
139
- async function handleGoCardlessWebhook(_request) {
257
+ async function handleGoCardlessWebhook(request) {
140
258
  try {
141
- api?.logger.info?.("Received GoCardless webhook");
142
- // TODO: Implement GoCardless webhook handling
143
- // - Verify signature
144
- // - Process mandate events
145
- // - Trigger sync if needed
146
- return { status: 200, body: { received: true } };
259
+ const ip = getClientIp(request);
260
+ // P0: Rate limiting check
261
+ const rateLimit = checkRateLimit("gocardless", ip);
262
+ if (!rateLimit.allowed) {
263
+ api?.logger.warn?.(`Rate limit exceeded for GoCardless webhook from ${ip}`);
264
+ return {
265
+ status: 429,
266
+ body: {
267
+ received: false,
268
+ error: `Rate limit exceeded. Retry after ${rateLimit.retryAfter} seconds`,
269
+ },
270
+ };
271
+ }
272
+ if (!processor) {
273
+ return {
274
+ status: 500,
275
+ body: { received: false, error: "Webhook processor not initialized" },
276
+ };
277
+ }
278
+ // Normalize request to Core format
279
+ const webhookRequest = {
280
+ body: request.body,
281
+ headers: request.headers,
282
+ query: request.query,
283
+ source: "gocardless",
284
+ // GoCardless doesn't provide timestamp/nonce in standard format
285
+ // Signature is in body.signature
286
+ signature: request.body?.signature,
287
+ };
288
+ // Process with Core
289
+ const response = await processor.process(webhookRequest);
290
+ // Convert Core response to OpenClaw format
291
+ return {
292
+ status: response.status,
293
+ body: {
294
+ received: response.body.received,
295
+ error: typeof response.body.error === "string"
296
+ ? response.body.error
297
+ : response.body.error?.message || response.body.error?.code,
298
+ },
299
+ };
147
300
  }
148
301
  catch (error) {
149
302
  api?.logger.error?.(`Error handling GoCardless webhook:`, error);
150
- return { status: 500, body: { received: false } };
303
+ return {
304
+ status: 500,
305
+ body: { received: false, error: "Internal server error" },
306
+ };
151
307
  }
152
308
  }
153
309
  /**
154
310
  * Handle test webhook
155
311
  *
156
- * Sends a test event to all configured webhooks to verify connectivity
312
+ * Sends a test event to all configured webhooks.
157
313
  */
158
314
  async function handleTestWebhook(_request) {
159
315
  try {
316
+ const ip = getClientIp(_request);
317
+ // P0: Rate limiting check
318
+ const rateLimit = checkRateLimit("test", ip);
319
+ if (!rateLimit.allowed) {
320
+ api?.logger.warn?.(`Rate limit exceeded for test webhook from ${ip}`);
321
+ return {
322
+ status: 429,
323
+ body: {
324
+ sent: false,
325
+ error: `Rate limit exceeded. Retry after ${rateLimit.retryAfter} seconds`,
326
+ },
327
+ };
328
+ }
160
329
  api?.logger.info?.("Received test webhook request");
161
330
  // Emit test event to all configured webhooks
162
331
  await emitEvent(toLogger(api.logger), configWebhooks, "webhook.test", {
@@ -173,4 +342,15 @@ async function handleTestWebhook(_request) {
173
342
  };
174
343
  }
175
344
  }
345
+ /**
346
+ * Cleanup rate limit entries (call periodically)
347
+ */
348
+ export function cleanupRateLimits() {
349
+ const now = Date.now();
350
+ for (const [key, entry] of rateLimitMap.entries()) {
351
+ if (now > entry.resetTime) {
352
+ rateLimitMap.delete(key);
353
+ }
354
+ }
355
+ }
176
356
  //# sourceMappingURL=webhook-handler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-handler.js","sourceRoot":"","sources":["../../src/services/webhook-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webhook-handler.js","sourceRoot":"","sources":["../../src/services/webhook-handler.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firela/billclaw-openclaw",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "BillClaw OpenClaw Plugin - Adapter for OpenClaw AI framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -20,16 +20,6 @@
20
20
  "publishConfig": {
21
21
  "access": "public"
22
22
  },
23
- "scripts": {
24
- "build": "tsc",
25
- "dev": "tsc --watch",
26
- "test": "vitest",
27
- "test:coverage": "vitest --coverage",
28
- "lint": "oxlint",
29
- "format": "oxfmt src/",
30
- "format:write": "oxfmt -w src/",
31
- "clean": "rm -rf dist"
32
- },
33
23
  "keywords": [
34
24
  "openclaw",
35
25
  "plugin",
@@ -58,9 +48,9 @@
58
48
  "vitest": "^3.0.0"
59
49
  },
60
50
  "dependencies": {
61
- "@firela/billclaw-core": "workspace:*",
62
51
  "plaid": "^32.0.0",
63
- "zod": "^3.25.0"
52
+ "zod": "^3.25.0",
53
+ "@firela/billclaw-core": "0.2.0"
64
54
  },
65
55
  "peerDependencies": {
66
56
  "openclaw": "^0.0.1"
@@ -72,5 +62,15 @@
72
62
  },
73
63
  "engines": {
74
64
  "node": ">=20.0.0"
65
+ },
66
+ "scripts": {
67
+ "build": "tsc",
68
+ "dev": "tsc --watch",
69
+ "test": "vitest",
70
+ "test:coverage": "vitest --coverage",
71
+ "lint": "oxlint",
72
+ "format": "oxfmt src/",
73
+ "format:write": "oxfmt -w src/",
74
+ "clean": "rm -rf dist"
75
75
  }
76
- }
76
+ }