koishi-plugin-spawn-modified 1.2.6 → 1.2.7
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/lib/index.d.ts +1 -0
- package/lib/index.js +15 -10
- package/package.json +1 -1
- package/src/index.ts +12 -3
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -63,6 +63,7 @@ exports.Config = koishi_1.Schema.object({
|
|
|
63
63
|
encoding: koishi_1.Schema.union(encodings).description('输出内容编码。').default('utf8'),
|
|
64
64
|
timeout: koishi_1.Schema.number().description('最长运行时间。').default(koishi_1.Time.minute),
|
|
65
65
|
renderImage: koishi_1.Schema.boolean().description('是否将命令执行结果渲染为图片(需要安装 puppeteer 插件)。').default(false),
|
|
66
|
+
exemptUsers: koishi_1.Schema.array(String).description('例外用户列表,格式为 "群组ID:用户ID"。私聊时群组ID为0。匹配的用户将无视一切过滤器。').default([]),
|
|
66
67
|
blockedCommands: koishi_1.Schema.array(String).description('违禁命令列表(命令的开头部分)。').default([]),
|
|
67
68
|
restrictDirectory: koishi_1.Schema.boolean().description('是否限制在当前目录及子目录内执行命令(禁止 cd 到上级或其他目录)。').default(false),
|
|
68
69
|
authority: koishi_1.Schema.number().description('exec 命令所需权限等级。').default(4),
|
|
@@ -328,30 +329,34 @@ function apply(ctx, config) {
|
|
|
328
329
|
ctx.i18n.define('zh-CN', require('./locales/zh-CN'));
|
|
329
330
|
ctx.command('exec <command:text>', { authority: (_a = config.authority) !== null && _a !== void 0 ? _a : 4 })
|
|
330
331
|
.action(function (_a, command_1) { return __awaiter(_this, [_a, command_1], void 0, function (_b, command) {
|
|
331
|
-
var filterList, filterMode, sessionId, rootDir, currentDir, cdValidation, pathValidation, timeout, state;
|
|
332
|
+
var guildId, userId, userKey, isExempt, filterList, filterMode, sessionId, rootDir, currentDir, cdValidation, pathValidation, timeout, state;
|
|
332
333
|
var _this = this;
|
|
333
|
-
var _c;
|
|
334
|
+
var _c, _d, _e;
|
|
334
335
|
var session = _b.session;
|
|
335
|
-
return __generator(this, function (
|
|
336
|
-
switch (
|
|
336
|
+
return __generator(this, function (_f) {
|
|
337
|
+
switch (_f.label) {
|
|
337
338
|
case 0:
|
|
338
339
|
if (!command) {
|
|
339
340
|
return [2 /*return*/, session.text('.expect-text')];
|
|
340
341
|
}
|
|
341
342
|
command = (0, koishi_1.h)('', koishi_1.h.parse(command)).toString(true);
|
|
342
|
-
|
|
343
|
+
guildId = session.guildId || '0';
|
|
344
|
+
userId = session.userId || '';
|
|
345
|
+
userKey = "".concat(guildId, ":").concat(userId);
|
|
346
|
+
isExempt = (_d = (_c = config.exemptUsers) === null || _c === void 0 ? void 0 : _c.some(function (entry) { return entry === userKey; })) !== null && _d !== void 0 ? _d : false;
|
|
347
|
+
filterList = (((_e = config.commandList) === null || _e === void 0 ? void 0 : _e.length) ? config.commandList : config.blockedCommands) || [];
|
|
343
348
|
filterMode = config.commandFilterMode || 'blacklist';
|
|
344
|
-
if (isCommandBlocked(command, filterMode, filterList)) {
|
|
349
|
+
if (!isExempt && isCommandBlocked(command, filterMode, filterList)) {
|
|
345
350
|
return [2 /*return*/, session.text('.blocked-command')];
|
|
346
351
|
}
|
|
347
352
|
sessionId = session.uid || session.channelId;
|
|
348
353
|
rootDir = path_1.default.resolve(ctx.baseDir, config.root);
|
|
349
354
|
currentDir = sessionDirs.get(sessionId) || rootDir;
|
|
350
|
-
cdValidation = validateCdCommand(command, currentDir, rootDir, config.restrictDirectory);
|
|
355
|
+
cdValidation = validateCdCommand(command, currentDir, rootDir, !isExempt && config.restrictDirectory);
|
|
351
356
|
if (!cdValidation.valid) {
|
|
352
357
|
return [2 /*return*/, session.text('.restricted-directory')];
|
|
353
358
|
}
|
|
354
|
-
pathValidation = validatePathAccess(command, currentDir, rootDir, config.restrictDirectory);
|
|
359
|
+
pathValidation = validatePathAccess(command, currentDir, rootDir, !isExempt && config.restrictDirectory);
|
|
355
360
|
if (!pathValidation.valid) {
|
|
356
361
|
return [2 /*return*/, session.text('.restricted-path')];
|
|
357
362
|
}
|
|
@@ -360,8 +365,8 @@ function apply(ctx, config) {
|
|
|
360
365
|
if (!!config.renderImage) return [3 /*break*/, 2];
|
|
361
366
|
return [4 /*yield*/, session.send(session.text('.started', state))];
|
|
362
367
|
case 1:
|
|
363
|
-
|
|
364
|
-
|
|
368
|
+
_f.sent();
|
|
369
|
+
_f.label = 2;
|
|
365
370
|
case 2: return [2 /*return*/, new Promise(function (resolve) {
|
|
366
371
|
var start = Date.now();
|
|
367
372
|
var child = (0, child_process_1.exec)(command, {
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -21,6 +21,7 @@ export interface Config {
|
|
|
21
21
|
encoding?: typeof encodings[number]
|
|
22
22
|
timeout?: number
|
|
23
23
|
renderImage?: boolean
|
|
24
|
+
exemptUsers?: string[]
|
|
24
25
|
blockedCommands?: string[]
|
|
25
26
|
restrictDirectory?: boolean
|
|
26
27
|
authority?: number
|
|
@@ -34,6 +35,7 @@ export const Config: Schema<Config> = Schema.object({
|
|
|
34
35
|
encoding: Schema.union(encodings).description('输出内容编码。').default('utf8'),
|
|
35
36
|
timeout: Schema.number().description('最长运行时间。').default(Time.minute),
|
|
36
37
|
renderImage: Schema.boolean().description('是否将命令执行结果渲染为图片(需要安装 puppeteer 插件)。').default(false),
|
|
38
|
+
exemptUsers: Schema.array(String).description('例外用户列表,格式为 "群组ID:用户ID"。私聊时群组ID为0。匹配的用户将无视一切过滤器。').default([]),
|
|
37
39
|
blockedCommands: Schema.array(String).description('违禁命令列表(命令的开头部分)。').default([]),
|
|
38
40
|
restrictDirectory: Schema.boolean().description('是否限制在当前目录及子目录内执行命令(禁止 cd 到上级或其他目录)。').default(false),
|
|
39
41
|
authority: Schema.number().description('exec 命令所需权限等级。').default(4),
|
|
@@ -441,21 +443,28 @@ export function apply(ctx: Context, config: Config) {
|
|
|
441
443
|
}
|
|
442
444
|
|
|
443
445
|
command = h('', h.parse(command)).toString(true)
|
|
446
|
+
|
|
447
|
+
// 检查是否为例外用户(无视一切过滤器)
|
|
448
|
+
const guildId = session.guildId || '0'
|
|
449
|
+
const userId = session.userId || ''
|
|
450
|
+
const userKey = `${guildId}:${userId}`
|
|
451
|
+
const isExempt = config.exemptUsers?.some(entry => entry === userKey) ?? false
|
|
452
|
+
|
|
444
453
|
// 检查命令过滤(黑/白名单);仅使用配置提供的正则
|
|
445
454
|
const filterList = (config.commandList?.length ? config.commandList : config.blockedCommands) || []
|
|
446
455
|
const filterMode = config.commandFilterMode || 'blacklist'
|
|
447
|
-
if (isCommandBlocked(command, filterMode, filterList)) {
|
|
456
|
+
if (!isExempt && isCommandBlocked(command, filterMode, filterList)) {
|
|
448
457
|
return session.text('.blocked-command')
|
|
449
458
|
}
|
|
450
459
|
const sessionId = session.uid || session.channelId
|
|
451
460
|
const rootDir = path.resolve(ctx.baseDir, config.root)
|
|
452
461
|
const currentDir = sessionDirs.get(sessionId) || rootDir
|
|
453
462
|
// 验证 cd 命令
|
|
454
|
-
const cdValidation = validateCdCommand(command, currentDir, rootDir, config.restrictDirectory)
|
|
463
|
+
const cdValidation = validateCdCommand(command, currentDir, rootDir, !isExempt && config.restrictDirectory)
|
|
455
464
|
if (!cdValidation.valid) {
|
|
456
465
|
return session.text('.restricted-directory')
|
|
457
466
|
}
|
|
458
|
-
const pathValidation = validatePathAccess(command, currentDir, rootDir, config.restrictDirectory)
|
|
467
|
+
const pathValidation = validatePathAccess(command, currentDir, rootDir, !isExempt && config.restrictDirectory)
|
|
459
468
|
if (!pathValidation.valid) {
|
|
460
469
|
return session.text('.restricted-path')
|
|
461
470
|
}
|