@modesto_ma/dsh-channels 0.5.0-beta.6 → 0.5.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/README.md +7 -6
- package/lib/client.js.map +1 -1
- package/lib/index.js +42 -15
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/access/cards.ts +5 -1
- package/src/access/controller.ts +14 -6
- package/src/access/policy.ts +7 -2
- package/src/access/requests.ts +1 -0
- package/src/config.ts +9 -2
- package/src/domain.ts +2 -2
- package/src/service.ts +1 -0
- package/src/settings/contract.ts +1 -0
- package/src/settings/surface.ts +8 -1
package/lib/index.js
CHANGED
|
@@ -37,10 +37,16 @@ function decideAccess(subject, config, snapshot) {
|
|
|
37
37
|
kind: "allow",
|
|
38
38
|
reason: "admin"
|
|
39
39
|
};
|
|
40
|
-
if (subject.chatType === "p2p")
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
if (subject.chatType === "p2p") {
|
|
41
|
+
if (config.dmAllowWhitelist && snapshot.users.has(subject.senderId)) return {
|
|
42
|
+
kind: "allow",
|
|
43
|
+
reason: "authorized-user"
|
|
44
|
+
};
|
|
45
|
+
return {
|
|
46
|
+
kind: "deny",
|
|
47
|
+
reason: "dm-non-admin"
|
|
48
|
+
};
|
|
49
|
+
}
|
|
44
50
|
if (!snapshot.groups.has(subject.chatId)) return {
|
|
45
51
|
kind: "deny",
|
|
46
52
|
reason: "group-not-authorized",
|
|
@@ -60,6 +66,8 @@ function decideAccess(subject, config, snapshot) {
|
|
|
60
66
|
//#region src/access/controller.ts
|
|
61
67
|
/** Fixed private-chat notice for non-administrators (no model call). */
|
|
62
68
|
const DM_DENY_TEXT = "非管理员禁用私聊功能哦~如需使用,请在管理员授权的群里 @ 我;或联系管理员把你的 user_id 加入白名单。";
|
|
69
|
+
/** Fixed private-chat notice for non-whitelisted users while `dmAllowWhitelist` is on. */
|
|
70
|
+
const DM_DENY_WHITELIST_TEXT = "你还不在白名单里,暂时不能私聊哦~发送 /userid 查看你的 user_id,请管理员加入白名单后即可使用。";
|
|
63
71
|
/** Fixed private-chat notice while no administrator is configured. */
|
|
64
72
|
const DM_UNCONFIGURED_TEXT = "机器人尚未配置管理员。发送 /userid 可查看你的 user_id,交给部署者配置后即可启用。";
|
|
65
73
|
/** Per-sender cooldown for the repeated private-chat notice (10 s). */
|
|
@@ -122,8 +130,9 @@ var AccessController = class {
|
|
|
122
130
|
/**
|
|
123
131
|
* Slash-command admission. Runs before any command card/topic/Session side
|
|
124
132
|
* effect. `open` mode keeps the legacy behavior; otherwise private chats
|
|
125
|
-
*
|
|
126
|
-
* group chats must pass the full admission
|
|
133
|
+
* admit whoever the admission matrix admits (with `/userid` as the
|
|
134
|
+
* bootstrap exception) and group chats must pass the full admission
|
|
135
|
+
* matrix; the administrator is
|
|
127
136
|
* never constrained by the whitelists, so all of their commands pass even
|
|
128
137
|
* inside an unauthorized group (`/auth` is the in-conversation grant
|
|
129
138
|
* entry).
|
|
@@ -133,7 +142,7 @@ var AccessController = class {
|
|
|
133
142
|
try {
|
|
134
143
|
if (msg.chatType === "p2p") {
|
|
135
144
|
if (commandName === "userid") return true;
|
|
136
|
-
if (this.
|
|
145
|
+
if (this.decide(msg).kind === "allow") return true;
|
|
137
146
|
await this.noticeDeniedDm(msg);
|
|
138
147
|
return false;
|
|
139
148
|
}
|
|
@@ -195,7 +204,8 @@ var AccessController = class {
|
|
|
195
204
|
const last = this.dmNoticeAt.get(msg.senderId);
|
|
196
205
|
if (last !== void 0 && now - last < DM_NOTICE_COOLDOWN_MS) return;
|
|
197
206
|
this.dmNoticeAt.set(msg.senderId, now);
|
|
198
|
-
const
|
|
207
|
+
const config = this.config();
|
|
208
|
+
const text = config.adminUserId === void 0 ? DM_UNCONFIGURED_TEXT : config.dmAllowWhitelist ? DM_DENY_WHITELIST_TEXT : DM_DENY_TEXT;
|
|
199
209
|
await this.sendText(msg.chatId, text, msg.messageId);
|
|
200
210
|
}
|
|
201
211
|
/** Best-effort fixed-text send; unavailable channel/failures only warn. */
|
|
@@ -400,7 +410,7 @@ function buildUserRequestCard(input) {
|
|
|
400
410
|
} else if (input.chatId !== void 0 && input.chatId !== "") elements.push(field("所在群", `\`${input.chatId}\``));
|
|
401
411
|
elements.push(field("申请时间", formatTime(input.now)));
|
|
402
412
|
elements.push(divider());
|
|
403
|
-
elements.push(note("授权后该用户可在所有已授权群里使用;私聊仍仅管理员可用。"));
|
|
413
|
+
elements.push(note(input.dmAllowWhitelist === true ? "授权后该用户可在所有已授权群里使用,也可以私聊机器人。" : "授权后该用户可在所有已授权群里使用;私聊仍仅管理员可用。"));
|
|
404
414
|
elements.push(decisionButtons(input.token, "授权用户", "忽略"));
|
|
405
415
|
return standaloneCard("**🙋 用户授权申请**", elements);
|
|
406
416
|
}
|
|
@@ -733,6 +743,7 @@ var AccessRequests = class {
|
|
|
733
743
|
...groupName === void 0 ? {} : { groupName },
|
|
734
744
|
...msg.senderName === void 0 ? {} : { requesterName: msg.senderName },
|
|
735
745
|
token: record.token,
|
|
746
|
+
dmAllowWhitelist: this.config().dmAllowWhitelist,
|
|
736
747
|
now
|
|
737
748
|
}), record);
|
|
738
749
|
return true;
|
|
@@ -1235,8 +1246,8 @@ const accessGroupRecordSchema = z.object({
|
|
|
1235
1246
|
});
|
|
1236
1247
|
/**
|
|
1237
1248
|
* One authorized user (`user_id`), global across every authorized group.
|
|
1238
|
-
* Private chats are administrator-only
|
|
1239
|
-
* conversations.
|
|
1249
|
+
* Private chats are administrator-only unless `dmAllowWhitelist` is on, so
|
|
1250
|
+
* by default this grant only affects group conversations.
|
|
1240
1251
|
*/
|
|
1241
1252
|
const accessUserRecordSchema = z.object({
|
|
1242
1253
|
/** Feishu `user_id` — also the table key. */
|
|
@@ -16269,14 +16280,21 @@ const configSchema = z.object({
|
|
|
16269
16280
|
* Admission policy for inbound Feishu traffic.
|
|
16270
16281
|
*
|
|
16271
16282
|
* - `guarded` (default): only the configured administrator can talk in
|
|
16272
|
-
* private chats
|
|
16273
|
-
*
|
|
16283
|
+
* private chats (plus whitelisted users when `dmAllowWhitelist` is on),
|
|
16284
|
+
* and a group conversation additionally requires the group to be
|
|
16285
|
+
* authorized and the sender to be the administrator or an explicitly
|
|
16274
16286
|
* authorized user.
|
|
16275
16287
|
* - `open`: legacy behavior — any user inside the app's availability scope
|
|
16276
16288
|
* can start a conversation. Debug/compatibility only; unsafe.
|
|
16277
16289
|
*/
|
|
16278
16290
|
accessMode: z.enum(["open", "guarded"]).default("guarded"),
|
|
16279
16291
|
/**
|
|
16292
|
+
* In `guarded` mode, also admit users on the global user whitelist
|
|
16293
|
+
* (`/auth user`) in private chats. Off by default: private chats stay
|
|
16294
|
+
* administrator-only. Each private-chat user already has an own workspace.
|
|
16295
|
+
*/
|
|
16296
|
+
dmAllowWhitelist: z.boolean().default(false),
|
|
16297
|
+
/**
|
|
16280
16298
|
* The unique administrator's Feishu `user_id`. Set it in the Web
|
|
16281
16299
|
* settings panel (or the profile config). Get it by sending `/userid` to the
|
|
16282
16300
|
* bot in a private chat. When unset, the Feishu app owner (looked up via
|
|
@@ -16436,6 +16454,7 @@ const EDITABLE_KEYS = [
|
|
|
16436
16454
|
"feishuTools.topicMessagesTimeoutMs",
|
|
16437
16455
|
"promptContextTimeoutMs",
|
|
16438
16456
|
"accessMode",
|
|
16457
|
+
"dmAllowWhitelist",
|
|
16439
16458
|
"adminUserId",
|
|
16440
16459
|
"authRequestTtlDays",
|
|
16441
16460
|
"feishuTools.wikiRead",
|
|
@@ -18503,6 +18522,7 @@ var FeishuService = class {
|
|
|
18503
18522
|
await this.delivery.standaloneReply(msg, standaloneInfoCard("**🔐 访问授权状态**", [
|
|
18504
18523
|
`**准入模式**:\`${this.config.accessMode}\``,
|
|
18505
18524
|
`**管理员**:${this.adminStatusLine()}`,
|
|
18525
|
+
`**私聊**:${this.config.dmAllowWhitelist ? "管理员与白名单用户" : "仅管理员"}`,
|
|
18506
18526
|
...msg.chatType === "group" ? [`**本群**:${this.accessStore.hasGroup(msg.chatId) ? "已授权" : "未授权"}(\`${msg.chatId}\`)`] : [],
|
|
18507
18527
|
`**白名单**:群 ${groups.length} 个 · 用户 ${users.length} 个 · 知识库 ${this.accessStore.wikiUserRecords().length} 个 · 待处理申请 ${pending.length} 个`,
|
|
18508
18528
|
"群授权:`/auth allow` 或 `/auth revoke`(在目标群内发);用户授权:`/auth user add @用户` 或 `/auth user add <user_id>`;知识库授权:`/auth wiki add @用户`。"
|
|
@@ -20060,6 +20080,7 @@ const BOOLEAN_KEYS = /* @__PURE__ */ new Set([
|
|
|
20060
20080
|
"welcomeOnboarding",
|
|
20061
20081
|
"slashCommandPanel",
|
|
20062
20082
|
"allowPermissionSwitch",
|
|
20083
|
+
"dmAllowWhitelist",
|
|
20063
20084
|
"acceptAttachments",
|
|
20064
20085
|
"prefetchImages",
|
|
20065
20086
|
"feishuTools.attachmentFetch",
|
|
@@ -20463,7 +20484,13 @@ const FIELD_META = {
|
|
|
20463
20484
|
label: "调试模式",
|
|
20464
20485
|
group: "access",
|
|
20465
20486
|
summary: "打开后所有人都能聊,不安全,只在调试时用",
|
|
20466
|
-
help: "
|
|
20487
|
+
help: "关闭时(默认):管理员随时可用;非管理员私聊会被拒绝(打开「白名单用户可私聊」后白名单用户也可以);群聊要同时满足群已授权、发言人在用户白名单里。授权入口有三个:群里 /auth 命令、授权卡、本页。撤销立即生效。"
|
|
20488
|
+
},
|
|
20489
|
+
dmAllowWhitelist: {
|
|
20490
|
+
label: "白名单用户可私聊",
|
|
20491
|
+
group: "access",
|
|
20492
|
+
summary: "关闭时私聊仅管理员可用",
|
|
20493
|
+
help: "打开后「已授权用户」里的人也可以私聊机器人,各自使用独立的私聊工作区,能力与群聊相同;不在白名单的人仍收到固定提示。撤销用户立即生效。"
|
|
20467
20494
|
},
|
|
20468
20495
|
adminUserId: {
|
|
20469
20496
|
label: "管理员 user_id",
|
|
@@ -21617,6 +21644,6 @@ function apply(ctx, config) {
|
|
|
21617
21644
|
}, "dsh-channels");
|
|
21618
21645
|
}
|
|
21619
21646
|
//#endregion
|
|
21620
|
-
export { AUTH_USER_TARGET_ERRORS, AccessController, AccessRequests, AccessStore, ApprovalAnswerer, CARD_MAX_BYTES, CARD_TARGET_BYTES, CATALOG_ROUTE, CHANNEL_COMMAND_NAMES, CONFIG_ROUTE, CREDENTIALS_ROUTE, Config, DM_DENY_TEXT, DM_UNCONFIGURED_TEXT, DSH_CHANNELS_VERSION, EDITABLE_KEYS, EMPTY_TOTALS, FIELD_DESCRIPTORS, FeishuService, HEALTH_DEPENDENCY_NAMES, INTERRUPTION_NOTICE, LOGICAL_EXPORT_FORMAT, LOGICAL_EXPORT_FORMAT_VERSION, MAX_QUESTION_OPTIONS, MAX_TABLES_PER_CARD, OverlayStore, PANEL_CHEVRON_TOKEN, PANEL_COPY, PANEL_ROUTE, PANEL_TITLES, PICK_DIRECTORY_ROUTE, QuestionAnswerer, REASONING_MAX_BYTES, RECONNECT_ROUTE, RESTART_KEYS, RouteOperationQueue, SESSION_HISTORY_DISPLAY_LIMIT, STATUS_ROUTE, SUPPORTED_COMMAND_NAMES, SettingsSurface, TRUNCATION_SUFFIX, TurnStreamer, accessGroupRecordSchema, accessRequestRecordSchema, accessUserRecordSchema, addUsage, appendSessionHistory, apply, applyCatalog, applyProjectionViews, armModelCommand, averageDecodeTokensPerSecond, averageTtftMs, buildApprovalCard, buildApprovalSettledCard, buildCard, buildCommandResultCard, buildCompactComparisonCard, buildGroupInfoCard, buildHealthCard, buildInterruptionCard, buildQuestionCard, buildQuestionSettledCard, buildRenewCard, buildRequestSettledCard, buildSessionHistoryCard, buildSessionStatusCard, buildUserRequestCard, buildWorkDirCard, cacheHitPct, cardJsonBytes, chatRouteKey, commandResultCardKind, compactFailureContext, countFiberStates, createHostCatalog, createLogicalSessionExport, createSettingsDirectoryPicker, decideAccess, defaultOverlayPath, emptyCatalog, ensureWorkspace, expiredRouteRecordSchema, feishuDomain, foldAll, foldEvent, foldHealthSnapshot, foldSessionStats, inflightSnapshotSchema, inject, isAdminUserId, isSameOriginRequest, isSupportedCommand, maskOpenIdTail, measureSessionContext, mergeOverlay, mountSettingsRoutes, name, normalizeCredentialValue, normalizeOverlay, normalizeRouteRecord, normalizeSessionHistory, parseOverlay, parseSlashCommand, pickEditable, processedRecordSchema, querySessionHistory, readProjectionViews, registerChannelCommands, registerModelCommand, registerSettingsRoutes, resolveAuthUserTarget, resolveDshHome, resolveWorkDir, routeRecordSchema, segmentCardContent, serializeLogicalSession, sessionDirOf, sessionHistoryEntrySchema, splitBodyForCard, stagingPathFor, stagingRoot, stripTables, supportedCommandHelp, supportedCommandList, tableBlocks, topicDirFor, topicTokenFor, usageFromBuckets, withDirectoryBrowse, workspacePathFor, workspaceTitleFor, worktreeBranchFor };
|
|
21647
|
+
export { AUTH_USER_TARGET_ERRORS, AccessController, AccessRequests, AccessStore, ApprovalAnswerer, CARD_MAX_BYTES, CARD_TARGET_BYTES, CATALOG_ROUTE, CHANNEL_COMMAND_NAMES, CONFIG_ROUTE, CREDENTIALS_ROUTE, Config, DM_DENY_TEXT, DM_DENY_WHITELIST_TEXT, DM_UNCONFIGURED_TEXT, DSH_CHANNELS_VERSION, EDITABLE_KEYS, EMPTY_TOTALS, FIELD_DESCRIPTORS, FeishuService, HEALTH_DEPENDENCY_NAMES, INTERRUPTION_NOTICE, LOGICAL_EXPORT_FORMAT, LOGICAL_EXPORT_FORMAT_VERSION, MAX_QUESTION_OPTIONS, MAX_TABLES_PER_CARD, OverlayStore, PANEL_CHEVRON_TOKEN, PANEL_COPY, PANEL_ROUTE, PANEL_TITLES, PICK_DIRECTORY_ROUTE, QuestionAnswerer, REASONING_MAX_BYTES, RECONNECT_ROUTE, RESTART_KEYS, RouteOperationQueue, SESSION_HISTORY_DISPLAY_LIMIT, STATUS_ROUTE, SUPPORTED_COMMAND_NAMES, SettingsSurface, TRUNCATION_SUFFIX, TurnStreamer, accessGroupRecordSchema, accessRequestRecordSchema, accessUserRecordSchema, addUsage, appendSessionHistory, apply, applyCatalog, applyProjectionViews, armModelCommand, averageDecodeTokensPerSecond, averageTtftMs, buildApprovalCard, buildApprovalSettledCard, buildCard, buildCommandResultCard, buildCompactComparisonCard, buildGroupInfoCard, buildHealthCard, buildInterruptionCard, buildQuestionCard, buildQuestionSettledCard, buildRenewCard, buildRequestSettledCard, buildSessionHistoryCard, buildSessionStatusCard, buildUserRequestCard, buildWorkDirCard, cacheHitPct, cardJsonBytes, chatRouteKey, commandResultCardKind, compactFailureContext, countFiberStates, createHostCatalog, createLogicalSessionExport, createSettingsDirectoryPicker, decideAccess, defaultOverlayPath, emptyCatalog, ensureWorkspace, expiredRouteRecordSchema, feishuDomain, foldAll, foldEvent, foldHealthSnapshot, foldSessionStats, inflightSnapshotSchema, inject, isAdminUserId, isSameOriginRequest, isSupportedCommand, maskOpenIdTail, measureSessionContext, mergeOverlay, mountSettingsRoutes, name, normalizeCredentialValue, normalizeOverlay, normalizeRouteRecord, normalizeSessionHistory, parseOverlay, parseSlashCommand, pickEditable, processedRecordSchema, querySessionHistory, readProjectionViews, registerChannelCommands, registerModelCommand, registerSettingsRoutes, resolveAuthUserTarget, resolveDshHome, resolveWorkDir, routeRecordSchema, segmentCardContent, serializeLogicalSession, sessionDirOf, sessionHistoryEntrySchema, splitBodyForCard, stagingPathFor, stagingRoot, stripTables, supportedCommandHelp, supportedCommandList, tableBlocks, topicDirFor, topicTokenFor, usageFromBuckets, withDirectoryBrowse, workspacePathFor, workspaceTitleFor, worktreeBranchFor };
|
|
21621
21648
|
|
|
21622
21649
|
//# sourceMappingURL=index.js.map
|