fix(chats): normalize JID, use hosted-aware checks, add statusCode to errors

Address review feedback on PR #186:
- Normalize JID with jidNormalizedUser() before validation to accept @c.us format
- Use isAnyPnUser/isAnyLidUser instead of isPnUser/isLidUser to support hosted JIDs
- Add { statusCode: 400 } to Boom errors for proper client error classification

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Renato Alcara
2026-02-15 23:22:34 -03:00
parent 9f1d0c4a43
commit 8f4e10289b
+13 -12
View File
@@ -50,8 +50,8 @@ import {
type BinaryNode, type BinaryNode,
getBinaryNodeChild, getBinaryNodeChild,
getBinaryNodeChildren, getBinaryNodeChildren,
isLidUser, isAnyLidUser,
isPnUser, isAnyPnUser,
jidDecode, jidDecode,
jidNormalizedUser, jidNormalizedUser,
reduceBinaryNodeToDictionary, reduceBinaryNodeToDictionary,
@@ -431,31 +431,32 @@ export const makeChatsSocket = (config: SocketConfig) => {
} }
const updateBlockStatus = async (jid: string, action: 'block' | 'unblock') => { const updateBlockStatus = async (jid: string, action: 'block' | 'unblock') => {
const normalizedJid = jidNormalizedUser(jid)
let lid: string let lid: string
let pn_jid: string | undefined let pn_jid: string | undefined
if (isLidUser(jid)) { if (isAnyLidUser(normalizedJid)) {
lid = jid lid = normalizedJid
if (action === 'block') { if (action === 'block') {
const pn = await signalRepository.lidMapping.getPNForLID(jid) const pn = await signalRepository.lidMapping.getPNForLID(normalizedJid)
if (!pn) { if (!pn) {
throw new Boom(`Unable to resolve PN JID for LID: ${jid}`) throw new Boom(`Unable to resolve PN JID for LID: ${jid}`, { statusCode: 400 })
} }
pn_jid = jidNormalizedUser(pn) pn_jid = jidNormalizedUser(pn)
} }
} else if (isPnUser(jid)) { } else if (isAnyPnUser(normalizedJid)) {
const mapped = await signalRepository.lidMapping.getLIDForPN(jid) const mapped = await signalRepository.lidMapping.getLIDForPN(normalizedJid)
if (!mapped) { if (!mapped) {
throw new Boom(`Unable to resolve LID for PN JID: ${jid}`) throw new Boom(`Unable to resolve LID for PN JID: ${jid}`, { statusCode: 400 })
} }
lid = mapped lid = mapped
if (action === 'block') { if (action === 'block') {
pn_jid = jidNormalizedUser(jid) pn_jid = normalizedJid
} }
} else { } else {
throw new Boom(`Invalid jid for block/unblock: ${jid}`) throw new Boom(`Invalid jid for block/unblock: ${jid}`, { statusCode: 400 })
} }
const itemAttrs: { action: 'block' | 'unblock'; jid: string; pn_jid?: string } = { const itemAttrs: { action: 'block' | 'unblock'; jid: string; pn_jid?: string } = {
@@ -734,7 +735,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
// and never for own profile pic (Chat model for self has no tcToken). // and never for own profile pic (Chat model for self has no tcToken).
// Including tctoken for own JID causes the server to never respond. // Including tctoken for own JID causes the server to never respond.
const normalizedJid = jidNormalizedUser(jid) const normalizedJid = jidNormalizedUser(jid)
const isUserJid = isPnUser(normalizedJid) || isLidUser(normalizedJid) const isUserJid = isAnyPnUser(normalizedJid) || isAnyLidUser(normalizedJid)
const me = authState.creds.me const me = authState.creds.me
const isSelf = const isSelf =
me && (normalizedJid === jidNormalizedUser(me.id) || (me.lid && normalizedJid === jidNormalizedUser(me.lid))) me && (normalizedJid === jidNormalizedUser(me.id) || (me.lid && normalizedJid === jidNormalizedUser(me.lid)))