@d0v3riz/baileys 6.7.19 → 6.7.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1263 -4
- package/WAProto/GenerateStatics.sh +3 -0
- package/WAProto/WAProto.proto +4633 -0
- package/WAProto/fix-imports.js +29 -0
- package/WAProto/index.d.ts +3212 -122
- package/WAProto/index.js +13516 -4182
- package/lib/Defaults/baileys-version.json +1 -1
- package/lib/Defaults/index.d.ts +4 -3
- package/lib/Defaults/index.d.ts.map +1 -0
- package/lib/Defaults/index.js +50 -54
- package/lib/Defaults/index.js.map +1 -0
- package/lib/Signal/Group/ciphertext-message.d.ts +10 -0
- package/lib/Signal/Group/ciphertext-message.d.ts.map +1 -0
- package/lib/Signal/Group/ciphertext-message.js +12 -0
- package/lib/Signal/Group/ciphertext-message.js.map +1 -0
- package/lib/Signal/Group/group-session-builder.d.ts +15 -0
- package/lib/Signal/Group/group-session-builder.d.ts.map +1 -0
- package/lib/Signal/Group/group-session-builder.js +30 -0
- package/lib/Signal/Group/group-session-builder.js.map +1 -0
- package/lib/Signal/Group/group_cipher.d.ts +18 -0
- package/lib/Signal/Group/group_cipher.d.ts.map +1 -0
- package/lib/Signal/Group/group_cipher.js +94 -0
- package/lib/Signal/Group/group_cipher.js.map +1 -0
- package/lib/Signal/Group/index.d.ts +12 -0
- package/lib/Signal/Group/index.d.ts.map +1 -0
- package/lib/Signal/Group/index.js +12 -0
- package/lib/Signal/Group/index.js.map +1 -0
- package/lib/Signal/Group/keyhelper.d.ts +11 -0
- package/lib/Signal/Group/keyhelper.d.ts.map +1 -0
- package/lib/Signal/Group/keyhelper.js +19 -0
- package/lib/Signal/Group/keyhelper.js.map +1 -0
- package/lib/Signal/Group/queue-job.d.ts +3 -0
- package/lib/Signal/Group/queue-job.d.ts.map +1 -0
- package/lib/Signal/Group/queue-job.js +57 -0
- package/lib/Signal/Group/queue-job.js.map +1 -0
- package/lib/Signal/Group/sender-chain-key.d.ts +14 -0
- package/lib/Signal/Group/sender-chain-key.d.ts.map +1 -0
- package/lib/Signal/Group/sender-chain-key.js +32 -0
- package/lib/Signal/Group/sender-chain-key.js.map +1 -0
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +17 -0
- package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +63 -0
- package/lib/Signal/Group/sender-key-distribution-message.js.map +1 -0
- package/lib/Signal/Group/sender-key-message.d.ts +19 -0
- package/lib/Signal/Group/sender-key-message.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-message.js +67 -0
- package/lib/Signal/Group/sender-key-message.js.map +1 -0
- package/lib/Signal/Group/sender-key-name.d.ts +18 -0
- package/lib/Signal/Group/sender-key-name.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-name.js +48 -0
- package/lib/Signal/Group/sender-key-name.js.map +1 -0
- package/lib/Signal/Group/sender-key-record.d.ts +31 -0
- package/lib/Signal/Group/sender-key-record.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-record.js +50 -0
- package/lib/Signal/Group/sender-key-record.js.map +1 -0
- package/lib/Signal/Group/sender-key-state.d.ts +39 -0
- package/lib/Signal/Group/sender-key-state.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-state.js +96 -0
- package/lib/Signal/Group/sender-key-state.js.map +1 -0
- package/lib/Signal/Group/sender-message-key.d.ts +12 -0
- package/lib/Signal/Group/sender-message-key.d.ts.map +1 -0
- package/{WASignalGroup/sender_message_key.js → lib/Signal/Group/sender-message-key.js} +27 -39
- package/lib/Signal/Group/sender-message-key.js.map +1 -0
- package/lib/Signal/libsignal.d.ts +3 -2
- package/lib/Signal/libsignal.d.ts.map +1 -0
- package/lib/Signal/libsignal.js +41 -61
- package/lib/Signal/libsignal.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 -18
- package/lib/Socket/Client/index.js.map +1 -0
- package/lib/Socket/Client/types.d.ts +2 -1
- package/lib/Socket/Client/types.d.ts.map +1 -0
- package/lib/Socket/Client/types.js +4 -6
- package/lib/Socket/Client/types.js.map +1 -0
- package/lib/Socket/Client/websocket.d.ts +2 -1
- package/lib/Socket/Client/websocket.d.ts.map +1 -0
- package/lib/Socket/Client/websocket.js +15 -27
- package/lib/Socket/Client/websocket.js.map +1 -0
- package/lib/Socket/business.d.ts +92 -62
- package/lib/Socket/business.d.ts.map +1 -0
- package/lib/Socket/business.js +37 -42
- package/lib/Socket/business.js.map +1 -0
- package/lib/Socket/chats.d.ts +31 -24
- package/lib/Socket/chats.d.ts.map +1 -0
- package/lib/Socket/chats.js +251 -198
- package/lib/Socket/chats.js.map +1 -0
- package/lib/Socket/communities.d.ts +219 -0
- package/lib/Socket/communities.d.ts.map +1 -0
- package/lib/Socket/communities.js +351 -0
- package/lib/Socket/communities.js.map +1 -0
- package/lib/Socket/groups.d.ts +47 -39
- package/lib/Socket/groups.d.ts.map +1 -0
- package/lib/Socket/groups.js +91 -82
- package/lib/Socket/groups.js.map +1 -0
- package/lib/Socket/index.d.ts +128 -68
- package/lib/Socket/index.d.ts.map +1 -0
- package/lib/Socket/index.js +16 -9
- package/lib/Socket/index.js.map +1 -0
- package/lib/Socket/messages-recv.d.ts +79 -49
- package/lib/Socket/messages-recv.d.ts.map +1 -0
- package/lib/Socket/messages-recv.js +364 -200
- package/lib/Socket/messages-recv.js.map +1 -0
- package/lib/Socket/messages-send.d.ts +76 -46
- package/lib/Socket/messages-send.d.ts.map +1 -0
- package/lib/Socket/messages-send.js +144 -120
- 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 +143 -0
- package/lib/Socket/newsletter.d.ts.map +1 -0
- package/lib/Socket/newsletter.js +179 -0
- package/lib/Socket/newsletter.js.map +1 -0
- package/lib/Socket/socket.d.ts +15 -14
- package/lib/Socket/socket.d.ts.map +1 -0
- package/lib/Socket/socket.js +153 -141
- package/lib/Socket/socket.js.map +1 -0
- package/lib/Socket/usync.d.ts +17 -16
- package/lib/Socket/usync.d.ts.map +1 -0
- package/lib/Socket/usync.js +19 -26
- package/lib/Socket/usync.js.map +1 -0
- package/lib/Types/Auth.d.ts +5 -4
- package/lib/Types/Auth.d.ts.map +1 -0
- package/lib/Types/Auth.js +2 -2
- package/lib/Types/Auth.js.map +1 -0
- package/lib/Types/Call.d.ts +1 -0
- package/lib/Types/Call.d.ts.map +1 -0
- package/lib/Types/Call.js +2 -2
- package/lib/Types/Call.js.map +1 -0
- package/lib/Types/Chat.d.ts +14 -8
- package/lib/Types/Chat.d.ts.map +1 -0
- package/lib/Types/Chat.js +8 -4
- package/lib/Types/Chat.js.map +1 -0
- package/lib/Types/Contact.d.ts +5 -0
- package/lib/Types/Contact.d.ts.map +1 -0
- package/lib/Types/Contact.js +2 -2
- package/lib/Types/Contact.js.map +1 -0
- package/lib/Types/Events.d.ts +38 -11
- package/lib/Types/Events.d.ts.map +1 -0
- package/lib/Types/Events.js +2 -2
- package/lib/Types/Events.js.map +1 -0
- package/lib/Types/GroupMetadata.d.ts +10 -4
- package/lib/Types/GroupMetadata.d.ts.map +1 -0
- package/lib/Types/GroupMetadata.js +2 -2
- package/lib/Types/GroupMetadata.js.map +1 -0
- package/lib/Types/Label.d.ts +1 -0
- package/lib/Types/Label.d.ts.map +1 -0
- package/lib/Types/Label.js +3 -5
- package/lib/Types/Label.js.map +1 -0
- package/lib/Types/LabelAssociation.d.ts +1 -0
- package/lib/Types/LabelAssociation.d.ts.map +1 -0
- package/lib/Types/LabelAssociation.js +3 -5
- package/lib/Types/LabelAssociation.js.map +1 -0
- package/lib/Types/Message.d.ts +21 -9
- package/lib/Types/Message.d.ts.map +1 -0
- package/lib/Types/Message.js +7 -7
- package/lib/Types/Message.js.map +1 -0
- package/lib/Types/Newsletter.d.ts +135 -0
- package/lib/Types/Newsletter.d.ts.map +1 -0
- package/lib/Types/Newsletter.js +31 -0
- package/lib/Types/Newsletter.js.map +1 -0
- package/lib/Types/Product.d.ts +2 -1
- package/lib/Types/Product.d.ts.map +1 -0
- package/lib/Types/Product.js +2 -2
- package/lib/Types/Product.js.map +1 -0
- package/lib/Types/Signal.d.ts +2 -1
- package/lib/Types/Signal.d.ts.map +1 -0
- package/lib/Types/Signal.js +2 -2
- package/lib/Types/Signal.js.map +1 -0
- package/lib/Types/Socket.d.ts +11 -10
- package/lib/Types/Socket.d.ts.map +1 -0
- package/lib/Types/Socket.js +3 -2
- package/lib/Types/Socket.js.map +1 -0
- package/lib/Types/State.d.ts +14 -2
- package/lib/Types/State.d.ts.map +1 -0
- package/lib/Types/State.js +13 -2
- package/lib/Types/State.js.map +1 -0
- package/lib/Types/USync.d.ts +3 -2
- package/lib/Types/USync.d.ts.map +1 -0
- package/lib/Types/USync.js +2 -2
- package/lib/Types/USync.js.map +1 -0
- package/lib/Types/index.d.ts +15 -13
- package/lib/Types/index.d.ts.map +1 -0
- package/lib/Types/index.js +15 -30
- package/lib/Types/index.js.map +1 -0
- package/lib/Utils/auth-utils.d.ts +3 -2
- package/lib/Utils/auth-utils.d.ts.map +1 -0
- package/lib/Utils/auth-utils.js +30 -40
- package/lib/Utils/auth-utils.js.map +1 -0
- package/lib/Utils/baileys-event-stream.d.ts +2 -1
- package/lib/Utils/baileys-event-stream.d.ts.map +1 -0
- package/lib/Utils/baileys-event-stream.js +15 -22
- package/lib/Utils/baileys-event-stream.js.map +1 -0
- package/lib/Utils/business.d.ts +3 -2
- package/lib/Utils/business.d.ts.map +1 -0
- package/lib/Utils/business.js +64 -75
- package/lib/Utils/business.js.map +1 -0
- package/lib/Utils/chat-utils.d.ts +12 -11
- package/lib/Utils/chat-utils.d.ts.map +1 -0
- package/lib/Utils/chat-utils.js +195 -194
- package/lib/Utils/chat-utils.js.map +1 -0
- package/lib/Utils/crypto.d.ts +2 -1
- package/lib/Utils/crypto.d.ts.map +1 -0
- package/lib/Utils/crypto.js +40 -95
- package/lib/Utils/crypto.js.map +1 -0
- package/lib/Utils/decode-wa-message.d.ts +7 -7
- package/lib/Utils/decode-wa-message.d.ts.map +1 -0
- package/lib/Utils/decode-wa-message.js +43 -41
- package/lib/Utils/decode-wa-message.js.map +1 -0
- package/lib/Utils/event-buffer.d.ts +6 -6
- package/lib/Utils/event-buffer.d.ts.map +1 -0
- package/lib/Utils/event-buffer.js +42 -59
- package/lib/Utils/event-buffer.js.map +1 -0
- package/lib/Utils/generics.d.ts +11 -9
- package/lib/Utils/generics.d.ts.map +1 -0
- package/lib/Utils/generics.js +105 -130
- package/lib/Utils/generics.js.map +1 -0
- package/lib/Utils/history.d.ts +4 -3
- package/lib/Utils/history.d.ts.map +1 -0
- package/lib/Utils/history.js +37 -46
- package/lib/Utils/history.js.map +1 -0
- package/lib/Utils/index.d.ts +18 -17
- package/lib/Utils/index.d.ts.map +1 -0
- package/lib/Utils/index.js +18 -33
- package/lib/Utils/index.js.map +1 -0
- package/lib/Utils/link-preview.d.ts +4 -3
- package/lib/Utils/link-preview.d.ts.map +1 -0
- package/lib/Utils/link-preview.js +14 -55
- package/lib/Utils/link-preview.js.map +1 -0
- package/lib/Utils/logger.d.ts +8 -6
- 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 +9 -8
- package/lib/Utils/lt-hash.d.ts.map +1 -0
- package/lib/Utils/lt-hash.js +23 -26
- package/lib/Utils/lt-hash.js.map +1 -0
- package/lib/Utils/make-mutex.d.ts +1 -0
- package/lib/Utils/make-mutex.d.ts.map +1 -0
- package/lib/Utils/make-mutex.js +6 -10
- package/lib/Utils/make-mutex.js.map +1 -0
- package/lib/Utils/messages-media.d.ts +20 -11
- package/lib/Utils/messages-media.d.ts.map +1 -0
- package/lib/Utils/messages-media.js +215 -253
- package/lib/Utils/messages-media.js.map +1 -0
- package/lib/Utils/messages.d.ts +9 -8
- package/lib/Utils/messages.d.ts.map +1 -0
- package/lib/Utils/messages.js +259 -228
- package/lib/Utils/messages.js.map +1 -0
- package/lib/Utils/noise-handler.d.ts +5 -4
- package/lib/Utils/noise-handler.d.ts.map +1 -0
- package/lib/Utils/noise-handler.js +22 -26
- package/lib/Utils/noise-handler.js.map +1 -0
- package/lib/Utils/process-message.d.ts +6 -5
- package/lib/Utils/process-message.d.ts.map +1 -0
- package/lib/Utils/process-message.js +109 -123
- package/lib/Utils/process-message.js.map +1 -0
- package/lib/Utils/signal.d.ts +5 -4
- package/lib/Utils/signal.d.ts.map +1 -0
- package/lib/Utils/signal.js +52 -55
- package/lib/Utils/signal.js.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.d.ts +2 -1
- package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.js +23 -27
- package/lib/Utils/use-multi-file-auth-state.js.map +1 -0
- package/lib/Utils/validate-connection.d.ts +4 -3
- package/lib/Utils/validate-connection.d.ts.map +1 -0
- package/lib/Utils/validate-connection.js +64 -75
- package/lib/Utils/validate-connection.js.map +1 -0
- package/lib/WABinary/constants.d.ts +5 -4
- package/lib/WABinary/constants.d.ts.map +1 -0
- package/lib/WABinary/constants.js +1280 -19
- package/lib/WABinary/constants.js.map +1 -0
- package/lib/WABinary/decode.d.ts +2 -1
- package/lib/WABinary/decode.d.ts.map +1 -0
- package/lib/WABinary/decode.js +15 -52
- package/lib/WABinary/decode.js.map +1 -0
- package/lib/WABinary/encode.d.ts +2 -1
- package/lib/WABinary/encode.d.ts.map +1 -0
- package/lib/WABinary/encode.js +7 -43
- package/lib/WABinary/encode.js.map +1 -0
- package/lib/WABinary/generic-utils.d.ts +4 -3
- package/lib/WABinary/generic-utils.d.ts.map +1 -0
- package/lib/WABinary/generic-utils.js +31 -39
- 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 -21
- package/lib/WABinary/index.js.map +1 -0
- package/lib/WABinary/jid-utils.d.ts +1 -0
- package/lib/WABinary/jid-utils.d.ts.map +1 -0
- package/lib/WABinary/jid-utils.js +21 -38
- package/lib/WABinary/jid-utils.js.map +1 -0
- package/lib/WABinary/types.d.ts +2 -1
- package/lib/WABinary/types.d.ts.map +1 -0
- package/lib/WABinary/types.js +2 -2
- package/lib/WABinary/types.js.map +1 -0
- package/lib/WAM/BinaryInfo.d.ts +2 -1
- package/lib/WAM/BinaryInfo.d.ts.map +1 -0
- package/lib/WAM/BinaryInfo.js +2 -5
- package/lib/WAM/BinaryInfo.js.map +1 -0
- package/lib/WAM/constants.d.ts +1 -0
- package/lib/WAM/constants.d.ts.map +1 -0
- package/lib/WAM/constants.js +2257 -2366
- package/lib/WAM/constants.js.map +1 -0
- package/lib/WAM/encode.d.ts +2 -1
- package/lib/WAM/encode.d.ts.map +1 -0
- package/lib/WAM/encode.js +15 -19
- 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 -19
- package/lib/WAM/index.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +4 -3
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +8 -11
- package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +3 -2
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +11 -14
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +3 -2
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +9 -12
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +3 -2
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +9 -13
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +4 -3
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +20 -22
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +3 -2
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +3 -6
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/index.d.ts +5 -4
- package/lib/WAUSync/Protocols/index.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/index.js +5 -20
- package/lib/WAUSync/Protocols/index.js.map +1 -0
- package/lib/WAUSync/USyncQuery.d.ts +4 -3
- package/lib/WAUSync/USyncQuery.d.ts.map +1 -0
- package/lib/WAUSync/USyncQuery.js +34 -32
- package/lib/WAUSync/USyncQuery.js.map +1 -0
- package/lib/WAUSync/USyncUser.d.ts +6 -5
- package/lib/WAUSync/USyncUser.d.ts.map +1 -0
- package/lib/WAUSync/USyncUser.js +2 -5
- 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 -19
- package/lib/WAUSync/index.js.map +1 -0
- package/lib/index.d.ts +9 -8
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +11 -30
- package/lib/index.js.map +1 -0
- package/package.json +36 -31
- package/WASignalGroup/GroupProtocol.js +0 -1697
- package/WASignalGroup/ciphertext_message.js +0 -16
- package/WASignalGroup/group_cipher.js +0 -120
- package/WASignalGroup/group_session_builder.js +0 -46
- package/WASignalGroup/index.js +0 -5
- package/WASignalGroup/keyhelper.js +0 -21
- package/WASignalGroup/protobufs.js +0 -3
- package/WASignalGroup/queue_job.js +0 -69
- package/WASignalGroup/sender_chain_key.js +0 -50
- package/WASignalGroup/sender_key_distribution_message.js +0 -78
- package/WASignalGroup/sender_key_message.js +0 -92
- package/WASignalGroup/sender_key_name.js +0 -70
- package/WASignalGroup/sender_key_record.js +0 -56
- package/WASignalGroup/sender_key_state.js +0 -129
|
@@ -1,107 +1,92 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.getStatusCodeForMediaRetry = exports.decryptMediaRetryData = exports.decodeMediaRetryNode = exports.encryptMediaRetryRequest = exports.getWAUploadToServer = exports.downloadEncryptedContent = exports.downloadContentFromMessage = exports.getUrlFromDirectPath = exports.encryptedStream = exports.getHttpStream = exports.getStream = exports.toBuffer = exports.toReadable = exports.mediaMessageSHA256B64 = exports.generateProfilePicture = exports.encodeBase64EncodedStringForUpload = exports.extractImageThumb = exports.hkdfInfoKey = void 0;
|
|
40
|
-
exports.getMediaKeys = getMediaKeys;
|
|
41
|
-
exports.getAudioDuration = getAudioDuration;
|
|
42
|
-
exports.getAudioWaveform = getAudioWaveform;
|
|
43
|
-
exports.generateThumbnail = generateThumbnail;
|
|
44
|
-
exports.extensionForMediaMessage = extensionForMediaMessage;
|
|
45
|
-
const boom_1 = require("@hapi/boom");
|
|
46
|
-
const axios_1 = __importDefault(require("axios"));
|
|
47
|
-
const child_process_1 = require("child_process");
|
|
48
|
-
const Crypto = __importStar(require("crypto"));
|
|
49
|
-
const events_1 = require("events");
|
|
50
|
-
const fs_1 = require("fs");
|
|
51
|
-
const os_1 = require("os");
|
|
52
|
-
const path_1 = require("path");
|
|
53
|
-
const stream_1 = require("stream");
|
|
54
|
-
const WAProto_1 = require("../../WAProto");
|
|
55
|
-
const Defaults_1 = require("../Defaults");
|
|
56
|
-
const WABinary_1 = require("../WABinary");
|
|
57
|
-
const crypto_1 = require("./crypto");
|
|
58
|
-
const generics_1 = require("./generics");
|
|
59
|
-
const getTmpFilesDirectory = () => (0, os_1.tmpdir)();
|
|
1
|
+
import { Boom } from '@hapi/boom';
|
|
2
|
+
import axios, {} from 'axios';
|
|
3
|
+
import { exec } from 'child_process';
|
|
4
|
+
import * as Crypto from 'crypto';
|
|
5
|
+
import { once } from 'events';
|
|
6
|
+
import { createReadStream, createWriteStream, promises as fs, WriteStream } from 'fs';
|
|
7
|
+
import { tmpdir } from 'os';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import { Readable, Transform } from 'stream';
|
|
10
|
+
import { URL } from 'url';
|
|
11
|
+
import { proto } from '../../WAProto/index.js';
|
|
12
|
+
import { DEFAULT_ORIGIN, MEDIA_HKDF_KEY_MAPPING, MEDIA_PATH_MAP } from '../Defaults/index.js';
|
|
13
|
+
import { getBinaryNodeChild, getBinaryNodeChildBuffer, jidNormalizedUser } from '../WABinary/index.js';
|
|
14
|
+
import { aesDecryptGCM, aesEncryptGCM, hkdf } from './crypto.js';
|
|
15
|
+
import { generateMessageIDV2 } from './generics.js';
|
|
16
|
+
const getTmpFilesDirectory = () => tmpdir();
|
|
60
17
|
const getImageProcessingLibrary = async () => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const jimp = await (Promise.resolve().then(() => __importStar(require('jimp'))).catch(() => { }));
|
|
64
|
-
return jimp;
|
|
65
|
-
})(),
|
|
66
|
-
(async () => {
|
|
67
|
-
const sharp = await (Promise.resolve().then(() => __importStar(require('sharp'))).catch(() => { }));
|
|
68
|
-
return sharp;
|
|
69
|
-
})()
|
|
70
|
-
]);
|
|
18
|
+
//@ts-ignore
|
|
19
|
+
const [jimp, sharp] = await Promise.all([import('jimp').catch(() => { }), import('sharp').catch(() => { })]);
|
|
71
20
|
if (sharp) {
|
|
72
21
|
return { sharp };
|
|
73
22
|
}
|
|
74
|
-
const jimp = (_jimp === null || _jimp === void 0 ? void 0 : _jimp.default) || _jimp;
|
|
75
23
|
if (jimp) {
|
|
76
24
|
return { jimp };
|
|
77
25
|
}
|
|
78
|
-
throw new
|
|
26
|
+
throw new Boom('No image processing library available');
|
|
79
27
|
};
|
|
80
|
-
const hkdfInfoKey = (type) => {
|
|
81
|
-
const hkdfInfo =
|
|
28
|
+
export const hkdfInfoKey = (type) => {
|
|
29
|
+
const hkdfInfo = MEDIA_HKDF_KEY_MAPPING[type];
|
|
82
30
|
return `WhatsApp ${hkdfInfo} Keys`;
|
|
83
31
|
};
|
|
84
|
-
|
|
32
|
+
export const getRawMediaUploadData = async (media, mediaType, logger) => {
|
|
33
|
+
const { stream } = await getStream(media);
|
|
34
|
+
logger?.debug('got stream for raw upload');
|
|
35
|
+
const hasher = Crypto.createHash('sha256');
|
|
36
|
+
const filePath = join(tmpdir(), mediaType + generateMessageIDV2());
|
|
37
|
+
const fileWriteStream = createWriteStream(filePath);
|
|
38
|
+
let fileLength = 0;
|
|
39
|
+
try {
|
|
40
|
+
for await (const data of stream) {
|
|
41
|
+
fileLength += data.length;
|
|
42
|
+
hasher.update(data);
|
|
43
|
+
if (!fileWriteStream.write(data)) {
|
|
44
|
+
await once(fileWriteStream, 'drain');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
fileWriteStream.end();
|
|
48
|
+
await once(fileWriteStream, 'finish');
|
|
49
|
+
stream.destroy();
|
|
50
|
+
const fileSha256 = hasher.digest();
|
|
51
|
+
logger?.debug('hashed data for raw upload');
|
|
52
|
+
return {
|
|
53
|
+
filePath: filePath,
|
|
54
|
+
fileSha256,
|
|
55
|
+
fileLength
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
fileWriteStream.destroy();
|
|
60
|
+
stream.destroy();
|
|
61
|
+
try {
|
|
62
|
+
await fs.unlink(filePath);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
//
|
|
66
|
+
}
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
85
70
|
/** generates all the keys required to encrypt/decrypt & sign a media message */
|
|
86
|
-
async function getMediaKeys(buffer, mediaType) {
|
|
71
|
+
export async function getMediaKeys(buffer, mediaType) {
|
|
87
72
|
if (!buffer) {
|
|
88
|
-
throw new
|
|
73
|
+
throw new Boom('Cannot derive from empty media key');
|
|
89
74
|
}
|
|
90
75
|
if (typeof buffer === 'string') {
|
|
91
76
|
buffer = Buffer.from(buffer.replace('data:;base64,', ''), 'base64');
|
|
92
77
|
}
|
|
93
78
|
// expand using HKDF to 112 bytes, also pass in the relevant app info
|
|
94
|
-
const expandedMediaKey = await
|
|
79
|
+
const expandedMediaKey = await hkdf(buffer, 112, { info: hkdfInfoKey(mediaType) });
|
|
95
80
|
return {
|
|
96
81
|
iv: expandedMediaKey.slice(0, 16),
|
|
97
82
|
cipherKey: expandedMediaKey.slice(16, 48),
|
|
98
|
-
macKey: expandedMediaKey.slice(48, 80)
|
|
83
|
+
macKey: expandedMediaKey.slice(48, 80)
|
|
99
84
|
};
|
|
100
85
|
}
|
|
101
86
|
/** Extracts video thumb using FFMPEG */
|
|
102
87
|
const extractVideoThumb = async (path, destPath, time, size) => new Promise((resolve, reject) => {
|
|
103
88
|
const cmd = `ffmpeg -ss ${time} -i ${path} -y -vf scale=${size.width}:-1 -vframes 1 -f image2 ${destPath}`;
|
|
104
|
-
|
|
89
|
+
exec(cmd, err => {
|
|
105
90
|
if (err) {
|
|
106
91
|
reject(err);
|
|
107
92
|
}
|
|
@@ -110,135 +95,119 @@ const extractVideoThumb = async (path, destPath, time, size) => new Promise((res
|
|
|
110
95
|
}
|
|
111
96
|
});
|
|
112
97
|
});
|
|
113
|
-
const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
98
|
+
export const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
99
|
+
// TODO: Move entirely to sharp, removing jimp as it supports readable streams
|
|
100
|
+
// This will have positive speed and performance impacts as well as minimizing RAM usage.
|
|
101
|
+
if (bufferOrFilePath instanceof Readable) {
|
|
102
|
+
bufferOrFilePath = await toBuffer(bufferOrFilePath);
|
|
117
103
|
}
|
|
118
104
|
const lib = await getImageProcessingLibrary();
|
|
119
|
-
if ('sharp' in lib && typeof
|
|
105
|
+
if ('sharp' in lib && typeof lib.sharp?.default === 'function') {
|
|
120
106
|
const img = lib.sharp.default(bufferOrFilePath);
|
|
121
107
|
const dimensions = await img.metadata();
|
|
122
|
-
const buffer = await img
|
|
123
|
-
.resize(width)
|
|
124
|
-
.jpeg({ quality: 50 })
|
|
125
|
-
.toBuffer();
|
|
108
|
+
const buffer = await img.resize(width).jpeg({ quality: 50 }).toBuffer();
|
|
126
109
|
return {
|
|
127
110
|
buffer,
|
|
128
111
|
original: {
|
|
129
112
|
width: dimensions.width,
|
|
130
|
-
height: dimensions.height
|
|
131
|
-
}
|
|
113
|
+
height: dimensions.height
|
|
114
|
+
}
|
|
132
115
|
};
|
|
133
116
|
}
|
|
134
|
-
else if ('jimp' in lib && typeof
|
|
135
|
-
const
|
|
136
|
-
const jimp = await read(bufferOrFilePath);
|
|
117
|
+
else if ('jimp' in lib && typeof lib.jimp?.Jimp === 'object') {
|
|
118
|
+
const jimp = await lib.jimp.Jimp.read(bufferOrFilePath);
|
|
137
119
|
const dimensions = {
|
|
138
|
-
width: jimp.
|
|
139
|
-
height: jimp.
|
|
120
|
+
width: jimp.width,
|
|
121
|
+
height: jimp.height
|
|
140
122
|
};
|
|
141
123
|
const buffer = await jimp
|
|
142
|
-
.
|
|
143
|
-
.
|
|
144
|
-
.getBufferAsync(MIME_JPEG);
|
|
124
|
+
.resize({ w: width, mode: lib.jimp.ResizeStrategy.BILINEAR })
|
|
125
|
+
.getBuffer('image/jpeg', { quality: 50 });
|
|
145
126
|
return {
|
|
146
127
|
buffer,
|
|
147
128
|
original: dimensions
|
|
148
129
|
};
|
|
149
130
|
}
|
|
150
131
|
else {
|
|
151
|
-
throw new
|
|
132
|
+
throw new Boom('No image processing library available');
|
|
152
133
|
}
|
|
153
134
|
};
|
|
154
|
-
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
.replace(/\=+$/, '')));
|
|
159
|
-
exports.encodeBase64EncodedStringForUpload = encodeBase64EncodedStringForUpload;
|
|
160
|
-
const generateProfilePicture = async (mediaUpload) => {
|
|
161
|
-
var _a, _b;
|
|
162
|
-
let bufferOrFilePath;
|
|
135
|
+
export const encodeBase64EncodedStringForUpload = (b64) => encodeURIComponent(b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, ''));
|
|
136
|
+
export const generateProfilePicture = async (mediaUpload, dimensions) => {
|
|
137
|
+
let buffer;
|
|
138
|
+
const { width: w = 640, height: h = 640 } = dimensions || {};
|
|
163
139
|
if (Buffer.isBuffer(mediaUpload)) {
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
else if ('url' in mediaUpload) {
|
|
167
|
-
bufferOrFilePath = mediaUpload.url.toString();
|
|
140
|
+
buffer = mediaUpload;
|
|
168
141
|
}
|
|
169
142
|
else {
|
|
170
|
-
|
|
143
|
+
// Use getStream to handle all WAMediaUpload types (Buffer, Stream, URL)
|
|
144
|
+
const { stream } = await getStream(mediaUpload);
|
|
145
|
+
// Convert the resulting stream to a buffer
|
|
146
|
+
buffer = await toBuffer(stream);
|
|
171
147
|
}
|
|
172
148
|
const lib = await getImageProcessingLibrary();
|
|
173
149
|
let img;
|
|
174
|
-
if ('sharp' in lib && typeof
|
|
175
|
-
img = lib.sharp
|
|
176
|
-
.
|
|
150
|
+
if ('sharp' in lib && typeof lib.sharp?.default === 'function') {
|
|
151
|
+
img = lib.sharp
|
|
152
|
+
.default(buffer)
|
|
153
|
+
.resize(w, h)
|
|
177
154
|
.jpeg({
|
|
178
|
-
quality: 50
|
|
155
|
+
quality: 50
|
|
179
156
|
})
|
|
180
157
|
.toBuffer();
|
|
181
158
|
}
|
|
182
|
-
else if ('jimp' in lib && typeof
|
|
183
|
-
const
|
|
184
|
-
const
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
img = cropped
|
|
188
|
-
.quality(50)
|
|
189
|
-
.resize(640, 640, RESIZE_BILINEAR)
|
|
190
|
-
.getBufferAsync(MIME_JPEG);
|
|
159
|
+
else if ('jimp' in lib && typeof lib.jimp?.Jimp === 'object') {
|
|
160
|
+
const jimp = await lib.jimp.Jimp.read(buffer);
|
|
161
|
+
const min = Math.min(jimp.width, jimp.height);
|
|
162
|
+
const cropped = jimp.crop({ x: 0, y: 0, w: min, h: min });
|
|
163
|
+
img = cropped.resize({ w, h, mode: lib.jimp.ResizeStrategy.BILINEAR }).getBuffer('image/jpeg', { quality: 50 });
|
|
191
164
|
}
|
|
192
165
|
else {
|
|
193
|
-
throw new
|
|
166
|
+
throw new Boom('No image processing library available');
|
|
194
167
|
}
|
|
195
168
|
return {
|
|
196
|
-
img: await img
|
|
169
|
+
img: await img
|
|
197
170
|
};
|
|
198
171
|
};
|
|
199
|
-
exports.generateProfilePicture = generateProfilePicture;
|
|
200
172
|
/** gets the SHA256 of the given media message */
|
|
201
|
-
const mediaMessageSHA256B64 = (message) => {
|
|
173
|
+
export const mediaMessageSHA256B64 = (message) => {
|
|
202
174
|
const media = Object.values(message)[0];
|
|
203
|
-
return
|
|
175
|
+
return media?.fileSha256 && Buffer.from(media.fileSha256).toString('base64');
|
|
204
176
|
};
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
const musicMetadata = await Promise.resolve().then(() => __importStar(require('music-metadata')));
|
|
177
|
+
export async function getAudioDuration(buffer) {
|
|
178
|
+
const musicMetadata = await import('music-metadata');
|
|
208
179
|
let metadata;
|
|
180
|
+
const options = {
|
|
181
|
+
duration: true
|
|
182
|
+
};
|
|
209
183
|
if (Buffer.isBuffer(buffer)) {
|
|
210
|
-
metadata = await musicMetadata.parseBuffer(buffer, undefined,
|
|
184
|
+
metadata = await musicMetadata.parseBuffer(buffer, undefined, options);
|
|
211
185
|
}
|
|
212
186
|
else if (typeof buffer === 'string') {
|
|
213
|
-
|
|
214
|
-
try {
|
|
215
|
-
metadata = await musicMetadata.parseStream(rStream, undefined, { duration: true });
|
|
216
|
-
}
|
|
217
|
-
finally {
|
|
218
|
-
rStream.destroy();
|
|
219
|
-
}
|
|
187
|
+
metadata = await musicMetadata.parseFile(buffer, options);
|
|
220
188
|
}
|
|
221
189
|
else {
|
|
222
|
-
metadata = await musicMetadata.parseStream(buffer, undefined,
|
|
190
|
+
metadata = await musicMetadata.parseStream(buffer, undefined, options);
|
|
223
191
|
}
|
|
224
192
|
return metadata.format.duration;
|
|
225
193
|
}
|
|
226
194
|
/**
|
|
227
195
|
referenced from and modifying https://github.com/wppconnect-team/wa-js/blob/main/src/chat/functions/prepareAudioWaveform.ts
|
|
228
196
|
*/
|
|
229
|
-
async function getAudioWaveform(buffer, logger) {
|
|
197
|
+
export async function getAudioWaveform(buffer, logger) {
|
|
230
198
|
try {
|
|
231
|
-
|
|
199
|
+
// @ts-ignore
|
|
200
|
+
const { default: decoder } = await import('audio-decode');
|
|
232
201
|
let audioData;
|
|
233
202
|
if (Buffer.isBuffer(buffer)) {
|
|
234
203
|
audioData = buffer;
|
|
235
204
|
}
|
|
236
205
|
else if (typeof buffer === 'string') {
|
|
237
|
-
const rStream =
|
|
238
|
-
audioData = await
|
|
206
|
+
const rStream = createReadStream(buffer);
|
|
207
|
+
audioData = await toBuffer(rStream);
|
|
239
208
|
}
|
|
240
209
|
else {
|
|
241
|
-
audioData = await
|
|
210
|
+
audioData = await toBuffer(buffer);
|
|
242
211
|
}
|
|
243
212
|
const audioBuffer = await decoder(audioData);
|
|
244
213
|
const rawData = audioBuffer.getChannelData(0); // We only need to work with one channel of data
|
|
@@ -255,23 +224,22 @@ async function getAudioWaveform(buffer, logger) {
|
|
|
255
224
|
}
|
|
256
225
|
// This guarantees that the largest data point will be set to 1, and the rest of the data will scale proportionally.
|
|
257
226
|
const multiplier = Math.pow(Math.max(...filteredData), -1);
|
|
258
|
-
const normalizedData = filteredData.map(
|
|
227
|
+
const normalizedData = filteredData.map(n => n * multiplier);
|
|
259
228
|
// Generate waveform like WhatsApp
|
|
260
|
-
const waveform = new Uint8Array(normalizedData.map(
|
|
229
|
+
const waveform = new Uint8Array(normalizedData.map(n => Math.floor(100 * n)));
|
|
261
230
|
return waveform;
|
|
262
231
|
}
|
|
263
232
|
catch (e) {
|
|
264
|
-
logger
|
|
233
|
+
logger?.debug('Failed to generate waveform: ' + e);
|
|
265
234
|
}
|
|
266
235
|
}
|
|
267
|
-
const toReadable = (buffer) => {
|
|
268
|
-
const readable = new
|
|
236
|
+
export const toReadable = (buffer) => {
|
|
237
|
+
const readable = new Readable({ read: () => { } });
|
|
269
238
|
readable.push(buffer);
|
|
270
239
|
readable.push(null);
|
|
271
240
|
return readable;
|
|
272
241
|
};
|
|
273
|
-
|
|
274
|
-
const toBuffer = async (stream) => {
|
|
242
|
+
export const toBuffer = async (stream) => {
|
|
275
243
|
const chunks = [];
|
|
276
244
|
for await (const chunk of stream) {
|
|
277
245
|
chunks.push(chunk);
|
|
@@ -279,45 +247,47 @@ const toBuffer = async (stream) => {
|
|
|
279
247
|
stream.destroy();
|
|
280
248
|
return Buffer.concat(chunks);
|
|
281
249
|
};
|
|
282
|
-
|
|
283
|
-
const getStream = async (item, opts) => {
|
|
250
|
+
export const getStream = async (item, opts) => {
|
|
284
251
|
if (Buffer.isBuffer(item)) {
|
|
285
|
-
return { stream:
|
|
252
|
+
return { stream: toReadable(item), type: 'buffer' };
|
|
286
253
|
}
|
|
287
254
|
if ('stream' in item) {
|
|
288
255
|
return { stream: item.stream, type: 'readable' };
|
|
289
256
|
}
|
|
290
|
-
|
|
291
|
-
|
|
257
|
+
const urlStr = item.url.toString();
|
|
258
|
+
if (urlStr.startsWith('data:')) {
|
|
259
|
+
const buffer = Buffer.from(urlStr.split(',')[1], 'base64');
|
|
260
|
+
return { stream: toReadable(buffer), type: 'buffer' };
|
|
292
261
|
}
|
|
293
|
-
|
|
262
|
+
if (urlStr.startsWith('http://') || urlStr.startsWith('https://')) {
|
|
263
|
+
return { stream: await getHttpStream(item.url, opts), type: 'remote' };
|
|
264
|
+
}
|
|
265
|
+
return { stream: createReadStream(item.url), type: 'file' };
|
|
294
266
|
};
|
|
295
|
-
exports.getStream = getStream;
|
|
296
267
|
/** generates a thumbnail for a given media, if required */
|
|
297
|
-
async function generateThumbnail(file, mediaType, options) {
|
|
298
|
-
var _a;
|
|
268
|
+
export async function generateThumbnail(file, mediaType, options) {
|
|
299
269
|
let thumbnail;
|
|
300
270
|
let originalImageDimensions;
|
|
301
271
|
if (mediaType === 'image') {
|
|
302
|
-
const { buffer, original } = await
|
|
272
|
+
const { buffer, original } = await extractImageThumb(file);
|
|
303
273
|
thumbnail = buffer.toString('base64');
|
|
304
274
|
if (original.width && original.height) {
|
|
305
275
|
originalImageDimensions = {
|
|
306
276
|
width: original.width,
|
|
307
|
-
height: original.height
|
|
277
|
+
height: original.height
|
|
308
278
|
};
|
|
309
279
|
}
|
|
310
280
|
}
|
|
311
281
|
else if (mediaType === 'video') {
|
|
312
|
-
const imgFilename =
|
|
282
|
+
const imgFilename = join(getTmpFilesDirectory(), generateMessageIDV2() + '.jpg');
|
|
313
283
|
try {
|
|
314
284
|
await extractVideoThumb(file, imgFilename, '00:00:00', { width: 32, height: 32 });
|
|
315
|
-
const buff = await
|
|
285
|
+
const buff = await fs.readFile(imgFilename);
|
|
316
286
|
thumbnail = buff.toString('base64');
|
|
317
|
-
await
|
|
287
|
+
await fs.unlink(imgFilename);
|
|
318
288
|
}
|
|
319
289
|
catch (err) {
|
|
320
|
-
|
|
290
|
+
options.logger?.debug('could not generate video thumb: ' + err);
|
|
321
291
|
}
|
|
322
292
|
}
|
|
323
293
|
return {
|
|
@@ -325,24 +295,22 @@ async function generateThumbnail(file, mediaType, options) {
|
|
|
325
295
|
originalImageDimensions
|
|
326
296
|
};
|
|
327
297
|
}
|
|
328
|
-
const getHttpStream = async (url, options = {}) => {
|
|
329
|
-
const fetched = await
|
|
298
|
+
export const getHttpStream = async (url, options = {}) => {
|
|
299
|
+
const fetched = await axios.get(url.toString(), { ...options, responseType: 'stream' });
|
|
330
300
|
return fetched.data;
|
|
331
301
|
};
|
|
332
|
-
|
|
333
|
-
const
|
|
334
|
-
|
|
335
|
-
const { stream, type } = await (0, exports.getStream)(media, opts);
|
|
336
|
-
logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
|
|
302
|
+
export const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
|
|
303
|
+
const { stream, type } = await getStream(media, opts);
|
|
304
|
+
logger?.debug('fetched media stream');
|
|
337
305
|
const mediaKey = Crypto.randomBytes(32);
|
|
338
306
|
const { cipherKey, iv, macKey } = await getMediaKeys(mediaKey, mediaType);
|
|
339
|
-
const encFilePath =
|
|
340
|
-
const encFileWriteStream =
|
|
307
|
+
const encFilePath = join(getTmpFilesDirectory(), mediaType + generateMessageIDV2() + '-enc');
|
|
308
|
+
const encFileWriteStream = createWriteStream(encFilePath);
|
|
341
309
|
let originalFileStream;
|
|
342
310
|
let originalFilePath;
|
|
343
311
|
if (saveOriginalFileIfRequired) {
|
|
344
|
-
originalFilePath =
|
|
345
|
-
originalFileStream =
|
|
312
|
+
originalFilePath = join(getTmpFilesDirectory(), mediaType + generateMessageIDV2() + '-original');
|
|
313
|
+
originalFileStream = createWriteStream(originalFilePath);
|
|
346
314
|
}
|
|
347
315
|
let fileLength = 0;
|
|
348
316
|
const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv);
|
|
@@ -357,16 +325,14 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
357
325
|
try {
|
|
358
326
|
for await (const data of stream) {
|
|
359
327
|
fileLength += data.length;
|
|
360
|
-
if (type === 'remote'
|
|
361
|
-
|
|
362
|
-
&& fileLength + data.length > opts.maxContentLength) {
|
|
363
|
-
throw new boom_1.Boom(`content length exceeded when encrypting "${type}"`, {
|
|
328
|
+
if (type === 'remote' && opts?.maxContentLength && fileLength + data.length > opts.maxContentLength) {
|
|
329
|
+
throw new Boom(`content length exceeded when encrypting "${type}"`, {
|
|
364
330
|
data: { media, type }
|
|
365
331
|
});
|
|
366
332
|
}
|
|
367
333
|
if (originalFileStream) {
|
|
368
334
|
if (!originalFileStream.write(data)) {
|
|
369
|
-
await
|
|
335
|
+
await once(originalFileStream, 'drain');
|
|
370
336
|
}
|
|
371
337
|
}
|
|
372
338
|
sha256Plain.update(data);
|
|
@@ -379,9 +345,9 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
379
345
|
const fileEncSha256 = sha256Enc.digest();
|
|
380
346
|
encFileWriteStream.write(mac);
|
|
381
347
|
encFileWriteStream.end();
|
|
382
|
-
|
|
348
|
+
originalFileStream?.end?.();
|
|
383
349
|
stream.destroy();
|
|
384
|
-
logger
|
|
350
|
+
logger?.debug('encrypted data successfully');
|
|
385
351
|
return {
|
|
386
352
|
mediaKey,
|
|
387
353
|
originalFilePath,
|
|
@@ -395,43 +361,44 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
395
361
|
catch (error) {
|
|
396
362
|
// destroy all streams with error
|
|
397
363
|
encFileWriteStream.destroy();
|
|
398
|
-
|
|
364
|
+
originalFileStream?.destroy?.();
|
|
399
365
|
aes.destroy();
|
|
400
366
|
hmac.destroy();
|
|
401
367
|
sha256Plain.destroy();
|
|
402
368
|
sha256Enc.destroy();
|
|
403
369
|
stream.destroy();
|
|
404
370
|
try {
|
|
405
|
-
await
|
|
371
|
+
await fs.unlink(encFilePath);
|
|
406
372
|
if (originalFilePath) {
|
|
407
|
-
await
|
|
373
|
+
await fs.unlink(originalFilePath);
|
|
408
374
|
}
|
|
409
375
|
}
|
|
410
376
|
catch (err) {
|
|
411
|
-
logger
|
|
377
|
+
logger?.error({ err }, 'failed deleting tmp files');
|
|
412
378
|
}
|
|
413
379
|
throw error;
|
|
414
380
|
}
|
|
415
381
|
};
|
|
416
|
-
exports.encryptedStream = encryptedStream;
|
|
417
382
|
const DEF_HOST = 'mmg.whatsapp.net';
|
|
418
383
|
const AES_CHUNK_SIZE = 16;
|
|
419
384
|
const toSmallestChunkSize = (num) => {
|
|
420
385
|
return Math.floor(num / AES_CHUNK_SIZE) * AES_CHUNK_SIZE;
|
|
421
386
|
};
|
|
422
|
-
const getUrlFromDirectPath = (directPath) => `https://${DEF_HOST}${directPath}`;
|
|
423
|
-
|
|
424
|
-
const
|
|
425
|
-
const downloadUrl = url
|
|
387
|
+
export const getUrlFromDirectPath = (directPath) => `https://${DEF_HOST}${directPath}`;
|
|
388
|
+
export const downloadContentFromMessage = async ({ mediaKey, directPath, url }, type, opts = {}) => {
|
|
389
|
+
const isValidMediaUrl = url?.startsWith('https://mmg.whatsapp.net/');
|
|
390
|
+
const downloadUrl = isValidMediaUrl ? url : getUrlFromDirectPath(directPath);
|
|
391
|
+
if (!downloadUrl) {
|
|
392
|
+
throw new Boom('No valid media URL or directPath present in message', { statusCode: 400 });
|
|
393
|
+
}
|
|
426
394
|
const keys = await getMediaKeys(mediaKey, type);
|
|
427
|
-
return
|
|
395
|
+
return downloadEncryptedContent(downloadUrl, keys, opts);
|
|
428
396
|
};
|
|
429
|
-
exports.downloadContentFromMessage = downloadContentFromMessage;
|
|
430
397
|
/**
|
|
431
398
|
* Decrypts and downloads an AES256-CBC encrypted file given the keys.
|
|
432
399
|
* Assumes the SHA256 of the plaintext is appended to the end of the ciphertext
|
|
433
400
|
* */
|
|
434
|
-
const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startByte, endByte, options } = {}) => {
|
|
401
|
+
export const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startByte, endByte, options } = {}) => {
|
|
435
402
|
let bytesFetched = 0;
|
|
436
403
|
let startChunk = 0;
|
|
437
404
|
let firstBlockIsIV = false;
|
|
@@ -446,8 +413,8 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
|
|
|
446
413
|
}
|
|
447
414
|
const endChunk = endByte ? toSmallestChunkSize(endByte || 0) + AES_CHUNK_SIZE : undefined;
|
|
448
415
|
const headers = {
|
|
449
|
-
...(options
|
|
450
|
-
Origin:
|
|
416
|
+
...(options?.headers || {}),
|
|
417
|
+
Origin: DEFAULT_ORIGIN
|
|
451
418
|
};
|
|
452
419
|
if (startChunk || endChunk) {
|
|
453
420
|
headers.Range = `bytes=${startChunk}-`;
|
|
@@ -456,11 +423,11 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
|
|
|
456
423
|
}
|
|
457
424
|
}
|
|
458
425
|
// download the message
|
|
459
|
-
const fetched = await
|
|
460
|
-
...options || {},
|
|
426
|
+
const fetched = await getHttpStream(downloadUrl, {
|
|
427
|
+
...(options || {}),
|
|
461
428
|
headers,
|
|
462
429
|
maxBodyLength: Infinity,
|
|
463
|
-
maxContentLength: Infinity
|
|
430
|
+
maxContentLength: Infinity
|
|
464
431
|
});
|
|
465
432
|
let remainingBytes = Buffer.from([]);
|
|
466
433
|
let aes;
|
|
@@ -475,7 +442,7 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
|
|
|
475
442
|
push(bytes);
|
|
476
443
|
}
|
|
477
444
|
};
|
|
478
|
-
const output = new
|
|
445
|
+
const output = new Transform({
|
|
479
446
|
transform(chunk, _, callback) {
|
|
480
447
|
let data = Buffer.concat([remainingBytes, chunk]);
|
|
481
448
|
const decryptLength = toSmallestChunkSize(data.length);
|
|
@@ -510,18 +477,15 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
|
|
|
510
477
|
catch (error) {
|
|
511
478
|
callback(error);
|
|
512
479
|
}
|
|
513
|
-
}
|
|
480
|
+
}
|
|
514
481
|
});
|
|
515
482
|
return fetched.pipe(output, { end: true });
|
|
516
483
|
};
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
const getExtension = (mimetype) => mimetype.split(';')[0].split('/')[1];
|
|
484
|
+
export function extensionForMediaMessage(message) {
|
|
485
|
+
const getExtension = (mimetype) => mimetype.split(';')[0]?.split('/')[1];
|
|
520
486
|
const type = Object.keys(message)[0];
|
|
521
487
|
let extension;
|
|
522
|
-
if (type === 'locationMessage' ||
|
|
523
|
-
type === 'liveLocationMessage' ||
|
|
524
|
-
type === 'productMessage') {
|
|
488
|
+
if (type === 'locationMessage' || type === 'liveLocationMessage' || type === 'productMessage') {
|
|
525
489
|
extension = '.jpeg';
|
|
526
490
|
}
|
|
527
491
|
else {
|
|
@@ -530,37 +494,36 @@ function extensionForMediaMessage(message) {
|
|
|
530
494
|
}
|
|
531
495
|
return extension;
|
|
532
496
|
}
|
|
533
|
-
const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
497
|
+
export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
534
498
|
return async (filePath, { mediaType, fileEncSha256B64, timeoutMs }) => {
|
|
535
|
-
var _a, _b;
|
|
536
499
|
// send a query JSON to obtain the url & auth token to upload our media
|
|
537
500
|
let uploadInfo = await refreshMediaConn(false);
|
|
538
501
|
let urls;
|
|
539
502
|
const hosts = [...customUploadHosts, ...uploadInfo.hosts];
|
|
540
|
-
fileEncSha256B64 =
|
|
503
|
+
fileEncSha256B64 = encodeBase64EncodedStringForUpload(fileEncSha256B64);
|
|
541
504
|
for (const { hostname } of hosts) {
|
|
542
505
|
logger.debug(`uploading to "${hostname}"`);
|
|
543
506
|
const auth = encodeURIComponent(uploadInfo.auth); // the auth token
|
|
544
|
-
const url = `https://${hostname}${
|
|
507
|
+
const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
|
|
545
508
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
546
509
|
let result;
|
|
547
510
|
try {
|
|
548
|
-
const body = await
|
|
511
|
+
const body = await axios.post(url, createReadStream(filePath), {
|
|
549
512
|
...options,
|
|
550
513
|
maxRedirects: 0,
|
|
551
514
|
headers: {
|
|
552
|
-
...options.headers || {},
|
|
515
|
+
...(options.headers || {}),
|
|
553
516
|
'Content-Type': 'application/octet-stream',
|
|
554
|
-
|
|
517
|
+
Origin: DEFAULT_ORIGIN
|
|
555
518
|
},
|
|
556
519
|
httpsAgent: fetchAgent,
|
|
557
520
|
timeout: timeoutMs,
|
|
558
521
|
responseType: 'json',
|
|
559
522
|
maxBodyLength: Infinity,
|
|
560
|
-
maxContentLength: Infinity
|
|
523
|
+
maxContentLength: Infinity
|
|
561
524
|
});
|
|
562
525
|
result = body.data;
|
|
563
|
-
if (
|
|
526
|
+
if (result?.url || result?.directPath) {
|
|
564
527
|
urls = {
|
|
565
528
|
mediaUrl: result.url,
|
|
566
529
|
directPath: result.direct_path
|
|
@@ -573,37 +536,36 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
|
|
|
573
536
|
}
|
|
574
537
|
}
|
|
575
538
|
catch (error) {
|
|
576
|
-
if (
|
|
577
|
-
result =
|
|
539
|
+
if (axios.isAxiosError(error)) {
|
|
540
|
+
result = error.response?.data;
|
|
578
541
|
}
|
|
579
|
-
const isLast = hostname ===
|
|
542
|
+
const isLast = hostname === hosts[uploadInfo.hosts.length - 1]?.hostname;
|
|
580
543
|
logger.warn({ trace: error.stack, uploadResult: result }, `Error in uploading to ${hostname} ${isLast ? '' : ', retrying...'}`);
|
|
581
544
|
}
|
|
582
545
|
}
|
|
583
546
|
if (!urls) {
|
|
584
|
-
throw new
|
|
547
|
+
throw new Boom('Media upload failed on all hosts', { statusCode: 500 });
|
|
585
548
|
}
|
|
586
549
|
return urls;
|
|
587
550
|
};
|
|
588
551
|
};
|
|
589
|
-
exports.getWAUploadToServer = getWAUploadToServer;
|
|
590
552
|
const getMediaRetryKey = (mediaKey) => {
|
|
591
|
-
return
|
|
553
|
+
return hkdf(mediaKey, 32, { info: 'WhatsApp Media Retry Notification' });
|
|
592
554
|
};
|
|
593
555
|
/**
|
|
594
556
|
* Generate a binary node that will request the phone to re-upload the media & return the newly uploaded URL
|
|
595
557
|
*/
|
|
596
|
-
const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
|
|
558
|
+
export const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
|
|
597
559
|
const recp = { stanzaId: key.id };
|
|
598
|
-
const recpBuffer =
|
|
560
|
+
const recpBuffer = proto.ServerErrorReceipt.encode(recp).finish();
|
|
599
561
|
const iv = Crypto.randomBytes(12);
|
|
600
562
|
const retryKey = await getMediaRetryKey(mediaKey);
|
|
601
|
-
const ciphertext =
|
|
563
|
+
const ciphertext = aesEncryptGCM(recpBuffer, retryKey, iv, Buffer.from(key.id));
|
|
602
564
|
const req = {
|
|
603
565
|
tag: 'receipt',
|
|
604
566
|
attrs: {
|
|
605
567
|
id: key.id,
|
|
606
|
-
to:
|
|
568
|
+
to: jidNormalizedUser(meId),
|
|
607
569
|
type: 'server-error'
|
|
608
570
|
},
|
|
609
571
|
content: [
|
|
@@ -622,7 +584,7 @@ const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
|
|
|
622
584
|
tag: 'rmr',
|
|
623
585
|
attrs: {
|
|
624
586
|
jid: key.remoteJid,
|
|
625
|
-
|
|
587
|
+
from_me: (!!key.fromMe).toString(),
|
|
626
588
|
// @ts-ignore
|
|
627
589
|
participant: key.participant || undefined
|
|
628
590
|
}
|
|
@@ -631,9 +593,8 @@ const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
|
|
|
631
593
|
};
|
|
632
594
|
return req;
|
|
633
595
|
};
|
|
634
|
-
|
|
635
|
-
const
|
|
636
|
-
const rmrNode = (0, WABinary_1.getBinaryNodeChild)(node, 'rmr');
|
|
596
|
+
export const decodeMediaRetryNode = (node) => {
|
|
597
|
+
const rmrNode = getBinaryNodeChild(node, 'rmr');
|
|
637
598
|
const event = {
|
|
638
599
|
key: {
|
|
639
600
|
id: node.attrs.id,
|
|
@@ -642,36 +603,37 @@ const decodeMediaRetryNode = (node) => {
|
|
|
642
603
|
participant: rmrNode.attrs.participant
|
|
643
604
|
}
|
|
644
605
|
};
|
|
645
|
-
const errorNode =
|
|
606
|
+
const errorNode = getBinaryNodeChild(node, 'error');
|
|
646
607
|
if (errorNode) {
|
|
647
608
|
const errorCode = +errorNode.attrs.code;
|
|
648
|
-
event.error = new
|
|
609
|
+
event.error = new Boom(`Failed to re-upload media (${errorCode})`, {
|
|
610
|
+
data: errorNode.attrs,
|
|
611
|
+
statusCode: getStatusCodeForMediaRetry(errorCode)
|
|
612
|
+
});
|
|
649
613
|
}
|
|
650
614
|
else {
|
|
651
|
-
const encryptedInfoNode =
|
|
652
|
-
const ciphertext =
|
|
653
|
-
const iv =
|
|
615
|
+
const encryptedInfoNode = getBinaryNodeChild(node, 'encrypt');
|
|
616
|
+
const ciphertext = getBinaryNodeChildBuffer(encryptedInfoNode, 'enc_p');
|
|
617
|
+
const iv = getBinaryNodeChildBuffer(encryptedInfoNode, 'enc_iv');
|
|
654
618
|
if (ciphertext && iv) {
|
|
655
619
|
event.media = { ciphertext, iv };
|
|
656
620
|
}
|
|
657
621
|
else {
|
|
658
|
-
event.error = new
|
|
622
|
+
event.error = new Boom('Failed to re-upload media (missing ciphertext)', { statusCode: 404 });
|
|
659
623
|
}
|
|
660
624
|
}
|
|
661
625
|
return event;
|
|
662
626
|
};
|
|
663
|
-
|
|
664
|
-
const decryptMediaRetryData = async ({ ciphertext, iv }, mediaKey, msgId) => {
|
|
627
|
+
export const decryptMediaRetryData = async ({ ciphertext, iv }, mediaKey, msgId) => {
|
|
665
628
|
const retryKey = await getMediaRetryKey(mediaKey);
|
|
666
|
-
const plaintext =
|
|
667
|
-
return
|
|
629
|
+
const plaintext = aesDecryptGCM(ciphertext, retryKey, iv, Buffer.from(msgId));
|
|
630
|
+
return proto.MediaRetryNotification.decode(plaintext);
|
|
668
631
|
};
|
|
669
|
-
|
|
670
|
-
const getStatusCodeForMediaRetry = (code) => MEDIA_RETRY_STATUS_MAP[code];
|
|
671
|
-
exports.getStatusCodeForMediaRetry = getStatusCodeForMediaRetry;
|
|
632
|
+
export const getStatusCodeForMediaRetry = (code) => MEDIA_RETRY_STATUS_MAP[code];
|
|
672
633
|
const MEDIA_RETRY_STATUS_MAP = {
|
|
673
|
-
[
|
|
674
|
-
[
|
|
675
|
-
[
|
|
676
|
-
[
|
|
634
|
+
[proto.MediaRetryNotification.ResultType.SUCCESS]: 200,
|
|
635
|
+
[proto.MediaRetryNotification.ResultType.DECRYPTION_ERROR]: 412,
|
|
636
|
+
[proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
|
|
637
|
+
[proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418
|
|
677
638
|
};
|
|
639
|
+
//# sourceMappingURL=messages-media.js.map
|