WhatsApp DMs can arrive with LID sender IDs even when WHATSAPP_ALLOWED_USERS is configured with phone numbers. The allowlist check now reads bridge session mapping files (lid-mapping-*.json) to resolve phone↔LID aliases, matching users regardless of which identifier format the message uses. Both the Python gateway (_is_user_authorized) and the Node bridge (allowlist.js) now share the same mapping-file-based resolution logic. Co-authored-by: Frederico Ribeiro <fr@tecompanytea.com>
80 lines
1.9 KiB
JavaScript
80 lines
1.9 KiB
JavaScript
import path from 'path';
|
|
import { existsSync, readFileSync } from 'fs';
|
|
|
|
export function normalizeWhatsAppIdentifier(value) {
|
|
return String(value || '')
|
|
.trim()
|
|
.replace(/:.*@/, '@')
|
|
.replace(/@.*/, '')
|
|
.replace(/^\+/, '');
|
|
}
|
|
|
|
export function parseAllowedUsers(rawValue) {
|
|
return new Set(
|
|
String(rawValue || '')
|
|
.split(',')
|
|
.map((value) => normalizeWhatsAppIdentifier(value))
|
|
.filter(Boolean)
|
|
);
|
|
}
|
|
|
|
function readMappingFile(sessionDir, identifier, suffix = '') {
|
|
const filePath = path.join(sessionDir, `lid-mapping-${identifier}${suffix}.json`);
|
|
if (!existsSync(filePath)) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const parsed = JSON.parse(readFileSync(filePath, 'utf8'));
|
|
const normalized = normalizeWhatsAppIdentifier(parsed);
|
|
return normalized || null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export function expandWhatsAppIdentifiers(identifier, sessionDir) {
|
|
const normalized = normalizeWhatsAppIdentifier(identifier);
|
|
if (!normalized) {
|
|
return new Set();
|
|
}
|
|
|
|
// Walk both phone->LID and LID->phone mapping files so allowlists can use
|
|
// either form transparently in bot mode.
|
|
const resolved = new Set();
|
|
const queue = [normalized];
|
|
|
|
while (queue.length > 0) {
|
|
const current = queue.shift();
|
|
if (!current || resolved.has(current)) {
|
|
continue;
|
|
}
|
|
|
|
resolved.add(current);
|
|
|
|
for (const suffix of ['', '_reverse']) {
|
|
const mapped = readMappingFile(sessionDir, current, suffix);
|
|
if (mapped && !resolved.has(mapped)) {
|
|
queue.push(mapped);
|
|
}
|
|
}
|
|
}
|
|
|
|
return resolved;
|
|
}
|
|
|
|
export function matchesAllowedUser(senderId, allowedUsers, sessionDir) {
|
|
if (!allowedUsers || allowedUsers.size === 0) {
|
|
return true;
|
|
}
|
|
|
|
const aliases = expandWhatsAppIdentifiers(senderId, sessionDir);
|
|
for (const alias of aliases) {
|
|
if (allowedUsers.has(alias)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|