fix(regression): restore external talk voice updates

This commit is contained in:
Tak Hoffman
2026-03-27 16:05:22 -05:00
parent 1a9abb13bd
commit eacd5ac3ef
2 changed files with 7 additions and 7 deletions

View File

@@ -249,12 +249,12 @@ describe("talk-voice plugin", () => {
expect(runtime.config.writeConfigFile).not.toHaveBeenCalled();
});
it("rejects /voice set from non-gateway channels without operator.admin", async () => {
it("allows /voice set from non-gateway channels without operator.admin", async () => {
const { runtime, run } = createElevenlabsVoiceSetHarness("telegram");
const result = await run();
expect(result.text).toContain("requires operator.admin");
expect(runtime.config.writeConfigFile).not.toHaveBeenCalled();
expect(runtime.config.writeConfigFile).toHaveBeenCalled();
expect(result.text).toContain("voice-a");
});
it("allows /voice set when operator.admin is present on a non-webchat channel", async () => {

View File

@@ -164,10 +164,10 @@ export default definePluginEntry({
}
if (action === "set") {
// Persistent config writes require operator.admin on every channel.
// Without this check, external channel senders could bypass the
// admin-only config.patch RPC by reaching writeConfigFile indirectly.
if (!ctx.gatewayClientScopes?.includes("operator.admin")) {
// 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")) {
return { text: `⚠️ ${commandLabel} set requires operator.admin.` };
}