@@ -30,7 +30,9 @@ import {
3030 getNextPreKeysNode ,
3131 makeEventBuffer ,
3232 makeNoiseHandler ,
33- promiseTimeout
33+ promiseTimeout ,
34+ signedKeyPair ,
35+ xmppSignedPreKey
3436} from '../Utils'
3537import { getPlatformId } from '../Utils/browser-utils'
3638import {
@@ -204,6 +206,39 @@ export const makeSocket = (config: SocketConfig) => {
204206 return result
205207 }
206208
209+ // Validate current key-bundle on server; on failure, trigger pre-key upload and rethrow
210+ const digestKeyBundle = async ( ) : Promise < void > => {
211+ const res = await query ( {
212+ tag : 'iq' ,
213+ attrs : { to : S_WHATSAPP_NET , type : 'get' , xmlns : 'encrypt' } ,
214+ content : [ { tag : 'digest' , attrs : { } } ]
215+ } )
216+ const digestNode = getBinaryNodeChild ( res , 'digest' )
217+ if ( ! digestNode ) {
218+ await uploadPreKeys ( )
219+ throw new Error ( 'encrypt/get digest returned no digest node' )
220+ }
221+ }
222+
223+ // Rotate our signed pre-key on server; on failure, run digest as fallback and rethrow
224+ const rotateSignedPreKey = async ( ) : Promise < void > => {
225+ const newId = ( creds . signedPreKey . keyId || 0 ) + 1
226+ const skey = await signedKeyPair ( creds . signedIdentityKey , newId )
227+ await query ( {
228+ tag : 'iq' ,
229+ attrs : { to : S_WHATSAPP_NET , type : 'set' , xmlns : 'encrypt' } ,
230+ content : [
231+ {
232+ tag : 'rotate' ,
233+ attrs : { } ,
234+ content : [ xmppSignedPreKey ( skey ) ]
235+ }
236+ ]
237+ } )
238+ // Persist new signed pre-key in creds
239+ ev . emit ( 'creds.update' , { signedPreKey : skey } )
240+ }
241+
207242 const executeUSyncQuery = async ( usyncQuery : USyncQuery ) => {
208243 if ( usyncQuery . protocols . length === 0 ) {
209244 throw new Boom ( 'USyncQuery must have at least one protocol' )
@@ -869,6 +904,13 @@ export const makeSocket = (config: SocketConfig) => {
869904 try {
870905 await uploadPreKeysToServerIfRequired ( )
871906 await sendPassiveIq ( 'active' )
907+
908+ // After successful login, validate our key-bundle against server
909+ try {
910+ await digestKeyBundle ( )
911+ } catch ( e ) {
912+ logger . warn ( { e } , 'failed to run digest after login' )
913+ }
872914 } catch ( err ) {
873915 logger . warn ( { err } , 'failed to send initial passive iq' )
874916 }
@@ -1007,6 +1049,8 @@ export const makeSocket = (config: SocketConfig) => {
10071049 onUnexpectedError,
10081050 uploadPreKeys,
10091051 uploadPreKeysToServerIfRequired,
1052+ digestKeyBundle,
1053+ rotateSignedPreKey,
10101054 requestPairingCode,
10111055 wamBuffer : publicWAMBuffer ,
10121056 /** Waits for the connection to WA to reach a state */
0 commit comments