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,9 +1,8 @@
|
|
|
1
1
|
import { dabbyConfig } from "./config.js";
|
|
2
2
|
import type {
|
|
3
3
|
DabbyConfig,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
DabbyAuthResultResponse,
|
|
4
|
+
DabbyVerifyCodeResponse,
|
|
5
|
+
DabbyCheckAuthStatusResponse,
|
|
7
6
|
} from "./types.js";
|
|
8
7
|
|
|
9
8
|
const resolveFetch = (): typeof fetch => {
|
|
@@ -15,110 +14,89 @@ const resolveFetch = (): typeof fetch => {
|
|
|
15
14
|
};
|
|
16
15
|
|
|
17
16
|
export class DabbyClient {
|
|
18
|
-
private cachedAccessToken: string | null = null;
|
|
19
|
-
private tokenExpiryTime: number = 0;
|
|
20
|
-
|
|
21
17
|
constructor(private config: DabbyConfig = dabbyConfig) {}
|
|
22
18
|
|
|
23
|
-
async
|
|
24
|
-
if (!this.config.
|
|
25
|
-
throw new Error("
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (!forceRefresh && this.cachedAccessToken && Date.now() < this.tokenExpiryTime) {
|
|
29
|
-
return this.cachedAccessToken;
|
|
19
|
+
async getVerifyCode(): Promise<DabbyVerifyCodeResponse["data"]> {
|
|
20
|
+
if (!this.config.apiKey) {
|
|
21
|
+
throw new Error("MFA_AUTH_API_KEY is not configured");
|
|
30
22
|
}
|
|
31
23
|
|
|
32
|
-
const url = `${this.config.apiBaseUrl}/getaccesstoken`;
|
|
33
|
-
const params = new URLSearchParams({
|
|
34
|
-
clientId: this.config.clientId,
|
|
35
|
-
clientSecret: this.config.clientSecret,
|
|
36
|
-
});
|
|
37
24
|
const fetch = resolveFetch();
|
|
38
|
-
const
|
|
39
|
-
|
|
25
|
+
const url = `${this.config.apiBaseUrl}/api/v1/getVerifyCode`;
|
|
26
|
+
|
|
27
|
+
const requestBody = {
|
|
28
|
+
apiKey: this.config.apiKey,
|
|
29
|
+
authType: "ScanAuth",
|
|
30
|
+
mode: "66",
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
console.log(`[mfa-auth] Fetching verify code from: ${url}`);
|
|
34
|
+
console.log(`[mfa-auth] Request body:`, JSON.stringify(requestBody, null, 2));
|
|
40
35
|
|
|
41
36
|
let lastError: any;
|
|
42
37
|
for (let i = 0; i < 3; i++) {
|
|
43
38
|
try {
|
|
44
|
-
const response = await fetch(
|
|
45
|
-
method: "
|
|
39
|
+
const response = await fetch(url, {
|
|
40
|
+
method: "POST",
|
|
46
41
|
headers: {
|
|
47
42
|
"Content-Type": "application/json",
|
|
48
43
|
"User-Agent": "OpenClaw/1.0 (mfa-auth)",
|
|
49
44
|
},
|
|
45
|
+
body: JSON.stringify(requestBody),
|
|
50
46
|
});
|
|
51
47
|
|
|
52
48
|
if (!response.ok) {
|
|
53
49
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
54
50
|
}
|
|
55
51
|
|
|
56
|
-
const data = (await response.json()) as
|
|
52
|
+
const data = (await response.json()) as DabbyVerifyCodeResponse;
|
|
53
|
+
|
|
54
|
+
console.log(`[mfa-auth] API response:`, JSON.stringify(data, null, 2));
|
|
57
55
|
|
|
58
56
|
if (data.retCode !== 0) {
|
|
59
|
-
throw new Error(`Dabby API error: ${data.
|
|
57
|
+
throw new Error(`Dabby API error: ${data.message} (code: ${data.retCode})`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!data.data) {
|
|
61
|
+
throw new Error("Dabby API returned empty data");
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
console.log(
|
|
65
|
+
`[mfa-auth] Verify code generated, certToken: ${data.data.certToken}, qrCodeUrl: ${data.data.qrCodeUrl}`,
|
|
66
|
+
);
|
|
64
67
|
|
|
65
|
-
|
|
68
|
+
// Append fromSource parameter to qrCodeUrl
|
|
69
|
+
const qrCodeUrlWithSource = data.data.qrCodeUrl.includes("?")
|
|
70
|
+
? `${data.data.qrCodeUrl}&fromSource=Cclawd`
|
|
71
|
+
: `${data.data.qrCodeUrl}?fromSource=Cclawd`;
|
|
66
72
|
|
|
67
|
-
|
|
73
|
+
console.log(`[mfa-auth] QR code URL with fromSource: ${qrCodeUrlWithSource}`);
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
...data.data,
|
|
77
|
+
qrCodeUrl: qrCodeUrlWithSource,
|
|
78
|
+
};
|
|
68
79
|
} catch (error: any) {
|
|
69
|
-
console.error(`[mfa-auth] Attempt ${i + 1} failed to get
|
|
80
|
+
console.error(`[mfa-auth] Attempt ${i + 1} failed to get verify code: ${error.message}`);
|
|
70
81
|
if (error.cause) {
|
|
71
82
|
console.error(`[mfa-auth] Failure cause:`, error.cause);
|
|
72
83
|
}
|
|
73
84
|
lastError = error;
|
|
74
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
85
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
75
86
|
}
|
|
76
87
|
}
|
|
77
88
|
|
|
78
|
-
console.error(`[mfa-auth] Failed to get
|
|
89
|
+
console.error(`[mfa-auth] Failed to get verify code after 3 attempts`);
|
|
79
90
|
throw lastError;
|
|
80
91
|
}
|
|
81
92
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const fetch = resolveFetch();
|
|
90
|
-
|
|
91
|
-
const url = `${this.config.apiBaseUrl}/authreq`;
|
|
92
|
-
const response = await fetch(url, {
|
|
93
|
-
method: "POST",
|
|
94
|
-
headers: {
|
|
95
|
-
"Content-Type": "application/json",
|
|
96
|
-
"User-Agent": "OpenClaw/1.0 (mfa-auth)",
|
|
97
|
-
},
|
|
98
|
-
body: JSON.stringify({
|
|
99
|
-
accessToken,
|
|
100
|
-
authType: "ScanAuth",
|
|
101
|
-
mode: 66,
|
|
102
|
-
}),
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
if (!response.ok) {
|
|
106
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const data = (await response.json()) as DabbyQrCodeResponse;
|
|
110
|
-
|
|
111
|
-
if (data.retCode !== 0) {
|
|
112
|
-
throw new Error(`Dabby API error: ${data.retMessage}`);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
console.log(`[mfa-auth] QR code generated, certToken: ${data.tokenInfo.certToken}`);
|
|
116
|
-
|
|
117
|
-
return data.tokenInfo;
|
|
118
|
-
} catch (error: any) {
|
|
119
|
-
console.error(`[mfa-auth] Failed to generate QR code: ${error.message}`);
|
|
120
|
-
throw error;
|
|
121
|
-
}
|
|
93
|
+
// Alias for backward compatibility if needed by other files, or just refactor them too.
|
|
94
|
+
// The plan said "Rename or keep original name". I'll keep this alias to minimize changes in other files for now,
|
|
95
|
+
// but I'll also update the other files to use getVerifyCode if I can.
|
|
96
|
+
// Actually, I'll update other files to use getVerifyCode as per plan step 4.
|
|
97
|
+
// But keeping it as alias is safer during transition.
|
|
98
|
+
async getQrCode(): Promise<DabbyVerifyCodeResponse["data"]> {
|
|
99
|
+
return this.getVerifyCode();
|
|
122
100
|
}
|
|
123
101
|
|
|
124
102
|
async getAuthResult(certToken: string): Promise<{
|
|
@@ -126,50 +104,53 @@ export class DabbyClient {
|
|
|
126
104
|
error?: string;
|
|
127
105
|
authObject?: { idNum: string; fullName: string };
|
|
128
106
|
}> {
|
|
107
|
+
if (!this.config.apiKey) {
|
|
108
|
+
return { status: "failed", error: "MFA_AUTH_API_KEY is not configured" };
|
|
109
|
+
}
|
|
110
|
+
|
|
129
111
|
try {
|
|
130
|
-
const accessToken = await this.getAccessToken();
|
|
131
112
|
const fetch = resolveFetch();
|
|
113
|
+
const url = `${this.config.apiBaseUrl}/api/v1/checkAuthStatus`;
|
|
114
|
+
|
|
115
|
+
const requestBody = {
|
|
116
|
+
apiKey: this.config.apiKey,
|
|
117
|
+
certToken,
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
console.log(`[mfa-auth] Checking auth status for certToken: ${certToken}`);
|
|
121
|
+
console.log(`[mfa-auth] CheckAuthStatus request body:`, JSON.stringify(requestBody, null, 2));
|
|
132
122
|
|
|
133
|
-
const url = `${this.config.apiBaseUrl}/authhist`;
|
|
134
123
|
const response = await fetch(url, {
|
|
135
124
|
method: "POST",
|
|
136
125
|
headers: {
|
|
137
126
|
"Content-Type": "application/json",
|
|
138
127
|
"User-Agent": "OpenClaw/1.0 (mfa-auth)",
|
|
139
128
|
},
|
|
140
|
-
body: JSON.stringify(
|
|
141
|
-
accessToken,
|
|
142
|
-
authHistQry: { certToken },
|
|
143
|
-
}),
|
|
129
|
+
body: JSON.stringify(requestBody),
|
|
144
130
|
});
|
|
145
131
|
|
|
146
132
|
if (!response.ok) {
|
|
147
133
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
148
134
|
}
|
|
149
135
|
|
|
150
|
-
const data
|
|
136
|
+
const data = (await response.json()) as DabbyCheckAuthStatusResponse;
|
|
137
|
+
|
|
138
|
+
console.log(`[mfa-auth] CheckAuthStatus response:`, JSON.stringify(data, null, 2));
|
|
151
139
|
|
|
152
|
-
// 处理特定的“等待中”状态码
|
|
153
|
-
// 4401: 该 certToken 未进行认证 -> 视为 Pending 状态,继续轮询
|
|
154
140
|
if (data.retCode !== 0) {
|
|
155
141
|
if (data.retCode === 4401) {
|
|
156
142
|
return { status: "pending" };
|
|
157
143
|
}
|
|
158
|
-
|
|
159
|
-
throw new Error(`Dabby API error: ${data.retMessage} (code: ${data.retCode})`);
|
|
144
|
+
throw new Error(`Dabby API error: ${data.message} (code: ${data.retCode})`);
|
|
160
145
|
}
|
|
161
146
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (resCode === 0) {
|
|
166
|
-
return { status: "verified", authObject };
|
|
147
|
+
if (data.data.authSuccess) {
|
|
148
|
+
return { status: "verified", authObject: data.data.authResult };
|
|
167
149
|
}
|
|
168
150
|
|
|
169
|
-
return { status: "failed", error:
|
|
151
|
+
return { status: "failed", error: data.data.message || "认证失败" };
|
|
170
152
|
} catch (error: any) {
|
|
171
153
|
console.error(`[mfa-auth] Failed to get auth result: ${error.message}`);
|
|
172
|
-
// Don't throw here, return error status so polling can continue or fail gracefully
|
|
173
154
|
return { status: "failed", error: error.message };
|
|
174
155
|
}
|
|
175
156
|
}
|
|
@@ -12,14 +12,14 @@ export type FeishuConfig = {
|
|
|
12
12
|
domain?: FeishuDomain;
|
|
13
13
|
accounts?: Record<string, FeishuAccountConfig>;
|
|
14
14
|
defaultAccount?: string;
|
|
15
|
-
//
|
|
15
|
+
// 其他字段忽略
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
export type FeishuAccountConfig = {
|
|
19
19
|
appId?: string;
|
|
20
20
|
appSecret?: string | { source: string; id: string };
|
|
21
21
|
domain?: FeishuDomain;
|
|
22
|
-
//
|
|
22
|
+
// 其他字段忽略
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
export type ResolvedFeishuAccount = {
|
|
@@ -29,8 +29,8 @@ class NotificationService {
|
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
if (channel === "webchat" || channel === "web") {
|
|
33
|
-
console.log(`[mfa-auth]
|
|
32
|
+
if (channel === "webchat" || channel === "web" || channel === "main" || channel === "desktop") {
|
|
33
|
+
console.log(`[mfa-auth] ${channel} channel: sending notification via WebSocket`);
|
|
34
34
|
await this.sendToWebChat(session, message);
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
@@ -172,8 +172,7 @@ class NotificationService {
|
|
|
172
172
|
),
|
|
173
173
|
);
|
|
174
174
|
}
|
|
175
|
-
} catch (e) {
|
|
176
|
-
}
|
|
175
|
+
} catch (e) {}
|
|
177
176
|
});
|
|
178
177
|
|
|
179
178
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -205,29 +204,35 @@ class NotificationService {
|
|
|
205
204
|
: undefined;
|
|
206
205
|
const sessionsRaw = Array.isArray(resultObject?.sessions) ? resultObject.sessions : [];
|
|
207
206
|
const webchatRows = sessionsRaw
|
|
208
|
-
.map((row) =>
|
|
209
|
-
row && typeof row === "object" ? (row as Record<string, unknown>) : undefined,
|
|
210
|
-
)
|
|
207
|
+
.map((row) => (row && typeof row === "object" ? (row as Record<string, unknown>) : undefined))
|
|
211
208
|
.filter((row): row is Record<string, unknown> => Boolean(row))
|
|
212
209
|
.filter((row) => {
|
|
213
|
-
const ch = String(row.channel ?? "")
|
|
210
|
+
const ch = String(row.channel ?? "")
|
|
211
|
+
.trim()
|
|
212
|
+
.toLowerCase();
|
|
214
213
|
const dc = row.deliveryContext as Record<string, unknown> | undefined;
|
|
215
|
-
const dcChannel = String(dc?.channel ?? "")
|
|
214
|
+
const dcChannel = String(dc?.channel ?? "")
|
|
215
|
+
.trim()
|
|
216
|
+
.toLowerCase();
|
|
216
217
|
return ch === "webchat" || ch === "web" || dcChannel === "webchat" || dcChannel === "web";
|
|
217
218
|
});
|
|
218
219
|
|
|
219
220
|
const exactRows = webchatRows.filter((row) => {
|
|
220
221
|
const dc = row.deliveryContext as Record<string, unknown> | undefined;
|
|
221
|
-
const peer = String(dc?.to ?? row.lastTo ?? "")
|
|
222
|
+
const peer = String(dc?.to ?? row.lastTo ?? "")
|
|
223
|
+
.trim()
|
|
224
|
+
.toLowerCase();
|
|
222
225
|
return peer.length > 0 && peer === normalizedTarget;
|
|
223
226
|
});
|
|
224
227
|
const fallbackRows = webchatRows.filter((row) => !exactRows.includes(row));
|
|
225
|
-
|
|
228
|
+
|
|
226
229
|
// Fuzzy match: include any webchat session that contains the userId in its key
|
|
227
230
|
const fuzzyRows = webchatRows.filter((row) => {
|
|
228
231
|
const key = String(row.key ?? "").toLowerCase();
|
|
229
232
|
// Ensure we don't duplicate rows already found
|
|
230
|
-
return
|
|
233
|
+
return (
|
|
234
|
+
key.includes(normalizedTarget) && !exactRows.includes(row) && !fallbackRows.includes(row)
|
|
235
|
+
);
|
|
231
236
|
});
|
|
232
237
|
|
|
233
238
|
const sortByUpdatedAtDesc = (a: Record<string, unknown>, b: Record<string, unknown>) => {
|
|
@@ -302,9 +307,9 @@ class NotificationService {
|
|
|
302
307
|
|
|
303
308
|
// Simplified assertion
|
|
304
309
|
if (response.code !== 0) {
|
|
305
|
-
|
|
310
|
+
throw new Error(`Feishu API error ${response.code}: ${response.msg}`);
|
|
306
311
|
}
|
|
307
|
-
|
|
312
|
+
|
|
308
313
|
const messageId = response.data?.message_id || "unknown";
|
|
309
314
|
console.log(`[mfa-auth] Feishu message sent: ${messageId} to ${to}`);
|
|
310
315
|
} catch (error) {
|
|
@@ -7,7 +7,6 @@ export abstract class BaseAuthProvider implements AuthMethodProvider {
|
|
|
7
7
|
|
|
8
8
|
abstract initialize(session: AuthSession): Promise<void>;
|
|
9
9
|
abstract verify(sessionId: string, userInput?: string): Promise<AuthResult>;
|
|
10
|
-
abstract generateAuthPage(session: AuthSession, authUrl: string): Promise<string>;
|
|
11
10
|
|
|
12
11
|
cleanup(sessionId: string): void {}
|
|
13
12
|
}
|