Skip to content

Commit 2afb4a5

Browse files
committed
fix(koishi): mount the command permission gate under inject so it follows the permission service
1 parent 4690be6 commit 2afb4a5

3 files changed

Lines changed: 121 additions & 43 deletions

File tree

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@chatluna/patchbay",
3-
"version": "0.1.2",
3+
"version": "0.1.3",
44
"description": "Cordis 4 patches for Koishi, Satori, Satori adapters and Cordis plugins, wired into yarn, pnpm or npm",
55
"type": "module",
66
"license": "MIT",

‎patchbay.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
"description": "Run Koishi on Cordis 4; also installed as koishi. Inject shapes are normalized by the @satorijs/core patch",
4141
"fixes": [
4242
"ChatLunaLab/boilerplate#12",
43-
"ChatLunaLab/v2-mirror#28"
43+
"ChatLunaLab/v2-mirror#28",
44+
"ChatLunaLab/v2-mirror#111"
4445
],
4546
"dependencies": {
4647
"cordis": "^4.0.0-rc.8"

‎patches/@koishijs+core@4.18.11.patch‎

Lines changed: 118 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ index b0e0826..004cff1 100644
292292
+export * from '@cordisjs/plugin-database';
293293
export { version };
294294
diff --git a/lib/index.mjs b/lib/index.mjs
295-
index b99cd02..cbac35c 100644
295+
index b99cd02..ddbf1bf 100644
296296
--- a/lib/index.mjs
297297
+++ b/lib/index.mjs
298298
@@ -2,16 +2,120 @@ var __defProp = Object.defineProperty;
@@ -691,27 +691,51 @@ index b99cd02..cbac35c 100644
691691
return this;
692692
}
693693
/** @deprecated */
694-
@@ -1095,7 +1231,9 @@ __name(toStringType, "toStringType");
694+
@@ -1095,6 +1231,43 @@ __name(toStringType, "toStringType");
695695
// src/command/validate.ts
696696
import { isNullable as isNullable2 } from "cosmokit";
697697
function validate(ctx) {
698-
- ctx.permissions.define("command:(name)", {
699-
+ const permissions = ctx.get("permissions", false);
700-
+ if (!permissions) return;
701-
+ permissions.define("command:(name)", {
698+
+ // patchbay: the gate comes and goes with the permission service, whichever loads first and across its reloads.
699+
+ ctx.inject(["permissions"], (ctx2) => validatePermissions(ctx2));
700+
+ ctx.before("command/execute", async (argv) => {
701+
+ const { args, options, command, session } = argv;
702+
+ function sendHint(message, ...param) {
703+
+ return command.config.showWarning ? session.text(message, param) : "";
704+
+ }
705+
+ __name(sendHint, "sendHint");
706+
+ if (command.config.checkArgCount) {
707+
+ let index = args.length;
708+
+ while (command._arguments[index]?.required) {
709+
+ const decl = command._arguments[index];
710+
+ await session.send(session.text("internal.prompt-argument", [
711+
+ session.text(`commands.${command.name}.arguments.${decl.name}`)
712+
+ ]));
713+
+ const source = await session.prompt();
714+
+ if (isNullable2(source)) {
715+
+ return sendHint("internal.insufficient-arguments", decl.name);
716+
+ }
717+
+ args.push(ctx.$commander.parseValue(source, "argument", argv, decl));
718+
+ index++;
719+
+ }
720+
+ const finalArg = command._arguments[command._arguments.length - 1] || {};
721+
+ if (args.length > command._arguments.length && !finalArg.variadic) {
722+
+ return sendHint("internal.redunant-arguments");
723+
+ }
724+
+ }
725+
+ if (command.config.checkUnknown) {
726+
+ const unknown = Object.keys(options).filter((key) => !command._options[key]);
727+
+ if (unknown.length) {
728+
+ return sendHint("internal.unknown-option", unknown.join(", "));
729+
+ }
730+
+ }
731+
+ }, true);
732+
+}
733+
+__name(validate, "validate");
734+
+function validatePermissions(ctx) {
735+
ctx.permissions.define("command:(name)", {
702736
depends: /* @__PURE__ */ __name(({ name }) => {
703737
const command = ctx.$commander.get(name);
704-
if (!command) return;
705-
@@ -1110,7 +1248,7 @@ function validate(ctx) {
706-
return ctx.$commander._commandList.map((command) => `command:${command.name}`);
707-
}, "list")
708-
});
709-
- ctx.permissions.define("command:(name):option:(name2)", {
710-
+ permissions.define("command:(name):option:(name2)", {
711-
depends: /* @__PURE__ */ __name(({ name, name2 }) => {
712-
return ctx.$commander.get(name)?._options[name2]?.dependencies;
713-
}, "depends"),
714-
@@ -1130,13 +1268,13 @@ function validate(ctx) {
738+
@@ -1130,50 +1303,19 @@ function validate(ctx) {
715739
return command.config.showWarning ? session.text(message, param) : "";
716740
}
717741
__name(sendHint, "sendHint");
@@ -720,15 +744,55 @@ index b99cd02..cbac35c 100644
720744
for (const option of Object.values(command._options)) {
721745
if (option.name in options) {
722746
- permissions.push(`command:${command.name}:option:${option.name}`);
747+
- }
748+
- }
749+
- if (!await ctx.permissions.test(permissions, session)) {
750+
- return sendHint("internal.low-authority");
751+
- }
752+
- }, true);
753+
- ctx.before("command/execute", async (argv) => {
754+
- const { args, options, command, session } = argv;
755+
- function sendHint(message, ...param) {
756+
- return command.config.showWarning ? session.text(message, param) : "";
757+
- }
758+
- __name(sendHint, "sendHint");
759+
- if (command.config.checkArgCount) {
760+
- let index = args.length;
761+
- while (command._arguments[index]?.required) {
762+
- const decl = command._arguments[index];
763+
- await session.send(session.text("internal.prompt-argument", [
764+
- session.text(`commands.${command.name}.arguments.${decl.name}`)
765+
- ]));
766+
- const source = await session.prompt();
767+
- if (isNullable2(source)) {
768+
- return sendHint("internal.insufficient-arguments", decl.name);
769+
- }
770+
- args.push(ctx.$commander.parseValue(source, "argument", argv, decl));
771+
- index++;
772+
- }
773+
- const finalArg = command._arguments[command._arguments.length - 1] || {};
774+
- if (args.length > command._arguments.length && !finalArg.variadic) {
775+
- return sendHint("internal.redunant-arguments");
723776
+ required.push(`command:${command.name}:option:${option.name}`);
724777
}
725778
}
726-
- if (!await ctx.permissions.test(permissions, session)) {
727-
+ if (!await permissions.test(required, session)) {
728-
return sendHint("internal.low-authority");
779+
- if (command.config.checkUnknown) {
780+
- const unknown = Object.keys(options).filter((key) => !command._options[key]);
781+
- if (unknown.length) {
782+
- return sendHint("internal.unknown-option", unknown.join(", "));
783+
- }
784+
+ if (!await ctx.permissions.test(required, session)) {
785+
+ const level = command.config.permissions?.map((name) => /^authority:(\d+)$/.exec(name)?.[1]).find(Boolean);
786+
+ return level === void 0 ? sendHint("internal.low-authority") : sendHint("internal.low-authority-level", command.displayName, level);
729787
}
730788
}, true);
731-
@@ -1182,7 +1320,7 @@ var Commander = class {
789+
}
790+
-__name(validate, "validate");
791+
+__name(validatePermissions, "validatePermissions");
792+
793+
// src/command/index.ts
794+
var isArray = Array.isArray;
795+
@@ -1182,7 +1324,7 @@ var Commander = class {
732796
constructor(ctx, config = {}) {
733797
this.ctx = ctx;
734798
this.config = config;
@@ -737,7 +801,7 @@ index b99cd02..cbac35c 100644
737801
ctx.plugin(validate);
738802
ctx.before("parse", (content, session) => {
739803
const { isDirect, stripped: { prefix, appel } } = session;
740-
@@ -1255,7 +1393,7 @@ var Commander = class {
804+
@@ -1255,7 +1397,7 @@ var Commander = class {
741805
permissions: Schema2.array(String).role("perms").default(["authority:0"]).description("权限继承。"),
742806
dependencies: Schema2.array(String).role("perms").description("权限依赖。")
743807
}), 1e3);
@@ -746,7 +810,7 @@ index b99cd02..cbac35c 100644
746810
const bots = ctx.bots.filter((v) => v.status === Universal3.Status.ONLINE && v.updateCommands);
747811
bots.forEach((bot) => this.updateCommands(bot));
748812
});
749-
@@ -1334,6 +1472,8 @@ var Commander = class {
813+
@@ -1334,6 +1476,8 @@ var Commander = class {
750814
static {
751815
__name(this, "Commander");
752816
}
@@ -755,7 +819,7 @@ index b99cd02..cbac35c 100644
755819
_commandList = [];
756820
defineElementDomain(name, key = name, type = name) {
757821
this.domain(name, (source, session) => {
758-
@@ -1456,13 +1596,14 @@ var Commander = class {
822+
@@ -1456,13 +1600,14 @@ var Commander = class {
759823
});
760824
Object.assign(parent.config, config);
761825
created.forEach((command) => this.ctx.emit("command-added", command));
@@ -773,7 +837,20 @@ index b99cd02..cbac35c 100644
773837
return this.ctx.set(service, { transform, ...options });
774838
}
775839
resolveDomain(type) {
776-
@@ -1570,6 +1711,8 @@ var I18n = class {
840+
@@ -1533,10 +1678,10 @@ import { fallback, LocaleTree } from "@koishijs/i18n-utils";
841+
import { h as h4, Logger as Logger2, Schema as Schema3 } from "@satorijs/core";
842+
843+
// src/locales/zh-CN.yml
844+
-var zh_CN_default = { general: { $: "通用设置", name: "中文", paren: "({0})", quote: "“{0}”", comma: ",", and: "和", or: "或", day: "天", hour: "小时", minute: "分钟", second: "秒" }, internal: { $: "核心文本", "error-encountered": "发生未知错误。", "low-authority": "权限不足。", "prompt-argument": "请发送{0}。", "insufficient-arguments": "缺少参数,输入帮助以查看用法。", "redunant-arguments": "存在多余参数,输入帮助以查看用法。", "invalid-argument": "参数 {0} 输入无效,{1}", "unknown-option": "存在未知选项 {0},输入帮助以查看用法。", "invalid-option": "选项 {0} 输入无效,{1}", "check-syntax": "输入帮助以查看用法。", "invalid-number": "请提供一个数字。", "invalid-integer": "请提供一个整数。", "invalid-posint": "请提供一个正整数。", "invalid-natural": "请提供一个非负整数。", "invalid-date": "请输入合法的时间。", "invalid-user": "请指定正确的用户。", "invalid-channel": "请指定正确的频道。", "invalid-image": "请上传图片。", "invalid-audio": "请上传音频。", "invalid-video": "请上传视频。", "invalid-file": "请上传文件。", "suggest-hint": "您要找的是不是{0}?", "suggest-command": "回复句号以使用推测的指令。" }, commands: { $: "指令系统" } };
845+
+var zh_CN_default = { general: { $: "通用设置", name: "中文", paren: "({0})", quote: "“{0}”", comma: ",", and: "和", or: "或", day: "天", hour: "小时", minute: "分钟", second: "秒" }, internal: { $: "核心文本", "error-encountered": "发生未知错误。", "low-authority": "权限不足。", "low-authority-level": "权限不足:{0} 需要 {1} 级权限。", "prompt-argument": "请发送{0}。", "insufficient-arguments": "缺少参数,输入帮助以查看用法。", "redunant-arguments": "存在多余参数,输入帮助以查看用法。", "invalid-argument": "参数 {0} 输入无效,{1}", "unknown-option": "存在未知选项 {0},输入帮助以查看用法。", "invalid-option": "选项 {0} 输入无效,{1}", "check-syntax": "输入帮助以查看用法。", "invalid-number": "请提供一个数字。", "invalid-integer": "请提供一个整数。", "invalid-posint": "请提供一个正整数。", "invalid-natural": "请提供一个非负整数。", "invalid-date": "请输入合法的时间。", "invalid-user": "请指定正确的用户。", "invalid-channel": "请指定正确的频道。", "invalid-image": "请上传图片。", "invalid-audio": "请上传音频。", "invalid-video": "请上传视频。", "invalid-file": "请上传文件。", "suggest-hint": "您要找的是不是{0}?", "suggest-command": "回复句号以使用推测的指令。" }, commands: { $: "指令系统" } };
846+
847+
// src/locales/en-US.yml
848+
-var en_US_default = { general: { $: "General Settings", name: "English", paren: " ({0}) ", quote: '"{0}"', comma: ",", and: "and", or: "or", day: "day", hour: "hour", minute: "minute", second: "second" }, internal: { $: "Internal Text", "error-encountered": "An unknown error has occurred.", "low-authority": "Low authority.", "prompt-argument": "请发送{0}。", "insufficient-arguments": "Insufficient arguments, type help to see usage.", "redunant-arguments": "Redunant arguments, type help to see usage.", "invalid-argument": "Invalid argument {0}, {1}", "unknown-option": "Unknown option {0}, type help to see usage.", "invalid-option": "Invalid option {0}, {1}", "check-syntax": "Type help to see usage.", "invalid-number": "Expect a number.", "invalid-integer": "Expect an integer.", "invalid-posint": "Expect a positive integer.", "invalid-natural": "Expect a non-negative integer.", "invalid-date": "Expect a valid date.", "invalid-user": "Expect a valid user.", "invalid-channel": "Expect a valid channel.", "invalid-image": "Expect an image.", "invalid-audio": "Expect an audio.", "invalid-video": "Expect a video.", "invalid-file": "Expect a file.", "suggest-hint": "Do you mean {0}?", "suggest-command": "Send a period to apply the suggestion." }, commands: { $: "Command System" } };
849+
+var en_US_default = { general: { $: "General Settings", name: "English", paren: " ({0}) ", quote: '"{0}"', comma: ",", and: "and", or: "or", day: "day", hour: "hour", minute: "minute", second: "second" }, internal: { $: "Internal Text", "error-encountered": "An unknown error has occurred.", "low-authority": "Low authority.", "low-authority-level": "Low authority: {0} needs level {1}.", "prompt-argument": "请发送{0}。", "insufficient-arguments": "Insufficient arguments, type help to see usage.", "redunant-arguments": "Redunant arguments, type help to see usage.", "invalid-argument": "Invalid argument {0}, {1}", "unknown-option": "Unknown option {0}, type help to see usage.", "invalid-option": "Invalid option {0}, {1}", "check-syntax": "Type help to see usage.", "invalid-number": "Expect a number.", "invalid-integer": "Expect an integer.", "invalid-posint": "Expect a positive integer.", "invalid-natural": "Expect a non-negative integer.", "invalid-date": "Expect a valid date.", "invalid-user": "Expect a valid user.", "invalid-channel": "Expect a valid channel.", "invalid-image": "Expect an image.", "invalid-audio": "Expect an audio.", "invalid-video": "Expect a video.", "invalid-file": "Expect a file.", "suggest-hint": "Do you mean {0}?", "suggest-command": "Send a period to apply the suggestion." }, commands: { $: "Command System" } };
850+
851+
// src/i18n.ts
852+
var logger2 = new Logger2("i18n");
853+
@@ -1570,6 +1715,8 @@ var I18n = class {
777854
static {
778855
__name(this, "I18n");
779856
}
@@ -782,7 +859,7 @@ index b99cd02..cbac35c 100644
782859
_data = {};
783860
_presets = {};
784861
locales;
785-
@@ -1613,7 +1756,7 @@ var I18n = class {
862+
@@ -1613,7 +1760,7 @@ var I18n = class {
786863
const dict = this._data[locale] ||= {};
787864
const paths = [...typeof args[0] === "string" ? this.set(locale, args[0] + ".", args[1]) : this.set(locale, "", args[0])];
788865
this.ctx.emit("internal/i18n");
@@ -791,7 +868,7 @@ index b99cd02..cbac35c 100644
791868
for (const path2 of paths) {
792869
delete dict[path2];
793870
}
794-
@@ -1680,7 +1823,7 @@ var I18n = class {
871+
@@ -1680,7 +1827,7 @@ var I18n = class {
795872
import { observe } from "@koishijs/utils";
796873
import { isNullable as isNullable4, makeArray as makeArray2 } from "cosmokit";
797874
import { h as h5, Logger as Logger3 } from "@satorijs/core";
@@ -800,7 +877,7 @@ index b99cd02..cbac35c 100644
800877
var logger3 = new Logger3("session");
801878
function collectFields(argv, collectors, fields) {
802879
for (const collector of collectors) {
803-
@@ -1700,7 +1843,8 @@ var KoishiSession = class {
880+
@@ -1700,7 +1847,8 @@ var KoishiSession = class {
804881
__name(this, "KoishiSession");
805882
}
806883
constructor(ctx) {
@@ -810,7 +887,7 @@ index b99cd02..cbac35c 100644
810887
resolve: "session.resolve",
811888
stripped: "session.stripped",
812889
username: "session.username",
813-
@@ -1969,7 +2113,7 @@ var KoishiSession = class {
890+
@@ -1969,7 +2117,7 @@ var KoishiSession = class {
814891
}
815892
}
816893
const { command } = argv;
@@ -819,7 +896,7 @@ index b99cd02..cbac35c 100644
819896
if (this.app.database) {
820897
if (!this.isDirect) {
821898
await this.observeChannel(this.collect("channel", argv, /* @__PURE__ */ new Set(["permissions", "locales"])));
822-
@@ -2058,8 +2202,7 @@ var logger4 = new Logger4("app");
899+
@@ -2058,8 +2206,7 @@ var logger4 = new Logger4("app");
823900
var Permissions = class {
824901
constructor(ctx) {
825902
this.ctx = ctx;
@@ -829,7 +906,7 @@ index b99cd02..cbac35c 100644
829906
this.define("authority:(value)", {
830907
check: /* @__PURE__ */ __name(({ value }, { user }) => {
831908
return !user || user.authority >= +value;
832-
@@ -2076,6 +2219,8 @@ var Permissions = class {
909+
@@ -2076,6 +2223,8 @@ var Permissions = class {
833910
static {
834911
__name(this, "Permissions");
835912
}
@@ -838,7 +915,7 @@ index b99cd02..cbac35c 100644
838915
store = [];
839916
define(pattern, options) {
840917
const entry = {
841-
@@ -2167,7 +2312,8 @@ var KoishiBot = class {
918+
@@ -2167,7 +2316,8 @@ var KoishiBot = class {
842919
__name(this, "KoishiBot");
843920
}
844921
constructor(ctx) {
@@ -848,7 +925,7 @@ index b99cd02..cbac35c 100644
848925
getGuildMemberMap: "bot.getGuildMemberMap",
849926
broadcast: "bot.broadcast"
850927
});
851-
@@ -2238,9 +2384,11 @@ var SchemaService = class {
928+
@@ -2238,9 +2388,11 @@ var SchemaService = class {
852929
static {
853930
__name(this, "SchemaService");
854931
}
@@ -861,7 +938,7 @@ index b99cd02..cbac35c 100644
861938
const target = this.get(name);
862939
const index = target.list.findIndex((a) => a[kSchemaOrder] < order);
863940
schema[kSchemaOrder] = order;
864-
@@ -2250,7 +2398,7 @@ var SchemaService = class {
941+
@@ -2250,7 +2402,7 @@ var SchemaService = class {
865942
target.list.push(schema);
866943
}
867944
this.ctx.emit("internal/schema", name);
@@ -870,7 +947,7 @@ index b99cd02..cbac35c 100644
870947
remove3(target.list, schema);
871948
this.ctx.emit("internal/schema", name);
872949
});
873-
@@ -2259,10 +2407,10 @@ var SchemaService = class {
950+
@@ -2259,10 +2411,10 @@ var SchemaService = class {
874951
return this._data[name] ||= Schema4.intersect([]);
875952
}
876953
set(name, schema) {
@@ -883,7 +960,7 @@ index b99cd02..cbac35c 100644
883960
delete this._data[name];
884961
this.ctx.emit("internal/schema", name);
885962
});
886-
@@ -2272,6 +2420,95 @@ var SchemaService = class {
963+
@@ -2272,6 +2424,95 @@ var SchemaService = class {
887964
// src/context.ts
888965
import { Adapter as Adapter2, Bot as Bot3, Element, h as h6, HTTP as HTTP2, Logger as Logger5, MessageEncoder, Messenger, Quester, Schema as Schema6, segment, Universal as Universal5, z } from "@satorijs/core";
889966
import { resolveConfig } from "cordis";
@@ -979,7 +1056,7 @@ index b99cd02..cbac35c 100644
9791056
var Context = class extends satori.Context {
9801057
static {
9811058
__name(this, "Context");
982-
@@ -2279,31 +2516,8 @@ var Context = class extends satori.Context {
1059+
@@ -2279,31 +2520,8 @@ var Context = class extends satori.Context {
9831060
static shadow = /* @__PURE__ */ Symbol.for("session.shadow");
9841061
constructor(config = {}) {
9851062
super(config);
@@ -1013,7 +1090,7 @@ index b99cd02..cbac35c 100644
10131090
}
10141091
/** @deprecated use `ctx.root` instead */
10151092
get app() {
1016-
@@ -2313,25 +2527,6 @@ var Context = class extends satori.Context {
1093+
@@ -2313,25 +2531,6 @@ var Context = class extends satori.Context {
10171094
get options() {
10181095
return this.root.config;
10191096
}
@@ -1039,7 +1116,7 @@ index b99cd02..cbac35c 100644
10391116
before(name, listener, append = false) {
10401117
const seg = name.split("/");
10411118
seg[seg.length - 1] = "before-" + seg[seg.length - 1];
1042-
@@ -2339,19 +2534,36 @@ var Context = class extends satori.Context {
1119+
@@ -2339,19 +2538,36 @@ var Context = class extends satori.Context {
10431120
}
10441121
};
10451122
var Koishi = class extends cordis.Service {
@@ -1083,7 +1160,7 @@ index b99cd02..cbac35c 100644
10831160
};
10841161
((Context3) => {
10851162
Context3.Config = Schema5.intersect([
1086-
@@ -2399,12 +2611,15 @@ var Service3 = class extends satori.Service {
1163+
@@ -2399,12 +2615,15 @@ var Service3 = class extends satori.Service {
10871164
this.ctx = new Context();
10881165
}
10891166
};
@@ -1099,7 +1176,7 @@ index b99cd02..cbac35c 100644
10991176
Context as App,
11001177
Argv,
11011178
Bot3 as Bot,
1102-
@@ -2426,6 +2641,7 @@ export {
1179+
@@ -2426,6 +2645,7 @@ export {
11031180
Schema6 as Schema,
11041181
SchemaService,
11051182
Service3 as Service,

0 commit comments

Comments
 (0)