mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 09:21:23 +00:00
fix(outbound): return error instead of silently redirecting to allowList[0] (#13578)
This commit is contained in:
@@ -108,15 +108,15 @@ describe("outbound", () => {
|
||||
expect(result.to).toBe("allowed");
|
||||
});
|
||||
|
||||
it("should fallback to first allowlist entry when target not in list", () => {
|
||||
it("should error when target not in allowlist (implicit mode)", () => {
|
||||
const result = twitchOutbound.resolveTarget({
|
||||
to: "#notallowed",
|
||||
mode: "implicit",
|
||||
allowFrom: ["#primary", "#secondary"],
|
||||
});
|
||||
|
||||
expect(result.ok).toBe(true);
|
||||
expect(result.to).toBe("primary");
|
||||
expect(result.ok).toBe(false);
|
||||
expect(result.error).toContain("Twitch");
|
||||
});
|
||||
|
||||
it("should accept any target when allowlist is empty", () => {
|
||||
@@ -130,15 +130,15 @@ describe("outbound", () => {
|
||||
expect(result.to).toBe("anychannel");
|
||||
});
|
||||
|
||||
it("should use first allowlist entry when no target provided", () => {
|
||||
it("should error when no target provided with allowlist", () => {
|
||||
const result = twitchOutbound.resolveTarget({
|
||||
to: undefined,
|
||||
mode: "implicit",
|
||||
allowFrom: ["#fallback", "#other"],
|
||||
});
|
||||
|
||||
expect(result.ok).toBe(true);
|
||||
expect(result.to).toBe("fallback");
|
||||
expect(result.ok).toBe(false);
|
||||
expect(result.error).toContain("Twitch");
|
||||
});
|
||||
|
||||
it("should return error when no target and no allowlist", () => {
|
||||
@@ -163,6 +163,17 @@ describe("outbound", () => {
|
||||
expect(result.error).toContain("Missing target");
|
||||
});
|
||||
|
||||
it("should error when target normalizes to empty string", () => {
|
||||
const result = twitchOutbound.resolveTarget({
|
||||
to: "#",
|
||||
mode: "explicit",
|
||||
allowFrom: [],
|
||||
});
|
||||
|
||||
expect(result.ok).toBe(false);
|
||||
expect(result.error).toContain("Twitch");
|
||||
});
|
||||
|
||||
it("should filter wildcard from allowlist when checking membership", () => {
|
||||
const result = twitchOutbound.resolveTarget({
|
||||
to: "#mychannel",
|
||||
|
||||
@@ -54,6 +54,12 @@ export const twitchOutbound: ChannelOutboundAdapter = {
|
||||
// If target is provided, normalize and validate it
|
||||
if (trimmed) {
|
||||
const normalizedTo = normalizeTwitchChannel(trimmed);
|
||||
if (!normalizedTo) {
|
||||
return {
|
||||
ok: false,
|
||||
error: missingTargetError("Twitch", "<channel-name>"),
|
||||
};
|
||||
}
|
||||
|
||||
// For implicit/heartbeat modes with allowList, check against allowlist
|
||||
if (mode === "implicit" || mode === "heartbeat") {
|
||||
@@ -63,26 +69,22 @@ export const twitchOutbound: ChannelOutboundAdapter = {
|
||||
if (allowList.includes(normalizedTo)) {
|
||||
return { ok: true, to: normalizedTo };
|
||||
}
|
||||
// Fallback to first allowFrom entry
|
||||
return { ok: true, to: allowList[0] };
|
||||
return {
|
||||
ok: false,
|
||||
error: missingTargetError("Twitch", "<channel-name>"),
|
||||
};
|
||||
}
|
||||
|
||||
// For explicit mode, accept any valid channel name
|
||||
return { ok: true, to: normalizedTo };
|
||||
}
|
||||
|
||||
// No target provided, use allowFrom fallback
|
||||
if (allowList.length > 0) {
|
||||
return { ok: true, to: allowList[0] };
|
||||
}
|
||||
// No target provided - error
|
||||
|
||||
// No target and no allowFrom - error
|
||||
return {
|
||||
ok: false,
|
||||
error: missingTargetError(
|
||||
"Twitch",
|
||||
"<channel-name> or channels.twitch.accounts.<account>.allowFrom[0]",
|
||||
),
|
||||
error: missingTargetError("Twitch", "<channel-name>"),
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user