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