fix(types): remove non-null assertions in groups.ts, noise-handler.ts, messages-recv.ts (partial)
- groups.ts: Replace ! assertions with ?? fallbacks for group attrs - noise-handler.ts: Add proper validation for serverHello fields before use, remove all ! assertions (9 total), throw Boom errors for missing fields - messages-recv.ts: Fix contradictory messageKey?.id! pattern (partial, more coming) https://claude.ai/code/session_01E2cfX1N3sJgCJBTvzGazSG
This commit is contained in:
@@ -316,19 +316,19 @@ export const extractGroupMetadata = (result: BinaryNode) => {
|
|||||||
descId = descChild.attrs.id
|
descId = descChild.attrs.id
|
||||||
}
|
}
|
||||||
|
|
||||||
const groupId = group.attrs.id!.includes('@') ? group.attrs.id : jidEncode(group.attrs.id!, 'g.us')
|
const groupId = (group.attrs.id ?? '').includes('@') ? group.attrs.id : jidEncode(group.attrs.id ?? '', 'g.us')
|
||||||
const eph = getBinaryNodeChild(group, 'ephemeral')?.attrs.expiration
|
const eph = getBinaryNodeChild(group, 'ephemeral')?.attrs.expiration
|
||||||
const memberAddMode = getBinaryNodeChildString(group, 'member_add_mode') === 'all_member_add'
|
const memberAddMode = getBinaryNodeChildString(group, 'member_add_mode') === 'all_member_add'
|
||||||
const metadata: GroupMetadata = {
|
const metadata: GroupMetadata = {
|
||||||
id: groupId!,
|
id: groupId,
|
||||||
notify: group.attrs.notify,
|
notify: group.attrs.notify,
|
||||||
addressingMode: group.attrs.addressing_mode === 'lid' ? WAMessageAddressingMode.LID : WAMessageAddressingMode.PN,
|
addressingMode: group.attrs.addressing_mode === 'lid' ? WAMessageAddressingMode.LID : WAMessageAddressingMode.PN,
|
||||||
subject: group.attrs.subject!,
|
subject: group.attrs.subject ?? '',
|
||||||
subjectOwner: group.attrs.s_o,
|
subjectOwner: group.attrs.s_o,
|
||||||
subjectOwnerPn: group.attrs.s_o_pn,
|
subjectOwnerPn: group.attrs.s_o_pn,
|
||||||
subjectTime: +group.attrs.s_t!,
|
subjectTime: +group.attrs.s_t ?? '0',
|
||||||
size: group.attrs.size ? +group.attrs.size : getBinaryNodeChildren(group, 'participant').length,
|
size: group.attrs.size ? +group.attrs.size : getBinaryNodeChildren(group, 'participant').length,
|
||||||
creation: +group.attrs.creation!,
|
creation: +group.attrs.creation ?? '0',
|
||||||
owner: group.attrs.creator ? jidNormalizedUser(group.attrs.creator) : undefined,
|
owner: group.attrs.creator ? jidNormalizedUser(group.attrs.creator) : undefined,
|
||||||
ownerPn: group.attrs.creator_pn ? jidNormalizedUser(group.attrs.creator_pn) : undefined,
|
ownerPn: group.attrs.creator_pn ? jidNormalizedUser(group.attrs.creator_pn) : undefined,
|
||||||
owner_country_code: group.attrs.creator_country_code,
|
owner_country_code: group.attrs.creator_country_code,
|
||||||
@@ -347,7 +347,7 @@ export const extractGroupMetadata = (result: BinaryNode) => {
|
|||||||
participants: getBinaryNodeChildren(group, 'participant').map(({ attrs }) => {
|
participants: getBinaryNodeChildren(group, 'participant').map(({ attrs }) => {
|
||||||
// TODO: Store LID MAPPINGS
|
// TODO: Store LID MAPPINGS
|
||||||
return {
|
return {
|
||||||
id: attrs.jid!,
|
id: attrs.jid ?? '',
|
||||||
phoneNumber: isLidUser(attrs.jid) && isPnUser(attrs.phone_number) ? attrs.phone_number : undefined,
|
phoneNumber: isLidUser(attrs.jid) && isPnUser(attrs.phone_number) ? attrs.phone_number : undefined,
|
||||||
lid: isPnUser(attrs.jid) && isLidUser(attrs.lid) ? attrs.lid : undefined,
|
lid: isPnUser(attrs.jid) && isLidUser(attrs.lid) ? attrs.lid : undefined,
|
||||||
admin: (attrs.type || null) as GroupParticipant['admin']
|
admin: (attrs.type || null) as GroupParticipant['admin']
|
||||||
|
|||||||
+11
-10
@@ -156,16 +156,16 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
throw new Boom('Not authenticated')
|
throw new Boom('Not authenticated')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await placeholderResendCache.get(messageKey?.id!)) {
|
if (await placeholderResendCache.get(messageKey?.id)) {
|
||||||
logger.debug({ messageKey }, 'already requested resend')
|
logger.debug({ messageKey }, 'already requested resend')
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
await placeholderResendCache.set(messageKey?.id!, true)
|
await placeholderResendCache.set(messageKey?.id, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
await delay(2000)
|
await delay(2000)
|
||||||
|
|
||||||
if (!(await placeholderResendCache.get(messageKey?.id!))) {
|
if (!(await placeholderResendCache.get(messageKey?.id))) {
|
||||||
logger.debug({ messageKey }, 'message received while resend requested')
|
logger.debug({ messageKey }, 'message received while resend requested')
|
||||||
return 'RESOLVED'
|
return 'RESOLVED'
|
||||||
}
|
}
|
||||||
@@ -180,9 +180,9 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
if (await placeholderResendCache.get(messageKey?.id!)) {
|
if (await placeholderResendCache.get(messageKey?.id)) {
|
||||||
logger.debug({ messageKey }, 'PDO message without response after 8 seconds. Phone possibly offline')
|
logger.debug({ messageKey }, 'PDO message without response after 8 seconds. Phone possibly offline')
|
||||||
await placeholderResendCache.del(messageKey?.id!)
|
await placeholderResendCache.del(messageKey?.id)
|
||||||
}
|
}
|
||||||
}, 8_000)
|
}, 8_000)
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
if (update.jid && update.user) {
|
if (update.jid && update.user) {
|
||||||
ev.emit('newsletter-participants.update', {
|
ev.emit('newsletter-participants.update', {
|
||||||
id: update.jid,
|
id: update.jid,
|
||||||
author: node.attrs.from!,
|
author: node.attrs.from ?? '',
|
||||||
user: update.user,
|
user: update.user,
|
||||||
new_role: 'ADMIN',
|
new_role: 'ADMIN',
|
||||||
action: 'promote'
|
action: 'promote'
|
||||||
@@ -251,9 +251,10 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
|
|
||||||
// Handles newsletter notifications
|
// Handles newsletter notifications
|
||||||
const handleNewsletterNotification = async (node: BinaryNode) => {
|
const handleNewsletterNotification = async (node: BinaryNode) => {
|
||||||
const from = node.attrs.from!
|
const from = node.attrs.from ?? ''
|
||||||
const child = getAllBinaryNodeChildren(node)[0]!
|
const child = getAllBinaryNodeChildren(node)[0]
|
||||||
const author = node.attrs.participant!
|
if (!child) return
|
||||||
|
const author = node.attrs.participant ?? ''
|
||||||
|
|
||||||
logger.info({ from, child }, 'got newsletter notification')
|
logger.info({ from, child }, 'got newsletter notification')
|
||||||
|
|
||||||
@@ -261,7 +262,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
case 'reaction':
|
case 'reaction':
|
||||||
const reactionUpdate = {
|
const reactionUpdate = {
|
||||||
id: from,
|
id: from,
|
||||||
server_id: child.attrs.message_id!,
|
server_id: child.attrs.message_id ?? '',
|
||||||
reaction: {
|
reaction: {
|
||||||
code: getBinaryNodeChildString(child, 'reaction'),
|
code: getBinaryNodeChildString(child, 'reaction'),
|
||||||
count: 1
|
count: 1
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ export const makeNoiseHandler = ({
|
|||||||
while (true) {
|
while (true) {
|
||||||
if (inBytes.length < 3) return
|
if (inBytes.length < 3) return
|
||||||
|
|
||||||
size = (inBytes[0]! << 16) | (inBytes[1]! << 8) | inBytes[2]!
|
size = (inBytes[0] << 16) | (inBytes[1] << 8) | inBytes[2]
|
||||||
|
|
||||||
if (inBytes.length < size + 3) return
|
if (inBytes.length < size + 3) return
|
||||||
|
|
||||||
@@ -180,13 +180,25 @@ export const makeNoiseHandler = ({
|
|||||||
mixIntoKey,
|
mixIntoKey,
|
||||||
finishInit,
|
finishInit,
|
||||||
processHandshake: ({ serverHello }: proto.HandshakeMessage, noiseKey: KeyPair) => {
|
processHandshake: ({ serverHello }: proto.HandshakeMessage, noiseKey: KeyPair) => {
|
||||||
authenticate(serverHello!.ephemeral!)
|
if (!serverHello?.ephemeral) {
|
||||||
mixIntoKey(Curve.sharedKey(privateKey, serverHello!.ephemeral!))
|
throw new Boom('Missing server hello ephemeral', { statusCode: 500 })
|
||||||
|
}
|
||||||
|
|
||||||
const decStaticContent = decrypt(serverHello!.static!)
|
if (!serverHello?.static) {
|
||||||
|
throw new Boom('Missing server hello static', { statusCode: 500 })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!serverHello?.payload) {
|
||||||
|
throw new Boom('Missing server hello payload', { statusCode: 500 })
|
||||||
|
}
|
||||||
|
|
||||||
|
authenticate(serverHello.ephemeral)
|
||||||
|
mixIntoKey(Curve.sharedKey(privateKey, serverHello.ephemeral))
|
||||||
|
|
||||||
|
const decStaticContent = decrypt(serverHello.static)
|
||||||
mixIntoKey(Curve.sharedKey(privateKey, decStaticContent))
|
mixIntoKey(Curve.sharedKey(privateKey, decStaticContent))
|
||||||
|
|
||||||
const certDecoded = decrypt(serverHello!.payload!)
|
const certDecoded = decrypt(serverHello.payload)
|
||||||
|
|
||||||
const { intermediate: certIntermediate, leaf } = proto.CertChain.decode(certDecoded)
|
const { intermediate: certIntermediate, leaf } = proto.CertChain.decode(certDecoded)
|
||||||
// leaf
|
// leaf
|
||||||
@@ -202,7 +214,11 @@ export const makeNoiseHandler = ({
|
|||||||
|
|
||||||
const { issuerSerial } = details
|
const { issuerSerial } = details
|
||||||
|
|
||||||
const verify = Curve.verify(details.key!, leaf.details, leaf.signature)
|
if (!details.key) {
|
||||||
|
throw new Boom('Missing certificate key', { statusCode: 500 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const verify = Curve.verify(details.key, leaf.details, leaf.signature)
|
||||||
|
|
||||||
const verifyIntermediate = Curve.verify(
|
const verifyIntermediate = Curve.verify(
|
||||||
WA_CERT_DETAILS.PUBLIC_KEY,
|
WA_CERT_DETAILS.PUBLIC_KEY,
|
||||||
@@ -223,7 +239,7 @@ export const makeNoiseHandler = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const keyEnc = encrypt(noiseKey.public)
|
const keyEnc = encrypt(noiseKey.public)
|
||||||
mixIntoKey(Curve.sharedKey(noiseKey.private, serverHello!.ephemeral!))
|
mixIntoKey(Curve.sharedKey(noiseKey.private, serverHello.ephemeral))
|
||||||
|
|
||||||
return keyEnc
|
return keyEnc
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user