cclawd 1.0.0 → 1.0.2
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/dist/{active-listener-DYmI7imH.js → active-listener-BLd27Pxd.js} +2 -2
- package/dist/{api-key-rotation-DLU4jvSu.js → api-key-rotation-Dg3JlNDQ.js} +1 -1
- package/dist/{audio-preflight-C9TMbRb4.js → audio-preflight-eV5m9mMp.js} +15 -15
- package/dist/{audio-transcription-runner-Q5zG_hYd.js → audio-transcription-runner-CQU4Eg1M.js} +10 -10
- package/dist/{audit-membership-runtime-DhxSwFnF.js → audit-membership-runtime-hXUuer4x.js} +6 -6
- package/dist/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +35 -35
- package/dist/bundled/bootstrap-extra-files/handler.js +5 -5
- package/dist/bundled/command-logger/handler.js +2 -2
- package/dist/bundled/session-memory/handler.js +35 -35
- package/dist/{channel-activity-Bx08UTAg.js → channel-activity-dT3cYb0e.js} +2 -2
- package/dist/{commands-registry-llLVCTH9.js → commands-registry-CyLMCPuP.js} +2 -2
- package/dist/compact.runtime-DGRl4st4.js +39 -0
- package/dist/{deliver-DJf2ZBpe.js → deliver-B6eTtXSk.js} +19 -19
- package/dist/deliver-runtime-CLDpY6AW.js +19 -0
- package/dist/deps-send-discord.runtime-CxADlame.js +19 -0
- package/dist/deps-send-imessage.runtime-Wi79xm6H.js +18 -0
- package/dist/deps-send-signal.runtime-BDtzvsnR.js +17 -0
- package/dist/deps-send-slack.runtime-CgX24hgT.js +17 -0
- package/dist/deps-send-telegram.runtime-CEWc7ePn.js +20 -0
- package/dist/deps-send-whatsapp.runtime-B1KJ7YOp.js +43 -0
- package/dist/{diagnostic-BCCMF3O_.js → diagnostic-BZmAxdu9.js} +2 -2
- package/dist/{env-aYXLHjfZ.js → env-lw2hsIUY.js} +1 -1
- package/dist/{fetch-bvgIiupu.js → fetch-C0iyt-Iz.js} +3 -3
- package/dist/{fetch-DCTUdr1U.js → fetch-CMLoICyN.js} +5 -5
- package/dist/{fetch-guard-CqpEmMQ2.js → fetch-guard-DCj3k042.js} +2 -2
- package/dist/{frontmatter-DjZuS525.js → frontmatter-C_obXuTp.js} +3 -3
- package/dist/{github-copilot-token-CQmATy5E.js → github-copilot-token-8N63GdbE.js} +7 -7
- package/dist/{image-Q8E1-lZn.js → image-Bt49ybRv.js} +4 -4
- package/dist/image-runtime-Cilhq73U.js +12 -0
- package/dist/{ir-CzM3SxId.js → ir-CVtBjUiL.js} +6 -6
- package/dist/llm-slug-generator.js +35 -35
- package/dist/{logger-ChbX1G7s.js → logger-CbUVl62f.js} +7 -7
- package/dist/{login-B0mtU11X.js → login-D0fUoX-p.js} +4 -4
- package/dist/{login-qr-DY_i60f5.js → login-qr-ClBxstxZ.js} +10 -10
- package/dist/{manager-FAQPC0uO.js → manager-DSfEj66R.js} +12 -12
- package/dist/manager-runtime-BrZlGJsj.js +15 -0
- package/dist/{model-selection-wf3OY5DX.js → model-selection-CMEj8bpy.js} +130 -130
- package/dist/{outbound-Bw0dOVS7.js → outbound-BxIJyMzV.js} +6 -6
- package/dist/{outbound-attachment-1R6r9Pg_.js → outbound-attachment-CVJwpypG.js} +2 -2
- package/dist/{paths-C0HLtPu0.js → paths-CehYKFsO.js} +7 -7
- package/dist/{paths-hfkBoC7i.js → paths-DkxwiA8g.js} +5 -5
- package/dist/{pi-embedded-BAHaY-Oh.js → pi-embedded-CHNPEUAv.js} +159 -159
- package/dist/{pi-model-discovery-ItS07aJB.js → pi-model-discovery-D-r5y7kV.js} +7 -7
- package/dist/pi-model-discovery-runtime-DZQXYmdu.js +12 -0
- package/dist/{pi-tools.before-tool-call.runtime-D_mthvtC.js → pi-tools.before-tool-call.runtime-DagGpfw0.js} +10 -10
- package/dist/{proxy-fetch-c1ZUFFcO.js → proxy-fetch-BOh1PLOW.js} +1 -1
- package/dist/{pw-ai-Ok6KGelf.js → pw-ai-CoIUdns_.js} +9 -9
- package/dist/{qmd-manager-DhfEz4Ar.js → qmd-manager-DEscZz5_.js} +6 -6
- package/dist/{query-expansion-GqNV2iIE.js → query-expansion-BErUY8P2.js} +4 -4
- package/dist/runtime-whatsapp-login.runtime-ChqE9BkX.js +13 -0
- package/dist/runtime-whatsapp-outbound.runtime-yiy6jzKk.js +17 -0
- package/dist/{send-DPflcjM5.js → send-4rRrSKp9.js} +6 -6
- package/dist/{send-CEg4P96c.js → send-BKO1-P1t.js} +5 -5
- package/dist/{send-CS0ocZHl.js → send-EDBPXjTT.js} +3 -3
- package/dist/{send-6R8b9zsj.js → send-K2mAG7KC.js} +5 -5
- package/dist/{send-DwAoiT2p.js → send-V1MRV7QF.js} +25 -25
- package/dist/{session-BoIID5UR.js → session-CuVCho2m.js} +7 -7
- package/dist/{skill-commands-DhdiziMs.js → skill-commands-B55LOaMB.js} +9 -9
- package/dist/slash-commands.runtime-BchS0VkW.js +12 -0
- package/dist/slash-dispatch.runtime-BIKRY3fr.js +39 -0
- package/dist/slash-skill-commands.runtime-BP4jBHU9.js +13 -0
- package/dist/subagent-registry-runtime-DjEYzSyM.js +39 -0
- package/dist/{subsystem-C8z6w6xC.js → subsystem-DfXy5gUB.js} +14 -14
- package/dist/{tables-DQusRhkD.js → tables-BAGqh2XD.js} +1 -1
- package/dist/{target-errors-CfavnC9U.js → target-errors-CeBF8Pws.js} +1 -1
- package/dist/{tokens-BWDIKewp.js → tokens-6ul2IrzG.js} +1 -1
- package/dist/{web-CrcrTQ2c.js → web-BRSmQdtm.js} +39 -39
- package/dist/{whatsapp-actions-B0u0ZAme.js → whatsapp-actions-Dxb2K2Xh.js} +15 -15
- package/dist/{workspace-CWDYHR27.js → workspace-DGIcKCCW.js} +20 -20
- package/extensions/mfa-auth/README.md +33 -38
- package/extensions/mfa-auth/index.ts +97 -92
- package/extensions/mfa-auth/node_modules/.bin/qrcode-terminal +1 -6
- package/extensions/mfa-auth/node_modules/.bin/qrcode-terminal.cmd +17 -0
- package/extensions/mfa-auth/node_modules/.bin/qrcode-terminal.ps1 +0 -13
- package/extensions/mfa-auth/node_modules/.bin/tsx +1 -6
- package/extensions/mfa-auth/node_modules/.bin/tsx.cmd +17 -0
- package/extensions/mfa-auth/node_modules/.bin/tsx.ps1 +0 -13
- package/extensions/mfa-auth/node_modules/.package-lock.json +103 -0
- package/extensions/mfa-auth/package-lock.json +115 -0
- package/extensions/mfa-auth/package.json +1 -1
- package/extensions/mfa-auth/src/auth-manager.ts +4 -2
- package/extensions/mfa-auth/src/config.ts +1 -4
- package/extensions/mfa-auth/src/dabby-client.test.ts +68 -147
- package/extensions/mfa-auth/src/dabby-client.ts +70 -89
- package/extensions/mfa-auth/src/feishu-support/index.ts +2 -2
- package/extensions/mfa-auth/src/notification-service.ts +19 -14
- package/extensions/mfa-auth/src/providers/base.ts +0 -1
- package/extensions/mfa-auth/src/providers/qr-code.ts +3 -506
- package/extensions/mfa-auth/src/server.ts +3 -223
- package/extensions/mfa-auth/src/types.ts +13 -36
- package/package.json +458 -460
- package/dist/compact.runtime-BEn3giMt.js +0 -39
- package/dist/deliver-runtime-DkQ3XzGv.js +0 -19
- package/dist/deps-send-discord.runtime-BLpqSj6s.js +0 -19
- package/dist/deps-send-imessage.runtime-BFzyYqvR.js +0 -18
- package/dist/deps-send-signal.runtime-DT0TYCy1.js +0 -17
- package/dist/deps-send-slack.runtime-BhaGFfMX.js +0 -17
- package/dist/deps-send-telegram.runtime-B6Cic9NX.js +0 -20
- package/dist/deps-send-whatsapp.runtime-WtEhIq2S.js +0 -43
- package/dist/image-runtime-B1LFYfQ2.js +0 -12
- package/dist/manager-runtime-Da7ME9vS.js +0 -15
- package/dist/pi-model-discovery-runtime-DjM7Z1fx.js +0 -12
- package/dist/runtime-whatsapp-login.runtime-D4BRhQkK.js +0 -13
- package/dist/runtime-whatsapp-outbound.runtime-DJPpS6g-.js +0 -17
- package/dist/slash-commands.runtime-Cu1lTjV9.js +0 -12
- package/dist/slash-dispatch.runtime-DRVJEF4l.js +0 -39
- package/dist/slash-skill-commands.runtime-C373PJjv.js +0 -13
- package/dist/subagent-registry-runtime-D7hWBo1G.js +0 -39
- package/extensions/mfa-auth/node_modules/.bin/qrcode-terminal.CMD +0 -12
- package/extensions/mfa-auth/node_modules/.bin/tsx.CMD +0 -12
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
2
2
|
import { authManager } from "./src/auth-manager.js";
|
|
3
3
|
import { config } from "./src/config.js";
|
|
4
|
+
import { dabbyClient } from "./src/dabby-client.js";
|
|
4
5
|
import { NotificationService } from "./src/notification-service.js";
|
|
5
6
|
import { qrCodeAuthProvider } from "./src/providers/qr-code.js";
|
|
6
|
-
import {
|
|
7
|
+
import { setNotifyCallback } from "./src/server.js";
|
|
7
8
|
import type { AuthSession } from "./src/types.js";
|
|
8
9
|
|
|
9
|
-
let serverStarted = false;
|
|
10
10
|
const notificationService = NotificationService.getInstance();
|
|
11
11
|
const pendingAuthUsers = new Set<string>();
|
|
12
12
|
|
|
@@ -98,14 +98,17 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
98
98
|
const session = authManager.getLatestSessionByUserId(userId);
|
|
99
99
|
const metadata = session?.metadata as Record<string, unknown> | undefined;
|
|
100
100
|
|
|
101
|
-
if (metadata?.
|
|
101
|
+
if (metadata?.qrCodeUrl) {
|
|
102
102
|
pendingAuthUsers.delete(userId);
|
|
103
103
|
|
|
104
104
|
let messageText = "";
|
|
105
105
|
if (metadata.triggerType === "first_message") {
|
|
106
|
-
|
|
106
|
+
const isReauth = metadata.isReauth === true;
|
|
107
|
+
messageText = isReauth
|
|
108
|
+
? `🔐 重新认证\n\n📱 请点击以下链接完成扫码认证:\n${metadata.qrCodeUrl}\n\n验证有效期: ${Math.floor(config.timeout / 60000)} 分钟`
|
|
109
|
+
: `🔐 首次对话需要进行认证\n\n为了您的账户安全,首次对话前需要完成身份验证。\n\n📱 请点击以下链接完成扫码认证:\n${metadata.qrCodeUrl}\n\n验证有效期: ${Math.floor(config.timeout / 60000)} 分钟`;
|
|
107
110
|
} else if (metadata.triggerType === "sensitive_operation") {
|
|
108
|
-
messageText = `🔐 该操作需要二次认证\n\n检测到敏感操作: ${metadata.commandPreview}\n\n
|
|
111
|
+
messageText = `🔐 该操作需要二次认证\n\n检测到敏感操作: ${metadata.commandPreview}\n\n📱 请点击以下链接完成扫码认证:\n${metadata.qrCodeUrl}\n\n验证有效期: ${Math.floor(config.timeout / 60000)} 分钟\n\n验证成功后,请回复"确认"或者重新发送之前的命令以继续执行。`;
|
|
109
112
|
}
|
|
110
113
|
|
|
111
114
|
return { content: messageText };
|
|
@@ -207,7 +210,7 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
207
210
|
`[mfa-auth] Parsed from sessionKey: channel=${parsedChannel}, accountId=${parsedAccountId}, to=${parsedTo}`,
|
|
208
211
|
);
|
|
209
212
|
|
|
210
|
-
const session = authManager.generateSession(userId, {
|
|
213
|
+
const session = await authManager.generateSession(userId, {
|
|
211
214
|
sessionKey,
|
|
212
215
|
senderId: userId,
|
|
213
216
|
commandBody: command,
|
|
@@ -225,8 +228,6 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
225
228
|
return undefined;
|
|
226
229
|
}
|
|
227
230
|
|
|
228
|
-
const authUrl = `${getServerBaseUrl()}/mfa-auth/${session.sessionId}`;
|
|
229
|
-
|
|
230
231
|
api.logger.info(`[mfa-auth] Blocking sensitive tool call: ${toolName} from ${userId}`);
|
|
231
232
|
|
|
232
233
|
// For webchat, use userId as sessionKey instead of agent:main:<userId>
|
|
@@ -238,7 +239,7 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
238
239
|
parsedChannel,
|
|
239
240
|
parsedAccountId,
|
|
240
241
|
parsedTo || userId,
|
|
241
|
-
`🔐 该操作需要二次认证\n\n检测到敏感操作: ${preview}\n\n
|
|
242
|
+
`🔐 该操作需要二次认证\n\n检测到敏感操作: ${preview}\n\n📱 请点击以下链接完成扫码认证:\n${session.qrCodeUrl}\n\n验证有效期: ${Math.floor(config.timeout / 60000)} 分钟\n\n验证成功后,请回复"确认"或者重新发送之前的命令以继续执行。`,
|
|
242
243
|
userId,
|
|
243
244
|
sessionKeyForWebchat,
|
|
244
245
|
);
|
|
@@ -253,7 +254,7 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
253
254
|
// Also add to pending users as fallback
|
|
254
255
|
pendingAuthUsers.add(userId);
|
|
255
256
|
authManager.setSessionMetadata(session.sessionId, {
|
|
256
|
-
|
|
257
|
+
qrCodeUrl: session.qrCodeUrl,
|
|
257
258
|
triggerType: "sensitive_operation",
|
|
258
259
|
commandPreview: preview,
|
|
259
260
|
});
|
|
@@ -274,41 +275,29 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
274
275
|
}
|
|
275
276
|
|
|
276
277
|
if (parsedChannel && parsedChannel !== "web") {
|
|
277
|
-
if (
|
|
278
|
+
if (false) {
|
|
278
279
|
api.logger.warn(
|
|
279
280
|
`[mfa-auth] Channel ${parsedChannel} not supported, skipping auth notification`,
|
|
280
281
|
);
|
|
281
282
|
} else {
|
|
282
|
-
|
|
283
|
-
`[mfa-auth] Sensitive operation params: channel=${parsedChannel}, to=${parsedTo}, accountId=${parsedAccountId}, userId=${userId}`,
|
|
284
|
-
);
|
|
283
|
+
const messageText = `🔐 该操作需要二次认证\n\n检测到敏感操作: ${preview}\n\n📱 请点击以下链接完成扫码认证:\n${session.qrCodeUrl}\n\n验证有效期: ${Math.floor(config.timeout / 60000)} 分钟\n\n验证成功后,请回复"确认"或者重新发送之前的命令以继续执行。`;
|
|
285
284
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
);
|
|
285
|
+
await sendAuthMessage(
|
|
286
|
+
parsedChannel,
|
|
287
|
+
parsedAccountId,
|
|
288
|
+
parsedTo || userId,
|
|
289
|
+
messageText,
|
|
290
|
+
userId,
|
|
291
|
+
);
|
|
294
292
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
} catch (error) {
|
|
304
|
-
const errorDetails = error instanceof Error ? error.message : String(error);
|
|
305
|
-
api.logger.error(
|
|
306
|
-
`[mfa-auth] Failed to send sensitive operation auth notification: ${errorDetails}`,
|
|
307
|
-
);
|
|
308
|
-
api.logger.error(
|
|
309
|
-
`[mfa-auth] Sensitive operation notification details: channel=${parsedChannel}, to=${parsedTo}, accountId=${parsedAccountId}`,
|
|
310
|
-
);
|
|
311
|
-
}
|
|
293
|
+
startPollingForAuth(api, userId, session.sessionId, {
|
|
294
|
+
triggerType: "sensitive_operation",
|
|
295
|
+
isReauth: false,
|
|
296
|
+
channel: parsedChannel,
|
|
297
|
+
accountId: parsedAccountId,
|
|
298
|
+
to: parsedTo,
|
|
299
|
+
sessionKey: ctx.sessionKey || "",
|
|
300
|
+
});
|
|
312
301
|
}
|
|
313
302
|
}
|
|
314
303
|
|
|
@@ -332,6 +321,14 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
332
321
|
return;
|
|
333
322
|
}
|
|
334
323
|
|
|
324
|
+
const content = event.content || "";
|
|
325
|
+
const isReauthCommand = content.trim() === "/reauth";
|
|
326
|
+
|
|
327
|
+
if (isReauthCommand) {
|
|
328
|
+
api.logger.info(`[mfa-auth] /reauth command detected, skipping first message auth check`);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
|
|
335
332
|
const userId = event.from || ctx.conversationId || "unknown";
|
|
336
333
|
|
|
337
334
|
if (authManager.isUserVerifiedForFirstMessage(userId)) {
|
|
@@ -394,7 +391,7 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
394
391
|
}
|
|
395
392
|
}
|
|
396
393
|
|
|
397
|
-
const session = authManager.generateSession(userId, {
|
|
394
|
+
const session = await authManager.generateSession(userId, {
|
|
398
395
|
sessionKey,
|
|
399
396
|
senderId: userId,
|
|
400
397
|
commandBody: event.content || "",
|
|
@@ -414,14 +411,12 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
414
411
|
return;
|
|
415
412
|
}
|
|
416
413
|
|
|
417
|
-
const authUrl = `${getServerBaseUrl()}/mfa-auth/${session.sessionId}`;
|
|
418
|
-
|
|
419
414
|
api.logger.info(`[mfa-auth] Blocking first message from ${userId}`);
|
|
420
415
|
|
|
421
416
|
if (parsedChannel === "webchat" || parsedChannel === "web") {
|
|
422
417
|
pendingAuthUsers.add(userId);
|
|
423
418
|
authManager.setSessionMetadata(session.sessionId, {
|
|
424
|
-
|
|
419
|
+
qrCodeUrl: session.qrCodeUrl,
|
|
425
420
|
triggerType: "first_message",
|
|
426
421
|
});
|
|
427
422
|
|
|
@@ -438,41 +433,30 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
438
433
|
}
|
|
439
434
|
|
|
440
435
|
if (parsedChannel && parsedChannel !== "web") {
|
|
441
|
-
if (
|
|
436
|
+
if (false) {
|
|
442
437
|
api.logger.warn(
|
|
443
438
|
`[mfa-auth] Channel ${parsedChannel} not supported, skipping auth notification`,
|
|
444
439
|
);
|
|
445
440
|
} else {
|
|
446
|
-
|
|
447
|
-
`[mfa-auth] First message auth params: channel=${parsedChannel}, to=${parsedTo}, accountId=${parsedAccountId}, userId=${userId}`,
|
|
448
|
-
);
|
|
441
|
+
const messageText = `🔐 首次对话需要进行认证\n\n为了您的账户安全,首次对话前需要完成身份验证。\n\n📱 请点击以下链接完成扫码认证:\n${session.qrCodeUrl}\n\n验证有效期: ${Math.floor(config.timeout / 60000)} 分钟`;
|
|
449
442
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
443
|
+
await sendAuthMessage(
|
|
444
|
+
parsedChannel,
|
|
445
|
+
parsedAccountId,
|
|
446
|
+
parsedTo || userId,
|
|
447
|
+
messageText,
|
|
448
|
+
userId,
|
|
449
|
+
sessionKey,
|
|
450
|
+
);
|
|
458
451
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
} catch (error) {
|
|
468
|
-
const errorDetails = error instanceof Error ? error.message : String(error);
|
|
469
|
-
api.logger.error(
|
|
470
|
-
`[mfa-auth] Failed to send first message auth notification: ${errorDetails}`,
|
|
471
|
-
);
|
|
472
|
-
api.logger.error(
|
|
473
|
-
`[mfa-auth] Notification details: channel=${parsedChannel}, to=${parsedTo}, accountId=${parsedAccountId}`,
|
|
474
|
-
);
|
|
475
|
-
}
|
|
452
|
+
startPollingForAuth(api, userId, session.sessionId, {
|
|
453
|
+
triggerType: "first_message",
|
|
454
|
+
isReauth: false,
|
|
455
|
+
channel: parsedChannel,
|
|
456
|
+
accountId: parsedAccountId,
|
|
457
|
+
to: parsedTo,
|
|
458
|
+
sessionKey: sessionKey,
|
|
459
|
+
});
|
|
476
460
|
}
|
|
477
461
|
}
|
|
478
462
|
});
|
|
@@ -506,7 +490,7 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
506
490
|
|
|
507
491
|
api.logger.info(`[mfa-auth] Using sessionKey for reauth: ${sessionKey}`);
|
|
508
492
|
|
|
509
|
-
const session = authManager.generateSession(userId, {
|
|
493
|
+
const session = await authManager.generateSession(userId, {
|
|
510
494
|
sessionKey,
|
|
511
495
|
senderId: userId,
|
|
512
496
|
commandBody: "/reauth",
|
|
@@ -524,18 +508,23 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
524
508
|
return { text: "❌ 认证会话创建失败,请稍后重试。" };
|
|
525
509
|
}
|
|
526
510
|
|
|
527
|
-
const authUrl = `${getServerBaseUrl()}/mfa-auth/${session.sessionId}`;
|
|
528
|
-
|
|
529
511
|
api.logger.info(
|
|
530
512
|
`[mfa-auth] Reauth requested by user ${userId}, session=${session.sessionId}`,
|
|
531
513
|
);
|
|
532
514
|
|
|
533
|
-
const messageText = `🔐 重新认证\n\n
|
|
515
|
+
const messageText = `🔐 重新认证\n\n📱 请点击以下链接完成扫码认证:\n${session.qrCodeUrl}\n\n验证有效期: ${Math.floor(config.timeout / 60000)} 分钟`;
|
|
534
516
|
|
|
535
517
|
// Use sendAuthMessage to ensure consistent delivery via WebSocket for WebChat
|
|
536
518
|
// This will use the new robust session resolution logic
|
|
537
519
|
if (parsedChannel === "webchat" || parsedChannel === "web") {
|
|
538
520
|
try {
|
|
521
|
+
pendingAuthUsers.add(userId);
|
|
522
|
+
authManager.setSessionMetadata(session.sessionId, {
|
|
523
|
+
qrCodeUrl: session.qrCodeUrl,
|
|
524
|
+
triggerType: "first_message",
|
|
525
|
+
isReauth: true,
|
|
526
|
+
});
|
|
527
|
+
|
|
539
528
|
await sendAuthMessage(
|
|
540
529
|
parsedChannel,
|
|
541
530
|
parsedAccountId,
|
|
@@ -562,7 +551,7 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
562
551
|
}
|
|
563
552
|
}
|
|
564
553
|
|
|
565
|
-
if (!parsedChannel
|
|
554
|
+
if (!parsedChannel) {
|
|
566
555
|
api.logger.warn(`[mfa-auth] Channel ${parsedChannel} not supported`);
|
|
567
556
|
return { text: "❌ 当前渠道不支持认证。" };
|
|
568
557
|
}
|
|
@@ -576,7 +565,7 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
576
565
|
parsedChannel,
|
|
577
566
|
parsedAccountId,
|
|
578
567
|
parsedTo || userId,
|
|
579
|
-
`🔐 重新认证\n\n
|
|
568
|
+
`🔐 重新认证\n\n📱 请点击以下链接完成扫码认证:\n${session.qrCodeUrl}\n\n验证有效期: ${Math.floor(config.timeout / 60000)} 分钟`,
|
|
580
569
|
userId,
|
|
581
570
|
);
|
|
582
571
|
|
|
@@ -598,12 +587,7 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
598
587
|
},
|
|
599
588
|
});
|
|
600
589
|
|
|
601
|
-
|
|
602
|
-
api.logger.info("mfa-auth: Starting HTTP server...");
|
|
603
|
-
startHttpServer();
|
|
604
|
-
serverStarted = true;
|
|
605
|
-
api.logger.info("mfa-auth plugin loaded");
|
|
606
|
-
}
|
|
590
|
+
api.logger.info("mfa-auth plugin loaded");
|
|
607
591
|
}
|
|
608
592
|
|
|
609
593
|
function startPollingForAuth(
|
|
@@ -619,18 +603,11 @@ function startPollingForAuth(
|
|
|
619
603
|
sessionKey?: string;
|
|
620
604
|
},
|
|
621
605
|
) {
|
|
622
|
-
// Only start polling if notification is disabled (passive mode)
|
|
623
|
-
// Or we can always poll as a fallback?
|
|
624
|
-
// User asked for this SPECIFICALLY when enableAuthNotification is false.
|
|
625
|
-
// But if it's true, the callback will handle it.
|
|
626
|
-
// To avoid double notification, we should check the config here or ensure consumption is atomic.
|
|
627
|
-
// Since checkAndConsumeNotification is atomic, we can run this safely even if callback also runs.
|
|
628
|
-
|
|
629
606
|
api.logger.info(
|
|
630
607
|
`[mfa-auth] Starting polling for auth status: userId=${userId}, sessionId=${sessionId}`,
|
|
631
608
|
);
|
|
632
609
|
|
|
633
|
-
const pollInterval = setInterval(() => {
|
|
610
|
+
const pollInterval = setInterval(async () => {
|
|
634
611
|
let isVerified = false;
|
|
635
612
|
if (context.triggerType === "first_message") {
|
|
636
613
|
isVerified = authManager.isUserVerifiedForFirstMessage(userId);
|
|
@@ -638,6 +615,34 @@ function startPollingForAuth(
|
|
|
638
615
|
isVerified = authManager.isUserVerifiedForSensitiveOps(userId);
|
|
639
616
|
}
|
|
640
617
|
|
|
618
|
+
if (!isVerified) {
|
|
619
|
+
const session = authManager.getSession(sessionId);
|
|
620
|
+
if (session && session.certToken) {
|
|
621
|
+
try {
|
|
622
|
+
const authResult = await dabbyClient.getAuthResult(session.certToken);
|
|
623
|
+
if (authResult.status === "verified") {
|
|
624
|
+
api.logger.info(`[mfa-auth] Auth verification successful for session ${sessionId}`);
|
|
625
|
+
authManager.markUserVerified(
|
|
626
|
+
userId,
|
|
627
|
+
context.triggerType === "first_message" ? "first_message" : "sensitive_operation",
|
|
628
|
+
context.isReauth,
|
|
629
|
+
);
|
|
630
|
+
isVerified = true;
|
|
631
|
+
} else if (authResult.status === "failed" || authResult.status === "expired") {
|
|
632
|
+
api.logger.warn(
|
|
633
|
+
`[mfa-auth] Auth failed or expired for session ${sessionId}: ${authResult.error}`,
|
|
634
|
+
);
|
|
635
|
+
clearInterval(pollInterval);
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
} catch (error) {
|
|
639
|
+
api.logger.error(
|
|
640
|
+
`[mfa-auth] Failed to check auth status for session ${sessionId}: ${String(error)}`,
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
|
|
641
646
|
if (isVerified) {
|
|
642
647
|
clearInterval(pollInterval);
|
|
643
648
|
|
|
@@ -9,13 +9,8 @@ case `uname` in
|
|
|
9
9
|
;;
|
|
10
10
|
esac
|
|
11
11
|
|
|
12
|
-
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/bin/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/qrcode-terminal@0.12.0/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/node_modules"
|
|
14
|
-
else
|
|
15
|
-
export NODE_PATH="/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/bin/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/qrcode-terminal@0.12.0/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
-
fi
|
|
17
12
|
if [ -x "$basedir/node" ]; then
|
|
18
13
|
exec "$basedir/node" "$basedir/../qrcode-terminal/bin/qrcode-terminal.js" "$@"
|
|
19
|
-
else
|
|
14
|
+
else
|
|
20
15
|
exec node "$basedir/../qrcode-terminal/bin/qrcode-terminal.js" "$@"
|
|
21
16
|
fi
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
@ECHO off
|
|
2
|
+
GOTO start
|
|
3
|
+
:find_dp0
|
|
4
|
+
SET dp0=%~dp0
|
|
5
|
+
EXIT /b
|
|
6
|
+
:start
|
|
7
|
+
SETLOCAL
|
|
8
|
+
CALL :find_dp0
|
|
9
|
+
|
|
10
|
+
IF EXIST "%dp0%\node.exe" (
|
|
11
|
+
SET "_prog=%dp0%\node.exe"
|
|
12
|
+
) ELSE (
|
|
13
|
+
SET "_prog=node"
|
|
14
|
+
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\qrcode-terminal\bin\qrcode-terminal.js" %*
|
|
@@ -2,23 +2,11 @@
|
|
|
2
2
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
3
3
|
|
|
4
4
|
$exe=""
|
|
5
|
-
$pathsep=":"
|
|
6
|
-
$env_node_path=$env:NODE_PATH
|
|
7
|
-
$new_node_path="C:\Users\asta1\PycharmProjects\cclawd\node_modules\.pnpm\qrcode-terminal@0.12.0\node_modules\qrcode-terminal\bin\node_modules;C:\Users\asta1\PycharmProjects\cclawd\node_modules\.pnpm\qrcode-terminal@0.12.0\node_modules\qrcode-terminal\node_modules;C:\Users\asta1\PycharmProjects\cclawd\node_modules\.pnpm\qrcode-terminal@0.12.0\node_modules;C:\Users\asta1\PycharmProjects\cclawd\node_modules\.pnpm\node_modules"
|
|
8
5
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
9
6
|
# Fix case when both the Windows and Linux builds of Node
|
|
10
7
|
# are installed in the same directory
|
|
11
8
|
$exe=".exe"
|
|
12
|
-
$pathsep=";"
|
|
13
|
-
} else {
|
|
14
|
-
$new_node_path="/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/bin/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/qrcode-terminal@0.12.0/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/node_modules"
|
|
15
|
-
}
|
|
16
|
-
if ([string]::IsNullOrEmpty($env_node_path)) {
|
|
17
|
-
$env:NODE_PATH=$new_node_path
|
|
18
|
-
} else {
|
|
19
|
-
$env:NODE_PATH="$new_node_path$pathsep$env_node_path"
|
|
20
9
|
}
|
|
21
|
-
|
|
22
10
|
$ret=0
|
|
23
11
|
if (Test-Path "$basedir/node$exe") {
|
|
24
12
|
# Support pipeline input
|
|
@@ -37,5 +25,4 @@ if (Test-Path "$basedir/node$exe") {
|
|
|
37
25
|
}
|
|
38
26
|
$ret=$LASTEXITCODE
|
|
39
27
|
}
|
|
40
|
-
$env:NODE_PATH=$env_node_path
|
|
41
28
|
exit $ret
|
|
@@ -9,13 +9,8 @@ case `uname` in
|
|
|
9
9
|
;;
|
|
10
10
|
esac
|
|
11
11
|
|
|
12
|
-
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/dist/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/tsx@4.21.0/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/node_modules"
|
|
14
|
-
else
|
|
15
|
-
export NODE_PATH="/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/dist/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/tsx@4.21.0/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
-
fi
|
|
17
12
|
if [ -x "$basedir/node" ]; then
|
|
18
13
|
exec "$basedir/node" "$basedir/../tsx/dist/cli.mjs" "$@"
|
|
19
|
-
else
|
|
14
|
+
else
|
|
20
15
|
exec node "$basedir/../tsx/dist/cli.mjs" "$@"
|
|
21
16
|
fi
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
@ECHO off
|
|
2
|
+
GOTO start
|
|
3
|
+
:find_dp0
|
|
4
|
+
SET dp0=%~dp0
|
|
5
|
+
EXIT /b
|
|
6
|
+
:start
|
|
7
|
+
SETLOCAL
|
|
8
|
+
CALL :find_dp0
|
|
9
|
+
|
|
10
|
+
IF EXIST "%dp0%\node.exe" (
|
|
11
|
+
SET "_prog=%dp0%\node.exe"
|
|
12
|
+
) ELSE (
|
|
13
|
+
SET "_prog=node"
|
|
14
|
+
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\tsx\dist\cli.mjs" %*
|
|
@@ -2,23 +2,11 @@
|
|
|
2
2
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
3
3
|
|
|
4
4
|
$exe=""
|
|
5
|
-
$pathsep=":"
|
|
6
|
-
$env_node_path=$env:NODE_PATH
|
|
7
|
-
$new_node_path="C:\Users\asta1\PycharmProjects\cclawd\node_modules\.pnpm\tsx@4.21.0\node_modules\tsx\dist\node_modules;C:\Users\asta1\PycharmProjects\cclawd\node_modules\.pnpm\tsx@4.21.0\node_modules\tsx\node_modules;C:\Users\asta1\PycharmProjects\cclawd\node_modules\.pnpm\tsx@4.21.0\node_modules;C:\Users\asta1\PycharmProjects\cclawd\node_modules\.pnpm\node_modules"
|
|
8
5
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
9
6
|
# Fix case when both the Windows and Linux builds of Node
|
|
10
7
|
# are installed in the same directory
|
|
11
8
|
$exe=".exe"
|
|
12
|
-
$pathsep=";"
|
|
13
|
-
} else {
|
|
14
|
-
$new_node_path="/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/dist/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/tsx@4.21.0/node_modules:/mnt/c/Users/asta1/PycharmProjects/cclawd/node_modules/.pnpm/node_modules"
|
|
15
|
-
}
|
|
16
|
-
if ([string]::IsNullOrEmpty($env_node_path)) {
|
|
17
|
-
$env:NODE_PATH=$new_node_path
|
|
18
|
-
} else {
|
|
19
|
-
$env:NODE_PATH="$new_node_path$pathsep$env_node_path"
|
|
20
9
|
}
|
|
21
|
-
|
|
22
10
|
$ret=0
|
|
23
11
|
if (Test-Path "$basedir/node$exe") {
|
|
24
12
|
# Support pipeline input
|
|
@@ -37,5 +25,4 @@ if (Test-Path "$basedir/node$exe") {
|
|
|
37
25
|
}
|
|
38
26
|
$ret=$LASTEXITCODE
|
|
39
27
|
}
|
|
40
|
-
$env:NODE_PATH=$env_node_path
|
|
41
28
|
exit $ret
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "openclaw-mfa-auth",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"lockfileVersion": 3,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"packages": {
|
|
7
|
+
"../../node_modules/.pnpm/@larksuiteoapi+node-sdk@1.59.0/node_modules/@larksuiteoapi/node-sdk": {
|
|
8
|
+
"version": "1.59.0",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"axios": "~1.13.3",
|
|
12
|
+
"lodash.identity": "^3.0.0",
|
|
13
|
+
"lodash.merge": "^4.6.2",
|
|
14
|
+
"lodash.pickby": "^4.6.0",
|
|
15
|
+
"protobufjs": "^7.2.6",
|
|
16
|
+
"qs": "^6.14.2",
|
|
17
|
+
"ws": "^8.19.0"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@koa/router": "^12.0.0",
|
|
21
|
+
"@rollup/plugin-alias": "^3.1.9",
|
|
22
|
+
"@rollup/plugin-typescript": "^8.3.2",
|
|
23
|
+
"@types/jest": "^28.1.3",
|
|
24
|
+
"@types/lodash.merge": "^4.6.7",
|
|
25
|
+
"@types/lodash.pick": "^4.4.7",
|
|
26
|
+
"@types/qs": "^6.9.16",
|
|
27
|
+
"@types/ws": "^8.5.10",
|
|
28
|
+
"@typescript-eslint/parser": "^5.27.1",
|
|
29
|
+
"body-parser": "^1.20.1",
|
|
30
|
+
"eslint": "^8.17.0",
|
|
31
|
+
"eslint-config-airbnb-base": "^15.0.0",
|
|
32
|
+
"eslint-config-prettier": "^8.5.0",
|
|
33
|
+
"eslint-plugin-import": "^2.26.0",
|
|
34
|
+
"express": "^4.18.2",
|
|
35
|
+
"jest": "^28.1.1",
|
|
36
|
+
"koa": "^2.13.4",
|
|
37
|
+
"koa-body": "^5.0.0",
|
|
38
|
+
"prettier": "2.6.2",
|
|
39
|
+
"rollup": "^2.75.5",
|
|
40
|
+
"rollup-plugin-dts": "^4.2.2",
|
|
41
|
+
"rollup-plugin-license": "^2.8.1",
|
|
42
|
+
"ts-jest": "^28.0.5",
|
|
43
|
+
"ts-node": "^10.8.1",
|
|
44
|
+
"tsconfig-paths": "^4.0.0",
|
|
45
|
+
"tslib": "^2.4.0",
|
|
46
|
+
"typescript": "^4.7.3"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"../../node_modules/.pnpm/@types+node@20.19.37/node_modules/@types/node": {
|
|
50
|
+
"version": "20.19.37",
|
|
51
|
+
"dev": true,
|
|
52
|
+
"license": "MIT",
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"undici-types": "~6.21.0"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"../../node_modules/.pnpm/qrcode-terminal@0.12.0/node_modules/qrcode-terminal": {
|
|
58
|
+
"version": "0.12.0",
|
|
59
|
+
"bin": {
|
|
60
|
+
"qrcode-terminal": "bin/qrcode-terminal.js"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"expect.js": "*",
|
|
64
|
+
"jshint": "*",
|
|
65
|
+
"mocha": "*",
|
|
66
|
+
"sinon": "*"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"../../node_modules/.pnpm/tsx@4.21.0/node_modules/tsx": {
|
|
70
|
+
"version": "4.21.0",
|
|
71
|
+
"license": "MIT",
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"esbuild": "~0.27.0",
|
|
74
|
+
"get-tsconfig": "^4.7.5"
|
|
75
|
+
},
|
|
76
|
+
"bin": {
|
|
77
|
+
"tsx": "dist/cli.mjs"
|
|
78
|
+
},
|
|
79
|
+
"engines": {
|
|
80
|
+
"node": ">=18.0.0"
|
|
81
|
+
},
|
|
82
|
+
"optionalDependencies": {
|
|
83
|
+
"fsevents": "~2.3.3"
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
"node_modules/@larksuiteoapi/node-sdk": {
|
|
87
|
+
"resolved": "../../node_modules/.pnpm/@larksuiteoapi+node-sdk@1.59.0/node_modules/@larksuiteoapi/node-sdk",
|
|
88
|
+
"link": true
|
|
89
|
+
},
|
|
90
|
+
"node_modules/@types/node": {
|
|
91
|
+
"resolved": "../../node_modules/.pnpm/@types+node@20.19.37/node_modules/@types/node",
|
|
92
|
+
"link": true
|
|
93
|
+
},
|
|
94
|
+
"node_modules/qrcode-terminal": {
|
|
95
|
+
"resolved": "../../node_modules/.pnpm/qrcode-terminal@0.12.0/node_modules/qrcode-terminal",
|
|
96
|
+
"link": true
|
|
97
|
+
},
|
|
98
|
+
"node_modules/tsx": {
|
|
99
|
+
"resolved": "../../node_modules/.pnpm/tsx@4.21.0/node_modules/tsx",
|
|
100
|
+
"link": true
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|