mirror of https://github.com/openclaw/openclaw.git
harden talk-voice config persistence scope checks
This commit is contained in:
parent
ee52f64226
commit
a4e447a16e
|
|
@ -233,6 +233,14 @@ describe("talk-voice plugin", () => {
|
|||
expect(runtime.config.writeConfigFile).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("rejects /voice set from non-webchat gateway callers missing operator.admin", async () => {
|
||||
const { runtime, run } = createElevenlabsVoiceSetHarness("telegram", ["operator.write"]);
|
||||
const result = await run();
|
||||
|
||||
expect(result.text).toContain("requires operator.admin");
|
||||
expect(runtime.config.writeConfigFile).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("allows /voice set from gateway client with operator.admin scope", async () => {
|
||||
const { runtime, run } = createElevenlabsVoiceSetHarness("webchat", ["operator.admin"]);
|
||||
const result = await run();
|
||||
|
|
|
|||
|
|
@ -99,6 +99,15 @@ function asProviderBaseUrl(value: unknown): string | undefined {
|
|||
return trimmed || undefined;
|
||||
}
|
||||
|
||||
const TALK_ADMIN_SCOPE = "operator.admin";
|
||||
|
||||
function requiresAdminToSetVoice(channel: string, gatewayClientScopes?: readonly string[]): boolean {
|
||||
if (Array.isArray(gatewayClientScopes)) {
|
||||
return !gatewayClientScopes.includes(TALK_ADMIN_SCOPE);
|
||||
}
|
||||
return channel === "webchat";
|
||||
}
|
||||
|
||||
export default definePluginEntry({
|
||||
id: "talk-voice",
|
||||
name: "Talk Voice",
|
||||
|
|
@ -164,10 +173,9 @@ export default definePluginEntry({
|
|||
}
|
||||
|
||||
if (action === "set") {
|
||||
// Internal gateway callers already expose operator scopes and should
|
||||
// match the admin-only config.patch RPC. External channels rely on
|
||||
// the plugin command's authorized-sender gate instead.
|
||||
if (ctx.channel === "webchat" && !ctx.gatewayClientScopes?.includes("operator.admin")) {
|
||||
// Gateway callers can override messageChannel, so scope presence is
|
||||
// the reliable signal for internal admin-only mutations.
|
||||
if (requiresAdminToSetVoice(ctx.channel, ctx.gatewayClientScopes)) {
|
||||
return { text: `⚠️ ${commandLabel} set requires operator.admin.` };
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue