mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-08 06:54:24 +00:00
Merge branch 'main' into vincentkoc-code/issue-28140-invalid-config-fail-closed
This commit is contained in:
@@ -246,6 +246,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Security/Nostr: harden profile mutation/import loopback guards by failing closed on non-loopback forwarded client headers (`x-forwarded-for` / `x-real-ip`) and rejecting `sec-fetch-site: cross-site`; adds regression coverage for proxy-forwarded and browser cross-site mutation attempts.
|
||||
- CLI/bootstrap Node version hint maintenance: replace hardcoded nvm `22` instructions in `openclaw.mjs` with `MIN_NODE_MAJOR` interpolation so future minimum-Node bumps keep startup guidance in sync automatically. (#39056) Thanks @onstash.
|
||||
- Discord/native slash command auth: honor `commands.allowFrom.discord` (and `commands.allowFrom["*"]`) in guild slash-command pre-dispatch authorization so allowlisted senders are no longer incorrectly rejected as unauthorized. (#38794) Thanks @jskoiz and @thewilloftheshadow.
|
||||
- Outbound/message target normalization: ignore empty legacy `to`/`channelId` fields when explicit `target` is provided so valid target-based sends no longer fail legacy-param validation; includes regression coverage. (#38944) Thanks @Narcooo.
|
||||
|
||||
## 2026.3.2
|
||||
|
||||
|
||||
@@ -6,13 +6,17 @@ export const CHANNEL_TARGET_DESCRIPTION =
|
||||
export const CHANNEL_TARGETS_DESCRIPTION =
|
||||
"Recipient/channel targets (same format as --target); accepts ids or names when the directory is available.";
|
||||
|
||||
function hasNonEmptyString(value: unknown): value is string {
|
||||
return typeof value === "string" && value.trim().length > 0;
|
||||
}
|
||||
|
||||
export function applyTargetToParams(params: {
|
||||
action: string;
|
||||
args: Record<string, unknown>;
|
||||
}): void {
|
||||
const target = typeof params.args.target === "string" ? params.args.target.trim() : "";
|
||||
const hasLegacyTo = typeof params.args.to === "string";
|
||||
const hasLegacyChannelId = typeof params.args.channelId === "string";
|
||||
const hasLegacyTo = hasNonEmptyString(params.args.to);
|
||||
const hasLegacyChannelId = hasNonEmptyString(params.args.channelId);
|
||||
const mode =
|
||||
MESSAGE_ACTION_TARGET_MODE[params.action as keyof typeof MESSAGE_ACTION_TARGET_MODE] ?? "none";
|
||||
|
||||
|
||||
@@ -17,6 +17,21 @@ describe("normalizeMessageActionInput", () => {
|
||||
expect("channelId" in normalized).toBe(false);
|
||||
});
|
||||
|
||||
it("ignores empty-string legacy target fields when explicit target is present", () => {
|
||||
const normalized = normalizeMessageActionInput({
|
||||
action: "send",
|
||||
args: {
|
||||
target: "1214056829",
|
||||
channelId: "",
|
||||
to: " ",
|
||||
},
|
||||
});
|
||||
|
||||
expect(normalized.target).toBe("1214056829");
|
||||
expect(normalized.to).toBe("1214056829");
|
||||
expect("channelId" in normalized).toBe(false);
|
||||
});
|
||||
|
||||
it("maps legacy target fields into canonical target", () => {
|
||||
const normalized = normalizeMessageActionInput({
|
||||
action: "send",
|
||||
|
||||
@@ -19,11 +19,13 @@ export function normalizeMessageActionInput(params: {
|
||||
|
||||
const explicitTarget =
|
||||
typeof normalizedArgs.target === "string" ? normalizedArgs.target.trim() : "";
|
||||
const hasLegacyTargetFields =
|
||||
typeof normalizedArgs.to === "string" || typeof normalizedArgs.channelId === "string";
|
||||
const hasLegacyTarget =
|
||||
(typeof normalizedArgs.to === "string" && normalizedArgs.to.trim().length > 0) ||
|
||||
(typeof normalizedArgs.channelId === "string" && normalizedArgs.channelId.trim().length > 0);
|
||||
|
||||
if (explicitTarget && hasLegacyTarget) {
|
||||
if (explicitTarget && hasLegacyTargetFields) {
|
||||
delete normalizedArgs.to;
|
||||
delete normalizedArgs.channelId;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user