refactor: cleanup MD socket initial connect code + log more

This commit is contained in:
Adhiraj Singh
2022-03-24 20:33:55 +05:30
parent f82f5470cd
commit 1635b1e756
2 changed files with 31 additions and 21 deletions

View File

@@ -9,6 +9,8 @@ import { AuthenticationCreds, BaileysEventEmitter, DisconnectReason, SocketConfi
import { addTransactionCapability, bindWaitForConnectionUpdate, configureSuccessfulPairing, Curve, encodeBigEndian, generateLoginNode, generateOrGetPreKeys, generateRegistrationNode, getPreKeys, makeNoiseHandler, printQRIfNecessaryListener, promiseTimeout, useSingleFileAuthState, xmppPreKey, xmppSignedPreKey } from '../Utils' import { addTransactionCapability, bindWaitForConnectionUpdate, configureSuccessfulPairing, Curve, encodeBigEndian, generateLoginNode, generateOrGetPreKeys, generateRegistrationNode, getPreKeys, makeNoiseHandler, printQRIfNecessaryListener, promiseTimeout, useSingleFileAuthState, xmppPreKey, xmppSignedPreKey } from '../Utils'
import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, getBinaryNodeChild, S_WHATSAPP_NET } from '../WABinary' import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, getBinaryNodeChild, S_WHATSAPP_NET } from '../WABinary'
const INITIAL_PREKEY_COUNT = 30
/** /**
* Connects to WA servers and performs: * Connects to WA servers and performs:
* - simple queries (no retry mechanism, wait for connection establishment) * - simple queries (no retry mechanism, wait for connection establishment)
@@ -172,30 +174,34 @@ export const makeSocket = ({
/** connection handshake */ /** connection handshake */
const validateConnection = async() => { const validateConnection = async() => {
logger.info({ browser }, 'connected to WA Web') const helloMsg: proto.IHandshakeMessage = {
const init = proto.HandshakeMessage.encode({
clientHello: { ephemeral: ephemeralKeyPair.public } clientHello: { ephemeral: ephemeralKeyPair.public }
}).finish() }
logger.info({ browser, helloMsg }, 'connected to WA Web')
const init = proto.HandshakeMessage.encode(helloMsg).finish()
const result = await awaitNextMessage(init) const result = await awaitNextMessage(init)
const handshake = proto.HandshakeMessage.decode(result) const handshake = proto.HandshakeMessage.decode(result)
logger.debug('handshake recv from WA Web') logger.trace({ handshake }, 'handshake recv from WA Web')
const keyEnc = noise.processHandshake(handshake, creds.noiseKey) const keyEnc = noise.processHandshake(handshake, creds.noiseKey)
logger.info('handshake complete') logger.info('handshake complete')
let node: Uint8Array let node: proto.IClientPayload
if(!creds.me) { if(!creds.me) {
logger.info('not logged in, attempting registration...')
node = generateRegistrationNode(creds, { version, browser }) node = generateRegistrationNode(creds, { version, browser })
logger.info({ node }, 'not logged in, attempting registration...')
} else { } else {
logger.info('logging in...')
node = generateLoginNode(creds.me!.id, { version, browser }) node = generateLoginNode(creds.me!.id, { version, browser })
logger.info({ node }, 'logging in...')
} }
const payloadEnc = noise.encrypt(node) const payloadEnc = noise.encrypt(
proto.ClientPayload.encode(node).finish()
)
await sendRawMessage( await sendRawMessage(
proto.HandshakeMessage.encode({ proto.HandshakeMessage.encode({
clientFinish: { clientFinish: {
@@ -234,7 +240,7 @@ export const makeSocket = ({
/** generates and uploads a set of pre-keys */ /** generates and uploads a set of pre-keys */
const uploadPreKeys = async() => { const uploadPreKeys = async() => {
await assertingPreKeys(30, async preKeys => { await assertingPreKeys(INITIAL_PREKEY_COUNT, async preKeys => {
const node: BinaryNode = { const node: BinaryNode = {
tag: 'iq', tag: 'iq',
attrs: { attrs: {

View File

@@ -7,6 +7,8 @@ import { Curve, hmacSign } from './crypto'
import { encodeInt } from './generics' import { encodeInt } from './generics'
import { createSignalIdentity } from './signal' import { createSignalIdentity } from './signal'
type ClientPayloadConfig = Pick<SocketConfig, 'version' | 'browser'>
const getUserAgent = ({ version }: Pick<SocketConfig, 'version'>): proto.IUserAgent => ({ const getUserAgent = ({ version }: Pick<SocketConfig, 'version'>): proto.IUserAgent => ({
appVersion: { appVersion: {
primary: version[0], primary: version[0],
@@ -29,23 +31,29 @@ const getWebInfo = (): proto.IWebInfo => ({
webSubPlatform: proto.WebInfo.WebInfoWebSubPlatform.WEB_BROWSER webSubPlatform: proto.WebInfo.WebInfoWebSubPlatform.WEB_BROWSER
}) })
export const generateLoginNode = (userJid: string, config: Pick<SocketConfig, 'version' | 'browser'>) => { const getClientPayload = (config: ClientPayloadConfig): proto.IClientPayload => {
const { user, device } = jidDecode(userJid) return {
const payload: proto.IClientPayload = {
passive: true, passive: true,
connectType: proto.ClientPayload.ClientPayloadConnectType.WIFI_UNKNOWN, connectType: proto.ClientPayload.ClientPayloadConnectType.WIFI_UNKNOWN,
connectReason: proto.ClientPayload.ClientPayloadConnectReason.USER_ACTIVATED, connectReason: proto.ClientPayload.ClientPayloadConnectReason.USER_ACTIVATED,
userAgent: getUserAgent(config), userAgent: getUserAgent(config),
webInfo: getWebInfo(), webInfo: getWebInfo(),
}
}
export const generateLoginNode = (userJid: string, config: ClientPayloadConfig): proto.IClientPayload => {
const { user, device } = jidDecode(userJid)
const payload: proto.IClientPayload = {
...getClientPayload(config),
username: +user, username: +user,
device: device, device: device,
} }
return proto.ClientPayload.encode(payload).finish() return payload
} }
export const generateRegistrationNode = ( export const generateRegistrationNode = (
{ registrationId, signedPreKey, signedIdentityKey }: SignalCreds, { registrationId, signedPreKey, signedIdentityKey }: SignalCreds,
config: Pick<SocketConfig, 'version' | 'browser'> config: ClientPayloadConfig
) => { ) => {
// the app version needs to be md5 hashed // the app version needs to be md5 hashed
// and passed in // and passed in
@@ -68,9 +76,7 @@ export const generateRegistrationNode = (
const companionProto = proto.CompanionProps.encode(companion).finish() const companionProto = proto.CompanionProps.encode(companion).finish()
const registerPayload: proto.IClientPayload = { const registerPayload: proto.IClientPayload = {
connectReason: proto.ClientPayload.ClientPayloadConnectReason.USER_ACTIVATED, ...getClientPayload(config),
connectType: proto.ClientPayload.ClientPayloadConnectType.WIFI_UNKNOWN,
passive: false,
regData: { regData: {
buildHash: appVersionBuf, buildHash: appVersionBuf,
companionProps: companionProto, companionProps: companionProto,
@@ -81,11 +87,9 @@ export const generateRegistrationNode = (
eSkeyVal: signedPreKey.keyPair.public, eSkeyVal: signedPreKey.keyPair.public,
eSkeySig: signedPreKey.signature, eSkeySig: signedPreKey.signature,
}, },
userAgent: getUserAgent(config),
webInfo: getWebInfo(),
} }
return proto.ClientPayload.encode(registerPayload).finish() return registerPayload
} }
export const configureSuccessfulPairing = ( export const configureSuccessfulPairing = (