fix: suppress whatsapp pairing in self-phone mode
This commit is contained in:
@@ -12,6 +12,7 @@ export type ResolvedWhatsAppAccount = {
|
||||
enabled: boolean;
|
||||
authDir: string;
|
||||
isLegacyAuthDir: boolean;
|
||||
selfChatMode?: boolean;
|
||||
allowFrom?: string[];
|
||||
groupAllowFrom?: string[];
|
||||
groupPolicy?: GroupPolicy;
|
||||
@@ -103,6 +104,7 @@ export function resolveWhatsAppAccount(params: {
|
||||
enabled,
|
||||
authDir,
|
||||
isLegacyAuthDir: isLegacy,
|
||||
selfChatMode: accountCfg?.selfChatMode ?? params.cfg.whatsapp?.selfChatMode,
|
||||
allowFrom: accountCfg?.allowFrom ?? params.cfg.whatsapp?.allowFrom,
|
||||
groupAllowFrom:
|
||||
accountCfg?.groupAllowFrom ?? params.cfg.whatsapp?.groupAllowFrom,
|
||||
|
||||
@@ -202,6 +202,9 @@ export async function monitorWebInbox(options: {
|
||||
: undefined);
|
||||
const isSamePhone = from === selfE164;
|
||||
const isSelfChat = isSelfChatMode(selfE164, configuredAllowFrom);
|
||||
const isFromMe = Boolean(msg.key?.fromMe);
|
||||
const selfChatMode = account.selfChatMode ?? false;
|
||||
const selfPhoneMode = selfChatMode || isSelfChat;
|
||||
|
||||
// Pre-compute normalized allowlists for filtering
|
||||
const dmHasWildcard = allowFrom?.includes("*") ?? false;
|
||||
@@ -246,6 +249,12 @@ export async function monitorWebInbox(options: {
|
||||
|
||||
// DM access control (secure defaults): "pairing" (default) / "allowlist" / "open" / "disabled"
|
||||
if (!group) {
|
||||
if (isFromMe && !isSamePhone && selfPhoneMode) {
|
||||
logVerbose(
|
||||
"Skipping outbound self-phone DM (fromMe); no pairing reply needed.",
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (dmPolicy === "disabled") {
|
||||
logVerbose("Blocked dm (dmPolicy: disabled)");
|
||||
continue;
|
||||
|
||||
@@ -1099,6 +1099,110 @@ describe("web monitor inbox", () => {
|
||||
await listener.close();
|
||||
});
|
||||
|
||||
it("skips pairing replies for outbound DMs in same-phone mode", async () => {
|
||||
mockLoadConfig.mockReturnValue({
|
||||
whatsapp: {
|
||||
dmPolicy: "pairing",
|
||||
selfChatMode: true,
|
||||
},
|
||||
messages: {
|
||||
messagePrefix: undefined,
|
||||
responsePrefix: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
const onMessage = vi.fn();
|
||||
const listener = await monitorWebInbox({ verbose: false, onMessage });
|
||||
const sock = await createWaSocket();
|
||||
|
||||
const upsert = {
|
||||
type: "notify",
|
||||
messages: [
|
||||
{
|
||||
key: {
|
||||
id: "fromme-1",
|
||||
fromMe: true,
|
||||
remoteJid: "999@s.whatsapp.net",
|
||||
},
|
||||
message: { conversation: "hello" },
|
||||
messageTimestamp: 1_700_000_000,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
sock.ev.emit("messages.upsert", upsert);
|
||||
await new Promise((resolve) => setImmediate(resolve));
|
||||
|
||||
expect(onMessage).not.toHaveBeenCalled();
|
||||
expect(upsertPairingRequestMock).not.toHaveBeenCalled();
|
||||
expect(sock.sendMessage).not.toHaveBeenCalled();
|
||||
|
||||
mockLoadConfig.mockReturnValue({
|
||||
whatsapp: {
|
||||
allowFrom: ["*"],
|
||||
},
|
||||
messages: {
|
||||
messagePrefix: undefined,
|
||||
responsePrefix: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
await listener.close();
|
||||
});
|
||||
|
||||
it("still pairs outbound DMs when same-phone mode is disabled", async () => {
|
||||
mockLoadConfig.mockReturnValue({
|
||||
whatsapp: {
|
||||
dmPolicy: "pairing",
|
||||
selfChatMode: false,
|
||||
},
|
||||
messages: {
|
||||
messagePrefix: undefined,
|
||||
responsePrefix: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
const onMessage = vi.fn();
|
||||
const listener = await monitorWebInbox({ verbose: false, onMessage });
|
||||
const sock = await createWaSocket();
|
||||
|
||||
const upsert = {
|
||||
type: "notify",
|
||||
messages: [
|
||||
{
|
||||
key: {
|
||||
id: "fromme-2",
|
||||
fromMe: true,
|
||||
remoteJid: "999@s.whatsapp.net",
|
||||
},
|
||||
message: { conversation: "hello again" },
|
||||
messageTimestamp: 1_700_000_000,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
sock.ev.emit("messages.upsert", upsert);
|
||||
await new Promise((resolve) => setImmediate(resolve));
|
||||
|
||||
expect(onMessage).not.toHaveBeenCalled();
|
||||
expect(upsertPairingRequestMock).toHaveBeenCalledTimes(1);
|
||||
expect(sock.sendMessage).toHaveBeenCalledWith("999@s.whatsapp.net", {
|
||||
text: expect.stringContaining("Pairing code: PAIRCODE"),
|
||||
});
|
||||
|
||||
mockLoadConfig.mockReturnValue({
|
||||
whatsapp: {
|
||||
allowFrom: ["*"],
|
||||
},
|
||||
messages: {
|
||||
messagePrefix: undefined,
|
||||
responsePrefix: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
await listener.close();
|
||||
});
|
||||
|
||||
it("handles append messages by marking them read but skipping auto-reply", async () => {
|
||||
const onMessage = vi.fn();
|
||||
const listener = await monitorWebInbox({ verbose: false, onMessage });
|
||||
|
||||
Reference in New Issue
Block a user