fix(whatsapp): preserve BR variants across self-chat and heartbeat
This commit is contained in:
parent
43ae3bc489
commit
5247c29331
@ -510,5 +510,10 @@ describe("web processMessage inbound context", () => {
|
||||
await processMessage(args);
|
||||
|
||||
expect(updateLastRouteMock).toHaveBeenCalledTimes(1);
|
||||
expect(updateLastRouteMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
to: "+553598627740",
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -344,17 +344,18 @@ export async function processMessage(params: {
|
||||
cfg: params.cfg,
|
||||
msg: params.msg,
|
||||
});
|
||||
const shouldUpdateMainLastRoute =
|
||||
!pinnedMainDmRecipient ||
|
||||
(dmRouteTarget
|
||||
? areEquivalentWhatsAppDirectTargets(pinnedMainDmRecipient, dmRouteTarget)
|
||||
: false);
|
||||
const canonicalMainLastRouteTarget = pinnedMainDmRecipient
|
||||
? dmRouteTarget && areEquivalentWhatsAppDirectTargets(pinnedMainDmRecipient, dmRouteTarget)
|
||||
? pinnedMainDmRecipient
|
||||
: null
|
||||
: dmRouteTarget;
|
||||
const shouldUpdateMainLastRoute = Boolean(canonicalMainLastRouteTarget);
|
||||
const inboundLastRouteSessionKey = resolveInboundLastRouteSessionKey({
|
||||
route: params.route,
|
||||
sessionKey: params.route.sessionKey,
|
||||
});
|
||||
if (
|
||||
dmRouteTarget &&
|
||||
canonicalMainLastRouteTarget &&
|
||||
inboundLastRouteSessionKey === params.route.mainSessionKey &&
|
||||
shouldUpdateMainLastRoute
|
||||
) {
|
||||
@ -364,7 +365,7 @@ export async function processMessage(params: {
|
||||
storeAgentId: params.route.agentId,
|
||||
sessionKey: params.route.mainSessionKey,
|
||||
channel: "whatsapp",
|
||||
to: dmRouteTarget,
|
||||
to: canonicalMainLastRouteTarget,
|
||||
accountId: params.route.accountId,
|
||||
ctx: ctxPayload,
|
||||
warn: params.replyLogger.warn.bind(params.replyLogger),
|
||||
|
||||
@ -158,6 +158,33 @@ describe("WhatsApp dmPolicy precedence", () => {
|
||||
expect(sendMessageMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("treats BR ninth-digit variants as the same self-chat phone", async () => {
|
||||
setAccessControlTestConfig({
|
||||
channels: {
|
||||
whatsapp: {
|
||||
dmPolicy: "pairing",
|
||||
allowFrom: ["+5511988887777"],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const result = await checkInboundAccessControl({
|
||||
accountId: "default",
|
||||
from: "+5535998627740",
|
||||
selfE164: "+553598627740",
|
||||
senderE164: "+5535998627740",
|
||||
group: false,
|
||||
pushName: "Owner",
|
||||
isFromMe: false,
|
||||
sock: { sendMessage: sendMessageMock },
|
||||
remoteJid: "5535998627740@s.whatsapp.net",
|
||||
});
|
||||
|
||||
expect(result.allowed).toBe(true);
|
||||
expect(upsertPairingRequestMock).not.toHaveBeenCalled();
|
||||
expect(sendMessageMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("allows BR contacts when allowFrom and sender differ only by the ninth digit", async () => {
|
||||
setAccessControlTestConfig({
|
||||
channels: {
|
||||
|
||||
@ -73,7 +73,9 @@ export async function checkInboundAccessControl(params: {
|
||||
const dmAllowFrom = configuredAllowFrom.length > 0 ? configuredAllowFrom : defaultAllowFrom;
|
||||
const groupAllowFrom =
|
||||
account.groupAllowFrom ?? (configuredAllowFrom.length > 0 ? configuredAllowFrom : undefined);
|
||||
const isSamePhone = params.from === params.selfE164;
|
||||
const isSamePhone = params.selfE164
|
||||
? areEquivalentWhatsAppDirectTargets(params.from, params.selfE164)
|
||||
: false;
|
||||
const isSelfChat = account.selfChatMode ?? isSelfChatMode(params.selfE164, configuredAllowFrom);
|
||||
const pairingGraceMs =
|
||||
typeof params.pairingGraceMs === "number" && params.pairingGraceMs > 0
|
||||
|
||||
@ -66,6 +66,17 @@ describe("resolveWhatsAppHeartbeatRecipients", () => {
|
||||
expect(result).toEqual({ recipients: ["+15550000001"], source: "session-single" });
|
||||
});
|
||||
|
||||
it("treats BR ninth-digit variants as authorized session recipients", () => {
|
||||
setSessionStore({
|
||||
a: { lastChannel: "whatsapp", lastTo: "+5535998627740", updatedAt: 2, sessionId: "a" },
|
||||
});
|
||||
setAllowFromStore(["+553598627740"]);
|
||||
|
||||
const result = resolveWith();
|
||||
|
||||
expect(result).toEqual({ recipients: ["+5535998627740"], source: "session-single" });
|
||||
});
|
||||
|
||||
it("falls back to allowFrom when no session recipient is authorized", () => {
|
||||
setSingleUnauthorizedSessionWithAllowFrom();
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ import { loadSessionStore, resolveStorePath } from "../../config/sessions.js";
|
||||
import { readChannelAllowFromStoreSync } from "../../pairing/pairing-store.js";
|
||||
import { DEFAULT_ACCOUNT_ID } from "../../routing/session-key.js";
|
||||
import { normalizeE164 } from "../../utils.js";
|
||||
import { areEquivalentWhatsAppDirectTargets } from "../../whatsapp/normalize.js";
|
||||
import { normalizeChatChannelId } from "../registry.js";
|
||||
|
||||
type HeartbeatRecipientsResult = { recipients: string[]; source: string };
|
||||
@ -72,10 +73,13 @@ export function resolveWhatsAppHeartbeatRecipients(
|
||||
}
|
||||
|
||||
if (allowFrom.length > 0) {
|
||||
const allowSet = new Set(allowFrom);
|
||||
const authorizedSessionRecipients = sessionRecipients
|
||||
.map((entry) => entry.to)
|
||||
.filter((recipient) => allowSet.has(recipient));
|
||||
.filter((recipient) =>
|
||||
allowFrom.some((allowedRecipient) =>
|
||||
areEquivalentWhatsAppDirectTargets(allowedRecipient, recipient),
|
||||
),
|
||||
);
|
||||
if (authorizedSessionRecipients.length === 1) {
|
||||
return { recipients: [authorizedSessionRecipients[0]], source: "session-single" };
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user