mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-28 17:43:05 +00:00
fix: preserve approval surface parity
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
isTelegramExecApprovalAuthorizedSender,
|
||||
isTelegramExecApprovalClientEnabled,
|
||||
} from "../../../extensions/telegram/api.js";
|
||||
import { callGateway } from "../../gateway/call.js";
|
||||
import { ErrorCodes } from "../../gateway/protocol/index.js";
|
||||
import { logVerbose } from "../../globals.js";
|
||||
@@ -70,6 +74,17 @@ function buildResolvedByLabel(params: Parameters<CommandHandler>[0]): string {
|
||||
return `${channel}:${sender}`;
|
||||
}
|
||||
|
||||
function isAuthorizedTelegramExecSender(params: Parameters<CommandHandler>[0]): boolean {
|
||||
if (params.command.channel !== "telegram") {
|
||||
return false;
|
||||
}
|
||||
return isTelegramExecApprovalAuthorizedSender({
|
||||
cfg: params.cfg,
|
||||
accountId: params.ctx.AccountId,
|
||||
senderId: params.command.senderId,
|
||||
});
|
||||
}
|
||||
|
||||
function readErrorCode(value: unknown): string | null {
|
||||
return typeof value === "string" && value.trim() ? value : null;
|
||||
}
|
||||
@@ -159,6 +174,8 @@ export const handleApproveCommand: CommandHandler = async (params, allowTextComm
|
||||
return { shouldContinue: false, reply: { text: parsed.error } };
|
||||
}
|
||||
|
||||
const isPluginId = parsed.id.startsWith("plugin:");
|
||||
const telegramExecAuthorizedSender = isAuthorizedTelegramExecSender(params);
|
||||
const execApprovalAuthorization = resolveApprovalCommandAuthorization({
|
||||
cfg: params.cfg,
|
||||
channel: params.command.channel,
|
||||
@@ -183,6 +200,18 @@ export const handleApproveCommand: CommandHandler = async (params, allowTextComm
|
||||
return { shouldContinue: false };
|
||||
}
|
||||
|
||||
if (
|
||||
params.command.channel === "telegram" &&
|
||||
!isPluginId &&
|
||||
!telegramExecAuthorizedSender &&
|
||||
!isTelegramExecApprovalClientEnabled({ cfg: params.cfg, accountId: params.ctx.AccountId })
|
||||
) {
|
||||
return {
|
||||
shouldContinue: false,
|
||||
reply: { text: "❌ Telegram exec approvals are not enabled for this bot account." },
|
||||
};
|
||||
}
|
||||
|
||||
const missingScope = requireGatewayClientScopeForInternalChannel(params, {
|
||||
label: "/approve",
|
||||
allowedScopes: ["operator.approvals", "operator.admin"],
|
||||
|
||||
@@ -993,7 +993,7 @@ describe("/approve command", () => {
|
||||
expect(callGatewayMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("accepts Telegram /approve from exec target recipients even when native approvals are disabled", async () => {
|
||||
it("ignores Telegram /approve from exec target recipients when native approvals are disabled", async () => {
|
||||
const cfg = {
|
||||
commands: { text: true },
|
||||
approvals: {
|
||||
@@ -1020,13 +1020,8 @@ describe("/approve command", () => {
|
||||
|
||||
const result = await handleCommands(params);
|
||||
expect(result.shouldContinue).toBe(false);
|
||||
expect(result.reply?.text).toContain("Approval allow-once submitted");
|
||||
expect(callGatewayMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
method: "exec.approval.resolve",
|
||||
params: { id: "abc12345", decision: "allow-once" },
|
||||
}),
|
||||
);
|
||||
expect(result.reply).toBeUndefined();
|
||||
expect(callGatewayMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("requires configured Discord approvers for exec approvals", async () => {
|
||||
@@ -1261,7 +1256,7 @@ describe("/approve command", () => {
|
||||
expectGatewayCalls: 2,
|
||||
},
|
||||
{
|
||||
name: "telegram disabled native delivery now reports plain approval auth denial",
|
||||
name: "telegram disabled native delivery reports the channel-disabled message",
|
||||
cfg: createTelegramApproveCfg(null),
|
||||
commandBody: "/approve abc12345 allow-once",
|
||||
ctx: {
|
||||
@@ -1270,7 +1265,7 @@ describe("/approve command", () => {
|
||||
SenderId: "123",
|
||||
},
|
||||
setup: undefined,
|
||||
expectedText: "not authorized to approve exec requests on Telegram",
|
||||
expectedText: "Telegram exec approvals are not enabled",
|
||||
expectGatewayCalls: 0,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -100,6 +100,13 @@ describe("createApproverRestrictedNativeApprovalAdapter", () => {
|
||||
action: "approve",
|
||||
}),
|
||||
).toEqual({ kind: "disabled" });
|
||||
expect(
|
||||
getActionAvailabilityState({
|
||||
cfg: {} as never,
|
||||
accountId: "disabled",
|
||||
action: "approve",
|
||||
}),
|
||||
).toEqual({ kind: "disabled" });
|
||||
expect(hasConfiguredDmRoute.hasConfiguredDmRoute({ cfg: {} as never })).toBe(true);
|
||||
expect(nativeCapabilities).toEqual({
|
||||
enabled: true,
|
||||
|
||||
@@ -92,7 +92,7 @@ function buildApproverRestrictedNativeApprovalCapability(
|
||||
accountId?: string | null;
|
||||
action: "approve";
|
||||
}) =>
|
||||
params.hasApprovers({ cfg, accountId })
|
||||
params.hasApprovers({ cfg, accountId }) && params.isNativeDeliveryEnabled({ cfg, accountId })
|
||||
? ({ kind: "enabled" } as const)
|
||||
: ({ kind: "disabled" } as const),
|
||||
approvals: {
|
||||
|
||||
Reference in New Issue
Block a user