import { issuePairingChallenge } from "../../../../src/pairing/pairing-challenge.js"; import { upsertChannelPairingRequest } from "../../../../src/pairing/pairing-store.js"; import { readStoreAllowFromForDmPolicy, resolveDmGroupAccessWithLists, } from "../../../../src/security/dm-policy-shared.js"; import { isSignalSenderAllowed, type SignalSender } from "../identity.js"; type SignalDmPolicy = "open" | "pairing" | "allowlist" | "disabled"; type SignalGroupPolicy = "open" | "allowlist" | "disabled"; export async function resolveSignalAccessState(params: { accountId: string; dmPolicy: SignalDmPolicy; groupPolicy: SignalGroupPolicy; allowFrom: string[]; groupAllowFrom: string[]; sender: SignalSender; }) { const storeAllowFrom = await readStoreAllowFromForDmPolicy({ provider: "signal", accountId: params.accountId, dmPolicy: params.dmPolicy, }); const resolveAccessDecision = (isGroup: boolean) => resolveDmGroupAccessWithLists({ isGroup, dmPolicy: params.dmPolicy, groupPolicy: params.groupPolicy, allowFrom: params.allowFrom, groupAllowFrom: params.groupAllowFrom, storeAllowFrom, isSenderAllowed: (allowEntries) => isSignalSenderAllowed(params.sender, allowEntries), }); const dmAccess = resolveAccessDecision(false); return { resolveAccessDecision, dmAccess, effectiveDmAllow: dmAccess.effectiveAllowFrom, effectiveGroupAllow: dmAccess.effectiveGroupAllowFrom, }; } export async function handleSignalDirectMessageAccess(params: { dmPolicy: SignalDmPolicy; dmAccessDecision: "allow" | "block" | "pairing"; senderId: string; senderIdLine: string; senderDisplay: string; senderName?: string; accountId: string; sendPairingReply: (text: string) => Promise; log: (message: string) => void; }): Promise { if (params.dmAccessDecision === "allow") { return true; } if (params.dmAccessDecision === "block") { if (params.dmPolicy !== "disabled") { params.log(`Blocked signal sender ${params.senderDisplay} (dmPolicy=${params.dmPolicy})`); } return false; } if (params.dmPolicy === "pairing") { await issuePairingChallenge({ channel: "signal", senderId: params.senderId, senderIdLine: params.senderIdLine, meta: { name: params.senderName }, upsertPairingRequest: async ({ id, meta }) => await upsertChannelPairingRequest({ channel: "signal", id, accountId: params.accountId, meta, }), sendPairingReply: params.sendPairingReply, onCreated: () => { params.log(`signal pairing request sender=${params.senderId}`); }, onReplyError: (err) => { params.log(`signal pairing reply failed for ${params.senderId}: ${String(err)}`); }, }); } return false; }