@kodelyth/zalouser 2026.5.39 → 2026.6.1
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/README.md +120 -0
- package/dist/accounts-DOefD_if.js +66 -0
- package/dist/accounts.runtime-KT101uuu.js +2 -0
- package/dist/api-DSWT4Dh_.js +133 -0
- package/dist/api.js +7 -0
- package/dist/channel-pby_3Sur.js +602 -0
- package/dist/channel-plugin-api.js +2 -0
- package/dist/channel.runtime-0aJ2O7Y8.js +25 -0
- package/dist/channel.setup-CqyWwqcQ.js +9 -0
- package/dist/contract-api.js +3 -0
- package/dist/doctor-contract-B9EvrW0j.js +128 -0
- package/dist/doctor-contract-api.js +2 -0
- package/dist/index.js +27 -0
- package/dist/monitor-CVtrUqyW.js +708 -0
- package/dist/runtime-api.js +19 -0
- package/dist/secret-contract-api.js +5 -0
- package/dist/security-audit-D_rftvs-.js +34 -0
- package/dist/send-uRjUB8mG.js +542 -0
- package/dist/session-route-CalHiv1d.js +92 -0
- package/dist/setup-entry.js +11 -0
- package/dist/setup-plugin-api.js +2 -0
- package/dist/setup-surface-Cfj4GQlB.js +360 -0
- package/dist/shared-DjK0e2FC.js +160 -0
- package/dist/test-api.js +5 -0
- package/dist/zalo-js-B80cRyDF.js +1285 -0
- package/package.json +20 -7
- package/api.js +0 -7
- package/channel-plugin-api.js +0 -7
- package/contract-api.js +0 -7
- package/doctor-contract-api.js +0 -7
- package/index.js +0 -7
- package/runtime-api.js +0 -7
- package/secret-contract-api.js +0 -7
- package/setup-entry.js +0 -7
- package/setup-plugin-api.js +0 -7
- package/test-api.js +0 -7
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineBundledChannelSetupEntry } from "klaw/plugin-sdk/channel-entry-contract";
|
|
2
|
+
//#region extensions/zalouser/setup-entry.ts
|
|
3
|
+
var setup_entry_default = defineBundledChannelSetupEntry({
|
|
4
|
+
importMetaUrl: import.meta.url,
|
|
5
|
+
plugin: {
|
|
6
|
+
specifier: "./setup-plugin-api.js",
|
|
7
|
+
exportName: "zalouserSetupPlugin"
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
//#endregion
|
|
11
|
+
export { setup_entry_default as default };
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import { a as resolveZalouserAccountSync, i as resolveDefaultZalouserAccountId, r as listZalouserAccountIds, t as checkZcaAuthenticated } from "./accounts-DOefD_if.js";
|
|
2
|
+
import { i as writeQrDataUrlToTempFile } from "./shared-DjK0e2FC.js";
|
|
3
|
+
import { b as waitForZaloQrLogin, c as logoutZaloProfile, d as resolveZaloGroupsByEntries, l as resolveZaloAllowFromEntries, y as startZaloQrLogin } from "./zalo-js-B80cRyDF.js";
|
|
4
|
+
import { DEFAULT_ACCOUNT_ID, addWildcardAllowFrom, createSetupTranslator, formatCliCommand, formatDocsLink, formatResolvedUnresolvedNote, mergeAllowFromEntries, normalizeAccountId, patchScopedAccountConfig } from "klaw/plugin-sdk/setup";
|
|
5
|
+
//#region \0rolldown/runtime.js
|
|
6
|
+
var __defProp = Object.defineProperty;
|
|
7
|
+
var __exportAll = (all, no_symbols) => {
|
|
8
|
+
let target = {};
|
|
9
|
+
for (var name in all) __defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true
|
|
12
|
+
});
|
|
13
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
14
|
+
return target;
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region extensions/zalouser/src/setup-surface.ts
|
|
18
|
+
var setup_surface_exports = /* @__PURE__ */ __exportAll({ zalouserSetupWizard: () => zalouserSetupWizard });
|
|
19
|
+
const t = createSetupTranslator();
|
|
20
|
+
const channel = "zalouser";
|
|
21
|
+
const ZALOUSER_ALLOW_FROM_PLACEHOLDER = t("wizard.zalouser.allowFromPlaceholder");
|
|
22
|
+
const ZALOUSER_GROUPS_PLACEHOLDER = t("wizard.zalouser.groupsPlaceholder");
|
|
23
|
+
const ZALOUSER_DM_ACCESS_TITLE = t("wizard.zalouser.dmAccessTitle");
|
|
24
|
+
const ZALOUSER_ALLOWLIST_TITLE = t("wizard.zalouser.allowlistTitle");
|
|
25
|
+
const ZALOUSER_GROUPS_TITLE = t("wizard.zalouser.groupsTitle");
|
|
26
|
+
function parseZalouserEntries(raw) {
|
|
27
|
+
return raw.split(/[\n,;]+/g).map((entry) => entry.trim()).filter(Boolean);
|
|
28
|
+
}
|
|
29
|
+
function setZalouserAccountScopedConfig(cfg, accountId, defaultPatch, accountPatch = defaultPatch) {
|
|
30
|
+
return patchScopedAccountConfig({
|
|
31
|
+
cfg,
|
|
32
|
+
channelKey: channel,
|
|
33
|
+
accountId,
|
|
34
|
+
patch: defaultPatch,
|
|
35
|
+
accountPatch
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function setZalouserDmPolicy(cfg, accountId, policy) {
|
|
39
|
+
const resolvedAccountId = normalizeAccountId(accountId) ?? DEFAULT_ACCOUNT_ID;
|
|
40
|
+
const resolved = resolveZalouserAccountSync({
|
|
41
|
+
cfg,
|
|
42
|
+
accountId: resolvedAccountId
|
|
43
|
+
});
|
|
44
|
+
return setZalouserAccountScopedConfig(cfg, resolvedAccountId, {
|
|
45
|
+
dmPolicy: policy,
|
|
46
|
+
...policy === "open" ? { allowFrom: addWildcardAllowFrom(resolved.config.allowFrom) } : {}
|
|
47
|
+
}, {
|
|
48
|
+
dmPolicy: policy,
|
|
49
|
+
...policy === "open" ? { allowFrom: addWildcardAllowFrom(resolved.config.allowFrom) } : {}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function setZalouserGroupPolicy(cfg, accountId, groupPolicy) {
|
|
53
|
+
return setZalouserAccountScopedConfig(cfg, accountId, { groupPolicy });
|
|
54
|
+
}
|
|
55
|
+
function setZalouserGroupAllowlist(cfg, accountId, groupKeys) {
|
|
56
|
+
return setZalouserAccountScopedConfig(cfg, accountId, { groups: Object.fromEntries(groupKeys.map((key) => [key, {
|
|
57
|
+
enabled: true,
|
|
58
|
+
requireMention: true
|
|
59
|
+
}])) });
|
|
60
|
+
}
|
|
61
|
+
function ensureZalouserPluginEnabled(cfg) {
|
|
62
|
+
const next = {
|
|
63
|
+
...cfg,
|
|
64
|
+
plugins: {
|
|
65
|
+
...cfg.plugins,
|
|
66
|
+
entries: {
|
|
67
|
+
...cfg.plugins?.entries,
|
|
68
|
+
zalouser: {
|
|
69
|
+
...cfg.plugins?.entries?.zalouser,
|
|
70
|
+
enabled: true
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const allow = next.plugins?.allow;
|
|
76
|
+
if (!Array.isArray(allow) || allow.includes(channel)) return next;
|
|
77
|
+
return {
|
|
78
|
+
...next,
|
|
79
|
+
plugins: {
|
|
80
|
+
...next.plugins,
|
|
81
|
+
allow: [...allow, channel]
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
async function noteZalouserHelp(prompter) {
|
|
86
|
+
await prompter.note([
|
|
87
|
+
t("wizard.zalouser.helpQrLogin"),
|
|
88
|
+
"",
|
|
89
|
+
t("wizard.zalouser.helpZcaJs"),
|
|
90
|
+
"",
|
|
91
|
+
`Docs: ${formatDocsLink("/channels/zalouser", "zalouser")}`
|
|
92
|
+
].join("\n"), t("wizard.zalouser.setupTitle"));
|
|
93
|
+
}
|
|
94
|
+
async function promptZalouserAllowFrom(params) {
|
|
95
|
+
const { cfg, prompter, accountId } = params;
|
|
96
|
+
const resolved = resolveZalouserAccountSync({
|
|
97
|
+
cfg,
|
|
98
|
+
accountId
|
|
99
|
+
});
|
|
100
|
+
const existingAllowFrom = resolved.config.allowFrom ?? [];
|
|
101
|
+
while (true) {
|
|
102
|
+
const parts = parseZalouserEntries(await prompter.text({
|
|
103
|
+
message: t("wizard.zalouser.allowFromPrompt"),
|
|
104
|
+
placeholder: ZALOUSER_ALLOW_FROM_PLACEHOLDER,
|
|
105
|
+
initialValue: existingAllowFrom.length > 0 ? existingAllowFrom.join(", ") : void 0
|
|
106
|
+
}));
|
|
107
|
+
if (parts.length === 0) {
|
|
108
|
+
await prompter.note([
|
|
109
|
+
t("wizard.zalouser.noDmAllowlist"),
|
|
110
|
+
t("wizard.zalouser.directChatsBlocked"),
|
|
111
|
+
t("wizard.zalouser.peersLookupTip", { command: formatCliCommand("klaw directory peers list --channel zalouser") })
|
|
112
|
+
].join("\n"), ZALOUSER_ALLOWLIST_TITLE);
|
|
113
|
+
return setZalouserAccountScopedConfig(cfg, accountId, {
|
|
114
|
+
dmPolicy: "allowlist",
|
|
115
|
+
allowFrom: []
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
const resolvedEntries = await resolveZaloAllowFromEntries({
|
|
119
|
+
profile: resolved.profile,
|
|
120
|
+
entries: parts
|
|
121
|
+
});
|
|
122
|
+
const unresolved = resolvedEntries.filter((item) => !item.resolved).map((item) => item.input);
|
|
123
|
+
if (unresolved.length > 0) {
|
|
124
|
+
await prompter.note(t("wizard.zalouser.couldNotResolve", { entries: unresolved.join(", ") }), ZALOUSER_ALLOWLIST_TITLE);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const unique = mergeAllowFromEntries(existingAllowFrom, resolvedEntries.filter((item) => item.resolved && item.id).map((item) => item.id));
|
|
128
|
+
const notes = resolvedEntries.filter((item) => item.note).map((item) => `${item.input} -> ${item.id} (${item.note})`);
|
|
129
|
+
if (notes.length > 0) await prompter.note(notes.join("\n"), ZALOUSER_ALLOWLIST_TITLE);
|
|
130
|
+
return setZalouserAccountScopedConfig(cfg, accountId, {
|
|
131
|
+
dmPolicy: "allowlist",
|
|
132
|
+
allowFrom: unique
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const zalouserDmPolicy = {
|
|
137
|
+
label: "Zalo Personal",
|
|
138
|
+
channel,
|
|
139
|
+
policyKey: "channels.zalouser.dmPolicy",
|
|
140
|
+
allowFromKey: "channels.zalouser.allowFrom",
|
|
141
|
+
resolveConfigKeys: (cfg, accountId) => (accountId ?? resolveDefaultZalouserAccountId(cfg)) !== DEFAULT_ACCOUNT_ID ? {
|
|
142
|
+
policyKey: `channels.zalouser.accounts.${accountId ?? resolveDefaultZalouserAccountId(cfg)}.dmPolicy`,
|
|
143
|
+
allowFromKey: `channels.zalouser.accounts.${accountId ?? resolveDefaultZalouserAccountId(cfg)}.allowFrom`
|
|
144
|
+
} : {
|
|
145
|
+
policyKey: "channels.zalouser.dmPolicy",
|
|
146
|
+
allowFromKey: "channels.zalouser.allowFrom"
|
|
147
|
+
},
|
|
148
|
+
getCurrent: (cfg, accountId) => resolveZalouserAccountSync({
|
|
149
|
+
cfg,
|
|
150
|
+
accountId: accountId ?? resolveDefaultZalouserAccountId(cfg)
|
|
151
|
+
}).config.dmPolicy ?? "pairing",
|
|
152
|
+
setPolicy: (cfg, policy, accountId) => setZalouserDmPolicy(cfg, accountId ?? resolveDefaultZalouserAccountId(cfg), policy),
|
|
153
|
+
promptAllowFrom: async ({ cfg, prompter, accountId }) => {
|
|
154
|
+
return await promptZalouserAllowFrom({
|
|
155
|
+
cfg,
|
|
156
|
+
prompter,
|
|
157
|
+
accountId: accountId && normalizeAccountId(accountId) ? normalizeAccountId(accountId) ?? DEFAULT_ACCOUNT_ID : resolveDefaultZalouserAccountId(cfg)
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
async function promptZalouserQuickstartDmPolicy(params) {
|
|
162
|
+
const { cfg, prompter, accountId } = params;
|
|
163
|
+
const resolved = resolveZalouserAccountSync({
|
|
164
|
+
cfg,
|
|
165
|
+
accountId
|
|
166
|
+
});
|
|
167
|
+
const existingPolicy = resolved.config.dmPolicy ?? "pairing";
|
|
168
|
+
const existingAllowFrom = resolved.config.allowFrom ?? [];
|
|
169
|
+
const existingLabel = existingAllowFrom.length > 0 ? existingAllowFrom.join(", ") : "unset";
|
|
170
|
+
await prompter.note([
|
|
171
|
+
t("wizard.zalouser.dmHelpSeparate"),
|
|
172
|
+
t("wizard.zalouser.dmHelpPairing"),
|
|
173
|
+
t("wizard.zalouser.dmHelpAllowlist"),
|
|
174
|
+
t("wizard.zalouser.dmHelpOpen"),
|
|
175
|
+
t("wizard.zalouser.dmHelpDisabled"),
|
|
176
|
+
"",
|
|
177
|
+
`Current: dmPolicy=${existingPolicy}, allowFrom=${existingLabel}`,
|
|
178
|
+
t("wizard.zalouser.dmHelpAllowlistEmpty")
|
|
179
|
+
].join("\n"), ZALOUSER_DM_ACCESS_TITLE);
|
|
180
|
+
const policy = await prompter.select({
|
|
181
|
+
message: t("wizard.zalouser.dmPolicyPrompt"),
|
|
182
|
+
options: [
|
|
183
|
+
{
|
|
184
|
+
value: "pairing",
|
|
185
|
+
label: t("wizard.channels.dmPolicyPairing")
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
value: "allowlist",
|
|
189
|
+
label: t("wizard.channels.dmPolicyAllowlistOption")
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
value: "open",
|
|
193
|
+
label: t("wizard.channels.dmPolicyOpenOption")
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
value: "disabled",
|
|
197
|
+
label: t("wizard.channels.dmPolicyDisabledOption")
|
|
198
|
+
}
|
|
199
|
+
],
|
|
200
|
+
initialValue: existingPolicy
|
|
201
|
+
});
|
|
202
|
+
if (policy === "allowlist") return await promptZalouserAllowFrom({
|
|
203
|
+
cfg,
|
|
204
|
+
prompter,
|
|
205
|
+
accountId
|
|
206
|
+
});
|
|
207
|
+
return setZalouserDmPolicy(cfg, accountId, policy);
|
|
208
|
+
}
|
|
209
|
+
const zalouserSetupWizard = {
|
|
210
|
+
channel,
|
|
211
|
+
status: {
|
|
212
|
+
configuredLabel: t("wizard.channels.statusLoggedIn"),
|
|
213
|
+
unconfiguredLabel: t("wizard.channels.statusNeedsQrLogin"),
|
|
214
|
+
configuredHint: t("wizard.channels.statusRecommendedLoggedIn"),
|
|
215
|
+
unconfiguredHint: t("wizard.channels.statusRecommendedQrLogin"),
|
|
216
|
+
configuredScore: 1,
|
|
217
|
+
unconfiguredScore: 15,
|
|
218
|
+
resolveConfigured: async ({ cfg, accountId }) => {
|
|
219
|
+
const ids = accountId ? [accountId] : listZalouserAccountIds(cfg);
|
|
220
|
+
for (const resolvedAccountId of ids) if (await checkZcaAuthenticated(resolveZalouserAccountSync({
|
|
221
|
+
cfg,
|
|
222
|
+
accountId: resolvedAccountId
|
|
223
|
+
}).profile)) return true;
|
|
224
|
+
return false;
|
|
225
|
+
},
|
|
226
|
+
resolveStatusLines: async ({ cfg, accountId, configured }) => {
|
|
227
|
+
return [`${accountId && accountId !== DEFAULT_ACCOUNT_ID ? `Zalo Personal (${accountId})` : "Zalo Personal"}: ${configured ? "logged in" : "needs QR login"}`];
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
prepare: async ({ cfg, accountId, prompter, options }) => {
|
|
231
|
+
let next = cfg;
|
|
232
|
+
const account = resolveZalouserAccountSync({
|
|
233
|
+
cfg: next,
|
|
234
|
+
accountId
|
|
235
|
+
});
|
|
236
|
+
if (!await checkZcaAuthenticated(account.profile)) {
|
|
237
|
+
await noteZalouserHelp(prompter);
|
|
238
|
+
if (await prompter.confirm({
|
|
239
|
+
message: t("wizard.zalouser.loginQrPrompt"),
|
|
240
|
+
initialValue: true
|
|
241
|
+
})) {
|
|
242
|
+
const start = await startZaloQrLogin({
|
|
243
|
+
profile: account.profile,
|
|
244
|
+
timeoutMs: 35e3
|
|
245
|
+
});
|
|
246
|
+
if (start.qrDataUrl) {
|
|
247
|
+
const qrPath = await writeQrDataUrlToTempFile(start.qrDataUrl, account.profile);
|
|
248
|
+
await prompter.note([
|
|
249
|
+
start.message,
|
|
250
|
+
qrPath ? t("wizard.zalouser.qrImageSaved", { path: qrPath }) : t("wizard.zalouser.qrImageWriteFailed"),
|
|
251
|
+
t("wizard.zalouser.scanApproveContinue")
|
|
252
|
+
].join("\n"), t("wizard.zalouser.qrLoginTitle"));
|
|
253
|
+
if (await prompter.confirm({
|
|
254
|
+
message: t("wizard.zalouser.qrScannedPrompt"),
|
|
255
|
+
initialValue: true
|
|
256
|
+
})) {
|
|
257
|
+
const waited = await waitForZaloQrLogin({
|
|
258
|
+
profile: account.profile,
|
|
259
|
+
timeoutMs: 12e4
|
|
260
|
+
});
|
|
261
|
+
await prompter.note(waited.message, waited.connected ? t("common.done") : t("wizard.zalouser.loginPendingTitle"));
|
|
262
|
+
}
|
|
263
|
+
} else await prompter.note(start.message, t("wizard.zalouser.loginPendingTitle"));
|
|
264
|
+
}
|
|
265
|
+
} else if (!await prompter.confirm({
|
|
266
|
+
message: t("wizard.zalouser.keepSessionPrompt"),
|
|
267
|
+
initialValue: true
|
|
268
|
+
})) {
|
|
269
|
+
await logoutZaloProfile(account.profile);
|
|
270
|
+
const start = await startZaloQrLogin({
|
|
271
|
+
profile: account.profile,
|
|
272
|
+
force: true,
|
|
273
|
+
timeoutMs: 35e3
|
|
274
|
+
});
|
|
275
|
+
if (start.qrDataUrl) {
|
|
276
|
+
const qrPath = await writeQrDataUrlToTempFile(start.qrDataUrl, account.profile);
|
|
277
|
+
await prompter.note([start.message, qrPath ? t("wizard.zalouser.qrImageSaved", { path: qrPath }) : void 0].filter(Boolean).join("\n"), t("wizard.zalouser.qrLoginTitle"));
|
|
278
|
+
const waited = await waitForZaloQrLogin({
|
|
279
|
+
profile: account.profile,
|
|
280
|
+
timeoutMs: 12e4
|
|
281
|
+
});
|
|
282
|
+
await prompter.note(waited.message, waited.connected ? t("common.done") : t("wizard.zalouser.loginPendingTitle"));
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
next = setZalouserAccountScopedConfig(next, accountId, { profile: account.profile !== "default" ? account.profile : void 0 }, {
|
|
286
|
+
profile: account.profile,
|
|
287
|
+
enabled: true
|
|
288
|
+
});
|
|
289
|
+
if (options?.quickstartDefaults) next = await promptZalouserQuickstartDmPolicy({
|
|
290
|
+
cfg: next,
|
|
291
|
+
prompter,
|
|
292
|
+
accountId
|
|
293
|
+
});
|
|
294
|
+
return { cfg: next };
|
|
295
|
+
},
|
|
296
|
+
credentials: [],
|
|
297
|
+
groupAccess: {
|
|
298
|
+
label: "Zalo groups",
|
|
299
|
+
placeholder: ZALOUSER_GROUPS_PLACEHOLDER,
|
|
300
|
+
currentPolicy: ({ cfg, accountId }) => resolveZalouserAccountSync({
|
|
301
|
+
cfg,
|
|
302
|
+
accountId
|
|
303
|
+
}).config.groupPolicy ?? "allowlist",
|
|
304
|
+
currentEntries: ({ cfg, accountId }) => Object.keys(resolveZalouserAccountSync({
|
|
305
|
+
cfg,
|
|
306
|
+
accountId
|
|
307
|
+
}).config.groups ?? {}),
|
|
308
|
+
updatePrompt: ({ cfg, accountId }) => Boolean(resolveZalouserAccountSync({
|
|
309
|
+
cfg,
|
|
310
|
+
accountId
|
|
311
|
+
}).config.groups),
|
|
312
|
+
setPolicy: ({ cfg, accountId, policy }) => setZalouserGroupPolicy(cfg, accountId, policy),
|
|
313
|
+
resolveAllowlist: async ({ cfg, accountId, entries, prompter }) => {
|
|
314
|
+
if (entries.length === 0) {
|
|
315
|
+
await prompter.note([
|
|
316
|
+
t("wizard.zalouser.noGroupAllowlist"),
|
|
317
|
+
t("wizard.zalouser.groupChatsBlocked"),
|
|
318
|
+
t("wizard.zalouser.groupsLookupTip", { command: formatCliCommand("klaw directory groups list --channel zalouser") }),
|
|
319
|
+
t("wizard.zalouser.groupMentionRequirement")
|
|
320
|
+
].join("\n"), ZALOUSER_GROUPS_TITLE);
|
|
321
|
+
return [];
|
|
322
|
+
}
|
|
323
|
+
const updatedAccount = resolveZalouserAccountSync({
|
|
324
|
+
cfg,
|
|
325
|
+
accountId
|
|
326
|
+
});
|
|
327
|
+
try {
|
|
328
|
+
const resolved = await resolveZaloGroupsByEntries({
|
|
329
|
+
profile: updatedAccount.profile,
|
|
330
|
+
entries
|
|
331
|
+
});
|
|
332
|
+
const resolvedIds = resolved.filter((entry) => entry.resolved && entry.id).map((entry) => entry.id);
|
|
333
|
+
const unresolved = resolved.filter((entry) => !entry.resolved).map((entry) => entry.input);
|
|
334
|
+
const keys = [...resolvedIds, ...unresolved.map((entry) => entry.trim()).filter(Boolean)];
|
|
335
|
+
const resolution = formatResolvedUnresolvedNote({
|
|
336
|
+
resolved: resolvedIds,
|
|
337
|
+
unresolved
|
|
338
|
+
});
|
|
339
|
+
if (resolution) await prompter.note(resolution, ZALOUSER_GROUPS_TITLE);
|
|
340
|
+
return keys;
|
|
341
|
+
} catch (err) {
|
|
342
|
+
await prompter.note(t("wizard.zalouser.groupLookupFailed", { error: String(err) }), ZALOUSER_GROUPS_TITLE);
|
|
343
|
+
return entries.map((entry) => entry.trim()).filter(Boolean);
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
applyAllowlist: ({ cfg, accountId, resolved }) => setZalouserGroupAllowlist(cfg, accountId, resolved)
|
|
347
|
+
},
|
|
348
|
+
finalize: async ({ cfg, accountId, forceAllowFrom, options, prompter }) => {
|
|
349
|
+
let next = cfg;
|
|
350
|
+
if (forceAllowFrom && !options?.quickstartDefaults) next = await promptZalouserAllowFrom({
|
|
351
|
+
cfg: next,
|
|
352
|
+
prompter,
|
|
353
|
+
accountId
|
|
354
|
+
});
|
|
355
|
+
return { cfg: ensureZalouserPluginEnabled(next) };
|
|
356
|
+
},
|
|
357
|
+
dmPolicy: zalouserDmPolicy
|
|
358
|
+
};
|
|
359
|
+
//#endregion
|
|
360
|
+
export { zalouserSetupWizard as n, setup_surface_exports as t };
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { a as resolveZalouserAccountSync, i as resolveDefaultZalouserAccountId, r as listZalouserAccountIds, t as checkZcaAuthenticated } from "./accounts-DOefD_if.js";
|
|
2
|
+
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-B9EvrW0j.js";
|
|
3
|
+
import { n as isZalouserMutableGroupEntry } from "./security-audit-D_rftvs-.js";
|
|
4
|
+
import { formatAllowFromLowercase } from "klaw/plugin-sdk/allow-from";
|
|
5
|
+
import { AllowFromListSchema, DmPolicySchema, GroupPolicySchema, MarkdownConfigSchema, ToolPolicySchema, buildCatchallMultiAccountChannelSchema, buildChannelConfigSchema } from "klaw/plugin-sdk/channel-config-schema";
|
|
6
|
+
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "klaw/plugin-sdk/core";
|
|
7
|
+
import { isDangerousNameMatchingEnabled as isDangerousNameMatchingEnabled$1 } from "klaw/plugin-sdk/dangerous-name-runtime";
|
|
8
|
+
import { chunkTextForOutbound } from "klaw/plugin-sdk/text-chunking";
|
|
9
|
+
import { isNumericTargetId, sendPayloadWithChunkedTextAndMedia } from "klaw/plugin-sdk/reply-payload";
|
|
10
|
+
import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter } from "klaw/plugin-sdk/channel-config-helpers";
|
|
11
|
+
import fsp from "node:fs/promises";
|
|
12
|
+
import path from "node:path";
|
|
13
|
+
import { resolvePreferredKlawTmpDir } from "klaw/plugin-sdk/temp-path";
|
|
14
|
+
import { createDelegatedSetupWizardProxy, createPatchedAccountSetupAdapter, createSetupTranslator } from "klaw/plugin-sdk/setup-runtime";
|
|
15
|
+
import { describeAccountSnapshot } from "klaw/plugin-sdk/account-helpers";
|
|
16
|
+
import { z } from "zod";
|
|
17
|
+
import { createDangerousNameMatchingMutableAllowlistWarningCollector } from "klaw/plugin-sdk/channel-policy";
|
|
18
|
+
//#region extensions/zalouser/src/qr-temp-file.ts
|
|
19
|
+
async function writeQrDataUrlToTempFile(qrDataUrl, profile) {
|
|
20
|
+
const base64 = (qrDataUrl.trim().match(/^data:image\/png;base64,(.+)$/i)?.[1] ?? "").trim();
|
|
21
|
+
if (!base64) return null;
|
|
22
|
+
const safeProfile = profile.replace(/[^a-zA-Z0-9_-]+/g, "-") || "default";
|
|
23
|
+
const filePath = path.join(resolvePreferredKlawTmpDir(), `klaw-zalouser-qr-${safeProfile}.png`);
|
|
24
|
+
await fsp.writeFile(filePath, Buffer.from(base64, "base64"));
|
|
25
|
+
return filePath;
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region extensions/zalouser/src/setup-core.ts
|
|
29
|
+
const t = createSetupTranslator();
|
|
30
|
+
const channel = "zalouser";
|
|
31
|
+
const zalouserSetupAdapter = createPatchedAccountSetupAdapter({
|
|
32
|
+
channelKey: channel,
|
|
33
|
+
validateInput: () => null,
|
|
34
|
+
buildPatch: () => ({})
|
|
35
|
+
});
|
|
36
|
+
function createZalouserSetupWizardProxy(loadWizard) {
|
|
37
|
+
return createDelegatedSetupWizardProxy({
|
|
38
|
+
channel,
|
|
39
|
+
loadWizard,
|
|
40
|
+
status: {
|
|
41
|
+
configuredLabel: t("wizard.channels.statusLoggedIn"),
|
|
42
|
+
unconfiguredLabel: t("wizard.channels.statusNeedsQrLogin"),
|
|
43
|
+
configuredHint: t("wizard.channels.statusRecommendedLoggedIn"),
|
|
44
|
+
unconfiguredHint: t("wizard.channels.statusRecommendedQrLogin"),
|
|
45
|
+
configuredScore: 1,
|
|
46
|
+
unconfiguredScore: 15
|
|
47
|
+
},
|
|
48
|
+
credentials: [],
|
|
49
|
+
delegatePrepare: true,
|
|
50
|
+
delegateFinalize: true
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region extensions/zalouser/src/config-schema.ts
|
|
55
|
+
const groupConfigSchema = z.object({
|
|
56
|
+
enabled: z.boolean().optional(),
|
|
57
|
+
requireMention: z.boolean().optional(),
|
|
58
|
+
tools: ToolPolicySchema
|
|
59
|
+
});
|
|
60
|
+
const ZalouserConfigSchema = buildCatchallMultiAccountChannelSchema(z.object({
|
|
61
|
+
name: z.string().optional(),
|
|
62
|
+
enabled: z.boolean().optional(),
|
|
63
|
+
markdown: MarkdownConfigSchema,
|
|
64
|
+
profile: z.string().optional(),
|
|
65
|
+
dangerouslyAllowNameMatching: z.boolean().optional(),
|
|
66
|
+
dmPolicy: DmPolicySchema.optional(),
|
|
67
|
+
allowFrom: AllowFromListSchema,
|
|
68
|
+
historyLimit: z.number().int().min(0).optional(),
|
|
69
|
+
groupAllowFrom: AllowFromListSchema,
|
|
70
|
+
groupPolicy: GroupPolicySchema.optional().default("allowlist"),
|
|
71
|
+
groups: z.object({}).catchall(groupConfigSchema).optional(),
|
|
72
|
+
messagePrefix: z.string().optional(),
|
|
73
|
+
responsePrefix: z.string().optional()
|
|
74
|
+
}));
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region extensions/zalouser/src/doctor.ts
|
|
77
|
+
function asObjectRecord(value) {
|
|
78
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
79
|
+
}
|
|
80
|
+
const zalouserDoctor = {
|
|
81
|
+
dmAllowFromMode: "topOnly",
|
|
82
|
+
groupModel: "hybrid",
|
|
83
|
+
groupAllowFromFallbackToAllowFrom: false,
|
|
84
|
+
warnOnEmptyGroupSenderAllowlist: false,
|
|
85
|
+
legacyConfigRules,
|
|
86
|
+
normalizeCompatibilityConfig,
|
|
87
|
+
collectMutableAllowlistWarnings: createDangerousNameMatchingMutableAllowlistWarningCollector({
|
|
88
|
+
channel: "zalouser",
|
|
89
|
+
detector: isZalouserMutableGroupEntry,
|
|
90
|
+
collectLists: (scope) => {
|
|
91
|
+
const groups = asObjectRecord(scope.account.groups);
|
|
92
|
+
return groups ? [{
|
|
93
|
+
pathLabel: `${scope.prefix}.groups`,
|
|
94
|
+
list: Object.keys(groups)
|
|
95
|
+
}] : [];
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
};
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region extensions/zalouser/src/shared.ts
|
|
101
|
+
const zalouserMeta = {
|
|
102
|
+
id: "zalouser",
|
|
103
|
+
label: "Zalo Personal",
|
|
104
|
+
selectionLabel: "Zalo (Personal Account)",
|
|
105
|
+
docsPath: "/channels/zalouser",
|
|
106
|
+
docsLabel: "zalouser",
|
|
107
|
+
blurb: "Zalo personal account via QR code login.",
|
|
108
|
+
aliases: ["zlu"],
|
|
109
|
+
order: 85,
|
|
110
|
+
quickstartAllowFrom: false
|
|
111
|
+
};
|
|
112
|
+
const zalouserConfigAdapter = createScopedChannelConfigAdapter({
|
|
113
|
+
sectionKey: "zalouser",
|
|
114
|
+
listAccountIds: listZalouserAccountIds,
|
|
115
|
+
resolveAccount: adaptScopedAccountAccessor(resolveZalouserAccountSync),
|
|
116
|
+
defaultAccountId: resolveDefaultZalouserAccountId,
|
|
117
|
+
clearBaseFields: [
|
|
118
|
+
"profile",
|
|
119
|
+
"name",
|
|
120
|
+
"dmPolicy",
|
|
121
|
+
"allowFrom",
|
|
122
|
+
"historyLimit",
|
|
123
|
+
"groupAllowFrom",
|
|
124
|
+
"groupPolicy",
|
|
125
|
+
"groups",
|
|
126
|
+
"messagePrefix"
|
|
127
|
+
],
|
|
128
|
+
resolveAllowFrom: (account) => account.config.allowFrom,
|
|
129
|
+
formatAllowFrom: (allowFrom) => formatAllowFromLowercase({
|
|
130
|
+
allowFrom,
|
|
131
|
+
stripPrefixRe: /^(zalouser|zlu):/i
|
|
132
|
+
})
|
|
133
|
+
});
|
|
134
|
+
function createZalouserPluginBase(params) {
|
|
135
|
+
return {
|
|
136
|
+
id: "zalouser",
|
|
137
|
+
meta: zalouserMeta,
|
|
138
|
+
setupWizard: params.setupWizard,
|
|
139
|
+
capabilities: {
|
|
140
|
+
chatTypes: ["direct", "group"],
|
|
141
|
+
media: true,
|
|
142
|
+
reactions: true,
|
|
143
|
+
threads: false,
|
|
144
|
+
polls: false,
|
|
145
|
+
nativeCommands: false,
|
|
146
|
+
blockStreaming: true
|
|
147
|
+
},
|
|
148
|
+
doctor: zalouserDoctor,
|
|
149
|
+
reload: { configPrefixes: ["channels.zalouser"] },
|
|
150
|
+
configSchema: buildChannelConfigSchema(ZalouserConfigSchema),
|
|
151
|
+
config: {
|
|
152
|
+
...zalouserConfigAdapter,
|
|
153
|
+
isConfigured: async (account) => await checkZcaAuthenticated(account.profile),
|
|
154
|
+
describeAccount: (account) => describeAccountSnapshot({ account })
|
|
155
|
+
},
|
|
156
|
+
setup: params.setup
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
//#endregion
|
|
160
|
+
export { DEFAULT_ACCOUNT_ID as a, isNumericTargetId as c, writeQrDataUrlToTempFile as i, normalizeAccountId as l, createZalouserSetupWizardProxy as n, chunkTextForOutbound as o, zalouserSetupAdapter as r, isDangerousNameMatchingEnabled$1 as s, createZalouserPluginBase as t, sendPayloadWithChunkedTextAndMedia as u };
|
package/dist/test-api.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { a as resolveZalouserAccountSync, i as resolveDefaultZalouserAccountId, n as getZcaUserInfo, r as listZalouserAccountIds, t as checkZcaAuthenticated } from "./accounts-DOefD_if.js";
|
|
2
|
+
import { r as parseZalouserOutboundTarget } from "./session-route-CalHiv1d.js";
|
|
3
|
+
import { a as listZaloGroupMembers, b as waitForZaloQrLogin, c as logoutZaloProfile, d as resolveZaloGroupsByEntries, i as listZaloFriendsMatching, l as resolveZaloAllowFromEntries, n as getZaloUserInfo, s as listZaloGroupsMatching, t as checkZaloAuthenticated, y as startZaloQrLogin } from "./zalo-js-B80cRyDF.js";
|
|
4
|
+
import { i as sendMessageZalouser } from "./send-uRjUB8mG.js";
|
|
5
|
+
export { checkZaloAuthenticated, checkZcaAuthenticated, getZaloUserInfo, getZcaUserInfo, listZaloFriendsMatching, listZaloGroupMembers, listZaloGroupsMatching, listZalouserAccountIds, logoutZaloProfile, parseZalouserOutboundTarget, resolveDefaultZalouserAccountId, resolveZaloAllowFromEntries, resolveZaloGroupsByEntries, resolveZalouserAccountSync, sendMessageZalouser, startZaloQrLogin, waitForZaloQrLogin };
|