@pontalabs/baileys 1.0.5 → 1.0.6
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/LICENSE +1 -1
- package/README.md +267 -839
- package/WAProto/GenerateStatics.sh +3 -4
- package/WAProto/WAProto.proto +1215 -511
- package/WAProto/fix-imports.js +85 -0
- package/WAProto/index.d.ts +14017 -55
- package/WAProto/index.js +97689 -29
- package/engine-requirements.js +10 -0
- package/lib/Defaults/index.d.ts +72 -74
- package/lib/Defaults/index.d.ts.map +1 -0
- package/lib/Defaults/index.js +94 -108
- package/lib/Defaults/index.js.map +1 -0
- package/lib/Signal/Group/ciphertext-message.d.ts +8 -7
- package/lib/Signal/Group/ciphertext-message.d.ts.map +1 -0
- package/lib/Signal/Group/ciphertext-message.js +9 -16
- package/lib/Signal/Group/ciphertext-message.js.map +1 -0
- package/lib/Signal/Group/group-session-builder.d.ts +11 -13
- package/lib/Signal/Group/group-session-builder.d.ts.map +1 -0
- package/lib/Signal/Group/group-session-builder.js +19 -61
- package/lib/Signal/Group/group-session-builder.js.map +1 -0
- package/lib/Signal/Group/group_cipher.d.ts +14 -16
- package/lib/Signal/Group/group_cipher.d.ts.map +1 -0
- package/lib/Signal/Group/group_cipher.js +41 -70
- package/lib/Signal/Group/group_cipher.js.map +1 -0
- package/lib/Signal/Group/index.d.ts +12 -11
- package/lib/Signal/Group/index.d.ts.map +1 -0
- package/lib/Signal/Group/index.js +12 -61
- package/lib/Signal/Group/index.js.map +1 -0
- package/lib/Signal/Group/keyhelper.d.ts +9 -14
- package/lib/Signal/Group/keyhelper.d.ts.map +1 -0
- package/lib/Signal/Group/keyhelper.js +10 -58
- package/lib/Signal/Group/keyhelper.js.map +1 -0
- package/lib/Signal/Group/sender-chain-key.d.ts +13 -13
- package/lib/Signal/Group/sender-chain-key.d.ts.map +1 -0
- package/lib/Signal/Group/sender-chain-key.js +13 -34
- package/lib/Signal/Group/sender-chain-key.js.map +1 -0
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -16
- package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +28 -36
- package/lib/Signal/Group/sender-key-distribution-message.js.map +1 -0
- package/lib/Signal/Group/sender-key-message.d.ts +18 -18
- package/lib/Signal/Group/sender-key-message.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-message.js +38 -45
- package/lib/Signal/Group/sender-key-message.js.map +1 -0
- package/lib/Signal/Group/sender-key-name.d.ts +14 -15
- package/lib/Signal/Group/sender-key-name.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-name.js +20 -31
- package/lib/Signal/Group/sender-key-name.js.map +1 -0
- package/lib/Signal/Group/sender-key-record.d.ts +24 -25
- package/lib/Signal/Group/sender-key-record.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-record.js +18 -35
- package/lib/Signal/Group/sender-key-record.js.map +1 -0
- package/lib/Signal/Group/sender-key-state.d.ts +29 -34
- package/lib/Signal/Group/sender-key-state.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-state.js +37 -100
- package/lib/Signal/Group/sender-key-state.js.map +1 -0
- package/lib/Signal/Group/sender-message-key.d.ts +11 -10
- package/lib/Signal/Group/sender-message-key.d.ts.map +1 -0
- package/lib/Signal/Group/sender-message-key.js +15 -22
- package/lib/Signal/Group/sender-message-key.js.map +1 -0
- package/lib/Signal/libsignal.d.ts +5 -8
- package/lib/Signal/libsignal.d.ts.map +1 -0
- package/lib/Signal/libsignal.js +288 -142
- package/lib/Signal/libsignal.js.map +1 -0
- package/lib/Signal/lid-mapping.d.ts +23 -28
- package/lib/Signal/lid-mapping.d.ts.map +1 -0
- package/lib/Signal/lid-mapping.js +277 -184
- 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 +29 -37
- package/lib/Socket/Client/websocket.js.map +1 -0
- package/lib/Socket/business.d.ts +208 -178
- package/lib/Socket/business.d.ts.map +1 -0
- package/lib/Socket/business.js +91 -127
- package/lib/Socket/business.js.map +1 -0
- package/lib/Socket/chats.d.ts +120 -93
- package/lib/Socket/chats.d.ts.map +1 -0
- package/lib/Socket/chats.js +727 -652
- package/lib/Socket/chats.js.map +1 -0
- package/lib/Socket/communities.d.ts +273 -0
- package/lib/Socket/communities.d.ts.map +1 -0
- package/lib/Socket/communities.js +431 -0
- package/lib/Socket/communities.js.map +1 -0
- package/lib/Socket/dugong.js +261 -0
- package/lib/Socket/dugong.js.bak +204 -0
- package/lib/Socket/groups.d.ts +143 -111
- package/lib/Socket/groups.d.ts.map +1 -0
- package/lib/Socket/groups.js +165 -177
- package/lib/Socket/groups.js.map +1 -0
- package/lib/Socket/index.d.ts +252 -183
- package/lib/Socket/index.d.ts.map +1 -0
- package/lib/Socket/index.js +38 -18
- package/lib/Socket/index.js.bak +44 -0
- package/lib/Socket/index.js.map +1 -0
- package/lib/Socket/messages-recv.d.ts +196 -167
- package/lib/Socket/messages-recv.d.ts.map +1 -0
- package/lib/Socket/messages-recv.js +1443 -1563
- package/lib/Socket/messages-recv.js.map +1 -0
- package/lib/Socket/messages-send.d.ts +192 -158
- package/lib/Socket/messages-send.d.ts.map +1 -0
- package/lib/Socket/messages-send.js +1102 -1208
- package/lib/Socket/messages-send.js.bak +1400 -0
- package/lib/Socket/messages-send.js.map +1 -0
- package/lib/Socket/mex.d.ts +3 -0
- package/lib/Socket/mex.d.ts.map +1 -0
- package/lib/Socket/mex.js +42 -0
- package/lib/Socket/mex.js.map +1 -0
- package/lib/Socket/newsletter.d.ts +163 -138
- package/lib/Socket/newsletter.d.ts.map +1 -0
- package/lib/Socket/newsletter.js +153 -249
- package/lib/Socket/newsletter.js.map +1 -0
- package/lib/Socket/socket.d.ts +50 -36
- package/lib/Socket/socket.d.ts.map +1 -0
- package/lib/Socket/socket.js +749 -820
- package/lib/Socket/socket.js.map +1 -0
- package/lib/Store/index.d.ts +4 -4
- package/lib/Store/index.d.ts.map +1 -0
- package/lib/Store/index.js +4 -24
- package/lib/Store/index.js.map +1 -0
- package/lib/Store/make-in-memory-store.d.ts +44 -104
- package/lib/Store/make-in-memory-store.d.ts.map +1 -0
- package/lib/Store/make-in-memory-store.js +199 -213
- package/lib/Store/make-in-memory-store.js.map +1 -0
- package/lib/Store/make-ordered-dictionary.d.ts +13 -12
- package/lib/Store/make-ordered-dictionary.d.ts.map +1 -0
- package/lib/Store/make-ordered-dictionary.js +38 -45
- package/lib/Store/make-ordered-dictionary.js.map +1 -0
- package/lib/Store/object-repository.d.ts +11 -10
- package/lib/Store/object-repository.d.ts.map +1 -0
- package/lib/Store/object-repository.js +9 -16
- package/lib/Store/object-repository.js.map +1 -0
- package/lib/Types/Auth.d.ts +93 -97
- 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 -3
- package/lib/Types/Bussines.js.map +1 -0
- package/lib/Types/Call.d.ts +14 -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 +78 -97
- 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 +12 -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 +206 -176
- 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 +53 -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 +248 -412
- package/lib/Types/Message.d.ts.map +1 -0
- package/lib/Types/Message.js +17 -19
- package/lib/Types/Message.js.map +1 -0
- package/lib/Types/Mex.d.ts +141 -0
- package/lib/Types/Mex.d.ts.map +1 -0
- package/lib/Types/Mex.js +37 -0
- package/lib/Types/Mex.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/RichType.d.ts +3 -0
- package/lib/Types/RichType.d.ts.map +1 -0
- package/lib/Types/RichType.js +23 -0
- package/lib/Types/RichType.js.bak +23 -0
- package/lib/Types/RichType.js.map +1 -0
- package/lib/Types/Signal.d.ts +71 -82
- 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 +76 -81
- 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 +75 -19
- package/lib/Types/State.d.ts.map +1 -0
- package/lib/Types/State.js +56 -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 -62
- package/lib/Types/index.d.ts.map +1 -0
- package/lib/Types/index.js +26 -50
- package/lib/Types/index.js.map +1 -0
- package/lib/Utils/auth-utils.d.ts +13 -10
- package/lib/Utils/auth-utils.d.ts.map +1 -0
- package/lib/Utils/auth-utils.js +213 -472
- package/lib/Utils/auth-utils.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 +88 -70
- package/lib/Utils/chat-utils.d.ts.map +1 -0
- package/lib/Utils/chat-utils.js +466 -403
- package/lib/Utils/chat-utils.js.map +1 -0
- package/lib/Utils/companion-reg-client-utils.d.ts +17 -0
- package/lib/Utils/companion-reg-client-utils.d.ts.map +1 -0
- package/lib/Utils/companion-reg-client-utils.js +35 -0
- package/lib/Utils/companion-reg-client-utils.js.map +1 -0
- package/lib/Utils/crypto.d.ts +27 -46
- package/lib/Utils/crypto.d.ts.map +1 -0
- package/lib/Utils/crypto.js +117 -188
- package/lib/Utils/crypto.js.map +1 -0
- package/lib/Utils/decode-wa-message.d.ts +58 -45
- package/lib/Utils/decode-wa-message.d.ts.map +1 -0
- package/lib/Utils/decode-wa-message.js +213 -303
- package/lib/Utils/decode-wa-message.js.map +1 -0
- package/lib/Utils/event-buffer.d.ts +14 -17
- package/lib/Utils/event-buffer.d.ts.map +1 -0
- package/lib/Utils/event-buffer.js +321 -296
- package/lib/Utils/event-buffer.js.map +1 -0
- package/lib/Utils/generics.d.ts +66 -92
- package/lib/Utils/generics.d.ts.map +1 -0
- package/lib/Utils/generics.js +270 -436
- package/lib/Utils/generics.js.map +1 -0
- package/lib/Utils/history.d.ts +24 -23
- package/lib/Utils/history.d.ts.map +1 -0
- package/lib/Utils/history.js +106 -76
- package/lib/Utils/history.js.map +1 -0
- package/lib/Utils/identity-change-handler.d.ts +44 -0
- package/lib/Utils/identity-change-handler.d.ts.map +1 -0
- package/lib/Utils/identity-change-handler.js +50 -0
- package/lib/Utils/identity-change-handler.js.map +1 -0
- package/lib/Utils/index.d.ts +24 -21
- package/lib/Utils/index.d.ts.map +1 -0
- package/lib/Utils/index.js +24 -41
- 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 +8 -14
- package/lib/Utils/lt-hash.d.ts.map +1 -0
- package/lib/Utils/lt-hash.js +3 -53
- package/lib/Utils/lt-hash.js.map +1 -0
- package/lib/Utils/make-mutex.d.ts +7 -7
- package/lib/Utils/make-mutex.d.ts.map +1 -0
- package/lib/Utils/make-mutex.js +28 -44
- package/lib/Utils/make-mutex.js.map +1 -0
- package/lib/Utils/message-retry-manager.d.ts +115 -88
- package/lib/Utils/message-retry-manager.d.ts.map +1 -0
- package/lib/Utils/message-retry-manager.js +265 -160
- package/lib/Utils/message-retry-manager.js.map +1 -0
- package/lib/Utils/messages-media.d.ts +105 -107
- package/lib/Utils/messages-media.d.ts.map +1 -0
- package/lib/Utils/messages-media.js +548 -619
- package/lib/Utils/messages-media.js.bak +786 -0
- package/lib/Utils/messages-media.js.map +1 -0
- package/lib/Utils/messages.d.ts +52 -66
- package/lib/Utils/messages.d.ts.map +1 -0
- package/lib/Utils/messages.js +1730 -1558
- package/lib/Utils/messages.js.backup +1768 -0
- package/lib/Utils/messages.js.bak +1809 -0
- package/lib/Utils/messages.js.bak2 +893 -0
- package/lib/Utils/messages.js.bak3 +1183 -0
- 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 +176 -130
- package/lib/Utils/noise-handler.js.map +1 -0
- package/lib/Utils/offline-node-processor.d.ts +17 -0
- package/lib/Utils/offline-node-processor.d.ts.map +1 -0
- package/lib/Utils/offline-node-processor.js +40 -0
- package/lib/Utils/offline-node-processor.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 +43 -32
- package/lib/Utils/process-message.d.ts.map +1 -0
- package/lib/Utils/process-message.js +484 -282
- package/lib/Utils/process-message.js.map +1 -0
- package/lib/Utils/reporting-utils.d.ts +11 -0
- package/lib/Utils/reporting-utils.d.ts.map +1 -0
- package/lib/Utils/reporting-utils.js +258 -0
- package/lib/Utils/reporting-utils.js.map +1 -0
- package/lib/Utils/rich-message-utils.d.ts +49 -0
- package/lib/Utils/rich-message-utils.d.ts.map +1 -0
- package/lib/Utils/rich-message-utils.js +1220 -724
- package/lib/Utils/rich-message-utils.js.backup +706 -0
- package/lib/Utils/rich-message-utils.js.bak +246 -0
- package/lib/Utils/rich-message-utils.js.map +1 -0
- package/lib/Utils/rich-message-utils.js.original +1332 -0
- package/lib/Utils/signal.d.ts +37 -32
- package/lib/Utils/signal.d.ts.map +1 -0
- package/lib/Utils/signal.js +140 -105
- package/lib/Utils/signal.js.map +1 -0
- package/lib/Utils/stanza-ack.d.ts +11 -0
- package/lib/Utils/stanza-ack.d.ts.map +1 -0
- package/lib/Utils/stanza-ack.js +38 -0
- package/lib/Utils/stanza-ack.js.map +1 -0
- package/lib/Utils/sync-action-utils.d.ts +19 -0
- package/lib/Utils/sync-action-utils.d.ts.map +1 -0
- package/lib/Utils/sync-action-utils.js +49 -0
- package/lib/Utils/sync-action-utils.js.map +1 -0
- package/lib/Utils/tc-token-utils.d.ts +37 -0
- package/lib/Utils/tc-token-utils.d.ts.map +1 -0
- package/lib/Utils/tc-token-utils.js +163 -0
- package/lib/Utils/tc-token-utils.js.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.d.ts +5 -5
- package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.js +70 -120
- package/lib/Utils/use-multi-file-auth-state.js.map +1 -0
- package/lib/Utils/use-single-file-auth-state.d.ts +11 -13
- package/lib/Utils/use-single-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-single-file-auth-state.js +92 -66
- package/lib/Utils/use-single-file-auth-state.js.map +1 -0
- package/lib/Utils/use-sqlite-auth-state.d.ts +11 -0
- package/lib/Utils/use-sqlite-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-sqlite-auth-state.js +109 -0
- package/lib/Utils/use-sqlite-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 +128 -113
- 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 +1451 -1292
- package/lib/WABinary/constants.js.bak +1373 -0
- 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 +163 -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 +110 -155
- 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 +177 -105
- 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 -51
- package/lib/WABinary/jid-utils.d.ts.map +1 -0
- package/lib/WABinary/jid-utils.js +83 -120
- 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 -109
- 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 +37 -21
- 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/USyncUsernameProtocol.d.ts +10 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.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 +6 -6
- package/lib/WAUSync/Protocols/index.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/index.js +6 -26
- package/lib/WAUSync/Protocols/index.js.map +1 -0
- package/lib/WAUSync/USyncQuery.d.ts +27 -28
- package/lib/WAUSync/USyncQuery.d.ts.map +1 -0
- package/lib/WAUSync/USyncQuery.js +68 -62
- package/lib/WAUSync/USyncQuery.js.map +1 -0
- package/lib/WAUSync/USyncUser.d.ts +15 -10
- package/lib/WAUSync/USyncUser.d.ts.map +1 -0
- package/lib/WAUSync/USyncUser.js +20 -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 +11 -12
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +12 -39
- package/lib/index.js.map +1 -0
- package/package.json +86 -42
package/lib/Utils/chat-utils.js
CHANGED
|
@@ -1,137 +1,136 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
const mutationKeys = async (keydata) => {
|
|
15
|
-
const expanded = await crypto_1.hkdf(keydata, 160, { info: 'WhatsApp Mutation Keys' })
|
|
1
|
+
import { Boom } from '@hapi/boom';
|
|
2
|
+
import { expandAppStateKeys } from 'whatsapp-rust-bridge';
|
|
3
|
+
import { proto } from '../../WAProto/index.js';
|
|
4
|
+
import { LabelAssociationType } from '../Types/LabelAssociation.js';
|
|
5
|
+
import { getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidNormalizedUser } from '../WABinary/index.js';
|
|
6
|
+
import { aesDecrypt, aesEncrypt, hmacSign } from './crypto.js';
|
|
7
|
+
import { toNumber } from './generics.js';
|
|
8
|
+
import { LT_HASH_ANTI_TAMPERING } from './lt-hash.js';
|
|
9
|
+
import { downloadContentFromMessage } from './messages-media.js';
|
|
10
|
+
import { emitSyncActionResults, processContactAction } from './sync-action-utils.js';
|
|
11
|
+
const mutationKeys = (keydata) => {
|
|
12
|
+
const keys = expandAppStateKeys(keydata);
|
|
16
13
|
return {
|
|
17
|
-
indexKey:
|
|
18
|
-
valueEncryptionKey:
|
|
19
|
-
valueMacKey:
|
|
20
|
-
snapshotMacKey:
|
|
21
|
-
patchMacKey:
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
14
|
+
indexKey: keys.indexKey,
|
|
15
|
+
valueEncryptionKey: keys.valueEncryptionKey,
|
|
16
|
+
valueMacKey: keys.valueMacKey,
|
|
17
|
+
snapshotMacKey: keys.snapshotMacKey,
|
|
18
|
+
patchMacKey: keys.patchMacKey
|
|
19
|
+
};
|
|
20
|
+
};
|
|
25
21
|
const generateMac = (operation, data, keyId, key) => {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const last = Buffer.alloc(8) // 8 bytes
|
|
41
|
-
last.set([keyData.length], last.length - 1)
|
|
42
|
-
const total = Buffer.concat([keyData, data, last])
|
|
43
|
-
const hmac = crypto_1.hmacSign(total, key, 'sha512')
|
|
44
|
-
return hmac.slice(0, 32)
|
|
45
|
-
}
|
|
46
|
-
|
|
22
|
+
const opByte = operation === proto.SyncdMutation.SyncdOperation.SET ? 0x01 : 0x02;
|
|
23
|
+
const keyIdBuffer = typeof keyId === 'string' ? Buffer.from(keyId, 'base64') : keyId;
|
|
24
|
+
const keyData = new Uint8Array(1 + keyIdBuffer.length);
|
|
25
|
+
keyData[0] = opByte;
|
|
26
|
+
keyData.set(keyIdBuffer, 1);
|
|
27
|
+
const last = new Uint8Array(8);
|
|
28
|
+
last[7] = keyData.length;
|
|
29
|
+
const total = new Uint8Array(keyData.length + data.length + last.length);
|
|
30
|
+
total.set(keyData, 0);
|
|
31
|
+
total.set(data, keyData.length);
|
|
32
|
+
total.set(last, keyData.length + data.length);
|
|
33
|
+
const hmac = hmacSign(total, key, 'sha512');
|
|
34
|
+
return hmac.subarray(0, 32);
|
|
35
|
+
};
|
|
47
36
|
const to64BitNetworkOrder = (e) => {
|
|
48
|
-
const buff = Buffer.alloc(8)
|
|
49
|
-
buff.writeUint32BE(e, 4)
|
|
50
|
-
return buff
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
const subBuffs = []
|
|
37
|
+
const buff = Buffer.alloc(8);
|
|
38
|
+
buff.writeUint32BE(e, 4);
|
|
39
|
+
return buff;
|
|
40
|
+
};
|
|
41
|
+
export const makeLtHashGenerator = ({ indexValueMap, hash }) => {
|
|
42
|
+
indexValueMap = { ...indexValueMap };
|
|
43
|
+
const addBuffs = [];
|
|
44
|
+
const subBuffs = [];
|
|
57
45
|
return {
|
|
58
46
|
mix: ({ indexMac, valueMac, operation }) => {
|
|
59
|
-
const indexMacBase64 = Buffer.from(indexMac).toString('base64')
|
|
60
|
-
const prevOp = indexValueMap[indexMacBase64]
|
|
61
|
-
if (operation ===
|
|
47
|
+
const indexMacBase64 = Buffer.from(indexMac).toString('base64');
|
|
48
|
+
const prevOp = indexValueMap[indexMacBase64];
|
|
49
|
+
if (operation === proto.SyncdMutation.SyncdOperation.REMOVE) {
|
|
62
50
|
if (!prevOp) {
|
|
63
|
-
|
|
51
|
+
// WA Web does not throw here — it logs a warning and skips the subtract.
|
|
52
|
+
// The missing REMOVE will cause an LTHash mismatch, which is handled
|
|
53
|
+
// by the MAC validation layer (snapshot recovery or retry).
|
|
54
|
+
return;
|
|
64
55
|
}
|
|
65
56
|
// remove from index value mac, since this mutation is erased
|
|
66
|
-
delete indexValueMap[indexMacBase64]
|
|
57
|
+
delete indexValueMap[indexMacBase64];
|
|
67
58
|
}
|
|
68
59
|
else {
|
|
69
|
-
addBuffs.push(
|
|
60
|
+
addBuffs.push(valueMac);
|
|
70
61
|
// add this index into the history map
|
|
71
|
-
indexValueMap[indexMacBase64] = { valueMac }
|
|
62
|
+
indexValueMap[indexMacBase64] = { valueMac };
|
|
72
63
|
}
|
|
73
64
|
if (prevOp) {
|
|
74
|
-
subBuffs.push(
|
|
65
|
+
subBuffs.push(prevOp.valueMac);
|
|
75
66
|
}
|
|
76
67
|
},
|
|
77
|
-
finish:
|
|
78
|
-
const
|
|
79
|
-
const result = await lt_hash_1.LT_HASH_ANTI_TAMPERING.subtractThenAdd(hashArrayBuffer, addBuffs, subBuffs)
|
|
80
|
-
const buffer = Buffer.from(result)
|
|
68
|
+
finish: () => {
|
|
69
|
+
const result = LT_HASH_ANTI_TAMPERING.subtractThenAdd(hash, subBuffs, addBuffs);
|
|
81
70
|
return {
|
|
82
|
-
hash:
|
|
71
|
+
hash: Buffer.from(result),
|
|
83
72
|
indexValueMap
|
|
84
|
-
}
|
|
73
|
+
};
|
|
85
74
|
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
75
|
+
};
|
|
76
|
+
};
|
|
89
77
|
const generateSnapshotMac = (lthash, version, name, key) => {
|
|
90
|
-
const total = Buffer.concat([
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
Buffer.from(name, 'utf-8')
|
|
94
|
-
])
|
|
95
|
-
return crypto_1.hmacSign(total, key, 'sha256')
|
|
96
|
-
}
|
|
97
|
-
|
|
78
|
+
const total = Buffer.concat([lthash, to64BitNetworkOrder(version), Buffer.from(name, 'utf-8')]);
|
|
79
|
+
return hmacSign(total, key, 'sha256');
|
|
80
|
+
};
|
|
98
81
|
const generatePatchMac = (snapshotMac, valueMacs, version, type, key) => {
|
|
99
|
-
const total = Buffer.concat([
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
82
|
+
const total = Buffer.concat([snapshotMac, ...valueMacs, to64BitNetworkOrder(version), Buffer.from(type, 'utf-8')]);
|
|
83
|
+
return hmacSign(total, key);
|
|
84
|
+
};
|
|
85
|
+
export const newLTHashState = () => ({ version: 0, hash: Buffer.alloc(128), indexValueMap: {} });
|
|
86
|
+
export const ensureLTHashStateVersion = (state) => {
|
|
87
|
+
if (typeof state.version !== 'number' || isNaN(state.version)) {
|
|
88
|
+
state.version = 0;
|
|
89
|
+
}
|
|
90
|
+
return state;
|
|
91
|
+
};
|
|
92
|
+
export const MAX_SYNC_ATTEMPTS = 2;
|
|
93
|
+
/**
|
|
94
|
+
* Check if an error is a missing app state sync key.
|
|
95
|
+
* WA Web treats these as "Blocked" (waits for key arrival), not fatal.
|
|
96
|
+
* In Baileys we retry with a snapshot which may use a different key.
|
|
97
|
+
*/
|
|
98
|
+
export const isMissingKeyError = (error) => {
|
|
99
|
+
return error?.data?.isMissingKey === true;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Determines if an app state sync error is unrecoverable.
|
|
103
|
+
* TypeError indicates a WASM crash; otherwise we give up after MAX_SYNC_ATTEMPTS.
|
|
104
|
+
* Missing keys are NOT checked here — they are handled separately as "Blocked".
|
|
105
|
+
*/
|
|
106
|
+
export const isAppStateSyncIrrecoverable = (error, attempts) => {
|
|
107
|
+
return attempts >= MAX_SYNC_ATTEMPTS || error?.name === 'TypeError';
|
|
108
|
+
};
|
|
109
|
+
export const encodeSyncdPatch = async ({ type, index, syncAction, apiVersion, operation }, myAppStateKeyId, state, getAppStateSyncKey) => {
|
|
110
|
+
const key = !!myAppStateKeyId ? await getAppStateSyncKey(myAppStateKeyId) : undefined;
|
|
112
111
|
if (!key) {
|
|
113
|
-
throw new
|
|
112
|
+
throw new Boom(`myAppStateKey ("${myAppStateKeyId}") not present`, { data: { isMissingKey: true } });
|
|
114
113
|
}
|
|
115
|
-
const encKeyId = Buffer.from(myAppStateKeyId, 'base64')
|
|
116
|
-
state = { ...state, indexValueMap: { ...state.indexValueMap } }
|
|
117
|
-
const indexBuffer = Buffer.from(JSON.stringify(index))
|
|
118
|
-
const dataProto =
|
|
114
|
+
const encKeyId = Buffer.from(myAppStateKeyId, 'base64');
|
|
115
|
+
state = { ...state, indexValueMap: { ...state.indexValueMap } };
|
|
116
|
+
const indexBuffer = Buffer.from(JSON.stringify(index));
|
|
117
|
+
const dataProto = proto.SyncActionData.fromObject({
|
|
119
118
|
index: indexBuffer,
|
|
120
119
|
value: syncAction,
|
|
121
120
|
padding: new Uint8Array(0),
|
|
122
121
|
version: apiVersion
|
|
123
|
-
})
|
|
124
|
-
const encoded =
|
|
125
|
-
const keyValue =
|
|
126
|
-
const encValue =
|
|
127
|
-
const valueMac = generateMac(operation, encValue, encKeyId, keyValue.valueMacKey)
|
|
128
|
-
const indexMac =
|
|
122
|
+
});
|
|
123
|
+
const encoded = proto.SyncActionData.encode(dataProto).finish();
|
|
124
|
+
const keyValue = mutationKeys(key.keyData);
|
|
125
|
+
const encValue = aesEncrypt(encoded, keyValue.valueEncryptionKey);
|
|
126
|
+
const valueMac = generateMac(operation, encValue, encKeyId, keyValue.valueMacKey);
|
|
127
|
+
const indexMac = hmacSign(indexBuffer, keyValue.indexKey);
|
|
129
128
|
// update LT hash
|
|
130
|
-
const generator = makeLtHashGenerator(state)
|
|
131
|
-
generator.mix({ indexMac, valueMac, operation })
|
|
132
|
-
Object.assign(state,
|
|
133
|
-
state.version += 1
|
|
134
|
-
const snapshotMac = generateSnapshotMac(state.hash, state.version, type, keyValue.snapshotMacKey)
|
|
129
|
+
const generator = makeLtHashGenerator(state);
|
|
130
|
+
generator.mix({ indexMac, valueMac, operation });
|
|
131
|
+
Object.assign(state, generator.finish());
|
|
132
|
+
state.version += 1;
|
|
133
|
+
const snapshotMac = generateSnapshotMac(state.hash, state.version, type, keyValue.snapshotMacKey);
|
|
135
134
|
const patch = {
|
|
136
135
|
patchMac: generatePatchMac(snapshotMac, [valueMac], state.version, type, keyValue.patchMacKey),
|
|
137
136
|
snapshotMac: snapshotMac,
|
|
@@ -150,236 +149,271 @@ const encodeSyncdPatch = async ({ type, index, syncAction, apiVersion, operation
|
|
|
150
149
|
}
|
|
151
150
|
}
|
|
152
151
|
]
|
|
153
|
-
}
|
|
154
|
-
const base64Index = indexMac.toString('base64')
|
|
155
|
-
state.indexValueMap[base64Index] = { valueMac }
|
|
156
|
-
return { patch, state }
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const
|
|
160
|
-
const
|
|
152
|
+
};
|
|
153
|
+
const base64Index = indexMac.toString('base64');
|
|
154
|
+
state.indexValueMap[base64Index] = { valueMac };
|
|
155
|
+
return { patch, state };
|
|
156
|
+
};
|
|
157
|
+
export const decodeSyncdMutations = async (msgMutations, initialState, getAppStateSyncKey, onMutation, validateMacs) => {
|
|
158
|
+
const ltGenerator = makeLtHashGenerator(initialState);
|
|
159
|
+
const derivedKeyCache = new Map();
|
|
161
160
|
// indexKey used to HMAC sign record.index.blob
|
|
162
161
|
// valueEncryptionKey used to AES-256-CBC encrypt record.value.blob[0:-32]
|
|
163
162
|
// the remaining record.value.blob[0:-32] is the mac, it the HMAC sign of key.keyId + decoded proto data + length of bytes in keyId
|
|
164
163
|
for (const msgMutation of msgMutations) {
|
|
165
164
|
// if it's a syncdmutation, get the operation property
|
|
166
165
|
// otherwise, if it's only a record -- it'll be a SET mutation
|
|
167
|
-
const operation = 'operation' in msgMutation ? msgMutation.operation :
|
|
168
|
-
const record =
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
166
|
+
const operation = 'operation' in msgMutation ? msgMutation.operation : proto.SyncdMutation.SyncdOperation.SET;
|
|
167
|
+
const record = 'record' in msgMutation && !!msgMutation.record ? msgMutation.record : msgMutation;
|
|
168
|
+
let key;
|
|
169
|
+
try {
|
|
170
|
+
key = await getKey(record.keyId.id);
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
// Missing-key errors must propagate so the orchestrator can park the
|
|
174
|
+
// collection (Blocked) and retry when APP_STATE_SYNC_KEY_SHARE arrives.
|
|
175
|
+
// Other errors → individual record corruption, skip and keep going.
|
|
176
|
+
if (isMissingKeyError(err))
|
|
177
|
+
throw err;
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const content = record.value.blob;
|
|
181
|
+
const encContent = content.subarray(0, -32);
|
|
182
|
+
const ogValueMac = content.subarray(-32);
|
|
173
183
|
if (validateMacs) {
|
|
174
|
-
const contentHmac = generateMac(operation, encContent, record.keyId.id, key.valueMacKey)
|
|
184
|
+
const contentHmac = generateMac(operation, encContent, record.keyId.id, key.valueMacKey);
|
|
175
185
|
if (Buffer.compare(contentHmac, ogValueMac) !== 0) {
|
|
176
|
-
|
|
186
|
+
// HMAC verification failed — skip this record
|
|
187
|
+
continue;
|
|
177
188
|
}
|
|
178
189
|
}
|
|
179
|
-
|
|
180
|
-
|
|
190
|
+
let result;
|
|
191
|
+
try {
|
|
192
|
+
result = aesDecrypt(encContent, key.valueEncryptionKey);
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
// decrypt failed — skip this record instead of aborting
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const syncAction = proto.SyncActionData.decode(result);
|
|
181
199
|
if (validateMacs) {
|
|
182
|
-
const hmac =
|
|
200
|
+
const hmac = hmacSign(syncAction.index, key.indexKey);
|
|
183
201
|
if (Buffer.compare(hmac, record.index.blob) !== 0) {
|
|
184
|
-
throw new
|
|
202
|
+
throw new Boom('HMAC index verification failed');
|
|
185
203
|
}
|
|
186
204
|
}
|
|
187
|
-
const indexStr = Buffer.from(syncAction.index).toString()
|
|
188
|
-
onMutation({ syncAction, index: JSON.parse(indexStr) })
|
|
205
|
+
const indexStr = Buffer.from(syncAction.index).toString();
|
|
206
|
+
onMutation({ syncAction, index: JSON.parse(indexStr) });
|
|
189
207
|
ltGenerator.mix({
|
|
190
208
|
indexMac: record.index.blob,
|
|
191
209
|
valueMac: ogValueMac,
|
|
192
210
|
operation: operation
|
|
193
|
-
})
|
|
211
|
+
});
|
|
194
212
|
}
|
|
195
|
-
return
|
|
213
|
+
return ltGenerator.finish();
|
|
196
214
|
async function getKey(keyId) {
|
|
197
|
-
const base64Key = Buffer.from(keyId).toString('base64')
|
|
198
|
-
const
|
|
215
|
+
const base64Key = Buffer.from(keyId).toString('base64');
|
|
216
|
+
const cached = derivedKeyCache.get(base64Key);
|
|
217
|
+
if (cached) {
|
|
218
|
+
return cached;
|
|
219
|
+
}
|
|
220
|
+
const keyEnc = await getAppStateSyncKey(base64Key);
|
|
199
221
|
if (!keyEnc) {
|
|
200
|
-
throw new
|
|
222
|
+
throw new Boom(`failed to find key "${base64Key}" to decode mutation`, {
|
|
223
|
+
data: { isMissingKey: true, msgMutations }
|
|
224
|
+
});
|
|
201
225
|
}
|
|
202
|
-
|
|
226
|
+
const keys = mutationKeys(keyEnc.keyData);
|
|
227
|
+
derivedKeyCache.set(base64Key, keys);
|
|
228
|
+
return keys;
|
|
203
229
|
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
const decodeSyncdPatch = async (msg, name, initialState, getAppStateSyncKey, onMutation, validateMacs) => {
|
|
230
|
+
};
|
|
231
|
+
export const decodeSyncdPatch = async (msg, name, initialState, getAppStateSyncKey, onMutation, validateMacs) => {
|
|
207
232
|
if (validateMacs) {
|
|
208
|
-
const base64Key = Buffer.from(msg.keyId.id).toString('base64')
|
|
209
|
-
const mainKeyObj = await getAppStateSyncKey(base64Key)
|
|
233
|
+
const base64Key = Buffer.from(msg.keyId.id).toString('base64');
|
|
234
|
+
const mainKeyObj = await getAppStateSyncKey(base64Key);
|
|
210
235
|
if (!mainKeyObj) {
|
|
211
|
-
throw new
|
|
236
|
+
throw new Boom(`failed to find key "${base64Key}" to decode patch`, { data: { isMissingKey: true, msg } });
|
|
212
237
|
}
|
|
213
|
-
const mainKey =
|
|
214
|
-
const mutationmacs = msg.mutations.map(mutation => mutation.record.value.blob.slice(-32))
|
|
215
|
-
const patchMac = generatePatchMac(msg.snapshotMac, mutationmacs,
|
|
238
|
+
const mainKey = mutationKeys(mainKeyObj.keyData);
|
|
239
|
+
const mutationmacs = msg.mutations.map(mutation => mutation.record.value.blob.slice(-32));
|
|
240
|
+
const patchMac = generatePatchMac(msg.snapshotMac, mutationmacs, toNumber(msg.version.version), name, mainKey.patchMacKey);
|
|
216
241
|
if (Buffer.compare(patchMac, msg.patchMac) !== 0) {
|
|
217
|
-
throw new
|
|
242
|
+
throw new Boom('Invalid patch mac');
|
|
218
243
|
}
|
|
219
244
|
}
|
|
220
|
-
const result = await decodeSyncdMutations(msg.mutations, initialState, getAppStateSyncKey, onMutation, validateMacs)
|
|
221
|
-
return result
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const
|
|
225
|
-
const
|
|
226
|
-
const
|
|
227
|
-
const final = {}
|
|
245
|
+
const result = await decodeSyncdMutations(msg.mutations, initialState, getAppStateSyncKey, onMutation, validateMacs);
|
|
246
|
+
return result;
|
|
247
|
+
};
|
|
248
|
+
export const extractSyncdPatches = async (result, options) => {
|
|
249
|
+
const syncNode = getBinaryNodeChild(result, 'sync');
|
|
250
|
+
const collectionNodes = getBinaryNodeChildren(syncNode, 'collection');
|
|
251
|
+
const final = {};
|
|
228
252
|
await Promise.all(collectionNodes.map(async (collectionNode) => {
|
|
229
|
-
const patchesNode =
|
|
230
|
-
const patches =
|
|
231
|
-
const snapshotNode =
|
|
232
|
-
const syncds = []
|
|
233
|
-
const name = collectionNode.attrs.name
|
|
234
|
-
const hasMorePatches = collectionNode.attrs.has_more_patches === 'true'
|
|
235
|
-
let snapshot = undefined
|
|
253
|
+
const patchesNode = getBinaryNodeChild(collectionNode, 'patches');
|
|
254
|
+
const patches = getBinaryNodeChildren(patchesNode || collectionNode, 'patch');
|
|
255
|
+
const snapshotNode = getBinaryNodeChild(collectionNode, 'snapshot');
|
|
256
|
+
const syncds = [];
|
|
257
|
+
const name = collectionNode.attrs.name;
|
|
258
|
+
const hasMorePatches = collectionNode.attrs.has_more_patches === 'true';
|
|
259
|
+
let snapshot = undefined;
|
|
236
260
|
if (snapshotNode && !!snapshotNode.content) {
|
|
237
261
|
if (!Buffer.isBuffer(snapshotNode)) {
|
|
238
|
-
snapshotNode.content = Buffer.from(Object.values(snapshotNode.content))
|
|
262
|
+
snapshotNode.content = Buffer.from(Object.values(snapshotNode.content));
|
|
239
263
|
}
|
|
240
|
-
const blobRef =
|
|
241
|
-
const data = await downloadExternalBlob(blobRef, options)
|
|
242
|
-
snapshot =
|
|
264
|
+
const blobRef = proto.ExternalBlobReference.decode(snapshotNode.content);
|
|
265
|
+
const data = await downloadExternalBlob(blobRef, options);
|
|
266
|
+
snapshot = proto.SyncdSnapshot.decode(data);
|
|
243
267
|
}
|
|
244
268
|
for (let { content } of patches) {
|
|
245
269
|
if (content) {
|
|
246
270
|
if (!Buffer.isBuffer(content)) {
|
|
247
|
-
content = Buffer.from(Object.values(content))
|
|
271
|
+
content = Buffer.from(Object.values(content));
|
|
248
272
|
}
|
|
249
|
-
const syncd =
|
|
273
|
+
const syncd = proto.SyncdPatch.decode(content);
|
|
250
274
|
if (!syncd.version) {
|
|
251
|
-
syncd.version = { version: +collectionNode.attrs.version + 1 }
|
|
275
|
+
syncd.version = { version: +collectionNode.attrs.version + 1 };
|
|
252
276
|
}
|
|
253
|
-
syncds.push(syncd)
|
|
277
|
+
syncds.push(syncd);
|
|
254
278
|
}
|
|
255
279
|
}
|
|
256
|
-
final[name] = { patches: syncds, hasMorePatches, snapshot }
|
|
257
|
-
}))
|
|
258
|
-
return final
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const
|
|
262
|
-
const
|
|
263
|
-
const bufferArray = []
|
|
280
|
+
final[name] = { patches: syncds, hasMorePatches, snapshot };
|
|
281
|
+
}));
|
|
282
|
+
return final;
|
|
283
|
+
};
|
|
284
|
+
export const downloadExternalBlob = async (blob, options) => {
|
|
285
|
+
const stream = await downloadContentFromMessage(blob, 'md-app-state', { options });
|
|
286
|
+
const bufferArray = [];
|
|
264
287
|
for await (const chunk of stream) {
|
|
265
|
-
bufferArray.push(chunk)
|
|
266
|
-
}
|
|
267
|
-
return Buffer.concat(bufferArray)
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
const
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
const
|
|
278
|
-
newState.version
|
|
279
|
-
const mutationMap = {}
|
|
280
|
-
const areMutationsRequired = typeof minimumVersionNumber === 'undefined'
|
|
281
|
-
|| newState.version > minimumVersionNumber
|
|
288
|
+
bufferArray.push(chunk);
|
|
289
|
+
}
|
|
290
|
+
return Buffer.concat(bufferArray);
|
|
291
|
+
};
|
|
292
|
+
export const downloadExternalPatch = async (blob, options) => {
|
|
293
|
+
const buffer = await downloadExternalBlob(blob, options);
|
|
294
|
+
const syncData = proto.SyncdMutations.decode(buffer);
|
|
295
|
+
return syncData;
|
|
296
|
+
};
|
|
297
|
+
export const decodeSyncdSnapshot = async (name, snapshot, getAppStateSyncKey, minimumVersionNumber, validateMacs = true, logger) => {
|
|
298
|
+
const newState = newLTHashState();
|
|
299
|
+
newState.version = toNumber(snapshot.version.version);
|
|
300
|
+
const mutationMap = {};
|
|
301
|
+
const areMutationsRequired = typeof minimumVersionNumber === 'undefined' || newState.version > minimumVersionNumber;
|
|
282
302
|
const { hash, indexValueMap } = await decodeSyncdMutations(snapshot.records, newState, getAppStateSyncKey, areMutationsRequired
|
|
283
|
-
?
|
|
284
|
-
const index = mutation.syncAction.index?.toString()
|
|
285
|
-
mutationMap[index] = mutation
|
|
303
|
+
? mutation => {
|
|
304
|
+
const index = mutation.syncAction.index?.toString();
|
|
305
|
+
mutationMap[index] = mutation;
|
|
286
306
|
}
|
|
287
|
-
: () => { }, validateMacs)
|
|
288
|
-
newState.hash = hash
|
|
289
|
-
newState.indexValueMap = indexValueMap
|
|
307
|
+
: () => { }, validateMacs);
|
|
308
|
+
newState.hash = hash;
|
|
309
|
+
newState.indexValueMap = indexValueMap;
|
|
290
310
|
if (validateMacs) {
|
|
291
|
-
const base64Key = Buffer.from(snapshot.keyId.id).toString('base64')
|
|
292
|
-
const keyEnc = await getAppStateSyncKey(base64Key)
|
|
311
|
+
const base64Key = Buffer.from(snapshot.keyId.id).toString('base64');
|
|
312
|
+
const keyEnc = await getAppStateSyncKey(base64Key);
|
|
293
313
|
if (!keyEnc) {
|
|
294
|
-
throw new
|
|
314
|
+
throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { data: { isMissingKey: true } });
|
|
295
315
|
}
|
|
296
|
-
const result =
|
|
297
|
-
const computedSnapshotMac = generateSnapshotMac(newState.hash, newState.version, name, result.snapshotMacKey)
|
|
316
|
+
const result = mutationKeys(keyEnc.keyData);
|
|
317
|
+
const computedSnapshotMac = generateSnapshotMac(newState.hash, newState.version, name, result.snapshotMacKey);
|
|
298
318
|
if (Buffer.compare(snapshot.mac, computedSnapshotMac) !== 0) {
|
|
299
|
-
|
|
319
|
+
// LTHash verification may fail when decodeSyncdMutations skipped undecryptable
|
|
320
|
+
// records (poisoned server-side snapshot); the aggregate client hash diverges
|
|
321
|
+
// from the server-computed mac. Fall through with a warning so the session stays
|
|
322
|
+
// alive with partial state, symmetric to how decodePatches handles its own
|
|
323
|
+
// LTHash mismatch a few lines below.
|
|
324
|
+
logger?.warn({ name, version: newState.version }, 'LTHash verification failed on snapshot, continuing with partial state');
|
|
300
325
|
}
|
|
301
326
|
}
|
|
302
327
|
return {
|
|
303
328
|
state: newState,
|
|
304
329
|
mutationMap
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
const decodePatches = async (name, syncds, initial, getAppStateSyncKey, options, minimumVersionNumber, logger, validateMacs = true) => {
|
|
330
|
+
};
|
|
331
|
+
};
|
|
332
|
+
export const decodePatches = async (name, syncds, initial, getAppStateSyncKey, options, minimumVersionNumber, logger, validateMacs = true) => {
|
|
309
333
|
const newState = {
|
|
310
334
|
...initial,
|
|
311
335
|
indexValueMap: { ...initial.indexValueMap }
|
|
312
|
-
}
|
|
313
|
-
const mutationMap = {}
|
|
336
|
+
};
|
|
337
|
+
const mutationMap = {};
|
|
314
338
|
for (const syncd of syncds) {
|
|
315
|
-
const { version, keyId, snapshotMac } = syncd
|
|
339
|
+
const { version, keyId, snapshotMac } = syncd;
|
|
316
340
|
if (syncd.externalMutations) {
|
|
317
|
-
logger?.trace({ name, version }, 'downloading external patch')
|
|
318
|
-
const ref = await downloadExternalPatch(syncd.externalMutations, options)
|
|
319
|
-
logger?.debug({ name, version, mutations: ref.mutations.length }, 'downloaded external patch')
|
|
320
|
-
syncd.mutations?.push(...ref.mutations)
|
|
341
|
+
logger?.trace({ name, version }, 'downloading external patch');
|
|
342
|
+
const ref = await downloadExternalPatch(syncd.externalMutations, options);
|
|
343
|
+
logger?.debug({ name, version, mutations: ref.mutations.length }, 'downloaded external patch');
|
|
344
|
+
syncd.mutations?.push(...ref.mutations);
|
|
345
|
+
}
|
|
346
|
+
const patchVersion = toNumber(version.version);
|
|
347
|
+
newState.version = patchVersion;
|
|
348
|
+
const shouldMutate = typeof minimumVersionNumber === 'undefined' || patchVersion > minimumVersionNumber;
|
|
349
|
+
let decodeResult;
|
|
350
|
+
try {
|
|
351
|
+
decodeResult = await decodeSyncdPatch(syncd, name, newState, getAppStateSyncKey, shouldMutate
|
|
352
|
+
? mutation => {
|
|
353
|
+
const index = mutation.syncAction.index?.toString();
|
|
354
|
+
mutationMap[index] = mutation;
|
|
355
|
+
}
|
|
356
|
+
: () => { }, validateMacs);
|
|
321
357
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
}
|
|
331
|
-
: (() => { }), true)
|
|
332
|
-
newState.hash = decodeResult.hash
|
|
333
|
-
newState.indexValueMap = decodeResult.indexValueMap
|
|
358
|
+
catch (err) {
|
|
359
|
+
if (isMissingKeyError(err))
|
|
360
|
+
throw err;
|
|
361
|
+
logger?.warn({ name, version: patchVersion, error: err.message }, 'failed to decode patch, skipping');
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
newState.hash = decodeResult.hash;
|
|
365
|
+
newState.indexValueMap = decodeResult.indexValueMap;
|
|
334
366
|
if (validateMacs) {
|
|
335
|
-
const base64Key = Buffer.from(keyId.id).toString('base64')
|
|
336
|
-
const keyEnc = await getAppStateSyncKey(base64Key)
|
|
367
|
+
const base64Key = Buffer.from(keyId.id).toString('base64');
|
|
368
|
+
const keyEnc = await getAppStateSyncKey(base64Key);
|
|
337
369
|
if (!keyEnc) {
|
|
338
|
-
throw new
|
|
370
|
+
throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { data: { isMissingKey: true } });
|
|
339
371
|
}
|
|
340
|
-
const result =
|
|
341
|
-
const computedSnapshotMac = generateSnapshotMac(newState.hash, newState.version, name, result.snapshotMacKey)
|
|
372
|
+
const result = mutationKeys(keyEnc.keyData);
|
|
373
|
+
const computedSnapshotMac = generateSnapshotMac(newState.hash, newState.version, name, result.snapshotMacKey);
|
|
342
374
|
if (Buffer.compare(snapshotMac, computedSnapshotMac) !== 0) {
|
|
343
|
-
|
|
375
|
+
logger?.warn({ name, version: newState.version }, 'LTHash verification failed, skipping remaining patches');
|
|
376
|
+
break;
|
|
344
377
|
}
|
|
345
378
|
}
|
|
346
379
|
// clear memory used up by the mutations
|
|
347
|
-
syncd.mutations = []
|
|
380
|
+
syncd.mutations = [];
|
|
348
381
|
}
|
|
349
|
-
return { state: newState, mutationMap }
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
const
|
|
353
|
-
const OP = WAProto_1.proto.SyncdMutation.SyncdOperation
|
|
382
|
+
return { state: newState, mutationMap };
|
|
383
|
+
};
|
|
384
|
+
export const chatModificationToAppPatch = (mod, jid) => {
|
|
385
|
+
const OP = proto.SyncdMutation.SyncdOperation;
|
|
354
386
|
const getMessageRange = (lastMessages) => {
|
|
355
|
-
let messageRange
|
|
387
|
+
let messageRange;
|
|
356
388
|
if (Array.isArray(lastMessages)) {
|
|
357
|
-
const lastMsg = lastMessages[lastMessages.length - 1]
|
|
389
|
+
const lastMsg = lastMessages[lastMessages.length - 1];
|
|
358
390
|
messageRange = {
|
|
359
391
|
lastMessageTimestamp: lastMsg?.messageTimestamp,
|
|
360
|
-
messages: lastMessages?.length
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
392
|
+
messages: lastMessages?.length
|
|
393
|
+
? lastMessages.map(m => {
|
|
394
|
+
if (!m.key?.id || !m.key?.remoteJid) {
|
|
395
|
+
throw new Boom('Incomplete key', { statusCode: 400, data: m });
|
|
396
|
+
}
|
|
397
|
+
if (isJidGroup(m.key.remoteJid) && !m.key.fromMe && !m.key.participant) {
|
|
398
|
+
throw new Boom('Expected not from me message to have participant', { statusCode: 400, data: m });
|
|
399
|
+
}
|
|
400
|
+
if (!m.messageTimestamp || !toNumber(m.messageTimestamp)) {
|
|
401
|
+
throw new Boom('Missing timestamp in last message list', { statusCode: 400, data: m });
|
|
402
|
+
}
|
|
403
|
+
if (m.key.participant) {
|
|
404
|
+
m.key.participant = jidNormalizedUser(m.key.participant);
|
|
405
|
+
}
|
|
406
|
+
return m;
|
|
407
|
+
})
|
|
408
|
+
: undefined
|
|
409
|
+
};
|
|
376
410
|
}
|
|
377
411
|
else {
|
|
378
|
-
messageRange = lastMessages
|
|
412
|
+
messageRange = lastMessages;
|
|
379
413
|
}
|
|
380
|
-
return messageRange
|
|
381
|
-
}
|
|
382
|
-
let patch
|
|
414
|
+
return messageRange;
|
|
415
|
+
};
|
|
416
|
+
let patch;
|
|
383
417
|
if ('mute' in mod) {
|
|
384
418
|
patch = {
|
|
385
419
|
syncAction: {
|
|
@@ -392,7 +426,7 @@ const chatModificationToAppPatch = (mod, jid) => {
|
|
|
392
426
|
type: 'regular_high',
|
|
393
427
|
apiVersion: 2,
|
|
394
428
|
operation: OP.SET
|
|
395
|
-
}
|
|
429
|
+
};
|
|
396
430
|
}
|
|
397
431
|
else if ('archive' in mod) {
|
|
398
432
|
patch = {
|
|
@@ -406,7 +440,7 @@ const chatModificationToAppPatch = (mod, jid) => {
|
|
|
406
440
|
type: 'regular_low',
|
|
407
441
|
apiVersion: 3,
|
|
408
442
|
operation: OP.SET
|
|
409
|
-
}
|
|
443
|
+
};
|
|
410
444
|
}
|
|
411
445
|
else if ('markRead' in mod) {
|
|
412
446
|
patch = {
|
|
@@ -420,10 +454,10 @@ const chatModificationToAppPatch = (mod, jid) => {
|
|
|
420
454
|
type: 'regular_low',
|
|
421
455
|
apiVersion: 3,
|
|
422
456
|
operation: OP.SET
|
|
423
|
-
}
|
|
457
|
+
};
|
|
424
458
|
}
|
|
425
459
|
else if ('deleteForMe' in mod) {
|
|
426
|
-
const { timestamp, key, deleteMedia } = mod.deleteForMe
|
|
460
|
+
const { timestamp, key, deleteMedia } = mod.deleteForMe;
|
|
427
461
|
patch = {
|
|
428
462
|
syncAction: {
|
|
429
463
|
deleteMessageForMeAction: {
|
|
@@ -435,20 +469,20 @@ const chatModificationToAppPatch = (mod, jid) => {
|
|
|
435
469
|
type: 'regular_high',
|
|
436
470
|
apiVersion: 3,
|
|
437
471
|
operation: OP.SET
|
|
438
|
-
}
|
|
472
|
+
};
|
|
439
473
|
}
|
|
440
474
|
else if ('clear' in mod) {
|
|
441
475
|
patch = {
|
|
442
476
|
syncAction: {
|
|
443
477
|
clearChatAction: {
|
|
444
|
-
messageRange: getMessageRange(mod.lastMessages)
|
|
478
|
+
messageRange: getMessageRange(mod.lastMessages)
|
|
445
479
|
}
|
|
446
480
|
},
|
|
447
481
|
index: ['clearChat', jid, '1' /*the option here is 0 when keep starred messages is enabled*/, '0'],
|
|
448
482
|
type: 'regular_high',
|
|
449
483
|
apiVersion: 6,
|
|
450
484
|
operation: OP.SET
|
|
451
|
-
}
|
|
485
|
+
};
|
|
452
486
|
}
|
|
453
487
|
else if ('pin' in mod) {
|
|
454
488
|
patch = {
|
|
@@ -461,32 +495,32 @@ const chatModificationToAppPatch = (mod, jid) => {
|
|
|
461
495
|
type: 'regular_low',
|
|
462
496
|
apiVersion: 5,
|
|
463
497
|
operation: OP.SET
|
|
464
|
-
}
|
|
498
|
+
};
|
|
465
499
|
}
|
|
466
500
|
else if ('contact' in mod) {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
},
|
|
471
|
-
index: ['contact', jid],
|
|
472
|
-
type: 'critical_unblock_low',
|
|
501
|
+
patch = {
|
|
502
|
+
syncAction: {
|
|
503
|
+
contactAction: mod.contact || {}
|
|
504
|
+
},
|
|
505
|
+
index: ['contact', jid],
|
|
506
|
+
type: 'critical_unblock_low',
|
|
473
507
|
apiVersion: 2,
|
|
474
508
|
operation: mod.contact ? OP.SET : OP.REMOVE
|
|
475
|
-
}
|
|
509
|
+
};
|
|
476
510
|
}
|
|
477
511
|
else if ('disableLinkPreviews' in mod) {
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
512
|
+
patch = {
|
|
513
|
+
syncAction: {
|
|
514
|
+
privacySettingDisableLinkPreviewsAction: mod.disableLinkPreviews || {}
|
|
515
|
+
},
|
|
516
|
+
index: ['setting_disableLinkPreviews'],
|
|
517
|
+
type: 'regular',
|
|
518
|
+
apiVersion: 8,
|
|
519
|
+
operation: OP.SET
|
|
520
|
+
};
|
|
487
521
|
}
|
|
488
522
|
else if ('star' in mod) {
|
|
489
|
-
const key = mod.star.messages[0]
|
|
523
|
+
const key = mod.star.messages[0];
|
|
490
524
|
patch = {
|
|
491
525
|
syncAction: {
|
|
492
526
|
starAction: {
|
|
@@ -497,20 +531,20 @@ const chatModificationToAppPatch = (mod, jid) => {
|
|
|
497
531
|
type: 'regular_low',
|
|
498
532
|
apiVersion: 2,
|
|
499
533
|
operation: OP.SET
|
|
500
|
-
}
|
|
534
|
+
};
|
|
501
535
|
}
|
|
502
536
|
else if ('delete' in mod) {
|
|
503
537
|
patch = {
|
|
504
538
|
syncAction: {
|
|
505
539
|
deleteChatAction: {
|
|
506
|
-
messageRange: getMessageRange(mod.lastMessages)
|
|
540
|
+
messageRange: getMessageRange(mod.lastMessages)
|
|
507
541
|
}
|
|
508
542
|
},
|
|
509
543
|
index: ['deleteChat', jid, '1'],
|
|
510
544
|
type: 'regular_high',
|
|
511
545
|
apiVersion: 6,
|
|
512
546
|
operation: OP.SET
|
|
513
|
-
}
|
|
547
|
+
};
|
|
514
548
|
}
|
|
515
549
|
else if ('pushNameSetting' in mod) {
|
|
516
550
|
patch = {
|
|
@@ -522,8 +556,8 @@ const chatModificationToAppPatch = (mod, jid) => {
|
|
|
522
556
|
index: ['setting_pushName'],
|
|
523
557
|
type: 'critical_block',
|
|
524
558
|
apiVersion: 1,
|
|
525
|
-
operation: OP.SET
|
|
526
|
-
}
|
|
559
|
+
operation: OP.SET
|
|
560
|
+
};
|
|
527
561
|
}
|
|
528
562
|
else if ('quickReply' in mod) {
|
|
529
563
|
patch = {
|
|
@@ -540,7 +574,7 @@ const chatModificationToAppPatch = (mod, jid) => {
|
|
|
540
574
|
type: 'regular',
|
|
541
575
|
apiVersion: 2,
|
|
542
576
|
operation: OP.SET
|
|
543
|
-
}
|
|
577
|
+
};
|
|
544
578
|
}
|
|
545
579
|
else if ('addLabel' in mod) {
|
|
546
580
|
patch = {
|
|
@@ -555,64 +589,57 @@ const chatModificationToAppPatch = (mod, jid) => {
|
|
|
555
589
|
index: ['label_edit', mod.addLabel.id],
|
|
556
590
|
type: 'regular',
|
|
557
591
|
apiVersion: 3,
|
|
558
|
-
operation: OP.SET
|
|
559
|
-
}
|
|
592
|
+
operation: OP.SET
|
|
593
|
+
};
|
|
560
594
|
}
|
|
561
595
|
else if ('addChatLabel' in mod) {
|
|
562
596
|
patch = {
|
|
563
597
|
syncAction: {
|
|
564
598
|
labelAssociationAction: {
|
|
565
|
-
labeled: true
|
|
599
|
+
labeled: true
|
|
566
600
|
}
|
|
567
601
|
},
|
|
568
|
-
index: [
|
|
602
|
+
index: [LabelAssociationType.Chat, mod.addChatLabel.labelId, jid],
|
|
569
603
|
type: 'regular',
|
|
570
604
|
apiVersion: 3,
|
|
571
|
-
operation: OP.SET
|
|
572
|
-
}
|
|
605
|
+
operation: OP.SET
|
|
606
|
+
};
|
|
573
607
|
}
|
|
574
608
|
else if ('removeChatLabel' in mod) {
|
|
575
609
|
patch = {
|
|
576
610
|
syncAction: {
|
|
577
611
|
labelAssociationAction: {
|
|
578
|
-
labeled: false
|
|
612
|
+
labeled: false
|
|
579
613
|
}
|
|
580
614
|
},
|
|
581
|
-
index: [
|
|
615
|
+
index: [LabelAssociationType.Chat, mod.removeChatLabel.labelId, jid],
|
|
582
616
|
type: 'regular',
|
|
583
617
|
apiVersion: 3,
|
|
584
|
-
operation: OP.SET
|
|
585
|
-
}
|
|
618
|
+
operation: OP.SET
|
|
619
|
+
};
|
|
586
620
|
}
|
|
587
621
|
else if ('addMessageLabel' in mod) {
|
|
588
622
|
patch = {
|
|
589
623
|
syncAction: {
|
|
590
624
|
labelAssociationAction: {
|
|
591
|
-
labeled: true
|
|
625
|
+
labeled: true
|
|
592
626
|
}
|
|
593
627
|
},
|
|
594
|
-
index: [
|
|
595
|
-
LabelAssociation_1.LabelAssociationType.Message,
|
|
596
|
-
mod.addMessageLabel.labelId,
|
|
597
|
-
jid,
|
|
598
|
-
mod.addMessageLabel.messageId,
|
|
599
|
-
'0',
|
|
600
|
-
'0'
|
|
601
|
-
],
|
|
628
|
+
index: [LabelAssociationType.Message, mod.addMessageLabel.labelId, jid, mod.addMessageLabel.messageId, '0', '0'],
|
|
602
629
|
type: 'regular',
|
|
603
630
|
apiVersion: 3,
|
|
604
|
-
operation: OP.SET
|
|
605
|
-
}
|
|
631
|
+
operation: OP.SET
|
|
632
|
+
};
|
|
606
633
|
}
|
|
607
634
|
else if ('removeMessageLabel' in mod) {
|
|
608
635
|
patch = {
|
|
609
636
|
syncAction: {
|
|
610
637
|
labelAssociationAction: {
|
|
611
|
-
labeled: false
|
|
638
|
+
labeled: false
|
|
612
639
|
}
|
|
613
640
|
},
|
|
614
641
|
index: [
|
|
615
|
-
|
|
642
|
+
LabelAssociationType.Message,
|
|
616
643
|
mod.removeMessageLabel.labelId,
|
|
617
644
|
jid,
|
|
618
645
|
mod.removeMessageLabel.messageId,
|
|
@@ -621,31 +648,28 @@ const chatModificationToAppPatch = (mod, jid) => {
|
|
|
621
648
|
],
|
|
622
649
|
type: 'regular',
|
|
623
650
|
apiVersion: 3,
|
|
624
|
-
operation: OP.SET
|
|
625
|
-
}
|
|
651
|
+
operation: OP.SET
|
|
652
|
+
};
|
|
626
653
|
}
|
|
627
654
|
else {
|
|
628
|
-
throw new
|
|
629
|
-
}
|
|
630
|
-
patch.syncAction.timestamp = Date.now()
|
|
631
|
-
return patch
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
const
|
|
635
|
-
const
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
const { syncAction: { value: action }, index: [type, id, msgId, fromMe] } = syncAction
|
|
655
|
+
throw new Boom('not supported');
|
|
656
|
+
}
|
|
657
|
+
patch.syncAction.timestamp = Date.now();
|
|
658
|
+
return patch;
|
|
659
|
+
};
|
|
660
|
+
export const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) => {
|
|
661
|
+
const isInitialSync = !!initialSyncOpts;
|
|
662
|
+
const accountSettings = initialSyncOpts?.accountSettings;
|
|
663
|
+
logger?.trace({ syncAction, initialSync: !!initialSyncOpts }, 'processing sync action');
|
|
664
|
+
const { syncAction: { value: action }, index: [type, id, msgId, fromMe] } = syncAction;
|
|
639
665
|
if (action?.muteAction) {
|
|
640
666
|
ev.emit('chats.update', [
|
|
641
667
|
{
|
|
642
668
|
id,
|
|
643
|
-
muteEndTime: action.muteAction?.muted
|
|
644
|
-
? generics_1.toNumber(action.muteAction.muteEndTimestamp)
|
|
645
|
-
: null,
|
|
669
|
+
muteEndTime: action.muteAction?.muted ? toNumber(action.muteAction.muteEndTimestamp) : null,
|
|
646
670
|
conditional: getChatUpdateConditional(id, undefined)
|
|
647
671
|
}
|
|
648
|
-
])
|
|
672
|
+
]);
|
|
649
673
|
}
|
|
650
674
|
else if (action?.archiveChatAction || type === 'archive' || type === 'unarchive') {
|
|
651
675
|
// okay so we've to do some annoying computation here
|
|
@@ -654,38 +678,40 @@ const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) => {
|
|
|
654
678
|
// 1. if the account unarchiveChats setting is true
|
|
655
679
|
// a. if the chat is archived, and no further messages have been received -- simple, keep archived
|
|
656
680
|
// b. if the chat was archived, and the user received messages from the other person afterwards
|
|
657
|
-
//
|
|
658
|
-
//
|
|
681
|
+
// then the chat should be marked unarchved --
|
|
682
|
+
// we compare the timestamp of latest message from the other person to determine this
|
|
659
683
|
// 2. if the account unarchiveChats setting is false -- then it doesn't matter,
|
|
660
|
-
//
|
|
661
|
-
const archiveAction = action?.archiveChatAction
|
|
662
|
-
const isArchived = archiveAction
|
|
663
|
-
? archiveAction.archived
|
|
664
|
-
: type === 'archive'
|
|
684
|
+
// it'll always take an app state action to mark in unarchived -- which we'll get anyway
|
|
685
|
+
const archiveAction = action?.archiveChatAction;
|
|
686
|
+
const isArchived = archiveAction ? archiveAction.archived : type === 'archive';
|
|
665
687
|
// // basically we don't need to fire an "archive" update if the chat is being marked unarchvied
|
|
666
688
|
// // this only applies for the initial sync
|
|
667
689
|
// if(isInitialSync && !isArchived) {
|
|
668
|
-
//
|
|
690
|
+
// isArchived = false
|
|
669
691
|
// }
|
|
670
|
-
const msgRange = !accountSettings?.unarchiveChats ? undefined : archiveAction?.messageRange
|
|
692
|
+
const msgRange = !accountSettings?.unarchiveChats ? undefined : archiveAction?.messageRange;
|
|
671
693
|
// logger?.debug({ chat: id, syncAction }, 'message range archive')
|
|
672
|
-
ev.emit('chats.update', [
|
|
694
|
+
ev.emit('chats.update', [
|
|
695
|
+
{
|
|
673
696
|
id,
|
|
674
697
|
archived: isArchived,
|
|
675
698
|
conditional: getChatUpdateConditional(id, msgRange)
|
|
676
|
-
}
|
|
699
|
+
}
|
|
700
|
+
]);
|
|
677
701
|
}
|
|
678
702
|
else if (action?.markChatAsReadAction) {
|
|
679
|
-
const markReadAction = action.markChatAsReadAction
|
|
703
|
+
const markReadAction = action.markChatAsReadAction;
|
|
680
704
|
// basically we don't need to fire an "read" update if the chat is being marked as read
|
|
681
705
|
// because the chat is read by default
|
|
682
706
|
// this only applies for the initial sync
|
|
683
|
-
const isNullUpdate = isInitialSync && markReadAction.read
|
|
684
|
-
ev.emit('chats.update', [
|
|
707
|
+
const isNullUpdate = isInitialSync && markReadAction.read;
|
|
708
|
+
ev.emit('chats.update', [
|
|
709
|
+
{
|
|
685
710
|
id,
|
|
686
711
|
unreadCount: isNullUpdate ? null : !!markReadAction?.read ? 0 : -1,
|
|
687
712
|
conditional: getChatUpdateConditional(id, markReadAction?.messageRange)
|
|
688
|
-
}
|
|
713
|
+
}
|
|
714
|
+
]);
|
|
689
715
|
}
|
|
690
716
|
else if (action?.deleteMessageForMeAction || type === 'deleteMessageForMe') {
|
|
691
717
|
ev.emit('messages.delete', {
|
|
@@ -696,114 +722,151 @@ const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) => {
|
|
|
696
722
|
fromMe: fromMe === '1'
|
|
697
723
|
}
|
|
698
724
|
]
|
|
699
|
-
})
|
|
725
|
+
});
|
|
700
726
|
}
|
|
701
727
|
else if (action?.contactAction) {
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
name: action.contactAction.fullName,
|
|
705
|
-
lid: action.contactAction.lidJid || undefined,
|
|
706
|
-
phoneNumber: action.contactAction.pnJid || undefined
|
|
707
|
-
}])
|
|
728
|
+
const results = processContactAction(action.contactAction, id, logger);
|
|
729
|
+
emitSyncActionResults(ev, results);
|
|
708
730
|
}
|
|
709
731
|
else if (action?.pushNameSetting) {
|
|
710
|
-
const name = action?.pushNameSetting?.name
|
|
732
|
+
const name = action?.pushNameSetting?.name;
|
|
711
733
|
if (name && me?.name !== name) {
|
|
712
|
-
ev.emit('creds.update', { me: { ...me, name } })
|
|
734
|
+
ev.emit('creds.update', { me: { ...me, name } });
|
|
713
735
|
}
|
|
714
736
|
}
|
|
715
737
|
else if (action?.pinAction) {
|
|
716
|
-
ev.emit('chats.update', [
|
|
738
|
+
ev.emit('chats.update', [
|
|
739
|
+
{
|
|
717
740
|
id,
|
|
718
|
-
pinned: action.pinAction?.pinned ?
|
|
741
|
+
pinned: action.pinAction?.pinned ? toNumber(action.timestamp) : null,
|
|
719
742
|
conditional: getChatUpdateConditional(id, undefined)
|
|
720
|
-
}
|
|
743
|
+
}
|
|
744
|
+
]);
|
|
721
745
|
}
|
|
722
746
|
else if (action?.unarchiveChatsSetting) {
|
|
723
|
-
const unarchiveChats = !!action.unarchiveChatsSetting.unarchiveChats
|
|
724
|
-
ev.emit('creds.update', { accountSettings: { unarchiveChats } })
|
|
725
|
-
logger?.info(`archive setting updated => '${action.unarchiveChatsSetting.unarchiveChats}'`)
|
|
747
|
+
const unarchiveChats = !!action.unarchiveChatsSetting.unarchiveChats;
|
|
748
|
+
ev.emit('creds.update', { accountSettings: { unarchiveChats } });
|
|
749
|
+
logger?.info(`archive setting updated => '${action.unarchiveChatsSetting.unarchiveChats}'`);
|
|
726
750
|
if (accountSettings) {
|
|
727
|
-
accountSettings.unarchiveChats = unarchiveChats
|
|
751
|
+
accountSettings.unarchiveChats = unarchiveChats;
|
|
728
752
|
}
|
|
729
753
|
}
|
|
730
754
|
else if (action?.starAction || type === 'star') {
|
|
731
|
-
let starred = action?.starAction?.starred
|
|
755
|
+
let starred = action?.starAction?.starred;
|
|
732
756
|
if (typeof starred !== 'boolean') {
|
|
733
|
-
starred = syncAction.index[syncAction.index.length - 1] === '1'
|
|
757
|
+
starred = syncAction.index[syncAction.index.length - 1] === '1';
|
|
734
758
|
}
|
|
735
759
|
ev.emit('messages.update', [
|
|
736
760
|
{
|
|
737
761
|
key: { remoteJid: id, id: msgId, fromMe: fromMe === '1' },
|
|
738
762
|
update: { starred }
|
|
739
763
|
}
|
|
740
|
-
])
|
|
764
|
+
]);
|
|
741
765
|
}
|
|
742
766
|
else if (action?.deleteChatAction || type === 'deleteChat') {
|
|
743
767
|
if (!isInitialSync) {
|
|
744
|
-
ev.emit('chats.delete', [id])
|
|
768
|
+
ev.emit('chats.delete', [id]);
|
|
745
769
|
}
|
|
746
770
|
}
|
|
747
771
|
else if (action?.labelEditAction) {
|
|
748
|
-
const { name, color, deleted, predefinedId } = action.labelEditAction
|
|
772
|
+
const { name, color, deleted, predefinedId } = action.labelEditAction;
|
|
749
773
|
ev.emit('labels.edit', {
|
|
750
|
-
id,
|
|
774
|
+
id: id,
|
|
751
775
|
name: name,
|
|
752
776
|
color: color,
|
|
753
777
|
deleted: deleted,
|
|
754
778
|
predefinedId: predefinedId ? String(predefinedId) : undefined
|
|
755
|
-
})
|
|
779
|
+
});
|
|
756
780
|
}
|
|
757
781
|
else if (action?.labelAssociationAction) {
|
|
758
782
|
ev.emit('labels.association', {
|
|
759
|
-
type: action.labelAssociationAction.labeled
|
|
760
|
-
|
|
761
|
-
: 'remove',
|
|
762
|
-
association: type === LabelAssociation_1.LabelAssociationType.Chat
|
|
783
|
+
type: action.labelAssociationAction.labeled ? 'add' : 'remove',
|
|
784
|
+
association: type === LabelAssociationType.Chat
|
|
763
785
|
? {
|
|
764
|
-
type:
|
|
786
|
+
type: LabelAssociationType.Chat,
|
|
765
787
|
chatId: syncAction.index[2],
|
|
766
788
|
labelId: syncAction.index[1]
|
|
767
789
|
}
|
|
768
790
|
: {
|
|
769
|
-
type:
|
|
791
|
+
type: LabelAssociationType.Message,
|
|
770
792
|
chatId: syncAction.index[2],
|
|
771
793
|
messageId: syncAction.index[3],
|
|
772
794
|
labelId: syncAction.index[1]
|
|
773
795
|
}
|
|
774
|
-
})
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
else if (action?.localeSetting?.locale) {
|
|
799
|
+
ev.emit('settings.update', { setting: 'locale', value: action.localeSetting.locale });
|
|
800
|
+
}
|
|
801
|
+
else if (action?.timeFormatAction) {
|
|
802
|
+
ev.emit('settings.update', { setting: 'timeFormat', value: action.timeFormatAction });
|
|
803
|
+
}
|
|
804
|
+
else if (action?.pnForLidChatAction) {
|
|
805
|
+
if (action.pnForLidChatAction.pnJid) {
|
|
806
|
+
ev.emit('lid-mapping.update', { lid: id, pn: action.pnForLidChatAction.pnJid });
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
else if (action?.privacySettingRelayAllCalls) {
|
|
810
|
+
ev.emit('settings.update', {
|
|
811
|
+
setting: 'privacySettingRelayAllCalls',
|
|
812
|
+
value: action.privacySettingRelayAllCalls
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
else if (action?.statusPrivacy) {
|
|
816
|
+
ev.emit('settings.update', { setting: 'statusPrivacy', value: action.statusPrivacy });
|
|
817
|
+
}
|
|
818
|
+
else if (action?.lockChatAction) {
|
|
819
|
+
ev.emit('chats.lock', { id: id, locked: !!action.lockChatAction.locked });
|
|
820
|
+
}
|
|
821
|
+
else if (action?.privacySettingDisableLinkPreviewsAction) {
|
|
822
|
+
ev.emit('settings.update', {
|
|
823
|
+
setting: 'disableLinkPreviews',
|
|
824
|
+
value: action.privacySettingDisableLinkPreviewsAction
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
else if (action?.notificationActivitySettingAction?.notificationActivitySetting) {
|
|
828
|
+
ev.emit('settings.update', {
|
|
829
|
+
setting: 'notificationActivitySetting',
|
|
830
|
+
value: action.notificationActivitySettingAction.notificationActivitySetting
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
else if (action?.lidContactAction) {
|
|
834
|
+
ev.emit('contacts.upsert', [
|
|
835
|
+
{
|
|
836
|
+
id: id,
|
|
837
|
+
name: action.lidContactAction.fullName ||
|
|
838
|
+
action.lidContactAction.firstName ||
|
|
839
|
+
action.lidContactAction.username ||
|
|
840
|
+
undefined,
|
|
841
|
+
username: action.lidContactAction.username || undefined,
|
|
842
|
+
lid: id,
|
|
843
|
+
phoneNumber: undefined
|
|
844
|
+
}
|
|
845
|
+
]);
|
|
846
|
+
}
|
|
847
|
+
else if (action?.privacySettingChannelsPersonalisedRecommendationAction) {
|
|
848
|
+
ev.emit('settings.update', {
|
|
849
|
+
setting: 'channelsPersonalisedRecommendation',
|
|
850
|
+
value: action.privacySettingChannelsPersonalisedRecommendationAction
|
|
851
|
+
});
|
|
775
852
|
}
|
|
776
853
|
else {
|
|
777
|
-
logger?.debug({ syncAction, id }, 'unprocessable update')
|
|
854
|
+
logger?.debug({ syncAction, id }, 'unprocessable update');
|
|
778
855
|
}
|
|
779
856
|
function getChatUpdateConditional(id, msgRange) {
|
|
780
857
|
return isInitialSync
|
|
781
|
-
?
|
|
782
|
-
const chat = data.historySets.chats[id] || data.chatUpserts[id]
|
|
858
|
+
? data => {
|
|
859
|
+
const chat = data.historySets.chats[id] || data.chatUpserts[id];
|
|
783
860
|
if (chat) {
|
|
784
|
-
return msgRange ? isValidPatchBasedOnMessageRange(chat, msgRange) : true
|
|
861
|
+
return msgRange ? isValidPatchBasedOnMessageRange(chat, msgRange) : true;
|
|
785
862
|
}
|
|
786
863
|
}
|
|
787
|
-
: undefined
|
|
864
|
+
: undefined;
|
|
788
865
|
}
|
|
789
866
|
function isValidPatchBasedOnMessageRange(chat, msgRange) {
|
|
790
|
-
const lastMsgTimestamp = Number(msgRange?.lastMessageTimestamp || msgRange?.lastSystemMessageTimestamp || 0)
|
|
791
|
-
const chatLastMsgTimestamp = Number(chat?.lastMessageRecvTimestamp || 0)
|
|
792
|
-
return lastMsgTimestamp >= chatLastMsgTimestamp
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
module.exports = {
|
|
797
|
-
mutationKeys,
|
|
798
|
-
newLTHashState,
|
|
799
|
-
encodeSyncdPatch,
|
|
800
|
-
decodeSyncdMutations,
|
|
801
|
-
decodeSyncdPatch,
|
|
802
|
-
extractSyncdPatches,
|
|
803
|
-
downloadExternalBlob,
|
|
804
|
-
downloadExternalPatch,
|
|
805
|
-
decodeSyncdSnapshot,
|
|
806
|
-
decodePatches,
|
|
807
|
-
chatModificationToAppPatch,
|
|
808
|
-
processSyncAction
|
|
809
|
-
}
|
|
867
|
+
const lastMsgTimestamp = Number(msgRange?.lastMessageTimestamp || msgRange?.lastSystemMessageTimestamp || 0);
|
|
868
|
+
const chatLastMsgTimestamp = Number(chat?.lastMessageRecvTimestamp || 0);
|
|
869
|
+
return lastMsgTimestamp >= chatLastMsgTimestamp;
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
//# sourceMappingURL=chat-utils.js.map
|