lordceaser-baileys 2.0.37 → 2.0.39
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 +660 -1073
- package/WAProto/GenerateStatics.sh +4 -3
- package/WAProto/WAProto.proto +359 -2494
- package/WAProto/index.d.ts +31460 -8461
- package/WAProto/index.js +96236 -92883
- package/WASignalGroup/GroupProtocol.js +1697 -0
- package/WASignalGroup/ciphertext_message.js +16 -0
- package/WASignalGroup/group_cipher.js +120 -0
- package/WASignalGroup/group_session_builder.js +46 -0
- package/WASignalGroup/index.js +5 -0
- package/WASignalGroup/keyhelper.js +21 -0
- package/WASignalGroup/protobufs.js +3 -0
- package/WASignalGroup/queue_job.js +69 -0
- package/WASignalGroup/sender_chain_key.js +50 -0
- package/WASignalGroup/sender_key_distribution_message.js +78 -0
- package/WASignalGroup/sender_key_message.js +92 -0
- package/WASignalGroup/sender_key_name.js +70 -0
- package/WASignalGroup/sender_key_record.js +56 -0
- package/WASignalGroup/sender_key_state.js +129 -0
- package/{lib/Signal/Group/sender-message-key.js → WASignalGroup/sender_message_key.js} +16 -3
- package/lib/Defaults/baileys-version.json +3 -0
- package/lib/Defaults/index.d.ts +245 -37
- package/lib/Defaults/index.js +74 -82
- package/lib/Defaults/phonenumber-mcc.json +223 -0
- package/lib/Signal/libsignal.d.ts +3 -5
- package/lib/Signal/libsignal.js +80 -359
- package/lib/Socket/Client/{types.d.ts → abstract-socket-client.d.ts} +5 -4
- package/lib/Socket/Client/abstract-socket-client.js +13 -0
- package/lib/Socket/Client/index.d.ts +3 -3
- package/lib/Socket/Client/index.js +19 -3
- package/lib/Socket/Client/mobile-socket-client.d.ts +13 -0
- package/lib/Socket/Client/mobile-socket-client.js +65 -0
- package/lib/Socket/Client/{websocket.d.ts → web-socket-client.d.ts} +2 -3
- package/lib/Socket/Client/web-socket-client.js +62 -0
- package/lib/Socket/business.d.ts +87 -156
- package/lib/Socket/business.js +43 -162
- package/lib/Socket/chats.d.ts +40 -82
- package/lib/Socket/chats.js +284 -603
- package/lib/Socket/groups.d.ts +58 -96
- package/lib/Socket/groups.js +82 -115
- package/lib/Socket/index.d.ts +94 -204
- package/lib/Socket/index.js +9 -11
- package/lib/Socket/messages-recv.d.ts +77 -145
- package/lib/Socket/messages-recv.js +400 -1305
- package/lib/Socket/messages-send.d.ts +70 -141
- package/lib/Socket/messages-send.js +249 -717
- package/lib/Socket/registration.d.ts +242 -0
- package/lib/Socket/registration.js +166 -0
- package/lib/Socket/socket.d.ts +18 -34
- package/lib/Socket/socket.js +206 -557
- package/lib/Store/index.d.ts +3 -0
- package/lib/Store/index.js +10 -0
- package/lib/Store/make-cache-manager-store.d.ts +14 -0
- package/lib/Store/make-cache-manager-store.js +83 -0
- package/lib/Store/make-in-memory-store.d.ts +118 -0
- package/lib/Store/make-in-memory-store.js +422 -0
- package/lib/Store/make-ordered-dictionary.d.ts +13 -0
- package/lib/Store/make-ordered-dictionary.js +81 -0
- package/lib/Store/object-repository.d.ts +10 -0
- package/lib/Store/object-repository.js +27 -0
- package/lib/Types/Auth.d.ts +12 -19
- package/lib/Types/Auth.js +2 -2
- package/lib/Types/Call.d.ts +1 -3
- package/lib/Types/Call.js +2 -2
- package/lib/Types/Chat.d.ts +14 -31
- package/lib/Types/Chat.js +4 -8
- package/lib/Types/Contact.d.ts +1 -8
- package/lib/Types/Contact.js +2 -2
- package/lib/Types/Events.d.ts +17 -101
- package/lib/Types/Events.js +2 -2
- package/lib/Types/GroupMetadata.d.ts +3 -18
- package/lib/Types/GroupMetadata.js +2 -2
- package/lib/Types/Label.d.ts +0 -1
- package/lib/Types/Label.js +5 -3
- package/lib/Types/LabelAssociation.d.ts +0 -1
- package/lib/Types/LabelAssociation.js +5 -3
- package/lib/Types/Message.d.ts +29 -81
- package/lib/Types/Message.js +9 -11
- package/lib/Types/Product.d.ts +1 -2
- package/lib/Types/Product.js +2 -2
- package/lib/Types/Signal.d.ts +2 -32
- package/lib/Types/Signal.js +2 -2
- package/lib/Types/Socket.d.ts +26 -46
- package/lib/Types/Socket.js +2 -3
- package/lib/Types/State.d.ts +2 -72
- package/lib/Types/State.js +2 -56
- package/lib/Types/index.d.ts +13 -16
- package/lib/Types/index.js +30 -15
- package/lib/Utils/auth-utils.d.ts +6 -12
- package/lib/Utils/auth-utils.js +143 -239
- package/lib/Utils/baileys-event-stream.d.ts +16 -0
- package/lib/Utils/baileys-event-stream.js +63 -0
- package/lib/Utils/business.d.ts +2 -3
- package/lib/Utils/business.js +69 -66
- package/lib/Utils/chat-utils.d.ts +23 -52
- package/lib/Utils/chat-utils.js +248 -380
- package/lib/Utils/crypto.d.ts +21 -17
- package/lib/Utils/crypto.js +92 -57
- package/lib/Utils/decode-wa-message.d.ts +8 -54
- package/lib/Utils/decode-wa-message.js +57 -186
- package/lib/Utils/event-buffer.d.ts +8 -9
- package/lib/Utils/event-buffer.js +76 -178
- package/lib/Utils/generics.d.ts +23 -26
- package/lib/Utils/generics.js +166 -165
- package/lib/Utils/history.d.ts +11 -16
- package/lib/Utils/history.js +53 -93
- package/lib/Utils/index.d.ts +17 -22
- package/lib/Utils/index.js +33 -22
- package/lib/Utils/link-preview.d.ts +5 -5
- package/lib/Utils/link-preview.js +24 -16
- package/lib/Utils/logger.d.ts +3 -11
- package/lib/Utils/logger.js +7 -3
- package/lib/Utils/lt-hash.d.ts +12 -8
- package/lib/Utils/lt-hash.js +46 -3
- package/lib/Utils/make-mutex.d.ts +2 -4
- package/lib/Utils/make-mutex.js +34 -24
- package/lib/Utils/messages-media.d.ts +35 -61
- package/lib/Utils/messages-media.js +301 -415
- package/lib/Utils/messages.d.ts +18 -32
- package/lib/Utils/messages.js +261 -396
- package/lib/Utils/noise-handler.d.ts +13 -12
- package/lib/Utils/noise-handler.js +98 -144
- package/lib/Utils/process-message.d.ts +12 -30
- package/lib/Utils/process-message.js +163 -439
- package/lib/Utils/signal.d.ts +5 -20
- package/lib/Utils/signal.js +74 -114
- package/lib/Utils/use-multi-file-auth-state.d.ts +1 -2
- package/lib/Utils/use-multi-file-auth-state.js +33 -61
- package/lib/Utils/validate-connection.d.ts +6 -6
- package/lib/Utils/validate-connection.js +114 -119
- package/lib/WABinary/constants.d.ts +4 -5
- package/lib/WABinary/constants.js +20 -1281
- package/lib/WABinary/decode.d.ts +4 -4
- package/lib/WABinary/decode.js +43 -51
- package/lib/WABinary/encode.d.ts +3 -3
- package/lib/WABinary/encode.js +44 -32
- package/lib/WABinary/generic-utils.d.ts +6 -6
- package/lib/WABinary/generic-utils.js +43 -46
- package/lib/WABinary/index.d.ts +5 -6
- package/lib/WABinary/index.js +21 -6
- package/lib/WABinary/jid-utils.d.ts +6 -23
- package/lib/WABinary/jid-utils.js +39 -73
- package/lib/WABinary/types.d.ts +1 -2
- package/lib/WABinary/types.js +2 -2
- package/lib/WAM/BinaryInfo.d.ts +11 -3
- package/lib/WAM/BinaryInfo.js +5 -2
- package/lib/WAM/constants.d.ts +3 -5
- package/lib/WAM/constants.js +11958 -19461
- package/lib/WAM/encode.d.ts +3 -3
- package/lib/WAM/encode.js +22 -17
- package/lib/WAM/index.d.ts +3 -4
- package/lib/WAM/index.js +19 -4
- package/lib/index.d.ts +8 -9
- package/lib/index.js +30 -11
- package/package.json +2 -2
- package/WAProto/WAProto/GenerateStatics.sh +0 -3
- package/WAProto/WAProto/WAProto.proto +0 -5479
- package/WAProto/WAProto/fix-imports.js +0 -85
- package/WAProto/WAProto/index.d.ts +0 -14017
- package/WAProto/WAProto/index.js +0 -97691
- package/WAProto/fix-imports.js +0 -85
- package/lib/Defaults/index.d.ts.map +0 -1
- package/lib/Defaults/index.js.map +0 -1
- package/lib/Signal/Group/ciphertext-message.d.ts +0 -10
- package/lib/Signal/Group/ciphertext-message.d.ts.map +0 -1
- package/lib/Signal/Group/ciphertext-message.js +0 -12
- package/lib/Signal/Group/ciphertext-message.js.map +0 -1
- package/lib/Signal/Group/group-session-builder.d.ts +0 -15
- package/lib/Signal/Group/group-session-builder.d.ts.map +0 -1
- package/lib/Signal/Group/group-session-builder.js +0 -30
- package/lib/Signal/Group/group-session-builder.js.map +0 -1
- package/lib/Signal/Group/group_cipher.d.ts +0 -17
- package/lib/Signal/Group/group_cipher.d.ts.map +0 -1
- package/lib/Signal/Group/group_cipher.js +0 -82
- package/lib/Signal/Group/group_cipher.js.map +0 -1
- package/lib/Signal/Group/index.d.ts +0 -12
- package/lib/Signal/Group/index.d.ts.map +0 -1
- package/lib/Signal/Group/index.js +0 -12
- package/lib/Signal/Group/index.js.map +0 -1
- package/lib/Signal/Group/keyhelper.d.ts +0 -11
- package/lib/Signal/Group/keyhelper.d.ts.map +0 -1
- package/lib/Signal/Group/keyhelper.js +0 -18
- package/lib/Signal/Group/keyhelper.js.map +0 -1
- package/lib/Signal/Group/sender-chain-key.d.ts +0 -14
- package/lib/Signal/Group/sender-chain-key.d.ts.map +0 -1
- package/lib/Signal/Group/sender-chain-key.js +0 -26
- package/lib/Signal/Group/sender-chain-key.js.map +0 -1
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +0 -17
- package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +0 -1
- package/lib/Signal/Group/sender-key-distribution-message.js +0 -63
- package/lib/Signal/Group/sender-key-distribution-message.js.map +0 -1
- package/lib/Signal/Group/sender-key-message.d.ts +0 -19
- package/lib/Signal/Group/sender-key-message.d.ts.map +0 -1
- package/lib/Signal/Group/sender-key-message.js +0 -66
- package/lib/Signal/Group/sender-key-message.js.map +0 -1
- package/lib/Signal/Group/sender-key-name.d.ts +0 -18
- package/lib/Signal/Group/sender-key-name.d.ts.map +0 -1
- package/lib/Signal/Group/sender-key-name.js +0 -48
- package/lib/Signal/Group/sender-key-name.js.map +0 -1
- package/lib/Signal/Group/sender-key-record.d.ts +0 -31
- package/lib/Signal/Group/sender-key-record.d.ts.map +0 -1
- package/lib/Signal/Group/sender-key-record.js +0 -41
- package/lib/Signal/Group/sender-key-record.js.map +0 -1
- package/lib/Signal/Group/sender-key-state.d.ts +0 -39
- package/lib/Signal/Group/sender-key-state.d.ts.map +0 -1
- package/lib/Signal/Group/sender-key-state.js +0 -84
- package/lib/Signal/Group/sender-key-state.js.map +0 -1
- package/lib/Signal/Group/sender-message-key.d.ts +0 -12
- package/lib/Signal/Group/sender-message-key.d.ts.map +0 -1
- package/lib/Signal/Group/sender-message-key.js.map +0 -1
- package/lib/Signal/libsignal.d.ts.map +0 -1
- package/lib/Signal/libsignal.js.map +0 -1
- package/lib/Signal/lid-mapping.d.ts +0 -23
- package/lib/Signal/lid-mapping.d.ts.map +0 -1
- package/lib/Signal/lid-mapping.js +0 -277
- package/lib/Signal/lid-mapping.js.map +0 -1
- package/lib/Socket/Client/index.d.ts.map +0 -1
- package/lib/Socket/Client/index.js.map +0 -1
- package/lib/Socket/Client/types.d.ts.map +0 -1
- package/lib/Socket/Client/types.js +0 -11
- package/lib/Socket/Client/types.js.map +0 -1
- package/lib/Socket/Client/websocket.d.ts.map +0 -1
- package/lib/Socket/Client/websocket.js +0 -54
- package/lib/Socket/Client/websocket.js.map +0 -1
- package/lib/Socket/business.d.ts.map +0 -1
- package/lib/Socket/business.js.map +0 -1
- package/lib/Socket/chats.d.ts.map +0 -1
- package/lib/Socket/chats.js.map +0 -1
- package/lib/Socket/communities.d.ts +0 -273
- package/lib/Socket/communities.d.ts.map +0 -1
- package/lib/Socket/communities.js +0 -431
- package/lib/Socket/communities.js.map +0 -1
- package/lib/Socket/groups.d.ts.map +0 -1
- package/lib/Socket/groups.js.map +0 -1
- package/lib/Socket/index.d.ts.map +0 -1
- package/lib/Socket/index.js.map +0 -1
- package/lib/Socket/messages-recv.d.ts.map +0 -1
- package/lib/Socket/messages-recv.js.map +0 -1
- package/lib/Socket/messages-send.d.ts.map +0 -1
- package/lib/Socket/messages-send.js.map +0 -1
- package/lib/Socket/mex.d.ts +0 -3
- package/lib/Socket/mex.d.ts.map +0 -1
- package/lib/Socket/mex.js +0 -42
- package/lib/Socket/mex.js.map +0 -1
- package/lib/Socket/newsletter.d.ts +0 -170
- package/lib/Socket/newsletter.d.ts.map +0 -1
- package/lib/Socket/newsletter.js +0 -181
- package/lib/Socket/newsletter.js.map +0 -1
- package/lib/Socket/socket.d.ts.map +0 -1
- package/lib/Socket/socket.js.map +0 -1
- package/lib/Types/Auth.d.ts.map +0 -1
- package/lib/Types/Auth.js.map +0 -1
- package/lib/Types/Bussines.d.ts +0 -25
- package/lib/Types/Bussines.d.ts.map +0 -1
- package/lib/Types/Bussines.js +0 -2
- package/lib/Types/Bussines.js.map +0 -1
- package/lib/Types/Call.d.ts.map +0 -1
- package/lib/Types/Call.js.map +0 -1
- package/lib/Types/Chat.d.ts.map +0 -1
- package/lib/Types/Chat.js.map +0 -1
- package/lib/Types/Contact.d.ts.map +0 -1
- package/lib/Types/Contact.js.map +0 -1
- package/lib/Types/Events.d.ts.map +0 -1
- package/lib/Types/Events.js.map +0 -1
- package/lib/Types/GroupMetadata.d.ts.map +0 -1
- package/lib/Types/GroupMetadata.js.map +0 -1
- package/lib/Types/Label.d.ts.map +0 -1
- package/lib/Types/Label.js.map +0 -1
- package/lib/Types/LabelAssociation.d.ts.map +0 -1
- package/lib/Types/LabelAssociation.js.map +0 -1
- package/lib/Types/Message.d.ts.map +0 -1
- package/lib/Types/Message.js.map +0 -1
- package/lib/Types/Mex.d.ts +0 -141
- package/lib/Types/Mex.d.ts.map +0 -1
- package/lib/Types/Mex.js +0 -37
- package/lib/Types/Mex.js.map +0 -1
- package/lib/Types/Product.d.ts.map +0 -1
- package/lib/Types/Product.js.map +0 -1
- package/lib/Types/Signal.d.ts.map +0 -1
- package/lib/Types/Signal.js.map +0 -1
- package/lib/Types/Socket.d.ts.map +0 -1
- package/lib/Types/Socket.js.map +0 -1
- package/lib/Types/State.d.ts.map +0 -1
- package/lib/Types/State.js.map +0 -1
- package/lib/Types/USync.d.ts +0 -26
- package/lib/Types/USync.d.ts.map +0 -1
- package/lib/Types/USync.js +0 -2
- package/lib/Types/USync.js.map +0 -1
- package/lib/Types/index.d.ts.map +0 -1
- package/lib/Types/index.js.map +0 -1
- package/lib/Utils/auth-utils.d.ts.map +0 -1
- package/lib/Utils/auth-utils.js.map +0 -1
- package/lib/Utils/browser-utils.d.ts +0 -4
- package/lib/Utils/browser-utils.d.ts.map +0 -1
- package/lib/Utils/browser-utils.js +0 -29
- package/lib/Utils/browser-utils.js.map +0 -1
- package/lib/Utils/business.d.ts.map +0 -1
- package/lib/Utils/business.js.map +0 -1
- package/lib/Utils/chat-utils.d.ts.map +0 -1
- package/lib/Utils/chat-utils.js.map +0 -1
- package/lib/Utils/companion-reg-client-utils.d.ts +0 -17
- package/lib/Utils/companion-reg-client-utils.d.ts.map +0 -1
- package/lib/Utils/companion-reg-client-utils.js +0 -35
- package/lib/Utils/companion-reg-client-utils.js.map +0 -1
- package/lib/Utils/crypto.d.ts.map +0 -1
- package/lib/Utils/crypto.js.map +0 -1
- package/lib/Utils/decode-wa-message.d.ts.map +0 -1
- package/lib/Utils/decode-wa-message.js.map +0 -1
- package/lib/Utils/event-buffer.d.ts.map +0 -1
- package/lib/Utils/event-buffer.js.map +0 -1
- package/lib/Utils/generics.d.ts.map +0 -1
- package/lib/Utils/generics.js.map +0 -1
- package/lib/Utils/history.d.ts.map +0 -1
- package/lib/Utils/history.js.map +0 -1
- package/lib/Utils/identity-change-handler.d.ts +0 -44
- package/lib/Utils/identity-change-handler.d.ts.map +0 -1
- package/lib/Utils/identity-change-handler.js +0 -50
- package/lib/Utils/identity-change-handler.js.map +0 -1
- package/lib/Utils/index.d.ts.map +0 -1
- package/lib/Utils/index.js.map +0 -1
- package/lib/Utils/link-preview.d.ts.map +0 -1
- package/lib/Utils/link-preview.js.map +0 -1
- package/lib/Utils/logger.d.ts.map +0 -1
- package/lib/Utils/logger.js.map +0 -1
- package/lib/Utils/lt-hash.d.ts.map +0 -1
- package/lib/Utils/lt-hash.js.map +0 -1
- package/lib/Utils/make-mutex.d.ts.map +0 -1
- package/lib/Utils/make-mutex.js.map +0 -1
- package/lib/Utils/message-retry-manager.d.ts +0 -115
- package/lib/Utils/message-retry-manager.d.ts.map +0 -1
- package/lib/Utils/message-retry-manager.js +0 -265
- package/lib/Utils/message-retry-manager.js.map +0 -1
- package/lib/Utils/messages-media.d.ts.map +0 -1
- package/lib/Utils/messages-media.js.map +0 -1
- package/lib/Utils/messages.d.ts.map +0 -1
- package/lib/Utils/messages.js.map +0 -1
- package/lib/Utils/noise-handler.d.ts.map +0 -1
- package/lib/Utils/noise-handler.js.map +0 -1
- package/lib/Utils/offline-node-processor.d.ts +0 -17
- package/lib/Utils/offline-node-processor.d.ts.map +0 -1
- package/lib/Utils/offline-node-processor.js +0 -40
- package/lib/Utils/offline-node-processor.js.map +0 -1
- package/lib/Utils/pre-key-manager.d.ts +0 -28
- package/lib/Utils/pre-key-manager.d.ts.map +0 -1
- package/lib/Utils/pre-key-manager.js +0 -106
- package/lib/Utils/pre-key-manager.js.map +0 -1
- package/lib/Utils/process-message.d.ts.map +0 -1
- package/lib/Utils/process-message.js.map +0 -1
- package/lib/Utils/reporting-utils.d.ts +0 -11
- package/lib/Utils/reporting-utils.d.ts.map +0 -1
- package/lib/Utils/reporting-utils.js +0 -258
- package/lib/Utils/reporting-utils.js.map +0 -1
- package/lib/Utils/signal.d.ts.map +0 -1
- package/lib/Utils/signal.js.map +0 -1
- package/lib/Utils/stanza-ack.d.ts +0 -11
- package/lib/Utils/stanza-ack.d.ts.map +0 -1
- package/lib/Utils/stanza-ack.js +0 -38
- package/lib/Utils/stanza-ack.js.map +0 -1
- package/lib/Utils/sync-action-utils.d.ts +0 -19
- package/lib/Utils/sync-action-utils.d.ts.map +0 -1
- package/lib/Utils/sync-action-utils.js +0 -49
- package/lib/Utils/sync-action-utils.js.map +0 -1
- package/lib/Utils/tc-token-utils.d.ts +0 -37
- package/lib/Utils/tc-token-utils.d.ts.map +0 -1
- package/lib/Utils/tc-token-utils.js +0 -164
- package/lib/Utils/tc-token-utils.js.map +0 -1
- package/lib/Utils/use-multi-file-auth-state.d.ts.map +0 -1
- package/lib/Utils/use-multi-file-auth-state.js.map +0 -1
- package/lib/Utils/validate-connection.d.ts.map +0 -1
- package/lib/Utils/validate-connection.js.map +0 -1
- package/lib/WABinary/constants.d.ts.map +0 -1
- package/lib/WABinary/constants.js.map +0 -1
- package/lib/WABinary/decode.d.ts.map +0 -1
- package/lib/WABinary/decode.js.map +0 -1
- package/lib/WABinary/encode.d.ts.map +0 -1
- package/lib/WABinary/encode.js.map +0 -1
- package/lib/WABinary/generic-utils.d.ts.map +0 -1
- package/lib/WABinary/generic-utils.js.map +0 -1
- package/lib/WABinary/index.d.ts.map +0 -1
- package/lib/WABinary/index.js.map +0 -1
- package/lib/WABinary/jid-utils.d.ts.map +0 -1
- package/lib/WABinary/jid-utils.js.map +0 -1
- package/lib/WABinary/types.d.ts.map +0 -1
- package/lib/WABinary/types.js.map +0 -1
- package/lib/WAM/BinaryInfo.d.ts.map +0 -1
- package/lib/WAM/BinaryInfo.js.map +0 -1
- package/lib/WAM/constants.d.ts.map +0 -1
- package/lib/WAM/constants.js.map +0 -1
- package/lib/WAM/encode.d.ts.map +0 -1
- package/lib/WAM/encode.js.map +0 -1
- package/lib/WAM/index.d.ts.map +0 -1
- package/lib/WAM/index.js.map +0 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +0 -10
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +0 -52
- package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +0 -1
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +0 -23
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +0 -54
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js.map +0 -1
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +0 -13
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +0 -27
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js.map +0 -1
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +0 -13
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +0 -38
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js.map +0 -1
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +0 -10
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +0 -25
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js.map +0 -1
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +0 -26
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +0 -51
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js.map +0 -1
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +0 -10
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +0 -29
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js.map +0 -1
- package/lib/WAUSync/Protocols/index.d.ts +0 -6
- package/lib/WAUSync/Protocols/index.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/index.js +0 -6
- package/lib/WAUSync/Protocols/index.js.map +0 -1
- package/lib/WAUSync/USyncQuery.d.ts +0 -30
- package/lib/WAUSync/USyncQuery.d.ts.map +0 -1
- package/lib/WAUSync/USyncQuery.js +0 -98
- package/lib/WAUSync/USyncQuery.js.map +0 -1
- package/lib/WAUSync/USyncUser.d.ts +0 -17
- package/lib/WAUSync/USyncUser.d.ts.map +0 -1
- package/lib/WAUSync/USyncUser.js +0 -31
- package/lib/WAUSync/USyncUser.js.map +0 -1
- package/lib/WAUSync/index.d.ts +0 -4
- package/lib/WAUSync/index.d.ts.map +0 -1
- package/lib/WAUSync/index.js +0 -4
- package/lib/WAUSync/index.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
|
@@ -1,91 +1,95 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.getStatusCodeForMediaRetry = exports.decryptMediaRetryData = exports.decodeMediaRetryNode = exports.encryptMediaRetryRequest = exports.getWAUploadToServer = exports.extensionForMediaMessage = exports.downloadEncryptedContent = exports.downloadContentFromMessage = exports.getUrlFromDirectPath = exports.encryptedStream = exports.getHttpStream = exports.generateThumbnail = exports.getStream = exports.toBuffer = exports.toReadable = exports.getAudioWaveform = exports.getAudioDuration = exports.mediaMessageSHA256B64 = exports.generateProfilePicture = exports.encodeBase64EncodedStringForUpload = exports.extractImageThumb = exports.getMediaKeys = exports.hkdfInfoKey = void 0;
|
|
30
|
+
const boom_1 = require("@hapi/boom");
|
|
31
|
+
const axios_1 = __importDefault(require("axios"));
|
|
32
|
+
const child_process_1 = require("child_process");
|
|
33
|
+
const Crypto = __importStar(require("crypto"));
|
|
34
|
+
const events_1 = require("events");
|
|
35
|
+
const fs_1 = require("fs");
|
|
36
|
+
const os_1 = require("os");
|
|
37
|
+
const path_1 = require("path");
|
|
38
|
+
const stream_1 = require("stream");
|
|
39
|
+
const WAProto_1 = require("../../WAProto");
|
|
40
|
+
const Defaults_1 = require("../Defaults");
|
|
41
|
+
const WABinary_1 = require("../WABinary");
|
|
42
|
+
const crypto_1 = require("./crypto");
|
|
43
|
+
const generics_1 = require("./generics");
|
|
44
|
+
const getTmpFilesDirectory = () => (0, os_1.tmpdir)();
|
|
16
45
|
const getImageProcessingLibrary = async () => {
|
|
17
|
-
|
|
18
|
-
|
|
46
|
+
const [_jimp, sharp] = await Promise.all([
|
|
47
|
+
(async () => {
|
|
48
|
+
const jimp = await (import('jimp')
|
|
49
|
+
.catch(() => { }));
|
|
50
|
+
return jimp;
|
|
51
|
+
})(),
|
|
52
|
+
(async () => {
|
|
53
|
+
const sharp = await (import('sharp')
|
|
54
|
+
.catch(() => { }));
|
|
55
|
+
return sharp;
|
|
56
|
+
})()
|
|
57
|
+
]);
|
|
19
58
|
if (sharp) {
|
|
20
59
|
return { sharp };
|
|
21
60
|
}
|
|
61
|
+
const jimp = (_jimp === null || _jimp === void 0 ? void 0 : _jimp.default) || _jimp;
|
|
22
62
|
if (jimp) {
|
|
23
63
|
return { jimp };
|
|
24
64
|
}
|
|
25
|
-
throw new Boom('No image processing library available');
|
|
65
|
+
throw new boom_1.Boom('No image processing library available');
|
|
26
66
|
};
|
|
27
|
-
|
|
28
|
-
const hkdfInfo = MEDIA_HKDF_KEY_MAPPING[type];
|
|
67
|
+
const hkdfInfoKey = (type) => {
|
|
68
|
+
const hkdfInfo = Defaults_1.MEDIA_HKDF_KEY_MAPPING[type];
|
|
29
69
|
return `WhatsApp ${hkdfInfo} Keys`;
|
|
30
70
|
};
|
|
31
|
-
|
|
32
|
-
const { stream } = await getStream(media);
|
|
33
|
-
logger?.debug('got stream for raw upload');
|
|
34
|
-
const hasher = Crypto.createHash('sha256');
|
|
35
|
-
const filePath = join(tmpdir(), mediaType + generateMessageIDV2());
|
|
36
|
-
const fileWriteStream = createWriteStream(filePath);
|
|
37
|
-
let fileLength = 0;
|
|
38
|
-
try {
|
|
39
|
-
for await (const data of stream) {
|
|
40
|
-
fileLength += data.length;
|
|
41
|
-
hasher.update(data);
|
|
42
|
-
if (!fileWriteStream.write(data)) {
|
|
43
|
-
await once(fileWriteStream, 'drain');
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
fileWriteStream.end();
|
|
47
|
-
await once(fileWriteStream, 'finish');
|
|
48
|
-
stream.destroy();
|
|
49
|
-
const fileSha256 = hasher.digest();
|
|
50
|
-
logger?.debug('hashed data for raw upload');
|
|
51
|
-
return {
|
|
52
|
-
filePath: filePath,
|
|
53
|
-
fileSha256,
|
|
54
|
-
fileLength
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
fileWriteStream.destroy();
|
|
59
|
-
stream.destroy();
|
|
60
|
-
try {
|
|
61
|
-
await fs.unlink(filePath);
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
64
|
-
//
|
|
65
|
-
}
|
|
66
|
-
throw error;
|
|
67
|
-
}
|
|
68
|
-
};
|
|
71
|
+
exports.hkdfInfoKey = hkdfInfoKey;
|
|
69
72
|
/** generates all the keys required to encrypt/decrypt & sign a media message */
|
|
70
|
-
|
|
73
|
+
function getMediaKeys(buffer, mediaType) {
|
|
71
74
|
if (!buffer) {
|
|
72
|
-
throw new Boom('Cannot derive from empty media key');
|
|
75
|
+
throw new boom_1.Boom('Cannot derive from empty media key');
|
|
73
76
|
}
|
|
74
77
|
if (typeof buffer === 'string') {
|
|
75
78
|
buffer = Buffer.from(buffer.replace('data:;base64,', ''), 'base64');
|
|
76
79
|
}
|
|
77
80
|
// expand using HKDF to 112 bytes, also pass in the relevant app info
|
|
78
|
-
const expandedMediaKey = hkdf(buffer, 112, { info: hkdfInfoKey(mediaType) });
|
|
81
|
+
const expandedMediaKey = (0, crypto_1.hkdf)(buffer, 112, { info: (0, exports.hkdfInfoKey)(mediaType) });
|
|
79
82
|
return {
|
|
80
83
|
iv: expandedMediaKey.slice(0, 16),
|
|
81
84
|
cipherKey: expandedMediaKey.slice(16, 48),
|
|
82
|
-
macKey: expandedMediaKey.slice(48, 80)
|
|
85
|
+
macKey: expandedMediaKey.slice(48, 80),
|
|
83
86
|
};
|
|
84
87
|
}
|
|
88
|
+
exports.getMediaKeys = getMediaKeys;
|
|
85
89
|
/** Extracts video thumb using FFMPEG */
|
|
86
90
|
const extractVideoThumb = async (path, destPath, time, size) => new Promise((resolve, reject) => {
|
|
87
91
|
const cmd = `ffmpeg -ss ${time} -i ${path} -y -vf scale=${size.width}:-1 -vframes 1 -f image2 ${destPath}`;
|
|
88
|
-
exec(cmd, err => {
|
|
92
|
+
(0, child_process_1.exec)(cmd, (err) => {
|
|
89
93
|
if (err) {
|
|
90
94
|
reject(err);
|
|
91
95
|
}
|
|
@@ -94,121 +98,138 @@ const extractVideoThumb = async (path, destPath, time, size) => new Promise((res
|
|
|
94
98
|
}
|
|
95
99
|
});
|
|
96
100
|
});
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
bufferOrFilePath = await toBuffer(bufferOrFilePath);
|
|
101
|
+
const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
102
|
+
var _a, _b;
|
|
103
|
+
if (bufferOrFilePath instanceof stream_1.Readable) {
|
|
104
|
+
bufferOrFilePath = await (0, exports.toBuffer)(bufferOrFilePath);
|
|
102
105
|
}
|
|
103
106
|
const lib = await getImageProcessingLibrary();
|
|
104
|
-
if ('sharp' in lib && typeof lib.sharp
|
|
107
|
+
if ('sharp' in lib && typeof ((_a = lib.sharp) === null || _a === void 0 ? void 0 : _a.default) === 'function') {
|
|
105
108
|
const img = lib.sharp.default(bufferOrFilePath);
|
|
106
109
|
const dimensions = await img.metadata();
|
|
107
|
-
const buffer = await img
|
|
110
|
+
const buffer = await img
|
|
111
|
+
.resize(width)
|
|
112
|
+
.jpeg({ quality: 50 })
|
|
113
|
+
.toBuffer();
|
|
108
114
|
return {
|
|
109
115
|
buffer,
|
|
110
116
|
original: {
|
|
111
117
|
width: dimensions.width,
|
|
112
|
-
height: dimensions.height
|
|
113
|
-
}
|
|
118
|
+
height: dimensions.height,
|
|
119
|
+
},
|
|
114
120
|
};
|
|
115
121
|
}
|
|
116
|
-
else if ('jimp' in lib && typeof lib.jimp
|
|
117
|
-
const
|
|
122
|
+
else if ('jimp' in lib && typeof ((_b = lib.jimp) === null || _b === void 0 ? void 0 : _b.read) === 'function') {
|
|
123
|
+
const { read, MIME_JPEG, RESIZE_BILINEAR, AUTO } = lib.jimp;
|
|
124
|
+
const jimp = await read(bufferOrFilePath);
|
|
118
125
|
const dimensions = {
|
|
119
|
-
width: jimp.
|
|
120
|
-
height: jimp.
|
|
126
|
+
width: jimp.getWidth(),
|
|
127
|
+
height: jimp.getHeight()
|
|
121
128
|
};
|
|
122
129
|
const buffer = await jimp
|
|
123
|
-
.
|
|
124
|
-
.
|
|
130
|
+
.quality(50)
|
|
131
|
+
.resize(width, AUTO, RESIZE_BILINEAR)
|
|
132
|
+
.getBufferAsync(MIME_JPEG);
|
|
125
133
|
return {
|
|
126
134
|
buffer,
|
|
127
135
|
original: dimensions
|
|
128
136
|
};
|
|
129
137
|
}
|
|
130
138
|
else {
|
|
131
|
-
throw new Boom('No image processing library available');
|
|
139
|
+
throw new boom_1.Boom('No image processing library available');
|
|
132
140
|
}
|
|
133
141
|
};
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
142
|
+
exports.extractImageThumb = extractImageThumb;
|
|
143
|
+
const encodeBase64EncodedStringForUpload = (b64) => (encodeURIComponent(b64
|
|
144
|
+
.replace(/\+/g, '-')
|
|
145
|
+
.replace(/\//g, '_')
|
|
146
|
+
.replace(/\=+$/, '')));
|
|
147
|
+
exports.encodeBase64EncodedStringForUpload = encodeBase64EncodedStringForUpload;
|
|
148
|
+
const generateProfilePicture = async (mediaUpload) => {
|
|
149
|
+
var _a, _b;
|
|
150
|
+
let bufferOrFilePath;
|
|
138
151
|
if (Buffer.isBuffer(mediaUpload)) {
|
|
139
|
-
|
|
152
|
+
bufferOrFilePath = mediaUpload;
|
|
153
|
+
}
|
|
154
|
+
else if ('url' in mediaUpload) {
|
|
155
|
+
bufferOrFilePath = mediaUpload.url.toString();
|
|
140
156
|
}
|
|
141
157
|
else {
|
|
142
|
-
|
|
143
|
-
const { stream } = await getStream(mediaUpload);
|
|
144
|
-
// Convert the resulting stream to a buffer
|
|
145
|
-
buffer = await toBuffer(stream);
|
|
158
|
+
bufferOrFilePath = await (0, exports.toBuffer)(mediaUpload.stream);
|
|
146
159
|
}
|
|
147
160
|
const lib = await getImageProcessingLibrary();
|
|
148
161
|
let img;
|
|
149
|
-
if ('sharp' in lib && typeof lib.sharp
|
|
150
|
-
img = lib.sharp
|
|
151
|
-
.
|
|
152
|
-
.resize(w, h)
|
|
162
|
+
if ('sharp' in lib && typeof ((_a = lib.sharp) === null || _a === void 0 ? void 0 : _a.default) === 'function') {
|
|
163
|
+
img = lib.sharp.default(bufferOrFilePath)
|
|
164
|
+
.resize(640, 640)
|
|
153
165
|
.jpeg({
|
|
154
|
-
quality: 50
|
|
166
|
+
quality: 50,
|
|
155
167
|
})
|
|
156
168
|
.toBuffer();
|
|
157
169
|
}
|
|
158
|
-
else if ('jimp' in lib && typeof lib.jimp
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
const
|
|
162
|
-
|
|
170
|
+
else if ('jimp' in lib && typeof ((_b = lib.jimp) === null || _b === void 0 ? void 0 : _b.read) === 'function') {
|
|
171
|
+
const { read, MIME_JPEG, RESIZE_BILINEAR } = lib.jimp;
|
|
172
|
+
const jimp = await read(bufferOrFilePath);
|
|
173
|
+
const min = Math.min(jimp.getWidth(), jimp.getHeight());
|
|
174
|
+
const cropped = jimp.crop(0, 0, min, min);
|
|
175
|
+
img = cropped
|
|
176
|
+
.quality(50)
|
|
177
|
+
.resize(640, 640, RESIZE_BILINEAR)
|
|
178
|
+
.getBufferAsync(MIME_JPEG);
|
|
163
179
|
}
|
|
164
180
|
else {
|
|
165
|
-
throw new Boom('No image processing library available');
|
|
181
|
+
throw new boom_1.Boom('No image processing library available');
|
|
166
182
|
}
|
|
167
183
|
return {
|
|
168
|
-
img: await img
|
|
184
|
+
img: await img,
|
|
169
185
|
};
|
|
170
186
|
};
|
|
187
|
+
exports.generateProfilePicture = generateProfilePicture;
|
|
171
188
|
/** gets the SHA256 of the given media message */
|
|
172
|
-
|
|
189
|
+
const mediaMessageSHA256B64 = (message) => {
|
|
173
190
|
const media = Object.values(message)[0];
|
|
174
|
-
return media
|
|
191
|
+
return (media === null || media === void 0 ? void 0 : media.fileSha256) && Buffer.from(media.fileSha256).toString('base64');
|
|
175
192
|
};
|
|
176
|
-
|
|
193
|
+
exports.mediaMessageSHA256B64 = mediaMessageSHA256B64;
|
|
194
|
+
async function getAudioDuration(buffer) {
|
|
177
195
|
const musicMetadata = await import('music-metadata');
|
|
178
196
|
let metadata;
|
|
179
|
-
const options = {
|
|
180
|
-
duration: true
|
|
181
|
-
};
|
|
182
197
|
if (Buffer.isBuffer(buffer)) {
|
|
183
|
-
metadata = await musicMetadata.parseBuffer(buffer, undefined,
|
|
198
|
+
metadata = await musicMetadata.parseBuffer(buffer, undefined, { duration: true });
|
|
184
199
|
}
|
|
185
200
|
else if (typeof buffer === 'string') {
|
|
186
|
-
|
|
201
|
+
const rStream = (0, fs_1.createReadStream)(buffer);
|
|
202
|
+
try {
|
|
203
|
+
metadata = await musicMetadata.parseStream(rStream, undefined, { duration: true });
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
rStream.destroy();
|
|
207
|
+
}
|
|
187
208
|
}
|
|
188
209
|
else {
|
|
189
|
-
metadata = await musicMetadata.parseStream(buffer, undefined,
|
|
210
|
+
metadata = await musicMetadata.parseStream(buffer, undefined, { duration: true });
|
|
190
211
|
}
|
|
191
212
|
return metadata.format.duration;
|
|
192
213
|
}
|
|
214
|
+
exports.getAudioDuration = getAudioDuration;
|
|
193
215
|
/**
|
|
194
216
|
referenced from and modifying https://github.com/wppconnect-team/wa-js/blob/main/src/chat/functions/prepareAudioWaveform.ts
|
|
195
217
|
*/
|
|
196
|
-
|
|
218
|
+
async function getAudioWaveform(buffer, logger) {
|
|
197
219
|
try {
|
|
198
|
-
|
|
199
|
-
const { default: decoder } = await import('audio-decode');
|
|
220
|
+
const audioDecode = (buffer) => import('audio-decode').then(({ default: audioDecode }) => audioDecode(buffer));
|
|
200
221
|
let audioData;
|
|
201
222
|
if (Buffer.isBuffer(buffer)) {
|
|
202
223
|
audioData = buffer;
|
|
203
224
|
}
|
|
204
225
|
else if (typeof buffer === 'string') {
|
|
205
|
-
const rStream = createReadStream(buffer);
|
|
206
|
-
audioData = await toBuffer(rStream);
|
|
226
|
+
const rStream = (0, fs_1.createReadStream)(buffer);
|
|
227
|
+
audioData = await (0, exports.toBuffer)(rStream);
|
|
207
228
|
}
|
|
208
229
|
else {
|
|
209
|
-
audioData = await toBuffer(buffer);
|
|
230
|
+
audioData = await (0, exports.toBuffer)(buffer);
|
|
210
231
|
}
|
|
211
|
-
const audioBuffer = await
|
|
232
|
+
const audioBuffer = await audioDecode(audioData);
|
|
212
233
|
const rawData = audioBuffer.getChannelData(0); // We only need to work with one channel of data
|
|
213
234
|
const samples = 64; // Number of samples we want to have in our final data set
|
|
214
235
|
const blockSize = Math.floor(rawData.length / samples); // the number of samples in each subdivision
|
|
@@ -223,22 +244,24 @@ export async function getAudioWaveform(buffer, logger) {
|
|
|
223
244
|
}
|
|
224
245
|
// This guarantees that the largest data point will be set to 1, and the rest of the data will scale proportionally.
|
|
225
246
|
const multiplier = Math.pow(Math.max(...filteredData), -1);
|
|
226
|
-
const normalizedData = filteredData.map(n => n * multiplier);
|
|
247
|
+
const normalizedData = filteredData.map((n) => n * multiplier);
|
|
227
248
|
// Generate waveform like WhatsApp
|
|
228
|
-
const waveform = new Uint8Array(normalizedData.map(n => Math.floor(100 * n)));
|
|
249
|
+
const waveform = new Uint8Array(normalizedData.map((n) => Math.floor(100 * n)));
|
|
229
250
|
return waveform;
|
|
230
251
|
}
|
|
231
252
|
catch (e) {
|
|
232
|
-
logger
|
|
253
|
+
logger === null || logger === void 0 ? void 0 : logger.debug('Failed to generate waveform: ' + e);
|
|
233
254
|
}
|
|
234
255
|
}
|
|
235
|
-
|
|
236
|
-
|
|
256
|
+
exports.getAudioWaveform = getAudioWaveform;
|
|
257
|
+
const toReadable = (buffer) => {
|
|
258
|
+
const readable = new stream_1.Readable({ read: () => { } });
|
|
237
259
|
readable.push(buffer);
|
|
238
260
|
readable.push(null);
|
|
239
261
|
return readable;
|
|
240
262
|
};
|
|
241
|
-
|
|
263
|
+
exports.toReadable = toReadable;
|
|
264
|
+
const toBuffer = async (stream) => {
|
|
242
265
|
const chunks = [];
|
|
243
266
|
for await (const chunk of stream) {
|
|
244
267
|
chunks.push(chunk);
|
|
@@ -246,47 +269,45 @@ export const toBuffer = async (stream) => {
|
|
|
246
269
|
stream.destroy();
|
|
247
270
|
return Buffer.concat(chunks);
|
|
248
271
|
};
|
|
249
|
-
|
|
272
|
+
exports.toBuffer = toBuffer;
|
|
273
|
+
const getStream = async (item, opts) => {
|
|
250
274
|
if (Buffer.isBuffer(item)) {
|
|
251
|
-
return { stream: toReadable(item), type: 'buffer' };
|
|
275
|
+
return { stream: (0, exports.toReadable)(item), type: 'buffer' };
|
|
252
276
|
}
|
|
253
277
|
if ('stream' in item) {
|
|
254
278
|
return { stream: item.stream, type: 'readable' };
|
|
255
279
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
const buffer = Buffer.from(urlStr.split(',')[1], 'base64');
|
|
259
|
-
return { stream: toReadable(buffer), type: 'buffer' };
|
|
280
|
+
if (item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')) {
|
|
281
|
+
return { stream: await (0, exports.getHttpStream)(item.url, opts), type: 'remote' };
|
|
260
282
|
}
|
|
261
|
-
|
|
262
|
-
return { stream: await getHttpStream(item.url, opts), type: 'remote' };
|
|
263
|
-
}
|
|
264
|
-
return { stream: createReadStream(item.url), type: 'file' };
|
|
283
|
+
return { stream: (0, fs_1.createReadStream)(item.url), type: 'file' };
|
|
265
284
|
};
|
|
285
|
+
exports.getStream = getStream;
|
|
266
286
|
/** generates a thumbnail for a given media, if required */
|
|
267
|
-
|
|
287
|
+
async function generateThumbnail(file, mediaType, options) {
|
|
288
|
+
var _a;
|
|
268
289
|
let thumbnail;
|
|
269
290
|
let originalImageDimensions;
|
|
270
291
|
if (mediaType === 'image') {
|
|
271
|
-
const { buffer, original } = await extractImageThumb(file);
|
|
292
|
+
const { buffer, original } = await (0, exports.extractImageThumb)(file);
|
|
272
293
|
thumbnail = buffer.toString('base64');
|
|
273
294
|
if (original.width && original.height) {
|
|
274
295
|
originalImageDimensions = {
|
|
275
296
|
width: original.width,
|
|
276
|
-
height: original.height
|
|
297
|
+
height: original.height,
|
|
277
298
|
};
|
|
278
299
|
}
|
|
279
300
|
}
|
|
280
301
|
else if (mediaType === 'video') {
|
|
281
|
-
const imgFilename = join(getTmpFilesDirectory(),
|
|
302
|
+
const imgFilename = (0, path_1.join)(getTmpFilesDirectory(), (0, generics_1.generateMessageID)() + '.jpg');
|
|
282
303
|
try {
|
|
283
304
|
await extractVideoThumb(file, imgFilename, '00:00:00', { width: 32, height: 32 });
|
|
284
|
-
const buff = await
|
|
305
|
+
const buff = await fs_1.promises.readFile(imgFilename);
|
|
285
306
|
thumbnail = buff.toString('base64');
|
|
286
|
-
await
|
|
307
|
+
await fs_1.promises.unlink(imgFilename);
|
|
287
308
|
}
|
|
288
309
|
catch (err) {
|
|
289
|
-
options.logger
|
|
310
|
+
(_a = options.logger) === null || _a === void 0 ? void 0 : _a.debug('could not generate video thumb: ' + err);
|
|
290
311
|
}
|
|
291
312
|
}
|
|
292
313
|
return {
|
|
@@ -294,141 +315,117 @@ export async function generateThumbnail(file, mediaType, options) {
|
|
|
294
315
|
originalImageDimensions
|
|
295
316
|
};
|
|
296
317
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
headers: options.headers
|
|
302
|
-
});
|
|
303
|
-
if (!response.ok) {
|
|
304
|
-
throw new Boom(`Failed to fetch stream from ${url}`, { statusCode: response.status, data: { url } });
|
|
305
|
-
}
|
|
306
|
-
// @ts-ignore Node18+ Readable.fromWeb exists
|
|
307
|
-
return response.body instanceof Readable ? response.body : Readable.fromWeb(response.body);
|
|
318
|
+
exports.generateThumbnail = generateThumbnail;
|
|
319
|
+
const getHttpStream = async (url, options = {}) => {
|
|
320
|
+
const fetched = await axios_1.default.get(url.toString(), { ...options, responseType: 'stream' });
|
|
321
|
+
return fetched.data;
|
|
308
322
|
};
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
323
|
+
exports.getHttpStream = getHttpStream;
|
|
324
|
+
const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
|
|
325
|
+
const { stream, type } = await (0, exports.getStream)(media, opts);
|
|
326
|
+
logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
|
|
312
327
|
const mediaKey = Crypto.randomBytes(32);
|
|
313
|
-
const { cipherKey, iv, macKey } =
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
let
|
|
317
|
-
let
|
|
318
|
-
if (
|
|
319
|
-
|
|
320
|
-
|
|
328
|
+
const { cipherKey, iv, macKey } = getMediaKeys(mediaKey, mediaType);
|
|
329
|
+
const encWriteStream = new stream_1.Readable({ read: () => { } });
|
|
330
|
+
let bodyPath;
|
|
331
|
+
let writeStream;
|
|
332
|
+
let didSaveToTmpPath = false;
|
|
333
|
+
if (type === 'file') {
|
|
334
|
+
bodyPath = media.url;
|
|
335
|
+
}
|
|
336
|
+
else if (saveOriginalFileIfRequired) {
|
|
337
|
+
bodyPath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageID)());
|
|
338
|
+
writeStream = (0, fs_1.createWriteStream)(bodyPath);
|
|
339
|
+
didSaveToTmpPath = true;
|
|
321
340
|
}
|
|
322
341
|
let fileLength = 0;
|
|
323
342
|
const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv);
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const onChunk = async (buff) => {
|
|
328
|
-
sha256Enc.update(buff);
|
|
329
|
-
hmac.update(buff);
|
|
330
|
-
// Handle backpressure: if write returns false, wait for drain
|
|
331
|
-
if (!encFileWriteStream.write(buff)) {
|
|
332
|
-
await once(encFileWriteStream, 'drain');
|
|
333
|
-
}
|
|
334
|
-
};
|
|
343
|
+
let hmac = Crypto.createHmac('sha256', macKey).update(iv);
|
|
344
|
+
let sha256Plain = Crypto.createHash('sha256');
|
|
345
|
+
let sha256Enc = Crypto.createHash('sha256');
|
|
335
346
|
try {
|
|
336
347
|
for await (const data of stream) {
|
|
337
348
|
fileLength += data.length;
|
|
338
|
-
if (type === 'remote'
|
|
339
|
-
opts
|
|
340
|
-
fileLength + data.length > opts.maxContentLength) {
|
|
341
|
-
throw new Boom(`content length exceeded when encrypting "${type}"`, {
|
|
349
|
+
if (type === 'remote'
|
|
350
|
+
&& (opts === null || opts === void 0 ? void 0 : opts.maxContentLength)
|
|
351
|
+
&& fileLength + data.length > opts.maxContentLength) {
|
|
352
|
+
throw new boom_1.Boom(`content length exceeded when encrypting "${type}"`, {
|
|
342
353
|
data: { media, type }
|
|
343
354
|
});
|
|
344
355
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
356
|
+
sha256Plain = sha256Plain.update(data);
|
|
357
|
+
if (writeStream) {
|
|
358
|
+
if (!writeStream.write(data)) {
|
|
359
|
+
await (0, events_1.once)(writeStream, 'drain');
|
|
348
360
|
}
|
|
349
361
|
}
|
|
350
|
-
|
|
351
|
-
await onChunk(aes.update(data));
|
|
362
|
+
onChunk(aes.update(data));
|
|
352
363
|
}
|
|
353
|
-
|
|
364
|
+
onChunk(aes.final());
|
|
354
365
|
const mac = hmac.digest().slice(0, 10);
|
|
355
|
-
sha256Enc.update(mac);
|
|
366
|
+
sha256Enc = sha256Enc.update(mac);
|
|
356
367
|
const fileSha256 = sha256Plain.digest();
|
|
357
368
|
const fileEncSha256 = sha256Enc.digest();
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
encFileWriteStream.end();
|
|
362
|
-
originalFileStream?.end?.();
|
|
369
|
+
encWriteStream.push(mac);
|
|
370
|
+
encWriteStream.push(null);
|
|
371
|
+
writeStream === null || writeStream === void 0 ? void 0 : writeStream.end();
|
|
363
372
|
stream.destroy();
|
|
364
|
-
|
|
365
|
-
// This helps reduce memory pressure by allowing OS to release buffers
|
|
366
|
-
await encFinishPromise;
|
|
367
|
-
await originalFinishPromise;
|
|
368
|
-
logger?.debug('encrypted data successfully');
|
|
373
|
+
logger === null || logger === void 0 ? void 0 : logger.debug('encrypted data successfully');
|
|
369
374
|
return {
|
|
370
375
|
mediaKey,
|
|
371
|
-
|
|
372
|
-
|
|
376
|
+
encWriteStream,
|
|
377
|
+
bodyPath,
|
|
373
378
|
mac,
|
|
374
379
|
fileEncSha256,
|
|
375
380
|
fileSha256,
|
|
376
|
-
fileLength
|
|
381
|
+
fileLength,
|
|
382
|
+
didSaveToTmpPath
|
|
377
383
|
};
|
|
378
384
|
}
|
|
379
385
|
catch (error) {
|
|
380
386
|
// destroy all streams with error
|
|
381
|
-
|
|
382
|
-
|
|
387
|
+
encWriteStream.destroy();
|
|
388
|
+
writeStream === null || writeStream === void 0 ? void 0 : writeStream.destroy();
|
|
383
389
|
aes.destroy();
|
|
384
390
|
hmac.destroy();
|
|
385
391
|
sha256Plain.destroy();
|
|
386
392
|
sha256Enc.destroy();
|
|
387
393
|
stream.destroy();
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
394
|
+
if (didSaveToTmpPath) {
|
|
395
|
+
try {
|
|
396
|
+
await fs_1.promises.unlink(bodyPath);
|
|
397
|
+
}
|
|
398
|
+
catch (err) {
|
|
399
|
+
logger === null || logger === void 0 ? void 0 : logger.error({ err }, 'failed to save to tmp path');
|
|
392
400
|
}
|
|
393
|
-
}
|
|
394
|
-
catch (err) {
|
|
395
|
-
logger?.error({ err }, 'failed deleting tmp files');
|
|
396
401
|
}
|
|
397
402
|
throw error;
|
|
398
403
|
}
|
|
404
|
+
function onChunk(buff) {
|
|
405
|
+
sha256Enc = sha256Enc.update(buff);
|
|
406
|
+
hmac = hmac.update(buff);
|
|
407
|
+
encWriteStream.push(buff);
|
|
408
|
+
}
|
|
399
409
|
};
|
|
400
|
-
|
|
410
|
+
exports.encryptedStream = encryptedStream;
|
|
411
|
+
const DEF_HOST = 'mmg.whatsapp.net';
|
|
401
412
|
const AES_CHUNK_SIZE = 16;
|
|
402
413
|
const toSmallestChunkSize = (num) => {
|
|
403
414
|
return Math.floor(num / AES_CHUNK_SIZE) * AES_CHUNK_SIZE;
|
|
404
415
|
};
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
}
|
|
412
|
-
catch {
|
|
413
|
-
return undefined;
|
|
414
|
-
}
|
|
415
|
-
};
|
|
416
|
-
export const downloadContentFromMessage = async ({ mediaKey, directPath, url }, type, opts = {}) => {
|
|
417
|
-
// Fallback host: explicit opt > host parsed from `url` > DEF_MEDIA_HOST.
|
|
418
|
-
// Lets us honor a non-default host carried by the proto without forcing callers to thread it through.
|
|
419
|
-
const fallbackHost = opts.host ?? extractHost(url);
|
|
420
|
-
const downloadUrl = directPath ? getUrlFromDirectPath(directPath, fallbackHost) : url;
|
|
421
|
-
if (!downloadUrl) {
|
|
422
|
-
throw new Boom('No valid media URL or directPath present in message', { statusCode: 400 });
|
|
423
|
-
}
|
|
424
|
-
const keys = await getMediaKeys(mediaKey, type);
|
|
425
|
-
return downloadEncryptedContent(downloadUrl, keys, opts);
|
|
416
|
+
const getUrlFromDirectPath = (directPath) => `https://${DEF_HOST}${directPath}`;
|
|
417
|
+
exports.getUrlFromDirectPath = getUrlFromDirectPath;
|
|
418
|
+
const downloadContentFromMessage = ({ mediaKey, directPath, url }, type, opts = {}) => {
|
|
419
|
+
const downloadUrl = url || (0, exports.getUrlFromDirectPath)(directPath);
|
|
420
|
+
const keys = getMediaKeys(mediaKey, type);
|
|
421
|
+
return (0, exports.downloadEncryptedContent)(downloadUrl, keys, opts);
|
|
426
422
|
};
|
|
423
|
+
exports.downloadContentFromMessage = downloadContentFromMessage;
|
|
427
424
|
/**
|
|
428
425
|
* Decrypts and downloads an AES256-CBC encrypted file given the keys.
|
|
429
426
|
* Assumes the SHA256 of the plaintext is appended to the end of the ciphertext
|
|
430
427
|
* */
|
|
431
|
-
|
|
428
|
+
const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startByte, endByte, options } = {}) => {
|
|
432
429
|
let bytesFetched = 0;
|
|
433
430
|
let startChunk = 0;
|
|
434
431
|
let firstBlockIsIV = false;
|
|
@@ -442,14 +439,9 @@ export const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, {
|
|
|
442
439
|
}
|
|
443
440
|
}
|
|
444
441
|
const endChunk = endByte ? toSmallestChunkSize(endByte || 0) + AES_CHUNK_SIZE : undefined;
|
|
445
|
-
const headersInit = options?.headers ? options.headers : undefined;
|
|
446
442
|
const headers = {
|
|
447
|
-
...(
|
|
448
|
-
|
|
449
|
-
? Object.fromEntries(headersInit)
|
|
450
|
-
: headersInit
|
|
451
|
-
: {}),
|
|
452
|
-
Origin: DEFAULT_ORIGIN
|
|
443
|
+
...(options === null || options === void 0 ? void 0 : options.headers) || {},
|
|
444
|
+
Origin: Defaults_1.DEFAULT_ORIGIN,
|
|
453
445
|
};
|
|
454
446
|
if (startChunk || endChunk) {
|
|
455
447
|
headers.Range = `bytes=${startChunk}-`;
|
|
@@ -458,9 +450,11 @@ export const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, {
|
|
|
458
450
|
}
|
|
459
451
|
}
|
|
460
452
|
// download the message
|
|
461
|
-
const fetched = await getHttpStream(downloadUrl, {
|
|
462
|
-
...
|
|
463
|
-
headers
|
|
453
|
+
const fetched = await (0, exports.getHttpStream)(downloadUrl, {
|
|
454
|
+
...options || {},
|
|
455
|
+
headers,
|
|
456
|
+
maxBodyLength: Infinity,
|
|
457
|
+
maxContentLength: Infinity,
|
|
464
458
|
});
|
|
465
459
|
let remainingBytes = Buffer.from([]);
|
|
466
460
|
let aes;
|
|
@@ -475,9 +469,9 @@ export const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, {
|
|
|
475
469
|
push(bytes);
|
|
476
470
|
}
|
|
477
471
|
};
|
|
478
|
-
const output = new Transform({
|
|
472
|
+
const output = new stream_1.Transform({
|
|
479
473
|
transform(chunk, _, callback) {
|
|
480
|
-
let data =
|
|
474
|
+
let data = Buffer.concat([remainingBytes, chunk]);
|
|
481
475
|
const decryptLength = toSmallestChunkSize(data.length);
|
|
482
476
|
remainingBytes = data.slice(decryptLength);
|
|
483
477
|
data = data.slice(0, decryptLength);
|
|
@@ -510,15 +504,18 @@ export const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, {
|
|
|
510
504
|
catch (error) {
|
|
511
505
|
callback(error);
|
|
512
506
|
}
|
|
513
|
-
}
|
|
507
|
+
},
|
|
514
508
|
});
|
|
515
509
|
return fetched.pipe(output, { end: true });
|
|
516
510
|
};
|
|
517
|
-
|
|
518
|
-
|
|
511
|
+
exports.downloadEncryptedContent = downloadEncryptedContent;
|
|
512
|
+
function extensionForMediaMessage(message) {
|
|
513
|
+
const getExtension = (mimetype) => mimetype.split(';')[0].split('/')[1];
|
|
519
514
|
const type = Object.keys(message)[0];
|
|
520
515
|
let extension;
|
|
521
|
-
if (type === 'locationMessage' ||
|
|
516
|
+
if (type === 'locationMessage' ||
|
|
517
|
+
type === 'liveLocationMessage' ||
|
|
518
|
+
type === 'productMessage') {
|
|
522
519
|
extension = '.jpeg';
|
|
523
520
|
}
|
|
524
521
|
else {
|
|
@@ -527,158 +524,39 @@ export function extensionForMediaMessage(message) {
|
|
|
527
524
|
}
|
|
528
525
|
return extension;
|
|
529
526
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
typeof globalThis.Deno === 'undefined');
|
|
535
|
-
};
|
|
536
|
-
export const uploadWithNodeHttp = async ({ url, filePath, headers, timeoutMs, agent }, redirectCount = 0) => {
|
|
537
|
-
if (redirectCount > 5) {
|
|
538
|
-
throw new Error('Too many redirects');
|
|
539
|
-
}
|
|
540
|
-
const parsedUrl = new URL(url);
|
|
541
|
-
const httpModule = parsedUrl.protocol === 'https:' ? await import('https') : await import('http');
|
|
542
|
-
// Get file size for Content-Length header (required for Node.js streaming)
|
|
543
|
-
const fileStats = await fs.stat(filePath);
|
|
544
|
-
const fileSize = fileStats.size;
|
|
545
|
-
return new Promise((resolve, reject) => {
|
|
546
|
-
const req = httpModule.request({
|
|
547
|
-
hostname: parsedUrl.hostname,
|
|
548
|
-
port: parsedUrl.port || (parsedUrl.protocol === 'https:' ? 443 : 80),
|
|
549
|
-
path: parsedUrl.pathname + parsedUrl.search,
|
|
550
|
-
method: 'POST',
|
|
551
|
-
headers: {
|
|
552
|
-
...headers,
|
|
553
|
-
'Content-Length': fileSize
|
|
554
|
-
},
|
|
555
|
-
agent,
|
|
556
|
-
timeout: timeoutMs
|
|
557
|
-
}, res => {
|
|
558
|
-
// Handle redirects (3xx)
|
|
559
|
-
if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
560
|
-
res.resume(); // Consume response to free resources
|
|
561
|
-
const newUrl = new URL(res.headers.location, url).toString();
|
|
562
|
-
resolve(uploadWithNodeHttp({
|
|
563
|
-
url: newUrl,
|
|
564
|
-
filePath,
|
|
565
|
-
headers,
|
|
566
|
-
timeoutMs,
|
|
567
|
-
agent
|
|
568
|
-
}, redirectCount + 1));
|
|
569
|
-
return;
|
|
570
|
-
}
|
|
571
|
-
let body = '';
|
|
572
|
-
res.on('data', chunk => (body += chunk));
|
|
573
|
-
res.on('end', () => {
|
|
574
|
-
try {
|
|
575
|
-
resolve(JSON.parse(body));
|
|
576
|
-
}
|
|
577
|
-
catch {
|
|
578
|
-
resolve(undefined);
|
|
579
|
-
}
|
|
580
|
-
});
|
|
581
|
-
});
|
|
582
|
-
req.on('error', reject);
|
|
583
|
-
req.on('timeout', () => {
|
|
584
|
-
req.destroy();
|
|
585
|
-
reject(new Error('Upload timeout'));
|
|
586
|
-
});
|
|
587
|
-
const stream = createReadStream(filePath);
|
|
588
|
-
stream.pipe(req);
|
|
589
|
-
stream.on('error', err => {
|
|
590
|
-
req.destroy();
|
|
591
|
-
reject(err);
|
|
592
|
-
});
|
|
593
|
-
});
|
|
594
|
-
};
|
|
595
|
-
const uploadWithFetch = async ({ url, filePath, headers, timeoutMs, agent }) => {
|
|
596
|
-
// Convert Node.js Readable to Web ReadableStream
|
|
597
|
-
const nodeStream = createReadStream(filePath);
|
|
598
|
-
const webStream = Readable.toWeb(nodeStream);
|
|
599
|
-
// Native fetch only accepts Undici-style dispatchers, not generic https Agents.
|
|
600
|
-
const dispatcher = typeof agent?.dispatch === 'function' ? agent : undefined;
|
|
601
|
-
const response = await fetch(url, {
|
|
602
|
-
...(dispatcher ? { dispatcher } : {}),
|
|
603
|
-
method: 'POST',
|
|
604
|
-
body: webStream,
|
|
605
|
-
headers,
|
|
606
|
-
duplex: 'half',
|
|
607
|
-
signal: timeoutMs ? AbortSignal.timeout(timeoutMs) : undefined
|
|
608
|
-
});
|
|
609
|
-
try {
|
|
610
|
-
return (await response.json());
|
|
611
|
-
}
|
|
612
|
-
catch {
|
|
613
|
-
return undefined;
|
|
614
|
-
}
|
|
615
|
-
};
|
|
616
|
-
/**
|
|
617
|
-
* Uploads media to WhatsApp servers.
|
|
618
|
-
*
|
|
619
|
-
* ## Why we have two upload implementations:
|
|
620
|
-
*
|
|
621
|
-
* Node.js's native `fetch` (powered by undici) has a known bug where it buffers
|
|
622
|
-
* the entire request body in memory before sending, even when using streams.
|
|
623
|
-
* This causes memory issues with large files (e.g., 1GB file = 1GB+ memory usage).
|
|
624
|
-
* See: https://github.com/nodejs/undici/issues/4058
|
|
625
|
-
*
|
|
626
|
-
* Other runtimes (Bun, Deno, browsers) correctly stream the request body without
|
|
627
|
-
* buffering, so we can use the web-standard Fetch API there.
|
|
628
|
-
*
|
|
629
|
-
* ## Future considerations:
|
|
630
|
-
* Once the undici bug is fixed, we can simplify this to use only the Fetch API
|
|
631
|
-
* across all runtimes. Monitor the GitHub issue for updates.
|
|
632
|
-
*/
|
|
633
|
-
const uploadMedia = async (params, logger) => {
|
|
634
|
-
if (isNodeRuntime()) {
|
|
635
|
-
logger?.debug('Using Node.js https module for upload (avoids undici buffering bug)');
|
|
636
|
-
return uploadWithNodeHttp(params);
|
|
637
|
-
}
|
|
638
|
-
else {
|
|
639
|
-
logger?.debug('Using web-standard Fetch API for upload');
|
|
640
|
-
return uploadWithFetch(params);
|
|
641
|
-
}
|
|
642
|
-
};
|
|
643
|
-
export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
644
|
-
return async (filePath, { mediaType, fileEncSha256B64, timeoutMs }) => {
|
|
527
|
+
exports.extensionForMediaMessage = extensionForMediaMessage;
|
|
528
|
+
const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
529
|
+
return async (stream, { mediaType, fileEncSha256B64, timeoutMs }) => {
|
|
530
|
+
var _a, _b;
|
|
645
531
|
// send a query JSON to obtain the url & auth token to upload our media
|
|
646
532
|
let uploadInfo = await refreshMediaConn(false);
|
|
647
533
|
let urls;
|
|
648
534
|
const hosts = [...customUploadHosts, ...uploadInfo.hosts];
|
|
649
|
-
fileEncSha256B64 = encodeBase64EncodedStringForUpload(fileEncSha256B64);
|
|
650
|
-
// Prepare common headers
|
|
651
|
-
const customHeaders = (() => {
|
|
652
|
-
const hdrs = options?.headers;
|
|
653
|
-
if (!hdrs)
|
|
654
|
-
return {};
|
|
655
|
-
return Array.isArray(hdrs) ? Object.fromEntries(hdrs) : hdrs;
|
|
656
|
-
})();
|
|
657
|
-
const headers = {
|
|
658
|
-
...customHeaders,
|
|
659
|
-
'Content-Type': 'application/octet-stream',
|
|
660
|
-
Origin: DEFAULT_ORIGIN
|
|
661
|
-
};
|
|
535
|
+
fileEncSha256B64 = (0, exports.encodeBase64EncodedStringForUpload)(fileEncSha256B64);
|
|
662
536
|
for (const { hostname } of hosts) {
|
|
663
537
|
logger.debug(`uploading to "${hostname}"`);
|
|
664
|
-
const auth = encodeURIComponent(uploadInfo.auth);
|
|
665
|
-
const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
|
|
538
|
+
const auth = encodeURIComponent(uploadInfo.auth); // the auth token
|
|
539
|
+
const url = `https://${hostname}${Defaults_1.MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
|
|
666
540
|
let result;
|
|
667
541
|
try {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
542
|
+
const body = await axios_1.default.post(url, stream, {
|
|
543
|
+
...options,
|
|
544
|
+
headers: {
|
|
545
|
+
...options.headers || {},
|
|
546
|
+
'Content-Type': 'application/octet-stream',
|
|
547
|
+
'Origin': Defaults_1.DEFAULT_ORIGIN
|
|
548
|
+
},
|
|
549
|
+
httpsAgent: fetchAgent,
|
|
550
|
+
timeout: timeoutMs,
|
|
551
|
+
responseType: 'json',
|
|
552
|
+
maxBodyLength: Infinity,
|
|
553
|
+
maxContentLength: Infinity,
|
|
554
|
+
});
|
|
555
|
+
result = body.data;
|
|
556
|
+
if ((result === null || result === void 0 ? void 0 : result.url) || (result === null || result === void 0 ? void 0 : result.directPath)) {
|
|
676
557
|
urls = {
|
|
677
558
|
mediaUrl: result.url,
|
|
678
|
-
directPath: result.direct_path
|
|
679
|
-
meta_hmac: result.meta_hmac,
|
|
680
|
-
fbid: result.fbid,
|
|
681
|
-
ts: result.ts
|
|
559
|
+
directPath: result.direct_path
|
|
682
560
|
};
|
|
683
561
|
break;
|
|
684
562
|
}
|
|
@@ -688,33 +566,37 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, opt
|
|
|
688
566
|
}
|
|
689
567
|
}
|
|
690
568
|
catch (error) {
|
|
691
|
-
|
|
692
|
-
|
|
569
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
570
|
+
result = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data;
|
|
571
|
+
}
|
|
572
|
+
const isLast = hostname === ((_b = hosts[uploadInfo.hosts.length - 1]) === null || _b === void 0 ? void 0 : _b.hostname);
|
|
573
|
+
logger.warn({ trace: error.stack, uploadResult: result }, `Error in uploading to ${hostname} ${isLast ? '' : ', retrying...'}`);
|
|
693
574
|
}
|
|
694
575
|
}
|
|
695
576
|
if (!urls) {
|
|
696
|
-
throw new Boom('Media upload failed on all hosts', { statusCode: 500 });
|
|
577
|
+
throw new boom_1.Boom('Media upload failed on all hosts', { statusCode: 500 });
|
|
697
578
|
}
|
|
698
579
|
return urls;
|
|
699
580
|
};
|
|
700
581
|
};
|
|
582
|
+
exports.getWAUploadToServer = getWAUploadToServer;
|
|
701
583
|
const getMediaRetryKey = (mediaKey) => {
|
|
702
|
-
return hkdf(mediaKey, 32, { info: 'WhatsApp Media Retry Notification' });
|
|
584
|
+
return (0, crypto_1.hkdf)(mediaKey, 32, { info: 'WhatsApp Media Retry Notification' });
|
|
703
585
|
};
|
|
704
586
|
/**
|
|
705
587
|
* Generate a binary node that will request the phone to re-upload the media & return the newly uploaded URL
|
|
706
588
|
*/
|
|
707
|
-
|
|
589
|
+
const encryptMediaRetryRequest = (key, mediaKey, meId) => {
|
|
708
590
|
const recp = { stanzaId: key.id };
|
|
709
|
-
const recpBuffer = proto.ServerErrorReceipt.encode(recp).finish();
|
|
591
|
+
const recpBuffer = WAProto_1.proto.ServerErrorReceipt.encode(recp).finish();
|
|
710
592
|
const iv = Crypto.randomBytes(12);
|
|
711
593
|
const retryKey = getMediaRetryKey(mediaKey);
|
|
712
|
-
const ciphertext = aesEncryptGCM(recpBuffer, retryKey, iv, Buffer.from(key.id));
|
|
594
|
+
const ciphertext = (0, crypto_1.aesEncryptGCM)(recpBuffer, retryKey, iv, Buffer.from(key.id));
|
|
713
595
|
const req = {
|
|
714
596
|
tag: 'receipt',
|
|
715
597
|
attrs: {
|
|
716
598
|
id: key.id,
|
|
717
|
-
to: jidNormalizedUser(meId),
|
|
599
|
+
to: (0, WABinary_1.jidNormalizedUser)(meId),
|
|
718
600
|
type: 'server-error'
|
|
719
601
|
},
|
|
720
602
|
content: [
|
|
@@ -733,7 +615,7 @@ export const encryptMediaRetryRequest = (key, mediaKey, meId) => {
|
|
|
733
615
|
tag: 'rmr',
|
|
734
616
|
attrs: {
|
|
735
617
|
jid: key.remoteJid,
|
|
736
|
-
from_me: (!!key.fromMe).toString(),
|
|
618
|
+
'from_me': (!!key.fromMe).toString(),
|
|
737
619
|
// @ts-ignore
|
|
738
620
|
participant: key.participant || undefined
|
|
739
621
|
}
|
|
@@ -742,8 +624,9 @@ export const encryptMediaRetryRequest = (key, mediaKey, meId) => {
|
|
|
742
624
|
};
|
|
743
625
|
return req;
|
|
744
626
|
};
|
|
745
|
-
|
|
746
|
-
|
|
627
|
+
exports.encryptMediaRetryRequest = encryptMediaRetryRequest;
|
|
628
|
+
const decodeMediaRetryNode = (node) => {
|
|
629
|
+
const rmrNode = (0, WABinary_1.getBinaryNodeChild)(node, 'rmr');
|
|
747
630
|
const event = {
|
|
748
631
|
key: {
|
|
749
632
|
id: node.attrs.id,
|
|
@@ -752,37 +635,40 @@ export const decodeMediaRetryNode = (node) => {
|
|
|
752
635
|
participant: rmrNode.attrs.participant
|
|
753
636
|
}
|
|
754
637
|
};
|
|
755
|
-
const errorNode = getBinaryNodeChild(node, 'error');
|
|
638
|
+
const errorNode = (0, WABinary_1.getBinaryNodeChild)(node, 'error');
|
|
756
639
|
if (errorNode) {
|
|
757
640
|
const errorCode = +errorNode.attrs.code;
|
|
758
|
-
event.error = new Boom(`Failed to re-upload media (${errorCode})`, {
|
|
759
|
-
data: errorNode.attrs,
|
|
760
|
-
statusCode: getStatusCodeForMediaRetry(errorCode)
|
|
761
|
-
});
|
|
641
|
+
event.error = new boom_1.Boom(`Failed to re-upload media (${errorCode})`, { data: errorNode.attrs, statusCode: (0, exports.getStatusCodeForMediaRetry)(errorCode) });
|
|
762
642
|
}
|
|
763
643
|
else {
|
|
764
|
-
const encryptedInfoNode = getBinaryNodeChild(node, 'encrypt');
|
|
765
|
-
const ciphertext = getBinaryNodeChildBuffer(encryptedInfoNode, 'enc_p');
|
|
766
|
-
const iv = getBinaryNodeChildBuffer(encryptedInfoNode, 'enc_iv');
|
|
644
|
+
const encryptedInfoNode = (0, WABinary_1.getBinaryNodeChild)(node, 'encrypt');
|
|
645
|
+
const ciphertext = (0, WABinary_1.getBinaryNodeChildBuffer)(encryptedInfoNode, 'enc_p');
|
|
646
|
+
const iv = (0, WABinary_1.getBinaryNodeChildBuffer)(encryptedInfoNode, 'enc_iv');
|
|
767
647
|
if (ciphertext && iv) {
|
|
768
648
|
event.media = { ciphertext, iv };
|
|
769
649
|
}
|
|
770
650
|
else {
|
|
771
|
-
event.error = new Boom('Failed to re-upload media (missing ciphertext)', { statusCode: 404 });
|
|
651
|
+
event.error = new boom_1.Boom('Failed to re-upload media (missing ciphertext)', { statusCode: 404 });
|
|
772
652
|
}
|
|
773
653
|
}
|
|
774
654
|
return event;
|
|
775
655
|
};
|
|
776
|
-
|
|
656
|
+
exports.decodeMediaRetryNode = decodeMediaRetryNode;
|
|
657
|
+
const decryptMediaRetryData = ({ ciphertext, iv }, mediaKey, msgId) => {
|
|
777
658
|
const retryKey = getMediaRetryKey(mediaKey);
|
|
778
|
-
const plaintext = aesDecryptGCM(ciphertext, retryKey, iv, Buffer.from(msgId));
|
|
779
|
-
return proto.MediaRetryNotification.decode(plaintext);
|
|
659
|
+
const plaintext = (0, crypto_1.aesDecryptGCM)(ciphertext, retryKey, iv, Buffer.from(msgId));
|
|
660
|
+
return WAProto_1.proto.MediaRetryNotification.decode(plaintext);
|
|
780
661
|
};
|
|
781
|
-
|
|
662
|
+
exports.decryptMediaRetryData = decryptMediaRetryData;
|
|
663
|
+
const getStatusCodeForMediaRetry = (code) => MEDIA_RETRY_STATUS_MAP[code];
|
|
664
|
+
exports.getStatusCodeForMediaRetry = getStatusCodeForMediaRetry;
|
|
782
665
|
const MEDIA_RETRY_STATUS_MAP = {
|
|
783
|
-
[proto.MediaRetryNotification.ResultType.SUCCESS]: 200,
|
|
784
|
-
[proto.MediaRetryNotification.ResultType.DECRYPTION_ERROR]: 412,
|
|
785
|
-
[proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
|
|
786
|
-
[proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418
|
|
666
|
+
[WAProto_1.proto.MediaRetryNotification.ResultType.SUCCESS]: 200,
|
|
667
|
+
[WAProto_1.proto.MediaRetryNotification.ResultType.DECRYPTION_ERROR]: 412,
|
|
668
|
+
[WAProto_1.proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
|
|
669
|
+
[WAProto_1.proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418,
|
|
787
670
|
};
|
|
788
|
-
|
|
671
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
672
|
+
function __importStar(arg0) {
|
|
673
|
+
throw new Error('Function not implemented.');
|
|
674
|
+
}
|