/** Tests command authorization owner defaults for direct-message senders. */ import { describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../config/config.js"; import { resolveCommandAuthorization } from "./command-auth.js"; import type { MsgContext } from "./templating.js"; import { installDiscordRegistryHooks } from "./test-helpers/command-auth-registry-fixture.js"; installDiscordRegistryHooks(); describe("senderIsOwner only reflects explicit owner authorization", () => { it("does not treat direct-message senders as owners when no ownerAllowFrom is configured", () => { const cfg = { channels: { discord: {} }, } as OpenClawConfig; const ctx = { Provider: "discord", Surface: "discord", ChatType: "direct", From: "discord:123", SenderId: "123", } as MsgContext; const auth = resolveCommandAuthorization({ ctx, cfg, commandAuthorized: true, }); expect(auth.senderIsOwner).toBe(false); expect(auth.isAuthorizedSender).toBe(true); }); it("does not treat group-chat senders as owners when no ownerAllowFrom is configured", () => { const cfg = { channels: { discord: {} }, } as OpenClawConfig; const ctx = { Provider: "discord", Surface: "discord", ChatType: "group", From: "discord:123", SenderId: "123", } as MsgContext; const auth = resolveCommandAuthorization({ ctx, cfg, commandAuthorized: true, }); expect(auth.senderIsOwner).toBe(false); expect(auth.isAuthorizedSender).toBe(true); }); it("keeps channel-validated native group commands authorized without owner status", () => { const cfg = { channels: { telegram: {} }, } as OpenClawConfig; const ctx = { Provider: "telegram", Surface: "telegram", ChatType: "group", From: "telegram:group:-100123", SenderId: "200482621", CommandSource: "native", } as MsgContext; const auth = resolveCommandAuthorization({ ctx, cfg, commandAuthorized: true, }); expect(auth.senderIsOwner).toBe(false); expect(auth.isAuthorizedSender).toBe(true); }); it("senderIsOwner is false when ownerAllowFrom is configured and sender does not match", () => { const cfg = { channels: { discord: {} }, commands: { ownerAllowFrom: ["456"] }, } as OpenClawConfig; const ctx = { Provider: "discord", Surface: "discord", From: "discord:789", SenderId: "789", } as MsgContext; const auth = resolveCommandAuthorization({ ctx, cfg, commandAuthorized: true, }); expect(auth.senderIsOwner).toBe(false); }); it("does not let native command authorization bypass explicit owner allowlists", () => { const cfg = { channels: { telegram: {} }, commands: { ownerAllowFrom: ["456"] }, } as OpenClawConfig; const ctx = { Provider: "telegram", Surface: "telegram", ChatType: "group", From: "telegram:group:-100123", SenderId: "200482621", CommandSource: "native", } as MsgContext; const auth = resolveCommandAuthorization({ ctx, cfg, commandAuthorized: true, }); expect(auth.senderIsOwner).toBe(false); expect(auth.isAuthorizedSender).toBe(false); }); it("senderIsOwner is true when ownerAllowFrom matches sender", () => { const cfg = { channels: { discord: {} }, commands: { ownerAllowFrom: ["456"] }, } as OpenClawConfig; const ctx = { Provider: "discord", Surface: "discord", From: "discord:456", SenderId: "456", } as MsgContext; const auth = resolveCommandAuthorization({ ctx, cfg, commandAuthorized: true, }); expect(auth.senderIsOwner).toBe(true); }); it("senderIsOwner is true when ownerAllowFrom is wildcard (*)", () => { const cfg = { channels: { discord: {} }, commands: { ownerAllowFrom: ["*"] }, } as OpenClawConfig; const ctx = { Provider: "discord", Surface: "discord", From: "discord:anyone", SenderId: "anyone", } as MsgContext; const auth = resolveCommandAuthorization({ ctx, cfg, commandAuthorized: true, }); expect(auth.senderIsOwner).toBe(true); }); it("senderIsOwner is true for internal operator.admin sessions", () => { const cfg = {} as OpenClawConfig; const ctx = { Provider: "webchat", Surface: "webchat", GatewayClientScopes: ["operator.admin"], } as MsgContext; const auth = resolveCommandAuthorization({ ctx, cfg, commandAuthorized: true, }); expect(auth.senderIsOwner).toBe(true); }); });