@neelegirl/baileys 1.5.2 → 1.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -18
- package/WAProto/GenerateStatics.sh +3 -0
- package/WAProto/WAProto.proto +291 -665
- package/WAProto/fix-imports.js +29 -0
- package/WAProto/index.d.ts +2297 -48040
- package/WAProto/index.js +45500 -140101
- package/engine-requirements.js +10 -0
- package/lib/Defaults/index.d.ts +58 -64
- package/lib/Defaults/index.d.ts.map +1 -0
- package/lib/Defaults/index.js +74 -96
- package/lib/Defaults/index.js.map +1 -0
- package/lib/Signal/Group/ciphertext-message.d.ts +10 -0
- package/lib/Signal/Group/ciphertext-message.d.ts.map +1 -0
- package/lib/Signal/Group/ciphertext-message.js +12 -0
- package/lib/Signal/Group/ciphertext-message.js.map +1 -0
- package/lib/Signal/Group/group-session-builder.d.ts +15 -0
- package/lib/Signal/Group/group-session-builder.d.ts.map +1 -0
- package/lib/Signal/Group/group-session-builder.js +30 -0
- package/lib/Signal/Group/group-session-builder.js.map +1 -0
- package/lib/Signal/Group/group_cipher.d.ts +17 -0
- package/lib/Signal/Group/group_cipher.d.ts.map +1 -0
- package/lib/Signal/Group/group_cipher.js +82 -0
- package/lib/Signal/Group/group_cipher.js.map +1 -0
- package/lib/Signal/Group/index.d.ts +12 -0
- package/lib/Signal/Group/index.d.ts.map +1 -0
- package/lib/Signal/Group/index.js +12 -0
- package/lib/Signal/Group/index.js.map +1 -0
- package/lib/Signal/Group/keyhelper.d.ts +11 -0
- package/lib/Signal/Group/keyhelper.d.ts.map +1 -0
- package/lib/Signal/Group/keyhelper.js +18 -0
- package/lib/Signal/Group/keyhelper.js.map +1 -0
- package/lib/Signal/Group/sender-chain-key.d.ts +14 -0
- package/lib/Signal/Group/sender-chain-key.d.ts.map +1 -0
- package/lib/Signal/Group/sender-chain-key.js +26 -0
- package/lib/Signal/Group/sender-chain-key.js.map +1 -0
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +17 -0
- package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +63 -0
- package/lib/Signal/Group/sender-key-distribution-message.js.map +1 -0
- package/lib/Signal/Group/sender-key-message.d.ts +19 -0
- package/lib/Signal/Group/sender-key-message.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-message.js +66 -0
- package/lib/Signal/Group/sender-key-message.js.map +1 -0
- package/lib/Signal/Group/sender-key-name.d.ts +18 -0
- package/lib/Signal/Group/sender-key-name.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-name.js +48 -0
- package/lib/Signal/Group/sender-key-name.js.map +1 -0
- package/lib/Signal/Group/sender-key-record.d.ts +31 -0
- package/lib/Signal/Group/sender-key-record.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-record.js +41 -0
- package/lib/Signal/Group/sender-key-record.js.map +1 -0
- package/lib/Signal/Group/sender-key-state.d.ts +39 -0
- package/lib/Signal/Group/sender-key-state.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-state.js +84 -0
- package/lib/Signal/Group/sender-key-state.js.map +1 -0
- package/lib/Signal/Group/sender-message-key.d.ts +12 -0
- package/lib/Signal/Group/sender-message-key.d.ts.map +1 -0
- package/lib/Signal/{WASignalGroup/sender_message_key.js → Group/sender-message-key.js} +3 -16
- package/lib/Signal/Group/sender-message-key.js.map +1 -0
- package/lib/Signal/libsignal.d.ts +5 -4
- package/lib/Signal/libsignal.d.ts.map +1 -0
- package/lib/Signal/libsignal.js +292 -112
- package/lib/Signal/libsignal.js.map +1 -0
- package/lib/Signal/lid-mapping.d.ts +23 -0
- package/lib/Signal/lid-mapping.d.ts.map +1 -0
- package/lib/Signal/lid-mapping.js +171 -0
- package/lib/Signal/lid-mapping.js.map +1 -0
- package/lib/Socket/Client/index.d.ts +3 -2
- package/lib/Socket/Client/index.d.ts.map +1 -0
- package/lib/Socket/Client/index.js +3 -22
- package/lib/Socket/Client/index.js.map +1 -0
- package/lib/Socket/Client/types.d.ts +15 -15
- package/lib/Socket/Client/types.d.ts.map +1 -0
- package/lib/Socket/Client/types.js +8 -15
- package/lib/Socket/Client/types.js.map +1 -0
- package/lib/Socket/Client/websocket.d.ts +12 -12
- package/lib/Socket/Client/websocket.d.ts.map +1 -0
- package/lib/Socket/Client/websocket.js +24 -36
- package/lib/Socket/Client/websocket.js.map +1 -0
- package/lib/Socket/business.d.ts +178 -177
- package/lib/Socket/business.d.ts.map +1 -0
- package/lib/Socket/business.js +179 -71
- package/lib/Socket/business.js.map +1 -0
- package/lib/Socket/chats.d.ts +93 -93
- package/lib/Socket/chats.d.ts.map +1 -0
- package/lib/Socket/chats.js +474 -625
- package/lib/Socket/chats.js.map +1 -0
- package/lib/Socket/communities.d.ts +83 -62
- package/lib/Socket/communities.d.ts.map +1 -0
- package/lib/Socket/communities.js +412 -414
- package/lib/Socket/communities.js.map +1 -0
- package/lib/Socket/groups.d.ts +118 -112
- package/lib/Socket/groups.d.ts.map +1 -0
- package/lib/Socket/groups.js +146 -171
- package/lib/Socket/groups.js.map +1 -0
- package/lib/Socket/index.d.ts +222 -182
- package/lib/Socket/index.d.ts.map +1 -0
- package/lib/Socket/index.js +12 -17
- package/lib/Socket/index.js.map +1 -0
- package/lib/Socket/messages-recv.d.ts +165 -169
- package/lib/Socket/messages-recv.d.ts.map +1 -0
- package/lib/Socket/messages-recv.js +1185 -1721
- package/lib/Socket/messages-recv.js.map +1 -0
- package/lib/Socket/messages-send.d.ts +161 -159
- package/lib/Socket/messages-send.d.ts.map +1 -0
- package/lib/Socket/messages-send.js +650 -991
- package/lib/Socket/messages-send.js.map +1 -0
- package/lib/Socket/mex.d.ts +1 -0
- package/lib/Socket/mex.d.ts.map +1 -0
- package/lib/Socket/mex.js +4 -9
- package/lib/Socket/mex.js.map +1 -0
- package/lib/Socket/newsletter.d.ts +139 -139
- package/lib/Socket/newsletter.d.ts.map +1 -0
- package/lib/Socket/newsletter.js +153 -258
- package/lib/Socket/newsletter.js.map +1 -0
- package/lib/Socket/socket.d.ts +42 -36
- package/lib/Socket/socket.d.ts.map +1 -0
- package/lib/Socket/socket.js +623 -507
- package/lib/Socket/socket.js.map +1 -0
- package/lib/Types/Auth.d.ts +87 -96
- package/lib/Types/Auth.d.ts.map +1 -0
- package/lib/Types/Auth.js +2 -3
- package/lib/Types/Auth.js.map +1 -0
- package/lib/Types/Bussines.d.ts +25 -0
- package/lib/Types/Bussines.d.ts.map +1 -0
- package/lib/Types/Bussines.js +2 -0
- package/lib/Types/Bussines.js.map +1 -0
- package/lib/Types/Call.d.ts +13 -13
- package/lib/Types/Call.d.ts.map +1 -0
- package/lib/Types/Call.js +2 -3
- package/lib/Types/Call.js.map +1 -0
- package/lib/Types/Chat.d.ts +79 -94
- package/lib/Types/Chat.d.ts.map +1 -0
- package/lib/Types/Chat.js +8 -9
- package/lib/Types/Chat.js.map +1 -0
- package/lib/Types/Contact.d.ts +13 -9
- package/lib/Types/Contact.d.ts.map +1 -0
- package/lib/Types/Contact.js +2 -3
- package/lib/Types/Contact.js.map +1 -0
- package/lib/Types/Events.d.ts +152 -179
- package/lib/Types/Events.d.ts.map +1 -0
- package/lib/Types/Events.js +2 -3
- package/lib/Types/Events.js.map +1 -0
- package/lib/Types/GroupMetadata.d.ts +49 -48
- package/lib/Types/GroupMetadata.d.ts.map +1 -0
- package/lib/Types/GroupMetadata.js +2 -3
- package/lib/Types/GroupMetadata.js.map +1 -0
- package/lib/Types/Label.d.ts +13 -14
- package/lib/Types/Label.d.ts.map +1 -0
- package/lib/Types/Label.js +24 -30
- package/lib/Types/Label.js.map +1 -0
- package/lib/Types/LabelAssociation.d.ts +15 -20
- package/lib/Types/LabelAssociation.d.ts.map +1 -0
- package/lib/Types/LabelAssociation.js +6 -12
- package/lib/Types/LabelAssociation.js.map +1 -0
- package/lib/Types/Message.d.ts +234 -404
- package/lib/Types/Message.d.ts.map +1 -0
- package/lib/Types/Message.js +11 -13
- package/lib/Types/Message.js.map +1 -0
- package/lib/Types/Newsletter.d.ts +130 -104
- package/lib/Types/Newsletter.d.ts.map +1 -0
- package/lib/Types/Newsletter.js +31 -40
- package/lib/Types/Newsletter.js.map +1 -0
- package/lib/Types/Product.d.ts +58 -71
- package/lib/Types/Product.d.ts.map +1 -0
- package/lib/Types/Product.js +2 -3
- package/lib/Types/Product.js.map +1 -0
- package/lib/Types/Signal.d.ts +63 -55
- package/lib/Types/Signal.d.ts.map +1 -0
- package/lib/Types/Signal.js +2 -3
- package/lib/Types/Signal.js.map +1 -0
- package/lib/Types/Socket.d.ts +78 -65
- package/lib/Types/Socket.d.ts.map +1 -0
- package/lib/Types/Socket.js +3 -3
- package/lib/Types/Socket.js.map +1 -0
- package/lib/Types/State.d.ts +17 -19
- package/lib/Types/State.d.ts.map +1 -0
- package/lib/Types/State.js +13 -14
- package/lib/Types/State.js.map +1 -0
- package/lib/Types/USync.d.ts +8 -8
- package/lib/Types/USync.d.ts.map +1 -0
- package/lib/Types/USync.js +2 -3
- package/lib/Types/USync.js.map +1 -0
- package/lib/Types/index.d.ts +47 -61
- package/lib/Types/index.d.ts.map +1 -0
- package/lib/Types/index.js +26 -48
- package/lib/Types/index.js.map +1 -0
- package/lib/Utils/auth-utils.d.ts +8 -10
- package/lib/Utils/auth-utils.d.ts.map +1 -0
- package/lib/Utils/auth-utils.js +206 -154
- package/lib/Utils/auth-utils.js.map +1 -0
- package/lib/Utils/baileys-event-stream.d.ts +6 -7
- package/lib/Utils/baileys-event-stream.d.ts.map +1 -0
- package/lib/Utils/baileys-event-stream.js +29 -43
- package/lib/Utils/baileys-event-stream.js.map +1 -0
- package/lib/Utils/browser-utils.d.ts +4 -0
- package/lib/Utils/browser-utils.d.ts.map +1 -0
- package/lib/Utils/browser-utils.js +28 -0
- package/lib/Utils/browser-utils.js.map +1 -0
- package/lib/Utils/business.d.ts +14 -20
- package/lib/Utils/business.d.ts.map +1 -0
- package/lib/Utils/business.js +110 -134
- package/lib/Utils/business.js.map +1 -0
- package/lib/Utils/chat-utils.d.ts +57 -69
- package/lib/Utils/chat-utils.d.ts.map +1 -0
- package/lib/Utils/chat-utils.js +362 -380
- package/lib/Utils/chat-utils.js.map +1 -0
- package/lib/Utils/crypto.d.ts +30 -45
- package/lib/Utils/crypto.d.ts.map +1 -0
- package/lib/Utils/crypto.js +141 -178
- package/lib/Utils/crypto.js.map +1 -0
- package/lib/Utils/decode-wa-message.d.ts +42 -35
- package/lib/Utils/decode-wa-message.d.ts.map +1 -0
- package/lib/Utils/decode-wa-message.js +176 -150
- package/lib/Utils/decode-wa-message.js.map +1 -0
- package/lib/Utils/event-buffer.d.ts +12 -17
- package/lib/Utils/event-buffer.d.ts.map +1 -0
- package/lib/Utils/event-buffer.js +269 -286
- package/lib/Utils/event-buffer.js.map +1 -0
- package/lib/Utils/generics.d.ts +60 -99
- package/lib/Utils/generics.d.ts.map +1 -0
- package/lib/Utils/generics.js +244 -487
- package/lib/Utils/generics.js.map +1 -0
- package/lib/Utils/history.d.ts +18 -22
- package/lib/Utils/history.d.ts.map +1 -0
- package/lib/Utils/history.js +54 -80
- package/lib/Utils/history.js.map +1 -0
- package/lib/Utils/index.d.ts +20 -19
- package/lib/Utils/index.d.ts.map +1 -0
- package/lib/Utils/index.js +19 -39
- package/lib/Utils/index.js.map +1 -0
- package/lib/Utils/link-preview.d.ts +12 -14
- package/lib/Utils/link-preview.d.ts.map +1 -0
- package/lib/Utils/link-preview.js +40 -75
- package/lib/Utils/link-preview.js.map +1 -0
- package/lib/Utils/logger.d.ts +10 -11
- package/lib/Utils/logger.d.ts.map +1 -0
- package/lib/Utils/logger.js +3 -7
- package/lib/Utils/logger.js.map +1 -0
- package/lib/Utils/lt-hash.d.ts +12 -13
- package/lib/Utils/lt-hash.d.ts.map +1 -0
- package/lib/Utils/lt-hash.js +27 -37
- package/lib/Utils/lt-hash.js.map +1 -0
- package/lib/Utils/make-mutex.d.ts +6 -7
- package/lib/Utils/make-mutex.d.ts.map +1 -0
- package/lib/Utils/make-mutex.js +20 -29
- package/lib/Utils/make-mutex.js.map +1 -0
- package/lib/Utils/message-retry-manager.d.ts +82 -0
- package/lib/Utils/message-retry-manager.d.ts.map +1 -0
- package/lib/Utils/message-retry-manager.js +149 -0
- package/lib/Utils/message-retry-manager.js.map +1 -0
- package/lib/Utils/messages-media.d.ts +87 -102
- package/lib/Utils/messages-media.d.ts.map +1 -0
- package/lib/Utils/messages-media.js +427 -570
- package/lib/Utils/messages-media.js.map +1 -0
- package/lib/Utils/messages.d.ts +37 -64
- package/lib/Utils/messages.d.ts.map +1 -0
- package/lib/Utils/messages.js +511 -1270
- package/lib/Utils/messages.js.map +1 -0
- package/lib/Utils/noise-handler.d.ts +18 -18
- package/lib/Utils/noise-handler.d.ts.map +1 -0
- package/lib/Utils/noise-handler.js +101 -109
- package/lib/Utils/noise-handler.js.map +1 -0
- package/lib/Utils/pre-key-manager.d.ts +28 -0
- package/lib/Utils/pre-key-manager.d.ts.map +1 -0
- package/lib/Utils/pre-key-manager.js +106 -0
- package/lib/Utils/pre-key-manager.js.map +1 -0
- package/lib/Utils/process-message.d.ts +25 -32
- package/lib/Utils/process-message.d.ts.map +1 -0
- package/lib/Utils/process-message.js +266 -281
- package/lib/Utils/process-message.js.map +1 -0
- package/lib/Utils/signal.d.ts +24 -32
- package/lib/Utils/signal.d.ts.map +1 -0
- package/lib/Utils/signal.js +98 -105
- package/lib/Utils/signal.js.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.d.ts +5 -10
- package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.js +69 -186
- package/lib/Utils/use-multi-file-auth-state.js.map +1 -0
- package/lib/Utils/validate-connection.d.ts +11 -13
- package/lib/Utils/validate-connection.d.ts.map +1 -0
- package/lib/Utils/validate-connection.js +124 -116
- package/lib/Utils/validate-connection.js.map +1 -0
- package/lib/WABinary/constants.d.ts +25 -27
- package/lib/WABinary/constants.d.ts.map +1 -0
- package/lib/WABinary/constants.js +1277 -1292
- package/lib/WABinary/constants.js.map +1 -0
- package/lib/WABinary/decode.d.ts +7 -9
- package/lib/WABinary/decode.d.ts.map +1 -0
- package/lib/WABinary/decode.js +139 -189
- package/lib/WABinary/decode.js.map +1 -0
- package/lib/WABinary/encode.d.ts +3 -3
- package/lib/WABinary/encode.d.ts.map +1 -0
- package/lib/WABinary/encode.js +105 -154
- package/lib/WABinary/encode.js.map +1 -0
- package/lib/WABinary/generic-utils.d.ts +14 -27
- package/lib/WABinary/generic-utils.d.ts.map +1 -0
- package/lib/WABinary/generic-utils.js +62 -102
- package/lib/WABinary/generic-utils.js.map +1 -0
- package/lib/WABinary/index.d.ts +6 -5
- package/lib/WABinary/index.d.ts.map +1 -0
- package/lib/WABinary/index.js +6 -25
- package/lib/WABinary/index.js.map +1 -0
- package/lib/WABinary/jid-utils.d.ts +41 -46
- package/lib/WABinary/jid-utils.d.ts.map +1 -0
- package/lib/WABinary/jid-utils.js +84 -80
- package/lib/WABinary/jid-utils.js.map +1 -0
- package/lib/WABinary/types.d.ts +10 -13
- package/lib/WABinary/types.d.ts.map +1 -0
- package/lib/WABinary/types.js +2 -3
- package/lib/WABinary/types.js.map +1 -0
- package/lib/WAM/BinaryInfo.d.ts +8 -15
- package/lib/WAM/BinaryInfo.d.ts.map +1 -0
- package/lib/WAM/BinaryInfo.js +7 -14
- package/lib/WAM/BinaryInfo.js.map +1 -0
- package/lib/WAM/constants.d.ts +30 -37
- package/lib/WAM/constants.d.ts.map +1 -0
- package/lib/WAM/constants.js +19193 -11711
- package/lib/WAM/constants.js.map +1 -0
- package/lib/WAM/encode.d.ts +3 -3
- package/lib/WAM/encode.d.ts.map +1 -0
- package/lib/WAM/encode.js +95 -110
- package/lib/WAM/encode.js.map +1 -0
- package/lib/WAM/index.d.ts +4 -3
- package/lib/WAM/index.d.ts.map +1 -0
- package/lib/WAM/index.js +4 -23
- package/lib/WAM/index.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -9
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +12 -19
- package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +19 -22
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +18 -26
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +11 -12
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +12 -20
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +11 -12
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +16 -24
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +26 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +51 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +10 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +29 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/index.d.ts +5 -6
- package/lib/WAUSync/Protocols/index.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/index.js +5 -26
- package/lib/WAUSync/Protocols/index.js.map +1 -0
- package/lib/WAUSync/USyncQuery.d.ts +26 -28
- package/lib/WAUSync/USyncQuery.d.ts.map +1 -0
- package/lib/WAUSync/USyncQuery.js +64 -62
- package/lib/WAUSync/USyncQuery.js.map +1 -0
- package/lib/WAUSync/USyncUser.d.ts +11 -10
- package/lib/WAUSync/USyncUser.d.ts.map +1 -0
- package/lib/WAUSync/USyncUser.js +12 -19
- package/lib/WAUSync/USyncUser.js.map +1 -0
- package/lib/WAUSync/index.d.ts +4 -3
- package/lib/WAUSync/index.d.ts.map +1 -0
- package/lib/WAUSync/index.js +4 -23
- package/lib/WAUSync/index.js.map +1 -0
- package/lib/index.d.ts +10 -11
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +11 -33
- package/lib/index.js.map +1 -0
- package/package.json +48 -43
- package/lib/Defaults/baileys-version.json +0 -3
- package/lib/Defaults/phonenumber-mcc.json +0 -223
- package/lib/Signal/WASignalGroup/GroupProtocol.js +0 -1909
- package/lib/Signal/WASignalGroup/ciphertext_message.js +0 -16
- package/lib/Signal/WASignalGroup/generate-proto.sh +0 -1
- package/lib/Signal/WASignalGroup/group.proto +0 -42
- package/lib/Signal/WASignalGroup/group_cipher.js +0 -120
- package/lib/Signal/WASignalGroup/group_session_builder.js +0 -46
- package/lib/Signal/WASignalGroup/index.js +0 -6
- package/lib/Signal/WASignalGroup/keyhelper.js +0 -21
- package/lib/Signal/WASignalGroup/protobufs.js +0 -3
- package/lib/Signal/WASignalGroup/queue_job.js +0 -69
- package/lib/Signal/WASignalGroup/readme.md +0 -6
- package/lib/Signal/WASignalGroup/sender_chain_key.js +0 -50
- package/lib/Signal/WASignalGroup/sender_key_distribution_message.js +0 -78
- package/lib/Signal/WASignalGroup/sender_key_message.js +0 -92
- package/lib/Signal/WASignalGroup/sender_key_name.js +0 -70
- package/lib/Signal/WASignalGroup/sender_key_record.js +0 -56
- package/lib/Signal/WASignalGroup/sender_key_state.js +0 -129
- package/lib/Socket/Client/abstract-socket-client.d.ts +0 -15
- package/lib/Socket/Client/abstract-socket-client.js +0 -13
- package/lib/Socket/Client/mobile-socket-client.d.ts +0 -12
- package/lib/Socket/Client/mobile-socket-client.js +0 -65
- package/lib/Socket/registration.d.ts +0 -266
- package/lib/Socket/registration.js +0 -166
- package/lib/Socket/usync.d.ts +0 -37
- package/lib/Socket/usync.js +0 -83
- package/lib/Store/index.d.ts +0 -4
- package/lib/Store/index.js +0 -24
- package/lib/Store/make-cache-manager-store.d.ts +0 -14
- package/lib/Store/make-cache-manager-store.js +0 -90
- package/lib/Store/make-in-memory-store.d.ts +0 -123
- package/lib/Store/make-in-memory-store.js +0 -429
- package/lib/Store/make-ordered-dictionary.d.ts +0 -12
- package/lib/Store/make-ordered-dictionary.js +0 -86
- package/lib/Store/object-repository.d.ts +0 -10
- package/lib/Store/object-repository.js +0 -31
- package/lib/Types/MexUpdates.d.ts +0 -9
- package/lib/Types/MexUpdates.js +0 -18
- package/lib/Utils/use-mongo-file-auth-state.d.ts +0 -6
- package/lib/Utils/use-mongo-file-auth-state.js +0 -84
- package/lib/Utils/use-single-file-auth-state.d.ts +0 -13
- package/lib/Utils/use-single-file-auth-state.js +0 -80
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.d.ts +0 -28
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +0 -69
- package/lib/WAUSync/Protocols/USyncLIDProtocol.d.ts +0 -9
- package/lib/WAUSync/Protocols/USyncLIDProtocol.js +0 -30
package/lib/Socket/socket.js
CHANGED
|
@@ -1,218 +1,321 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const Client_1 = require("./Client")
|
|
15
|
-
|
|
1
|
+
import { Boom } from '@hapi/boom';
|
|
2
|
+
import { randomBytes } from 'crypto';
|
|
3
|
+
import { URL } from 'url';
|
|
4
|
+
import { promisify } from 'util';
|
|
5
|
+
import { proto } from '../../WAProto/index.js';
|
|
6
|
+
import { DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, INITIAL_PREKEY_COUNT, MIN_PREKEY_COUNT, MIN_UPLOAD_INTERVAL, NOISE_WA_HEADER, UPLOAD_TIMEOUT } from '../Defaults/index.js';
|
|
7
|
+
import { DisconnectReason } from '../Types/index.js';
|
|
8
|
+
import { addTransactionCapability, aesEncryptCTR, bindWaitForConnectionUpdate, bytesToCrockford, configureSuccessfulPairing, Curve, derivePairingCodeKey, generateLoginNode, generateMdTagPrefix, generateRegistrationNode, getCodeFromWSError, getErrorCodeFromStreamError, getNextPreKeysNode, makeEventBuffer, makeNoiseHandler, promiseTimeout } from '../Utils/index.js';
|
|
9
|
+
import { getPlatformId } from '../Utils/browser-utils.js';
|
|
10
|
+
import { assertNodeErrorFree, binaryNodeToString, encodeBinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isLidUser, jidDecode, jidEncode, S_WHATSAPP_NET } from '../WABinary/index.js';
|
|
11
|
+
import { BinaryInfo } from '../WAM/BinaryInfo.js';
|
|
12
|
+
import { USyncQuery, USyncUser } from '../WAUSync/index.js';
|
|
13
|
+
import { WebSocketClient } from './Client/index.js';
|
|
16
14
|
/**
|
|
17
15
|
* Connects to WA servers and performs:
|
|
18
16
|
* - simple queries (no retry mechanism, wait for connection establishment)
|
|
19
17
|
* - listen to messages and emit events
|
|
20
18
|
* - query phone connection
|
|
21
19
|
*/
|
|
22
|
-
const makeSocket = (config) => {
|
|
23
|
-
const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, browser, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository } = config
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
20
|
+
export const makeSocket = (config) => {
|
|
21
|
+
const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, browser, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository } = config;
|
|
22
|
+
const publicWAMBuffer = new BinaryInfo();
|
|
23
|
+
const uqTagId = generateMdTagPrefix();
|
|
24
|
+
const generateMessageTag = () => `${uqTagId}${epoch++}`;
|
|
25
|
+
if (config.printQRInTerminal) {
|
|
26
|
+
try {
|
|
27
|
+
import('qrcode-terminal').then(qrcode => {
|
|
28
|
+
ev.on('connection.update', ({ qr, connection }) => {
|
|
29
|
+
if (qr) {
|
|
30
|
+
console.log('\n🌸Offizielle @Neelegirl/Baileys Version 1.5.4🌸');
|
|
31
|
+
console.log('。☆✼★━━━━━━━━━━━━★✼☆。');
|
|
32
|
+
console.log('📱 Neuer QR-Code erhalten Powered By @neelegirl/baileys');
|
|
33
|
+
qrcode.default.generate(qr, { small: true });
|
|
34
|
+
console.log('。☆✼★━━━━━━━━━━━━★✼☆。\n');
|
|
35
|
+
}
|
|
36
|
+
if (connection === 'open') {
|
|
37
|
+
//console.log('✅ Verbindung zu WhatsApp erfolgreich aufgebaut!');
|
|
38
|
+
}
|
|
39
|
+
if (connection === 'close') {
|
|
40
|
+
//console.log('❌ Verbindung geschlossen. Warte auf neuen QR...');
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}).catch(() => {
|
|
44
|
+
//console.warn('⚠️ QR-Terminal-Modul nicht gefunden. Installiere es mit: npm install qrcode-terminal');
|
|
45
|
+
});
|
|
46
|
+
} catch (err) {
|
|
47
|
+
//console.warn('⚠️ Fehler beim Laden von qrcode-terminal:', err.message);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const url = typeof waWebSocketUrl === 'string' ? new URL(waWebSocketUrl) : waWebSocketUrl;
|
|
27
52
|
if (config.mobile || url.protocol === 'tcp:') {
|
|
28
|
-
throw new
|
|
53
|
+
throw new Boom('Mobile API is not supported anymore', { statusCode: DisconnectReason.loggedOut });
|
|
29
54
|
}
|
|
30
|
-
|
|
31
55
|
if (url.protocol === 'wss' && authState?.creds?.routingInfo) {
|
|
32
|
-
url.searchParams.append('ED', authState.creds.routingInfo.toString('base64url'))
|
|
56
|
+
url.searchParams.append('ED', authState.creds.routingInfo.toString('base64url'));
|
|
33
57
|
}
|
|
34
|
-
|
|
35
|
-
const ws = new Client_1.WebSocketClient(url, config)
|
|
36
|
-
|
|
37
|
-
ws.connect()
|
|
38
|
-
const ev = Utils_1.makeEventBuffer(logger)
|
|
39
|
-
|
|
40
58
|
/** ephemeral key pair used to encrypt/decrypt communication. Unique for each connection */
|
|
41
|
-
const ephemeralKeyPair =
|
|
42
|
-
|
|
59
|
+
const ephemeralKeyPair = Curve.generateKeyPair();
|
|
43
60
|
/** WA noise protocol wrapper */
|
|
44
|
-
const noise =
|
|
61
|
+
const noise = makeNoiseHandler({
|
|
45
62
|
keyPair: ephemeralKeyPair,
|
|
46
|
-
NOISE_HEADER:
|
|
63
|
+
NOISE_HEADER: NOISE_WA_HEADER,
|
|
47
64
|
logger,
|
|
48
65
|
routingInfo: authState?.creds?.routingInfo
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
// add transaction capability
|
|
54
|
-
const keys = Utils_1.addTransactionCapability(authState.keys, logger, transactionOpts)
|
|
55
|
-
const signalRepository = makeSignalRepository({ creds, keys })
|
|
56
|
-
|
|
57
|
-
let lastDateRecv
|
|
58
|
-
let epoch = 1
|
|
59
|
-
let keepAliveReq
|
|
60
|
-
let qrTimer
|
|
61
|
-
let closed = false
|
|
62
|
-
|
|
63
|
-
const uqTagId = Utils_1.generateMdTagPrefix()
|
|
64
|
-
const generateMessageTag = () => `${uqTagId}${epoch++}`
|
|
65
|
-
const sendPromise = util_1.promisify(ws.send)
|
|
66
|
-
|
|
66
|
+
});
|
|
67
|
+
const ws = new WebSocketClient(url, config);
|
|
68
|
+
ws.connect();
|
|
69
|
+
const sendPromise = promisify(ws.send);
|
|
67
70
|
/** send a raw buffer */
|
|
68
71
|
const sendRawMessage = async (data) => {
|
|
69
72
|
if (!ws.isOpen) {
|
|
70
|
-
throw new
|
|
73
|
+
throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed });
|
|
71
74
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
await Utils_1.promiseTimeout(connectTimeoutMs, async (resolve, reject) => {
|
|
75
|
+
const bytes = noise.encodeFrame(data);
|
|
76
|
+
await promiseTimeout(connectTimeoutMs, async (resolve, reject) => {
|
|
75
77
|
try {
|
|
76
|
-
await sendPromise.call(ws, bytes)
|
|
77
|
-
resolve()
|
|
78
|
+
await sendPromise.call(ws, bytes);
|
|
79
|
+
resolve();
|
|
78
80
|
}
|
|
79
81
|
catch (error) {
|
|
80
|
-
reject(error)
|
|
82
|
+
reject(error);
|
|
81
83
|
}
|
|
82
|
-
})
|
|
83
|
-
}
|
|
84
|
-
|
|
84
|
+
});
|
|
85
|
+
};
|
|
85
86
|
/** send a binary node */
|
|
86
87
|
const sendNode = (frame) => {
|
|
87
88
|
if (logger.level === 'trace') {
|
|
88
|
-
logger.trace({ xml:
|
|
89
|
+
logger.trace({ xml: binaryNodeToString(frame), msg: 'xml send' });
|
|
89
90
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return sendRawMessage(buff)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/** log & process any unexpected errors */
|
|
97
|
-
const onUnexpectedError = (err, msg) => {
|
|
98
|
-
logger.error({ err }, `unexpected error in '${msg}'`)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/** await the next incoming message */
|
|
102
|
-
const awaitNextMessage = async (sendMsg) => {
|
|
103
|
-
if (!ws.isOpen) {
|
|
104
|
-
throw new boom_1.Boom('Connection Closed', {
|
|
105
|
-
statusCode: Types_1.DisconnectReason.connectionClosed
|
|
106
|
-
})
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
let onOpen
|
|
110
|
-
let onClose
|
|
111
|
-
|
|
112
|
-
const result = Utils_1.promiseTimeout(connectTimeoutMs, (resolve, reject) => {
|
|
113
|
-
onOpen = resolve
|
|
114
|
-
onClose = mapWebSocketError(reject)
|
|
115
|
-
ws.on('frame', onOpen)
|
|
116
|
-
ws.on('close', onClose)
|
|
117
|
-
ws.on('error', onClose)
|
|
118
|
-
}).finally(() => {
|
|
119
|
-
ws.off('frame', onOpen)
|
|
120
|
-
ws.off('close', onClose)
|
|
121
|
-
ws.off('error', onClose)
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
if (sendMsg) {
|
|
125
|
-
sendRawMessage(sendMsg).catch(onClose)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return result
|
|
129
|
-
}
|
|
130
|
-
|
|
91
|
+
const buff = encodeBinaryNode(frame);
|
|
92
|
+
return sendRawMessage(buff);
|
|
93
|
+
};
|
|
131
94
|
/**
|
|
132
95
|
* Wait for a message with a certain tag to be received
|
|
133
96
|
* @param msgId the message tag to await
|
|
134
97
|
* @param timeoutMs timeout after which the promise will reject
|
|
135
98
|
*/
|
|
136
99
|
const waitForMessage = async (msgId, timeoutMs = defaultQueryTimeoutMs) => {
|
|
137
|
-
let onRecv
|
|
138
|
-
let onErr
|
|
100
|
+
let onRecv;
|
|
101
|
+
let onErr;
|
|
139
102
|
try {
|
|
140
|
-
|
|
141
|
-
onRecv =
|
|
103
|
+
const result = await promiseTimeout(timeoutMs, (resolve, reject) => {
|
|
104
|
+
onRecv = data => {
|
|
105
|
+
resolve(data);
|
|
106
|
+
};
|
|
142
107
|
onErr = err => {
|
|
143
|
-
reject(err ||
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
108
|
+
reject(err ||
|
|
109
|
+
new Boom('Connection Closed', {
|
|
110
|
+
statusCode: DisconnectReason.connectionClosed
|
|
111
|
+
}));
|
|
112
|
+
};
|
|
113
|
+
ws.on(`TAG:${msgId}`, onRecv);
|
|
114
|
+
ws.on('close', onErr);
|
|
115
|
+
ws.on('error', onErr);
|
|
116
|
+
return () => reject(new Boom('Query Cancelled'));
|
|
117
|
+
});
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
// Catch timeout and return undefined instead of throwing
|
|
122
|
+
if (error instanceof Boom && error.output?.statusCode === DisconnectReason.timedOut) {
|
|
123
|
+
logger?.warn?.({ msgId }, 'timed out waiting for message');
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
throw error;
|
|
149
127
|
}
|
|
150
|
-
|
|
151
128
|
finally {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
129
|
+
if (onRecv)
|
|
130
|
+
ws.off(`TAG:${msgId}`, onRecv);
|
|
131
|
+
if (onErr) {
|
|
132
|
+
ws.off('close', onErr);
|
|
133
|
+
ws.off('error', onErr);
|
|
134
|
+
}
|
|
155
135
|
}
|
|
156
|
-
}
|
|
157
|
-
|
|
136
|
+
};
|
|
158
137
|
/** send a query, and wait for its response. auto-generates message ID if not provided */
|
|
159
138
|
const query = async (node, timeoutMs) => {
|
|
160
139
|
if (!node.attrs.id) {
|
|
161
|
-
node.attrs.id = generateMessageTag()
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
140
|
+
node.attrs.id = generateMessageTag();
|
|
141
|
+
}
|
|
142
|
+
const msgId = node.attrs.id;
|
|
143
|
+
const result = await promiseTimeout(timeoutMs, async (resolve, reject) => {
|
|
144
|
+
const result = waitForMessage(msgId, timeoutMs).catch(reject);
|
|
145
|
+
sendNode(node)
|
|
146
|
+
.then(async () => resolve(await result))
|
|
147
|
+
.catch(reject);
|
|
148
|
+
});
|
|
149
|
+
if (result && 'tag' in result) {
|
|
150
|
+
assertNodeErrorFree(result);
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
};
|
|
154
|
+
const executeUSyncQuery = async (usyncQuery) => {
|
|
155
|
+
if (usyncQuery.protocols.length === 0) {
|
|
156
|
+
throw new Boom('USyncQuery must have at least one protocol');
|
|
157
|
+
}
|
|
158
|
+
// todo: validate users, throw WARNING on no valid users
|
|
159
|
+
// variable below has only validated users
|
|
160
|
+
const validUsers = usyncQuery.users;
|
|
161
|
+
const userNodes = validUsers.map(user => {
|
|
162
|
+
return {
|
|
163
|
+
tag: 'user',
|
|
164
|
+
attrs: {
|
|
165
|
+
jid: !user.phone ? user.id : undefined
|
|
166
|
+
},
|
|
167
|
+
content: usyncQuery.protocols.map(a => a.getUserElement(user)).filter(a => a !== null)
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
const listNode = {
|
|
171
|
+
tag: 'list',
|
|
172
|
+
attrs: {},
|
|
173
|
+
content: userNodes
|
|
174
|
+
};
|
|
175
|
+
const queryNode = {
|
|
176
|
+
tag: 'query',
|
|
177
|
+
attrs: {},
|
|
178
|
+
content: usyncQuery.protocols.map(a => a.getQueryElement())
|
|
179
|
+
};
|
|
180
|
+
const iq = {
|
|
181
|
+
tag: 'iq',
|
|
182
|
+
attrs: {
|
|
183
|
+
to: S_WHATSAPP_NET,
|
|
184
|
+
type: 'get',
|
|
185
|
+
xmlns: 'usync'
|
|
186
|
+
},
|
|
187
|
+
content: [
|
|
188
|
+
{
|
|
189
|
+
tag: 'usync',
|
|
190
|
+
attrs: {
|
|
191
|
+
context: usyncQuery.context,
|
|
192
|
+
mode: usyncQuery.mode,
|
|
193
|
+
sid: generateMessageTag(),
|
|
194
|
+
last: 'true',
|
|
195
|
+
index: '0'
|
|
196
|
+
},
|
|
197
|
+
content: [queryNode, listNode]
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
};
|
|
201
|
+
const result = await query(iq);
|
|
202
|
+
return usyncQuery.parseUSyncQueryResult(result);
|
|
203
|
+
};
|
|
204
|
+
const onWhatsApp = async (...phoneNumber) => {
|
|
205
|
+
let usyncQuery = new USyncQuery();
|
|
206
|
+
let contactEnabled = false;
|
|
207
|
+
for (const jid of phoneNumber) {
|
|
208
|
+
if (isLidUser(jid)) {
|
|
209
|
+
logger?.warn('LIDs are not supported with onWhatsApp');
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
if (!contactEnabled) {
|
|
214
|
+
contactEnabled = true;
|
|
215
|
+
usyncQuery = usyncQuery.withContactProtocol();
|
|
216
|
+
}
|
|
217
|
+
const phone = `+${jid.replace('+', '').split('@')[0]?.split(':')[0]}`;
|
|
218
|
+
usyncQuery.withUser(new USyncUser().withPhone(phone));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (usyncQuery.users.length === 0) {
|
|
222
|
+
return []; // return early without forcing an empty query
|
|
223
|
+
}
|
|
224
|
+
const results = await executeUSyncQuery(usyncQuery);
|
|
225
|
+
if (results) {
|
|
226
|
+
return results.list.filter(a => !!a.contact).map(({ contact, id }) => ({ jid: id, exists: contact }));
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
const pnFromLIDUSync = async (jids) => {
|
|
230
|
+
const usyncQuery = new USyncQuery().withLIDProtocol().withContext('background');
|
|
231
|
+
for (const jid of jids) {
|
|
232
|
+
if (isLidUser(jid)) {
|
|
233
|
+
logger?.warn('LID user found in LID fetch call');
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
usyncQuery.withUser(new USyncUser().withId(jid));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (usyncQuery.users.length === 0) {
|
|
241
|
+
return []; // return early without forcing an empty query
|
|
242
|
+
}
|
|
243
|
+
const results = await executeUSyncQuery(usyncQuery);
|
|
244
|
+
if (results) {
|
|
245
|
+
return results.list.filter(a => !!a.lid).map(({ lid, id }) => ({ pn: id, lid: lid }));
|
|
246
|
+
}
|
|
247
|
+
return [];
|
|
248
|
+
};
|
|
249
|
+
const ev = makeEventBuffer(logger);
|
|
250
|
+
const { creds } = authState;
|
|
251
|
+
// add transaction capability
|
|
252
|
+
const keys = addTransactionCapability(authState.keys, logger, transactionOpts);
|
|
253
|
+
const signalRepository = makeSignalRepository({ creds, keys }, logger, pnFromLIDUSync);
|
|
254
|
+
let lastDateRecv;
|
|
255
|
+
let epoch = 1;
|
|
256
|
+
let keepAliveReq;
|
|
257
|
+
let qrTimer;
|
|
258
|
+
let closed = false;
|
|
259
|
+
/** log & process any unexpected errors */
|
|
260
|
+
const onUnexpectedError = (err, msg) => {
|
|
261
|
+
logger.error({ err }, `unexpected error in '${msg}'`);
|
|
262
|
+
};
|
|
263
|
+
/** await the next incoming message */
|
|
264
|
+
const awaitNextMessage = async (sendMsg) => {
|
|
265
|
+
if (!ws.isOpen) {
|
|
266
|
+
throw new Boom('Connection Closed', {
|
|
267
|
+
statusCode: DisconnectReason.connectionClosed
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
let onOpen;
|
|
271
|
+
let onClose;
|
|
272
|
+
const result = promiseTimeout(connectTimeoutMs, (resolve, reject) => {
|
|
273
|
+
onOpen = resolve;
|
|
274
|
+
onClose = mapWebSocketError(reject);
|
|
275
|
+
ws.on('frame', onOpen);
|
|
276
|
+
ws.on('close', onClose);
|
|
277
|
+
ws.on('error', onClose);
|
|
278
|
+
}).finally(() => {
|
|
279
|
+
ws.off('frame', onOpen);
|
|
280
|
+
ws.off('close', onClose);
|
|
281
|
+
ws.off('error', onClose);
|
|
282
|
+
});
|
|
283
|
+
if (sendMsg) {
|
|
284
|
+
sendRawMessage(sendMsg).catch(onClose);
|
|
285
|
+
}
|
|
286
|
+
return result;
|
|
287
|
+
};
|
|
177
288
|
/** connection handshake */
|
|
178
289
|
const validateConnection = async () => {
|
|
179
290
|
let helloMsg = {
|
|
180
291
|
clientHello: { ephemeral: ephemeralKeyPair.public }
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
helloMsg
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
logger.trace({ handshake }, 'handshake recv from WA')
|
|
191
|
-
|
|
192
|
-
const keyEnc = await noise.processHandshake(handshake, creds.noiseKey)
|
|
193
|
-
let node
|
|
194
|
-
|
|
292
|
+
};
|
|
293
|
+
helloMsg = proto.HandshakeMessage.fromObject(helloMsg);
|
|
294
|
+
logger.info({ browser, helloMsg }, 'connected to WA');
|
|
295
|
+
const init = proto.HandshakeMessage.encode(helloMsg).finish();
|
|
296
|
+
const result = await awaitNextMessage(init);
|
|
297
|
+
const handshake = proto.HandshakeMessage.decode(result);
|
|
298
|
+
logger.trace({ handshake }, 'handshake recv from WA');
|
|
299
|
+
const keyEnc = await noise.processHandshake(handshake, creds.noiseKey);
|
|
300
|
+
let node;
|
|
195
301
|
if (!creds.me) {
|
|
196
|
-
node =
|
|
197
|
-
logger.info({ node }, 'not logged in, attempting registration...')
|
|
302
|
+
node = generateRegistrationNode(creds, config);
|
|
303
|
+
logger.info({ node }, 'not logged in, attempting registration...');
|
|
198
304
|
}
|
|
199
|
-
|
|
200
305
|
else {
|
|
201
|
-
node =
|
|
202
|
-
logger.info({ node }, 'logging in...')
|
|
306
|
+
node = generateLoginNode(creds.me.id, config);
|
|
307
|
+
logger.info({ node }, 'logging in...');
|
|
203
308
|
}
|
|
204
|
-
const payloadEnc = noise.encrypt(
|
|
205
|
-
|
|
206
|
-
await sendRawMessage(WAProto_1.proto.HandshakeMessage.encode({
|
|
309
|
+
const payloadEnc = noise.encrypt(proto.ClientPayload.encode(node).finish());
|
|
310
|
+
await sendRawMessage(proto.HandshakeMessage.encode({
|
|
207
311
|
clientFinish: {
|
|
208
312
|
static: keyEnc,
|
|
209
|
-
payload: payloadEnc
|
|
210
|
-
}
|
|
211
|
-
}).finish())
|
|
212
|
-
noise.finishInit()
|
|
213
|
-
startKeepAliveRequest()
|
|
214
|
-
}
|
|
215
|
-
|
|
313
|
+
payload: payloadEnc
|
|
314
|
+
}
|
|
315
|
+
}).finish());
|
|
316
|
+
noise.finishInit();
|
|
317
|
+
startKeepAliveRequest();
|
|
318
|
+
};
|
|
216
319
|
const getAvailablePreKeysOnServer = async () => {
|
|
217
320
|
const result = await query({
|
|
218
321
|
tag: 'iq',
|
|
@@ -220,193 +323,240 @@ const makeSocket = (config) => {
|
|
|
220
323
|
id: generateMessageTag(),
|
|
221
324
|
xmlns: 'encrypt',
|
|
222
325
|
type: 'get',
|
|
223
|
-
to:
|
|
326
|
+
to: S_WHATSAPP_NET
|
|
224
327
|
},
|
|
225
|
-
content: [
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
|
|
328
|
+
content: [{ tag: 'count', attrs: {} }]
|
|
329
|
+
});
|
|
330
|
+
const countChild = getBinaryNodeChild(result, 'count');
|
|
331
|
+
return +countChild.attrs.value;
|
|
332
|
+
};
|
|
333
|
+
// Pre-key upload state management
|
|
334
|
+
let uploadPreKeysPromise = null;
|
|
335
|
+
let lastUploadTime = 0;
|
|
235
336
|
/** generates and uploads a set of pre-keys to the server */
|
|
236
|
-
const uploadPreKeys = async (count =
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
337
|
+
const uploadPreKeys = async (count = MIN_PREKEY_COUNT, retryCount = 0) => {
|
|
338
|
+
// Check minimum interval (except for retries)
|
|
339
|
+
if (retryCount === 0) {
|
|
340
|
+
const timeSinceLastUpload = Date.now() - lastUploadTime;
|
|
341
|
+
if (timeSinceLastUpload < MIN_UPLOAD_INTERVAL) {
|
|
342
|
+
logger.debug(`Skipping upload, only ${timeSinceLastUpload}ms since last upload`);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// Prevent multiple concurrent uploads
|
|
347
|
+
if (uploadPreKeysPromise) {
|
|
348
|
+
logger.debug('Pre-key upload already in progress, waiting for completion');
|
|
349
|
+
await uploadPreKeysPromise;
|
|
350
|
+
}
|
|
351
|
+
const uploadLogic = async () => {
|
|
352
|
+
logger.info({ count, retryCount }, 'uploading pre-keys');
|
|
353
|
+
// Generate and save pre-keys atomically (prevents ID collisions on retry)
|
|
354
|
+
const node = await keys.transaction(async () => {
|
|
355
|
+
logger.debug({ requestedCount: count }, 'generating pre-keys with requested count');
|
|
356
|
+
const { update, node } = await getNextPreKeysNode({ creds, keys }, count);
|
|
357
|
+
// Update credentials immediately to prevent duplicate IDs on retry
|
|
358
|
+
ev.emit('creds.update', update);
|
|
359
|
+
return node; // Only return node since update is already used
|
|
360
|
+
}, creds?.me?.id || 'upload-pre-keys');
|
|
361
|
+
// Upload to server (outside transaction, can fail without affecting local keys)
|
|
362
|
+
try {
|
|
363
|
+
await query(node);
|
|
364
|
+
logger.info({ count }, 'uploaded pre-keys successfully');
|
|
365
|
+
lastUploadTime = Date.now();
|
|
366
|
+
}
|
|
367
|
+
catch (uploadError) {
|
|
368
|
+
logger.error({ uploadError: uploadError.toString(), count }, 'Failed to upload pre-keys to server');
|
|
369
|
+
// Exponential backoff retry (max 3 retries)
|
|
370
|
+
if (retryCount < 3) {
|
|
371
|
+
const backoffDelay = Math.min(1000 * Math.pow(2, retryCount), 10000);
|
|
372
|
+
logger.info(`Retrying pre-key upload in ${backoffDelay}ms`);
|
|
373
|
+
await new Promise(resolve => setTimeout(resolve, backoffDelay));
|
|
374
|
+
return uploadPreKeys(count, retryCount + 1);
|
|
375
|
+
}
|
|
376
|
+
throw uploadError;
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
// Add timeout protection
|
|
380
|
+
uploadPreKeysPromise = Promise.race([
|
|
381
|
+
uploadLogic(),
|
|
382
|
+
new Promise((_, reject) => setTimeout(() => reject(new Boom('Pre-key upload timeout', { statusCode: 408 })), UPLOAD_TIMEOUT))
|
|
383
|
+
]);
|
|
384
|
+
try {
|
|
385
|
+
await uploadPreKeysPromise;
|
|
386
|
+
}
|
|
387
|
+
finally {
|
|
388
|
+
uploadPreKeysPromise = null;
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
const verifyCurrentPreKeyExists = async () => {
|
|
392
|
+
const currentPreKeyId = creds.nextPreKeyId - 1;
|
|
393
|
+
if (currentPreKeyId <= 0) {
|
|
394
|
+
return { exists: false, currentPreKeyId: 0 };
|
|
395
|
+
}
|
|
396
|
+
const preKeys = await keys.get('pre-key', [currentPreKeyId.toString()]);
|
|
397
|
+
const exists = !!preKeys[currentPreKeyId.toString()];
|
|
398
|
+
return { exists, currentPreKeyId };
|
|
399
|
+
};
|
|
246
400
|
const uploadPreKeysToServerIfRequired = async () => {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
401
|
+
try {
|
|
402
|
+
let count = 0;
|
|
403
|
+
const preKeyCount = await getAvailablePreKeysOnServer();
|
|
404
|
+
if (preKeyCount === 0)
|
|
405
|
+
count = INITIAL_PREKEY_COUNT;
|
|
406
|
+
else
|
|
407
|
+
count = MIN_PREKEY_COUNT;
|
|
408
|
+
const { exists: currentPreKeyExists, currentPreKeyId } = await verifyCurrentPreKeyExists();
|
|
409
|
+
logger.info(`${preKeyCount} pre-keys found on server`);
|
|
410
|
+
logger.info(`Current prekey ID: ${currentPreKeyId}, exists in storage: ${currentPreKeyExists}`);
|
|
411
|
+
const lowServerCount = preKeyCount <= count;
|
|
412
|
+
const missingCurrentPreKey = !currentPreKeyExists && currentPreKeyId > 0;
|
|
413
|
+
const shouldUpload = lowServerCount || missingCurrentPreKey;
|
|
414
|
+
if (shouldUpload) {
|
|
415
|
+
const reasons = [];
|
|
416
|
+
if (lowServerCount)
|
|
417
|
+
reasons.push(`server count low (${preKeyCount})`);
|
|
418
|
+
if (missingCurrentPreKey)
|
|
419
|
+
reasons.push(`current prekey ${currentPreKeyId} missing from storage`);
|
|
420
|
+
logger.info(`Uploading PreKeys due to: ${reasons.join(', ')}`);
|
|
421
|
+
await uploadPreKeys(count);
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
logger.info(`PreKey validation passed - Server: ${preKeyCount}, Current prekey ${currentPreKeyId} exists`);
|
|
425
|
+
}
|
|
252
426
|
}
|
|
253
|
-
|
|
254
|
-
|
|
427
|
+
catch (error) {
|
|
428
|
+
logger.error({ error }, 'Failed to check/upload pre-keys during initialization');
|
|
429
|
+
// Don't throw - allow connection to continue even if pre-key check fails
|
|
430
|
+
}
|
|
431
|
+
};
|
|
255
432
|
const onMessageReceived = (data) => {
|
|
256
433
|
noise.decodeFrame(data, frame => {
|
|
257
434
|
// reset ping timeout
|
|
258
|
-
lastDateRecv = new Date()
|
|
259
|
-
let anyTriggered = false
|
|
260
|
-
anyTriggered = ws.emit('frame', frame)
|
|
261
|
-
|
|
435
|
+
lastDateRecv = new Date();
|
|
436
|
+
let anyTriggered = false;
|
|
437
|
+
anyTriggered = ws.emit('frame', frame);
|
|
262
438
|
// if it's a binary node
|
|
263
439
|
if (!(frame instanceof Uint8Array)) {
|
|
264
|
-
const msgId = frame.attrs.id
|
|
265
|
-
|
|
440
|
+
const msgId = frame.attrs.id;
|
|
266
441
|
if (logger.level === 'trace') {
|
|
267
|
-
logger.trace({ xml:
|
|
442
|
+
logger.trace({ xml: binaryNodeToString(frame), msg: 'recv xml' });
|
|
268
443
|
}
|
|
269
|
-
|
|
270
444
|
/* Check if this is a response to a message we sent */
|
|
271
|
-
anyTriggered = ws.emit(`${
|
|
272
|
-
|
|
445
|
+
anyTriggered = ws.emit(`${DEF_TAG_PREFIX}${msgId}`, frame) || anyTriggered;
|
|
273
446
|
/* Check if this is a response to a message we are expecting */
|
|
274
|
-
const l0 = frame.tag
|
|
275
|
-
const l1 = frame.attrs || {}
|
|
276
|
-
const l2 = Array.isArray(frame.content) ? frame.content[0]?.tag : ''
|
|
277
|
-
|
|
447
|
+
const l0 = frame.tag;
|
|
448
|
+
const l1 = frame.attrs || {};
|
|
449
|
+
const l2 = Array.isArray(frame.content) ? frame.content[0]?.tag : '';
|
|
278
450
|
for (const key of Object.keys(l1)) {
|
|
279
|
-
anyTriggered = ws.emit(`${
|
|
280
|
-
anyTriggered = ws.emit(`${
|
|
281
|
-
anyTriggered = ws.emit(`${
|
|
451
|
+
anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, frame) || anyTriggered;
|
|
452
|
+
anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, frame) || anyTriggered;
|
|
453
|
+
anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}`, frame) || anyTriggered;
|
|
282
454
|
}
|
|
283
|
-
|
|
284
|
-
anyTriggered = ws.emit(`${
|
|
285
|
-
anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0}`, frame) || anyTriggered
|
|
286
|
-
|
|
455
|
+
anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},,${l2}`, frame) || anyTriggered;
|
|
456
|
+
anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0}`, frame) || anyTriggered;
|
|
287
457
|
if (!anyTriggered && logger.level === 'debug') {
|
|
288
|
-
logger.debug({ unhandled: true, msgId, fromMe: false, frame }, 'communication recv')
|
|
458
|
+
logger.debug({ unhandled: true, msgId, fromMe: false, frame }, 'communication recv');
|
|
289
459
|
}
|
|
290
460
|
}
|
|
291
|
-
})
|
|
292
|
-
}
|
|
293
|
-
|
|
461
|
+
});
|
|
462
|
+
};
|
|
294
463
|
const end = (error) => {
|
|
295
464
|
if (closed) {
|
|
296
|
-
logger.trace({ trace: error?.stack }, 'connection already closed')
|
|
297
|
-
return
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
ws.removeAllListeners('
|
|
306
|
-
ws.removeAllListeners('open')
|
|
307
|
-
ws.removeAllListeners('message')
|
|
308
|
-
|
|
465
|
+
logger.trace({ trace: error?.stack }, 'connection already closed');
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
closed = true;
|
|
469
|
+
logger.info({ trace: error?.stack }, error ? 'connection errored' : 'connection closed');
|
|
470
|
+
clearInterval(keepAliveReq);
|
|
471
|
+
clearTimeout(qrTimer);
|
|
472
|
+
ws.removeAllListeners('close');
|
|
473
|
+
ws.removeAllListeners('open');
|
|
474
|
+
ws.removeAllListeners('message');
|
|
309
475
|
if (!ws.isClosed && !ws.isClosing) {
|
|
310
476
|
try {
|
|
311
|
-
ws.close()
|
|
477
|
+
ws.close();
|
|
312
478
|
}
|
|
313
|
-
catch
|
|
479
|
+
catch { }
|
|
314
480
|
}
|
|
315
|
-
|
|
316
481
|
ev.emit('connection.update', {
|
|
317
482
|
connection: 'close',
|
|
318
483
|
lastDisconnect: {
|
|
319
484
|
error,
|
|
320
485
|
date: new Date()
|
|
321
486
|
}
|
|
322
|
-
})
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
}
|
|
326
|
-
|
|
487
|
+
});
|
|
488
|
+
ev.removeAllListeners('connection.update');
|
|
489
|
+
};
|
|
327
490
|
const waitForSocketOpen = async () => {
|
|
328
491
|
if (ws.isOpen) {
|
|
329
|
-
return
|
|
492
|
+
return;
|
|
330
493
|
}
|
|
331
|
-
|
|
332
494
|
if (ws.isClosed || ws.isClosing) {
|
|
333
|
-
throw new
|
|
495
|
+
throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed });
|
|
334
496
|
}
|
|
335
|
-
|
|
336
|
-
let
|
|
337
|
-
let onClose
|
|
338
|
-
|
|
497
|
+
let onOpen;
|
|
498
|
+
let onClose;
|
|
339
499
|
await new Promise((resolve, reject) => {
|
|
340
|
-
onOpen = () => resolve(undefined)
|
|
341
|
-
onClose = mapWebSocketError(reject)
|
|
342
|
-
ws.on('open', onOpen)
|
|
343
|
-
ws.on('close', onClose)
|
|
344
|
-
ws.on('error', onClose)
|
|
500
|
+
onOpen = () => resolve(undefined);
|
|
501
|
+
onClose = mapWebSocketError(reject);
|
|
502
|
+
ws.on('open', onOpen);
|
|
503
|
+
ws.on('close', onClose);
|
|
504
|
+
ws.on('error', onClose);
|
|
345
505
|
}).finally(() => {
|
|
346
|
-
ws.off('open', onOpen)
|
|
347
|
-
ws.off('close', onClose)
|
|
348
|
-
ws.off('error', onClose)
|
|
349
|
-
})
|
|
350
|
-
}
|
|
351
|
-
|
|
506
|
+
ws.off('open', onOpen);
|
|
507
|
+
ws.off('close', onClose);
|
|
508
|
+
ws.off('error', onClose);
|
|
509
|
+
});
|
|
510
|
+
};
|
|
352
511
|
const startKeepAliveRequest = () => (keepAliveReq = setInterval(() => {
|
|
353
512
|
if (!lastDateRecv) {
|
|
354
|
-
lastDateRecv = new Date()
|
|
513
|
+
lastDateRecv = new Date();
|
|
355
514
|
}
|
|
356
|
-
|
|
357
|
-
const diff = Date.now() - lastDateRecv.getTime()
|
|
358
|
-
|
|
515
|
+
const diff = Date.now() - lastDateRecv.getTime();
|
|
359
516
|
/*
|
|
360
517
|
check if it's been a suspicious amount of time since the server responded with our last seen
|
|
361
518
|
it could be that the network is down
|
|
362
519
|
*/
|
|
363
520
|
if (diff > keepAliveIntervalMs + 5000) {
|
|
364
|
-
end(new
|
|
521
|
+
end(new Boom('Connection was lost', { statusCode: DisconnectReason.connectionLost }));
|
|
365
522
|
}
|
|
366
|
-
|
|
367
523
|
else if (ws.isOpen) {
|
|
368
524
|
// if its all good, send a keep alive request
|
|
369
525
|
query({
|
|
370
526
|
tag: 'iq',
|
|
371
527
|
attrs: {
|
|
372
528
|
id: generateMessageTag(),
|
|
373
|
-
to:
|
|
529
|
+
to: S_WHATSAPP_NET,
|
|
374
530
|
type: 'get',
|
|
375
|
-
xmlns: 'w:p'
|
|
531
|
+
xmlns: 'w:p'
|
|
376
532
|
},
|
|
377
533
|
content: [{ tag: 'ping', attrs: {} }]
|
|
378
534
|
}).catch(err => {
|
|
379
|
-
logger.error({ trace: err.stack }, 'error in sending keep alive')
|
|
380
|
-
})
|
|
535
|
+
logger.error({ trace: err.stack }, 'error in sending keep alive');
|
|
536
|
+
});
|
|
381
537
|
}
|
|
382
|
-
|
|
383
538
|
else {
|
|
384
|
-
logger.warn('keep alive called when WS not open')
|
|
539
|
+
logger.warn('keep alive called when WS not open');
|
|
385
540
|
}
|
|
386
|
-
}, keepAliveIntervalMs))
|
|
387
|
-
|
|
541
|
+
}, keepAliveIntervalMs));
|
|
388
542
|
/** i have no idea why this exists. pls enlighten me */
|
|
389
|
-
const sendPassiveIq = (tag) =>
|
|
543
|
+
const sendPassiveIq = (tag) => query({
|
|
390
544
|
tag: 'iq',
|
|
391
545
|
attrs: {
|
|
392
|
-
to:
|
|
546
|
+
to: S_WHATSAPP_NET,
|
|
393
547
|
xmlns: 'passive',
|
|
394
|
-
type: 'set'
|
|
548
|
+
type: 'set'
|
|
395
549
|
},
|
|
396
|
-
content: [
|
|
397
|
-
|
|
398
|
-
]
|
|
399
|
-
}))
|
|
400
|
-
|
|
550
|
+
content: [{ tag, attrs: {} }]
|
|
551
|
+
});
|
|
401
552
|
/** logout & invalidate connection */
|
|
402
553
|
const logout = async (msg) => {
|
|
403
|
-
const jid = authState.creds.me?.id
|
|
404
|
-
|
|
554
|
+
const jid = authState.creds.me?.id;
|
|
405
555
|
if (jid) {
|
|
406
556
|
await sendNode({
|
|
407
557
|
tag: 'iq',
|
|
408
558
|
attrs: {
|
|
409
|
-
to:
|
|
559
|
+
to: S_WHATSAPP_NET,
|
|
410
560
|
type: 'set',
|
|
411
561
|
id: generateMessageTag(),
|
|
412
562
|
xmlns: 'md'
|
|
@@ -420,292 +570,259 @@ const makeSocket = (config) => {
|
|
|
420
570
|
}
|
|
421
571
|
}
|
|
422
572
|
]
|
|
423
|
-
})
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
});
|
|
487
|
-
return authState.creds.pairingCode;
|
|
488
|
-
};
|
|
489
|
-
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
end(new Boom(msg || 'Intentional Logout', { statusCode: DisconnectReason.loggedOut }));
|
|
576
|
+
};
|
|
577
|
+
const requestPairingCode = async (phoneNumber, customPairingCode) => {
|
|
578
|
+
const pairingCode = customPairingCode ?? bytesToCrockford(randomBytes(5));
|
|
579
|
+
if (customPairingCode && customPairingCode?.length !== 8) {
|
|
580
|
+
throw new Error('Custom pairing code must be exactly 8 chars');
|
|
581
|
+
}
|
|
582
|
+
authState.creds.pairingCode = pairingCode;
|
|
583
|
+
authState.creds.me = {
|
|
584
|
+
id: jidEncode(phoneNumber, 's.whatsapp.net'),
|
|
585
|
+
name: '~'
|
|
586
|
+
};
|
|
587
|
+
ev.emit('creds.update', authState.creds);
|
|
588
|
+
await sendNode({
|
|
589
|
+
tag: 'iq',
|
|
590
|
+
attrs: {
|
|
591
|
+
to: S_WHATSAPP_NET,
|
|
592
|
+
type: 'set',
|
|
593
|
+
id: generateMessageTag(),
|
|
594
|
+
xmlns: 'md'
|
|
595
|
+
},
|
|
596
|
+
content: [
|
|
597
|
+
{
|
|
598
|
+
tag: 'link_code_companion_reg',
|
|
599
|
+
attrs: {
|
|
600
|
+
jid: authState.creds.me.id,
|
|
601
|
+
stage: 'companion_hello',
|
|
602
|
+
should_show_push_notification: 'true'
|
|
603
|
+
},
|
|
604
|
+
content: [
|
|
605
|
+
{
|
|
606
|
+
tag: 'link_code_pairing_wrapped_companion_ephemeral_pub',
|
|
607
|
+
attrs: {},
|
|
608
|
+
content: await generatePairingKey()
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
tag: 'companion_server_auth_key_pub',
|
|
612
|
+
attrs: {},
|
|
613
|
+
content: authState.creds.noiseKey.public
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
tag: 'companion_platform_id',
|
|
617
|
+
attrs: {},
|
|
618
|
+
content: getPlatformId(browser[1])
|
|
619
|
+
},
|
|
620
|
+
{
|
|
621
|
+
tag: 'companion_platform_display',
|
|
622
|
+
attrs: {},
|
|
623
|
+
content: `${browser[1]} (${browser[0]})`
|
|
624
|
+
},
|
|
625
|
+
{
|
|
626
|
+
tag: 'link_code_pairing_nonce',
|
|
627
|
+
attrs: {},
|
|
628
|
+
content: '0'
|
|
629
|
+
}
|
|
630
|
+
]
|
|
631
|
+
}
|
|
632
|
+
]
|
|
633
|
+
});
|
|
634
|
+
return authState.creds.pairingCode;
|
|
635
|
+
};
|
|
490
636
|
async function generatePairingKey() {
|
|
491
|
-
const salt =
|
|
492
|
-
const randomIv =
|
|
493
|
-
const key = await
|
|
494
|
-
const ciphered =
|
|
495
|
-
|
|
496
|
-
return Buffer.concat([salt, randomIv, ciphered])
|
|
637
|
+
const salt = randomBytes(32);
|
|
638
|
+
const randomIv = randomBytes(16);
|
|
639
|
+
const key = await derivePairingCodeKey(authState.creds.pairingCode, salt);
|
|
640
|
+
const ciphered = aesEncryptCTR(authState.creds.pairingEphemeralKeyPair.public, key, randomIv);
|
|
641
|
+
return Buffer.concat([salt, randomIv, ciphered]);
|
|
497
642
|
}
|
|
498
|
-
|
|
499
643
|
const sendWAMBuffer = (wamBuffer) => {
|
|
500
644
|
return query({
|
|
501
645
|
tag: 'iq',
|
|
502
646
|
attrs: {
|
|
503
|
-
to:
|
|
647
|
+
to: S_WHATSAPP_NET,
|
|
504
648
|
id: generateMessageTag(),
|
|
505
649
|
xmlns: 'w:stats'
|
|
506
650
|
},
|
|
507
651
|
content: [
|
|
508
652
|
{
|
|
509
653
|
tag: 'add',
|
|
510
|
-
attrs: {},
|
|
654
|
+
attrs: { t: Math.round(Date.now() / 1000) + '' },
|
|
511
655
|
content: wamBuffer
|
|
512
656
|
}
|
|
513
657
|
]
|
|
514
|
-
})
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
ws.on('message', onMessageReceived)
|
|
518
|
-
|
|
658
|
+
});
|
|
659
|
+
};
|
|
660
|
+
ws.on('message', onMessageReceived);
|
|
519
661
|
ws.on('open', async () => {
|
|
520
662
|
try {
|
|
521
|
-
await validateConnection()
|
|
663
|
+
await validateConnection();
|
|
522
664
|
}
|
|
523
665
|
catch (err) {
|
|
524
|
-
logger.error({ err }, 'error in validating connection')
|
|
525
|
-
end(err)
|
|
526
|
-
}
|
|
527
|
-
})
|
|
528
|
-
|
|
529
|
-
ws.on('
|
|
530
|
-
|
|
531
|
-
ws.on('close', () => end(new boom_1.Boom('Connection Terminated', { statusCode: Types_1.DisconnectReason.connectionClosed })))
|
|
532
|
-
|
|
666
|
+
logger.error({ err }, 'error in validating connection');
|
|
667
|
+
end(err);
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
ws.on('error', mapWebSocketError(end));
|
|
671
|
+
ws.on('close', () => end(new Boom('Connection Terminated', { statusCode: DisconnectReason.connectionClosed })));
|
|
533
672
|
// the server terminated the connection
|
|
534
|
-
ws.on('CB:xmlstreamend', () => end(new
|
|
535
|
-
|
|
673
|
+
ws.on('CB:xmlstreamend', () => end(new Boom('Connection Terminated by Server', { statusCode: DisconnectReason.connectionClosed })));
|
|
536
674
|
// QR gen
|
|
537
675
|
ws.on('CB:iq,type:set,pair-device', async (stanza) => {
|
|
538
676
|
const iq = {
|
|
539
677
|
tag: 'iq',
|
|
540
678
|
attrs: {
|
|
541
|
-
to:
|
|
679
|
+
to: S_WHATSAPP_NET,
|
|
542
680
|
type: 'result',
|
|
543
|
-
id: stanza.attrs.id
|
|
681
|
+
id: stanza.attrs.id
|
|
544
682
|
}
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
const
|
|
550
|
-
const
|
|
551
|
-
const
|
|
552
|
-
|
|
553
|
-
const advB64 = creds.advSecretKey
|
|
554
|
-
|
|
555
|
-
let qrMs = qrTimeout || 60000 // time to let a QR live
|
|
556
|
-
|
|
683
|
+
};
|
|
684
|
+
await sendNode(iq);
|
|
685
|
+
const pairDeviceNode = getBinaryNodeChild(stanza, 'pair-device');
|
|
686
|
+
const refNodes = getBinaryNodeChildren(pairDeviceNode, 'ref');
|
|
687
|
+
const noiseKeyB64 = Buffer.from(creds.noiseKey.public).toString('base64');
|
|
688
|
+
const identityKeyB64 = Buffer.from(creds.signedIdentityKey.public).toString('base64');
|
|
689
|
+
const advB64 = creds.advSecretKey;
|
|
690
|
+
let qrMs = qrTimeout || 60000; // time to let a QR live
|
|
557
691
|
const genPairQR = () => {
|
|
558
692
|
if (!ws.isOpen) {
|
|
559
|
-
return
|
|
693
|
+
return;
|
|
560
694
|
}
|
|
561
|
-
|
|
562
|
-
const refNode = refNodes.shift()
|
|
563
|
-
|
|
695
|
+
const refNode = refNodes.shift();
|
|
564
696
|
if (!refNode) {
|
|
565
|
-
end(new
|
|
566
|
-
return
|
|
697
|
+
end(new Boom('QR refs attempts ended', { statusCode: DisconnectReason.timedOut }));
|
|
698
|
+
return;
|
|
567
699
|
}
|
|
568
|
-
|
|
569
|
-
const
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
genPairQR()
|
|
578
|
-
})
|
|
579
|
-
|
|
700
|
+
const ref = refNode.content.toString('utf-8');
|
|
701
|
+
const qr = [ref, noiseKeyB64, identityKeyB64, advB64].join(',');
|
|
702
|
+
ev.emit('connection.update', { qr });
|
|
703
|
+
qrTimer = setTimeout(genPairQR, qrMs);
|
|
704
|
+
qrMs = qrTimeout || 20000; // shorter subsequent qrs
|
|
705
|
+
};
|
|
706
|
+
genPairQR();
|
|
707
|
+
});
|
|
580
708
|
// device paired for the first time
|
|
581
709
|
// if device pairs successfully, the server asks to restart the connection
|
|
582
710
|
ws.on('CB:iq,,pair-success', async (stanza) => {
|
|
583
|
-
logger.debug('pair success recv')
|
|
711
|
+
logger.debug('pair success recv');
|
|
584
712
|
try {
|
|
585
|
-
const { reply, creds: updatedCreds } =
|
|
586
|
-
logger.info({ me: updatedCreds.me, platform: updatedCreds.platform }, 'pairing configured successfully, expect to restart the connection...')
|
|
587
|
-
|
|
588
|
-
ev.emit('
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
await sendNode(reply)
|
|
592
|
-
}
|
|
593
|
-
|
|
713
|
+
const { reply, creds: updatedCreds } = configureSuccessfulPairing(stanza, creds);
|
|
714
|
+
logger.info({ me: updatedCreds.me, platform: updatedCreds.platform }, 'pairing configured successfully, expect to restart the connection...');
|
|
715
|
+
ev.emit('creds.update', updatedCreds);
|
|
716
|
+
ev.emit('connection.update', { isNewLogin: true, qr: undefined });
|
|
717
|
+
await sendNode(reply);
|
|
718
|
+
}
|
|
594
719
|
catch (error) {
|
|
595
|
-
logger.info({ trace: error.stack }, 'error in pairing')
|
|
596
|
-
end(error)
|
|
720
|
+
logger.info({ trace: error.stack }, 'error in pairing');
|
|
721
|
+
end(error);
|
|
597
722
|
}
|
|
598
|
-
})
|
|
599
|
-
|
|
723
|
+
});
|
|
600
724
|
// login complete
|
|
601
725
|
ws.on('CB:success', async (node) => {
|
|
602
726
|
try {
|
|
603
|
-
await uploadPreKeysToServerIfRequired()
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
logger.info('opened connection to WA')
|
|
608
|
-
|
|
609
|
-
clearTimeout(qrTimer) // will never happen in all likelyhood -- but just in case WA sends success on first try
|
|
610
|
-
ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } })
|
|
611
|
-
ev.emit('connection.update', { connection: 'open' })
|
|
612
|
-
}
|
|
613
|
-
|
|
727
|
+
await uploadPreKeysToServerIfRequired();
|
|
728
|
+
await sendPassiveIq('active');
|
|
729
|
+
}
|
|
614
730
|
catch (err) {
|
|
615
|
-
logger.
|
|
616
|
-
|
|
731
|
+
logger.warn({ err }, 'failed to send initial passive iq');
|
|
732
|
+
}
|
|
733
|
+
logger.info('opened connection to WA');
|
|
734
|
+
clearTimeout(qrTimer); // will never happen in all likelyhood -- but just in case WA sends success on first try
|
|
735
|
+
ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } });
|
|
736
|
+
ev.emit('connection.update', { connection: 'open' });
|
|
737
|
+
if (node.attrs.lid && authState.creds.me?.id) {
|
|
738
|
+
const myLID = node.attrs.lid;
|
|
739
|
+
process.nextTick(async () => {
|
|
740
|
+
try {
|
|
741
|
+
const myPN = authState.creds.me.id;
|
|
742
|
+
// Store our own LID-PN mapping
|
|
743
|
+
await signalRepository.lidMapping.storeLIDPNMappings([{ lid: myLID, pn: myPN }]);
|
|
744
|
+
// Create device list for our own user (needed for bulk migration)
|
|
745
|
+
const { user, device } = jidDecode(myPN);
|
|
746
|
+
await authState.keys.set({
|
|
747
|
+
'device-list': {
|
|
748
|
+
[user]: [device?.toString() || '0']
|
|
749
|
+
}
|
|
750
|
+
});
|
|
751
|
+
// migrate our own session
|
|
752
|
+
await signalRepository.migrateSession(myPN, myLID);
|
|
753
|
+
logger.info({ myPN, myLID }, 'Own LID session created successfully');
|
|
754
|
+
}
|
|
755
|
+
catch (error) {
|
|
756
|
+
logger.error({ error, lid: myLID }, 'Failed to create own LID session');
|
|
757
|
+
}
|
|
758
|
+
});
|
|
617
759
|
}
|
|
618
|
-
})
|
|
619
|
-
|
|
760
|
+
});
|
|
620
761
|
ws.on('CB:stream:error', (node) => {
|
|
621
|
-
logger.error({ node }, 'stream errored out')
|
|
622
|
-
const { reason, statusCode } =
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
})
|
|
626
|
-
|
|
762
|
+
logger.error({ node }, 'stream errored out');
|
|
763
|
+
const { reason, statusCode } = getErrorCodeFromStreamError(node);
|
|
764
|
+
end(new Boom(`Stream Errored (${reason})`, { statusCode, data: node }));
|
|
765
|
+
});
|
|
627
766
|
// stream fail, possible logout
|
|
628
767
|
ws.on('CB:failure', (node) => {
|
|
629
|
-
const reason = +(node.attrs.reason || 500)
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
})
|
|
633
|
-
|
|
768
|
+
const reason = +(node.attrs.reason || 500);
|
|
769
|
+
end(new Boom('Connection Failure', { statusCode: reason, data: node.attrs }));
|
|
770
|
+
});
|
|
634
771
|
ws.on('CB:ib,,downgrade_webclient', () => {
|
|
635
|
-
end(new
|
|
636
|
-
})
|
|
637
|
-
|
|
772
|
+
end(new Boom('Multi-device beta not joined', { statusCode: DisconnectReason.multideviceMismatch }));
|
|
773
|
+
});
|
|
638
774
|
ws.on('CB:ib,,offline_preview', (node) => {
|
|
639
|
-
logger.info('offline preview received', JSON.stringify(node))
|
|
640
|
-
|
|
775
|
+
logger.info('offline preview received', JSON.stringify(node));
|
|
641
776
|
sendNode({
|
|
642
777
|
tag: 'ib',
|
|
643
778
|
attrs: {},
|
|
644
779
|
content: [{ tag: 'offline_batch', attrs: { count: '100' } }]
|
|
645
|
-
})
|
|
646
|
-
})
|
|
647
|
-
|
|
780
|
+
});
|
|
781
|
+
});
|
|
648
782
|
ws.on('CB:ib,,edge_routing', (node) => {
|
|
649
|
-
const edgeRoutingNode =
|
|
650
|
-
const routingInfo =
|
|
651
|
-
|
|
783
|
+
const edgeRoutingNode = getBinaryNodeChild(node, 'edge_routing');
|
|
784
|
+
const routingInfo = getBinaryNodeChild(edgeRoutingNode, 'routing_info');
|
|
652
785
|
if (routingInfo?.content) {
|
|
653
|
-
authState.creds.routingInfo = Buffer.from(routingInfo?.content)
|
|
654
|
-
ev.emit('creds.update', authState.creds)
|
|
786
|
+
authState.creds.routingInfo = Buffer.from(routingInfo?.content);
|
|
787
|
+
ev.emit('creds.update', authState.creds);
|
|
655
788
|
}
|
|
656
|
-
})
|
|
657
|
-
|
|
658
|
-
let didStartBuffer = false
|
|
659
|
-
|
|
789
|
+
});
|
|
790
|
+
let didStartBuffer = false;
|
|
660
791
|
process.nextTick(() => {
|
|
661
792
|
if (creds.me?.id) {
|
|
662
793
|
// start buffering important events
|
|
663
794
|
// if we're logged in
|
|
664
|
-
ev.buffer()
|
|
665
|
-
didStartBuffer = true
|
|
795
|
+
ev.buffer();
|
|
796
|
+
didStartBuffer = true;
|
|
666
797
|
}
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
})
|
|
670
|
-
|
|
798
|
+
ev.emit('connection.update', { connection: 'connecting', receivedPendingNotifications: false, qr: undefined });
|
|
799
|
+
});
|
|
671
800
|
// called when all offline notifs are handled
|
|
672
801
|
ws.on('CB:ib,,offline', (node) => {
|
|
673
|
-
const child =
|
|
674
|
-
const offlineNotifs = +(child?.attrs.count || 0)
|
|
675
|
-
|
|
676
|
-
logger.info(`handled ${offlineNotifs} offline messages/notifications`)
|
|
677
|
-
|
|
802
|
+
const child = getBinaryNodeChild(node, 'offline');
|
|
803
|
+
const offlineNotifs = +(child?.attrs.count || 0);
|
|
804
|
+
logger.info(`handled ${offlineNotifs} offline messages/notifications`);
|
|
678
805
|
if (didStartBuffer) {
|
|
679
|
-
ev.flush()
|
|
680
|
-
logger.trace('flushed events for initial buffer')
|
|
806
|
+
ev.flush();
|
|
807
|
+
logger.trace('flushed events for initial buffer');
|
|
681
808
|
}
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
})
|
|
685
|
-
|
|
809
|
+
ev.emit('connection.update', { receivedPendingNotifications: true });
|
|
810
|
+
});
|
|
686
811
|
// update credentials when required
|
|
687
812
|
ev.on('creds.update', update => {
|
|
688
|
-
const name = update.me?.name
|
|
689
|
-
|
|
813
|
+
const name = update.me?.name;
|
|
690
814
|
// if name has just been received
|
|
691
815
|
if (creds.me?.name !== name) {
|
|
692
|
-
logger.debug({ name }, 'updated pushName')
|
|
693
|
-
|
|
816
|
+
logger.debug({ name }, 'updated pushName');
|
|
694
817
|
sendNode({
|
|
695
818
|
tag: 'presence',
|
|
696
|
-
attrs: { name }
|
|
819
|
+
attrs: { name: name }
|
|
697
820
|
}).catch(err => {
|
|
698
|
-
logger.warn({ trace: err.stack }, 'error in sending presence update on name change')
|
|
699
|
-
})
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
})
|
|
704
|
-
|
|
705
|
-
if (printQRInTerminal) {
|
|
706
|
-
Utils_1.printQRIfNecessaryListener(ev, logger)
|
|
707
|
-
}
|
|
708
|
-
|
|
821
|
+
logger.warn({ trace: err.stack }, 'error in sending presence update on name change');
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
Object.assign(creds, update);
|
|
825
|
+
});
|
|
709
826
|
return {
|
|
710
827
|
type: 'md',
|
|
711
828
|
ws,
|
|
@@ -713,7 +830,7 @@ const makeSocket = (config) => {
|
|
|
713
830
|
authState: { creds, keys },
|
|
714
831
|
signalRepository,
|
|
715
832
|
get user() {
|
|
716
|
-
return authState.creds.me
|
|
833
|
+
return authState.creds.me;
|
|
717
834
|
},
|
|
718
835
|
generateMessageTag,
|
|
719
836
|
query,
|
|
@@ -727,22 +844,21 @@ const makeSocket = (config) => {
|
|
|
727
844
|
uploadPreKeys,
|
|
728
845
|
uploadPreKeysToServerIfRequired,
|
|
729
846
|
requestPairingCode,
|
|
847
|
+
wamBuffer: publicWAMBuffer,
|
|
730
848
|
/** Waits for the connection to WA to reach a state */
|
|
731
|
-
waitForConnectionUpdate:
|
|
849
|
+
waitForConnectionUpdate: bindWaitForConnectionUpdate(ev),
|
|
732
850
|
sendWAMBuffer,
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
851
|
+
executeUSyncQuery,
|
|
852
|
+
onWhatsApp
|
|
853
|
+
};
|
|
854
|
+
};
|
|
736
855
|
/**
|
|
737
856
|
* map the websocket error to the right type
|
|
738
857
|
* so it can be retried by the caller
|
|
739
858
|
* */
|
|
740
859
|
function mapWebSocketError(handler) {
|
|
741
860
|
return (error) => {
|
|
742
|
-
handler(new
|
|
743
|
-
}
|
|
861
|
+
handler(new Boom(`WebSocket Error (${error?.message})`, { statusCode: getCodeFromWSError(error), data: error }));
|
|
862
|
+
};
|
|
744
863
|
}
|
|
745
|
-
|
|
746
|
-
module.exports = {
|
|
747
|
-
makeSocket
|
|
748
|
-
}
|
|
864
|
+
//# sourceMappingURL=socket.js.map
|