@clawchatsai/connector 0.0.17 → 0.0.19

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.
@@ -25,7 +25,7 @@ const blockedConnections = new Map(); // connectionId → unblock timestamp
25
25
  let lastUsedTotpStep = 0;
26
26
  /** Max nonces to prevent memory leaks from connection storms */
27
27
  const MAX_PENDING_NONCES = 10;
28
- const AUTH_TIMEOUT_MS = 30_000;
28
+ const AUTH_TIMEOUT_MS = 60_000; // 60s — enough time to open authenticator app and enter code
29
29
  const MAX_FAILURES = 5;
30
30
  const BLOCK_DURATION_MS = 60_000;
31
31
  // ---------------------------------------------------------------------------
@@ -147,6 +147,7 @@ export async function handleAuthMessage(dc, connectionId, msg, config) {
147
147
  }
148
148
  // Verify Google ID token (skipped when not configured or in dev mode)
149
149
  const skipGoogle = !config.google.clientId || config.google.clientId === 'dev-placeholder'
150
+ || idToken === 'signaling-verified'
150
151
  || (config.devMode && idToken === 'dev-mode-no-google');
151
152
  if (skipGoogle) {
152
153
  console.log('[Auth] Skipping Google ID token verification (not configured)');
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  * Spec: specs/multitenant-p2p.md sections 6.1-6.2
11
11
  */
12
12
  export declare const PLUGIN_ID = "connector";
13
- export declare const PLUGIN_VERSION = "0.0.17";
13
+ export declare const PLUGIN_VERSION = "0.0.19";
14
14
  interface PluginServiceContext {
15
15
  stateDir: string;
16
16
  logger: {
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ import { generateSessionSecret } from './session-token.js';
22
22
  // Inline from shared/api-version.ts to avoid rootDir conflict
23
23
  const CURRENT_API_VERSION = 1;
24
24
  export const PLUGIN_ID = 'connector';
25
- export const PLUGIN_VERSION = '0.0.17';
25
+ export const PLUGIN_VERSION = '0.0.19';
26
26
  /** Max DataChannel message size (~256KB, leave room for envelope) */
27
27
  const MAX_DC_MESSAGE_SIZE = 256 * 1024;
28
28
  /** Active DataChannel connections: connectionId → send function */
package/dist/shim.d.ts CHANGED
@@ -56,6 +56,11 @@ declare class FakeRes extends Writable {
56
56
  }
57
57
  /**
58
58
  * Dispatch an RPC request through handleRequest and return the response.
59
+ *
60
+ * Safety nets:
61
+ * 1. If handleRequest() throws, we return a 500 with the error message.
62
+ * 2. If res.finished never resolves (handleRequest forgot to call res.end()),
63
+ * we time out after RPC_TIMEOUT_MS and return a 504.
59
64
  */
60
65
  export declare function dispatchRpc(rpc: RpcRequest, handleRequest: HandleRequestFn): Promise<RpcResponse>;
61
66
  export {};
package/dist/shim.js CHANGED
@@ -137,14 +137,51 @@ function tryJsonParse(buf) {
137
137
  return buf.toString('base64');
138
138
  }
139
139
  }
140
+ /** RPC dispatch timeout — if handleRequest doesn't call res.end() within
141
+ * this window, we return a 504 so the browser isn't left hanging. */
142
+ const RPC_TIMEOUT_MS = 30_000;
140
143
  /**
141
144
  * Dispatch an RPC request through handleRequest and return the response.
145
+ *
146
+ * Safety nets:
147
+ * 1. If handleRequest() throws, we return a 500 with the error message.
148
+ * 2. If res.finished never resolves (handleRequest forgot to call res.end()),
149
+ * we time out after RPC_TIMEOUT_MS and return a 504.
142
150
  */
143
151
  export async function dispatchRpc(rpc, handleRequest) {
144
152
  const req = new FakeReq(rpc);
145
153
  const res = new FakeRes();
146
- await handleRequest(req, res);
147
- const result = await res.finished;
154
+ try {
155
+ await handleRequest(req, res);
156
+ }
157
+ catch (err) {
158
+ const message = err instanceof Error ? err.message : String(err);
159
+ const stack = err instanceof Error ? err.stack : undefined;
160
+ console.error(`[RPC] handleRequest threw for ${rpc.method} ${rpc.url}: ${message}`);
161
+ if (stack)
162
+ console.error(stack);
163
+ return {
164
+ id: rpc.id,
165
+ status: 500,
166
+ headers: {},
167
+ body: JSON.stringify({ error: 'Internal server error', detail: message }),
168
+ };
169
+ }
170
+ // Wait for res.finished, but give up after RPC_TIMEOUT_MS
171
+ const result = await Promise.race([
172
+ res.finished,
173
+ new Promise((_, reject) => setTimeout(() => reject(new Error('RPC_TIMEOUT')), RPC_TIMEOUT_MS)),
174
+ ]).catch((err) => {
175
+ console.error(`[RPC] Response never completed for ${rpc.method} ${rpc.url}: ${err.message}`);
176
+ return {
177
+ status: 504,
178
+ headers: {},
179
+ body: Buffer.from(JSON.stringify({
180
+ error: 'Gateway timeout',
181
+ detail: `Plugin did not respond within ${RPC_TIMEOUT_MS / 1000}s for ${rpc.method} ${rpc.url}`,
182
+ })),
183
+ };
184
+ });
148
185
  return {
149
186
  id: rpc.id,
150
187
  status: result.status,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawchatsai/connector",
3
- "version": "0.0.17",
3
+ "version": "0.0.19",
4
4
  "type": "module",
5
5
  "description": "ClawChats OpenClaw plugin — P2P tunnel + local API bridge",
6
6
  "main": "dist/index.js",