mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix: validate imessage action integers
This commit is contained in:
@@ -304,6 +304,52 @@ describe("imessage message actions", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("rejects fractional chatId params before resolving chat GUIDs", async () => {
|
||||
probeMock.getCachedIMessagePrivateApiStatus.mockReturnValue({
|
||||
available: true,
|
||||
v2Ready: true,
|
||||
selectors: {},
|
||||
});
|
||||
|
||||
await expect(
|
||||
imessageMessageActions.handleAction?.({
|
||||
action: "react",
|
||||
cfg: cfg(),
|
||||
params: {
|
||||
chatId: 42.5,
|
||||
messageId: "message-guid",
|
||||
emoji: "👍",
|
||||
},
|
||||
} as never),
|
||||
).rejects.toThrow("chatId must be a positive integer");
|
||||
|
||||
expect(runtimeMock.resolveChatGuidForTarget).not.toHaveBeenCalled();
|
||||
expect(runtimeMock.sendReaction).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("rejects fractional partIndex values before invoking bridge actions", async () => {
|
||||
probeMock.getCachedIMessagePrivateApiStatus.mockReturnValue({
|
||||
available: true,
|
||||
v2Ready: true,
|
||||
selectors: {},
|
||||
});
|
||||
|
||||
await expect(
|
||||
imessageMessageActions.handleAction?.({
|
||||
action: "react",
|
||||
cfg: cfg(),
|
||||
params: {
|
||||
chatGuid: "iMessage;+;chat0000",
|
||||
messageId: "message-guid",
|
||||
emoji: "👍",
|
||||
partIndex: 1.5,
|
||||
},
|
||||
} as never),
|
||||
).rejects.toThrow("partIndex must be a non-negative integer");
|
||||
|
||||
expect(runtimeMock.sendReaction).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("resolves short message ids before invoking bridge actions", async () => {
|
||||
probeMock.getCachedIMessagePrivateApiStatus.mockReturnValue({
|
||||
available: true,
|
||||
|
||||
@@ -2,7 +2,8 @@ import { readBooleanParam } from "openclaw/plugin-sdk/boolean-param";
|
||||
import {
|
||||
createActionGate,
|
||||
jsonResult,
|
||||
readNumberParam,
|
||||
readNonNegativeIntegerParam,
|
||||
readPositiveIntegerParam,
|
||||
readReactionParams,
|
||||
readStringParam,
|
||||
} from "openclaw/plugin-sdk/channel-actions";
|
||||
@@ -103,7 +104,7 @@ async function resolveChatGuid(params: {
|
||||
if (explicitChatGuid) {
|
||||
return explicitChatGuid;
|
||||
}
|
||||
const explicitChatId = readNumberParam(params.actionParams, "chatId", { integer: true });
|
||||
const explicitChatId = readPositiveIntegerParam(params.actionParams, "chatId");
|
||||
if (typeof explicitChatId === "number") {
|
||||
const resolved = await params.runtime.resolveChatGuidForTarget({
|
||||
target: { kind: "chat_id", chatId: explicitChatId },
|
||||
@@ -198,7 +199,7 @@ function buildChatContextFromActionParams(params: {
|
||||
}): IMessageChatContext {
|
||||
const explicitChatGuid = readStringParam(params.actionParams, "chatGuid")?.trim();
|
||||
const explicitChatIdentifier = readStringParam(params.actionParams, "chatIdentifier")?.trim();
|
||||
const explicitChatId = readNumberParam(params.actionParams, "chatId", { integer: true });
|
||||
const explicitChatId = readPositiveIntegerParam(params.actionParams, "chatId");
|
||||
// Trim before the truthy check so a whitespace-only currentChannelId can't
|
||||
// reach parseIMessageTarget (which throws on empty/whitespace input and
|
||||
// would abort the whole action with a confusing "target is required").
|
||||
@@ -486,7 +487,7 @@ export const imessageMessageActions: ChannelMessageActionAdapter = {
|
||||
);
|
||||
}
|
||||
const resolvedMessageId = messageId();
|
||||
const partIndex = readNumberParam(params, "partIndex", { integer: true });
|
||||
const partIndex = readNonNegativeIntegerParam(params, "partIndex");
|
||||
const resolvedChatGuid = await chatGuid();
|
||||
const reactionsToSend = remove && !reaction ? [...TAPBACK_KINDS] : reaction ? [reaction] : [];
|
||||
for (const kind of reactionsToSend) {
|
||||
@@ -512,7 +513,7 @@ export const imessageMessageActions: ChannelMessageActionAdapter = {
|
||||
if (!text) {
|
||||
throw new Error("iMessage edit requires text, newText, or message.");
|
||||
}
|
||||
const partIndex = readNumberParam(params, "partIndex", { integer: true });
|
||||
const partIndex = readNonNegativeIntegerParam(params, "partIndex");
|
||||
const backwardsCompatMessage = readStringParam(params, "backwardsCompatMessage");
|
||||
const resolvedChatGuid = await chatGuid();
|
||||
await runtime.editMessage({
|
||||
@@ -529,7 +530,7 @@ export const imessageMessageActions: ChannelMessageActionAdapter = {
|
||||
if (action === "unsend") {
|
||||
await assertPrivateApiEnabled();
|
||||
const resolvedMessageId = messageId({ requireFromMe: true });
|
||||
const partIndex = readNumberParam(params, "partIndex", { integer: true });
|
||||
const partIndex = readNonNegativeIntegerParam(params, "partIndex");
|
||||
const resolvedChatGuid = await chatGuid();
|
||||
await runtime.unsendMessage({
|
||||
chatGuid: resolvedChatGuid,
|
||||
@@ -569,7 +570,7 @@ export const imessageMessageActions: ChannelMessageActionAdapter = {
|
||||
);
|
||||
}
|
||||
}
|
||||
const partIndex = readNumberParam(params, "partIndex", { integer: true });
|
||||
const partIndex = readNonNegativeIntegerParam(params, "partIndex");
|
||||
const resolvedChatGuid = await chatGuid();
|
||||
const result = await runtime.sendRichMessage({
|
||||
chatGuid: resolvedChatGuid,
|
||||
|
||||
Reference in New Issue
Block a user