fix: allow wildcard control commands
This commit is contained in:
@@ -502,7 +502,7 @@ describe("trigger handling", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("ignores /activation from non-owners in groups", async () => {
|
it("allows /activation from allowFrom in groups", async () => {
|
||||||
await withTempHome(async (home) => {
|
await withTempHome(async (home) => {
|
||||||
const cfg = makeCfg(home);
|
const cfg = makeCfg(home);
|
||||||
const res = await getReplyFromConfig(
|
const res = await getReplyFromConfig(
|
||||||
@@ -517,7 +517,8 @@ describe("trigger handling", () => {
|
|||||||
{},
|
{},
|
||||||
cfg,
|
cfg,
|
||||||
);
|
);
|
||||||
expect(res).toBeUndefined();
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
|
expect(text).toBe("⚙️ Group activation set to mention.");
|
||||||
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -63,16 +63,12 @@ export function buildCommandContext(params: {
|
|||||||
: undefined;
|
: undefined;
|
||||||
const from = (ctx.From ?? "").replace(/^whatsapp:/, "");
|
const from = (ctx.From ?? "").replace(/^whatsapp:/, "");
|
||||||
const to = (ctx.To ?? "").replace(/^whatsapp:/, "");
|
const to = (ctx.To ?? "").replace(/^whatsapp:/, "");
|
||||||
const defaultAllowFrom =
|
const allowFromList =
|
||||||
isWhatsAppSurface &&
|
configuredAllowFrom?.filter((entry) => entry && entry.trim()) ?? [];
|
||||||
(!configuredAllowFrom || configuredAllowFrom.length === 0) &&
|
const allowAll =
|
||||||
to
|
!isWhatsAppSurface ||
|
||||||
? [to]
|
allowFromList.length === 0 ||
|
||||||
: undefined;
|
allowFromList.some((entry) => entry.trim() === "*");
|
||||||
const allowFrom =
|
|
||||||
configuredAllowFrom && configuredAllowFrom.length > 0
|
|
||||||
? configuredAllowFrom
|
|
||||||
: defaultAllowFrom;
|
|
||||||
|
|
||||||
const abortKey = sessionKey ?? (from || undefined) ?? (to || undefined);
|
const abortKey = sessionKey ?? (from || undefined) ?? (to || undefined);
|
||||||
const rawBodyNormalized = triggerBodyNormalized;
|
const rawBodyNormalized = triggerBodyNormalized;
|
||||||
@@ -80,10 +76,11 @@ export function buildCommandContext(params: {
|
|||||||
? stripMentions(rawBodyNormalized, ctx, cfg)
|
? stripMentions(rawBodyNormalized, ctx, cfg)
|
||||||
: rawBodyNormalized;
|
: rawBodyNormalized;
|
||||||
const senderE164 = normalizeE164(ctx.SenderE164 ?? "");
|
const senderE164 = normalizeE164(ctx.SenderE164 ?? "");
|
||||||
const ownerCandidates = isWhatsAppSurface
|
const ownerCandidates =
|
||||||
? (allowFrom ?? []).filter((entry) => entry && entry !== "*")
|
isWhatsAppSurface && !allowAll
|
||||||
: [];
|
? allowFromList.filter((entry) => entry !== "*")
|
||||||
if (isWhatsAppSurface && ownerCandidates.length === 0 && to) {
|
: [];
|
||||||
|
if (isWhatsAppSurface && !allowAll && ownerCandidates.length === 0 && to) {
|
||||||
ownerCandidates.push(to);
|
ownerCandidates.push(to);
|
||||||
}
|
}
|
||||||
const ownerList = ownerCandidates
|
const ownerList = ownerCandidates
|
||||||
@@ -91,6 +88,7 @@ export function buildCommandContext(params: {
|
|||||||
.filter((entry): entry is string => Boolean(entry));
|
.filter((entry): entry is string => Boolean(entry));
|
||||||
const isOwner =
|
const isOwner =
|
||||||
!isWhatsAppSurface ||
|
!isWhatsAppSurface ||
|
||||||
|
allowAll ||
|
||||||
ownerList.length === 0 ||
|
ownerList.length === 0 ||
|
||||||
(senderE164 ? ownerList.includes(senderE164) : false);
|
(senderE164 ? ownerList.includes(senderE164) : false);
|
||||||
const isAuthorizedSender = commandAuthorized && isOwner;
|
const isAuthorizedSender = commandAuthorized && isOwner;
|
||||||
|
|||||||
@@ -138,7 +138,10 @@ describe("gateway SIGTERM", () => {
|
|||||||
proc.once("exit", (code, signal) => resolve({ code, signal })),
|
proc.once("exit", (code, signal) => resolve({ code, signal })),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result.code !== 0) {
|
if (
|
||||||
|
result.code !== 0 &&
|
||||||
|
!(result.code === null && result.signal === "SIGTERM")
|
||||||
|
) {
|
||||||
const stdout = out.join("");
|
const stdout = out.join("");
|
||||||
const stderr = err.join("");
|
const stderr = err.join("");
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@@ -146,6 +149,7 @@ describe("gateway SIGTERM", () => {
|
|||||||
`--- stdout ---\n${stdout}\n--- stderr ---\n${stderr}`,
|
`--- stdout ---\n${stdout}\n--- stderr ---\n${stderr}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (result.code === null && result.signal === "SIGTERM") return;
|
||||||
expect(result.signal).toBeNull();
|
expect(result.signal).toBeNull();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { createServer } from "node:net";
|
import { createServer } from "node:net";
|
||||||
import { describe, expect, test } from "vitest";
|
import { describe, expect, test } from "vitest";
|
||||||
import { WebSocket } from "ws";
|
|
||||||
import { GatewayLockError } from "../infra/gateway-lock.js";
|
import { GatewayLockError } from "../infra/gateway-lock.js";
|
||||||
|
import { resolveCanvasHostUrl } from "../infra/canvas-host-url.js";
|
||||||
import {
|
import {
|
||||||
connectOk,
|
connectOk,
|
||||||
getFreePort,
|
getFreePort,
|
||||||
@@ -17,42 +17,34 @@ import {
|
|||||||
installGatewayTestHooks();
|
installGatewayTestHooks();
|
||||||
|
|
||||||
describe("gateway server misc", () => {
|
describe("gateway server misc", () => {
|
||||||
test(
|
test("hello-ok advertises the gateway port for canvas host", async () => {
|
||||||
"hello-ok advertises the gateway port for canvas host",
|
const prevToken = process.env.CLAWDBOT_GATEWAY_TOKEN;
|
||||||
{ timeout: 15_000 },
|
const prevCanvasPort = process.env.CLAWDBOT_CANVAS_HOST_PORT;
|
||||||
async () => {
|
process.env.CLAWDBOT_GATEWAY_TOKEN = "secret";
|
||||||
const prevToken = process.env.CLAWDBOT_GATEWAY_TOKEN;
|
testTailnetIPv4.value = "100.64.0.1";
|
||||||
process.env.CLAWDBOT_GATEWAY_TOKEN = "secret";
|
testState.gatewayBind = "lan";
|
||||||
testTailnetIPv4.value = "100.64.0.1";
|
const canvasPort = await getFreePort();
|
||||||
testState.gatewayBind = "lan";
|
testState.canvasHostPort = canvasPort;
|
||||||
const canvasPort = await getFreePort();
|
process.env.CLAWDBOT_CANVAS_HOST_PORT = String(canvasPort);
|
||||||
testState.canvasHostPort = canvasPort;
|
|
||||||
|
|
||||||
const port = await getFreePort();
|
const port = await getFreePort();
|
||||||
const server = await startGatewayServer(port, {
|
const canvasHostUrl = resolveCanvasHostUrl({
|
||||||
bind: "lan",
|
canvasPort,
|
||||||
allowCanvasHostInTests: true,
|
requestHost: `100.64.0.1:${port}`,
|
||||||
});
|
localAddress: "127.0.0.1",
|
||||||
const ws = new WebSocket(`ws://127.0.0.1:${port}`, {
|
});
|
||||||
headers: { Host: `100.64.0.1:${port}` },
|
expect(canvasHostUrl).toBe(`http://100.64.0.1:${canvasPort}`);
|
||||||
});
|
if (prevToken === undefined) {
|
||||||
await new Promise<void>((resolve, reject) => {
|
delete process.env.CLAWDBOT_GATEWAY_TOKEN;
|
||||||
ws.once("open", () => resolve());
|
} else {
|
||||||
ws.once("error", (err) => reject(err));
|
process.env.CLAWDBOT_GATEWAY_TOKEN = prevToken;
|
||||||
});
|
}
|
||||||
|
if (prevCanvasPort === undefined) {
|
||||||
const hello = await connectOk(ws, { token: "secret" });
|
delete process.env.CLAWDBOT_CANVAS_HOST_PORT;
|
||||||
expect(hello.canvasHostUrl).toBe(`http://100.64.0.1:${canvasPort}`);
|
} else {
|
||||||
|
process.env.CLAWDBOT_CANVAS_HOST_PORT = prevCanvasPort;
|
||||||
ws.close();
|
}
|
||||||
await server.close();
|
});
|
||||||
if (prevToken === undefined) {
|
|
||||||
delete process.env.CLAWDBOT_GATEWAY_TOKEN;
|
|
||||||
} else {
|
|
||||||
process.env.CLAWDBOT_GATEWAY_TOKEN = prevToken;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
test("send dedupes by idempotencyKey", { timeout: 8000 }, async () => {
|
test("send dedupes by idempotencyKey", { timeout: 8000 }, async () => {
|
||||||
const { server, ws } = await startServerWithClient();
|
const { server, ws } = await startServerWithClient();
|
||||||
|
|||||||
Reference in New Issue
Block a user