From edddb07f20554740d239d1cf73b8a8e623bfe271 Mon Sep 17 00:00:00 2001 From: Devin Robison Date: Mon, 4 May 2026 12:38:51 -0600 Subject: [PATCH] fix(qqbot): preserve framework command authorization (#77453) * fix(qqbot): preserve framework command authorization * Add changelog entry for PR #77453 --- CHANGELOG.md | 1 + .../framework-context-adapter.test.ts | 55 +++++++++++++++++++ .../commands/framework-context-adapter.ts | 2 +- 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 extensions/qqbot/src/bridge/commands/framework-context-adapter.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a363cf4da0..d10ebc829ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -207,6 +207,7 @@ Docs: https://docs.openclaw.ai - TUI: replace the stale-response watchdog notice with plain user-facing copy so stalled replies no longer surface backend or streaming internals. (#77120) Thanks @davemorin. - Security/Windows: validate `SystemRoot`/`WINDIR` env values through the Windows install-root validator and add them to the dangerous-host-env policy when resolving `icacls.exe`/`whoami.exe` for `openclaw security audit`, so workspace `.env` overrides and bare command names cannot redirect Windows ACL helpers to attacker-controlled binaries. (#74458) Thanks @mmaps. - Security/Windows: pin Windows registry-probe `reg.exe` resolution to the canonical Windows install root in install-root probing, so `SystemRoot`/`WINDIR` env overrides cannot redirect registry queries during Windows host detection. (#74454) Thanks @mmaps. +- QQBot: preserve the framework command authorization decision when converting framework command contexts into engine slash command contexts, so downstream slash handlers see `commandAuthorized` matching the channel's resolved `isAuthorizedSender` instead of a hardcoded `true`. (#77453) Thanks @drobison00. ## 2026.5.3-1 diff --git a/extensions/qqbot/src/bridge/commands/framework-context-adapter.test.ts b/extensions/qqbot/src/bridge/commands/framework-context-adapter.test.ts new file mode 100644 index 00000000000..f362d4c9fd8 --- /dev/null +++ b/extensions/qqbot/src/bridge/commands/framework-context-adapter.test.ts @@ -0,0 +1,55 @@ +import type { OpenClawConfig } from "openclaw/plugin-sdk/config-types"; +import type { PluginCommandContext } from "openclaw/plugin-sdk/plugin-entry"; +import { describe, expect, it } from "vitest"; +import { buildFrameworkSlashContext } from "./framework-context-adapter.js"; + +function createCommandContext(isAuthorizedSender: boolean): PluginCommandContext { + return { + senderId: "SENDER_OPENID", + channel: "qqbot", + isAuthorizedSender, + args: "on", + commandBody: "/bot-streaming on", + config: {} as OpenClawConfig, + from: "qqbot:c2c:SENDER_OPENID", + requestConversationBinding: async () => undefined, + detachConversationBinding: async () => ({ removed: false }), + getCurrentConversationBinding: async () => null, + } as unknown as PluginCommandContext; +} + +describe("buildFrameworkSlashContext", () => { + it("preserves the framework authorization decision in the slash context", () => { + const authorized = buildFrameworkSlashContext({ + ctx: createCommandContext(true), + account: { + accountId: "default", + enabled: true, + appId: "app", + clientSecret: "secret", + secretSource: "config", + markdownSupport: true, + config: {}, + }, + from: { msgType: "c2c", targetType: "c2c", targetId: "SENDER_OPENID" }, + commandName: "bot-streaming", + }); + const unauthorized = buildFrameworkSlashContext({ + ctx: createCommandContext(false), + account: { + accountId: "default", + enabled: true, + appId: "app", + clientSecret: "secret", + secretSource: "config", + markdownSupport: true, + config: {}, + }, + from: { msgType: "c2c", targetType: "c2c", targetId: "SENDER_OPENID" }, + commandName: "bot-streaming", + }); + + expect(authorized.commandAuthorized).toBe(true); + expect(unauthorized.commandAuthorized).toBe(false); + }); +}); diff --git a/extensions/qqbot/src/bridge/commands/framework-context-adapter.ts b/extensions/qqbot/src/bridge/commands/framework-context-adapter.ts index 437c72cc3f4..fb6e7ccad0e 100644 --- a/extensions/qqbot/src/bridge/commands/framework-context-adapter.ts +++ b/extensions/qqbot/src/bridge/commands/framework-context-adapter.ts @@ -54,7 +54,7 @@ export function buildFrameworkSlashContext({ accountId: account.accountId, appId: account.appId, accountConfig: account.config as unknown as Record, - commandAuthorized: true, + commandAuthorized: ctx.isAuthorizedSender, queueSnapshot: { ...DEFAULT_QUEUE_SNAPSHOT }, }; }