@d0v3riz/baileys 6.7.20 → 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/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 +2 -0
- package/lib/Signal/Group/queue-job.d.ts.map +1 -0
- package/lib/Signal/Group/queue-job.js +5 -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 +89 -59
- 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 +28 -21
- package/lib/Socket/chats.d.ts.map +1 -0
- package/lib/Socket/chats.js +195 -142
- 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 +43 -35
- package/lib/Socket/groups.d.ts.map +1 -0
- package/lib/Socket/groups.js +57 -63
- package/lib/Socket/groups.js.map +1 -0
- package/lib/Socket/index.d.ts +125 -65
- 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 +75 -45
- package/lib/Socket/messages-recv.d.ts.map +1 -0
- package/lib/Socket/messages-recv.js +303 -156
- package/lib/Socket/messages-recv.js.map +1 -0
- package/lib/Socket/messages-send.d.ts +72 -42
- package/lib/Socket/messages-send.d.ts.map +1 -0
- package/lib/Socket/messages-send.js +100 -83
- 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 +13 -12
- package/lib/Socket/socket.d.ts.map +1 -0
- package/lib/Socket/socket.js +135 -116
- package/lib/Socket/socket.js.map +1 -0
- package/lib/Socket/usync.d.ts +15 -14
- 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 +13 -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 +37 -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 -1
- 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 +15 -8
- 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 +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 -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 +24 -33
- 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 +144 -138
- 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 +7 -7
- package/lib/Utils/decode-wa-message.d.ts.map +1 -0
- package/lib/Utils/decode-wa-message.js +42 -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 +10 -8
- package/lib/Utils/generics.d.ts.map +1 -0
- package/lib/Utils/generics.js +88 -111
- 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 -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 +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 +20 -11
- package/lib/Utils/messages-media.d.ts.map +1 -0
- package/lib/Utils/messages-media.js +191 -214
- package/lib/Utils/messages-media.js.map +1 -0
- package/lib/Utils/messages.d.ts +8 -7
- package/lib/Utils/messages.d.ts.map +1 -0
- package/lib/Utils/messages.js +218 -197
- 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 +7 -10
- 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 +28 -28
|
@@ -1,97 +1,82 @@
|
|
|
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),
|
|
@@ -101,7 +86,7 @@ async function getMediaKeys(buffer, mediaType) {
|
|
|
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,13 +95,14 @@ 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
108
|
const buffer = await img.resize(width).jpeg({ quality: 50 }).toBuffer();
|
|
@@ -128,72 +114,68 @@ const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
|
128
114
|
}
|
|
129
115
|
};
|
|
130
116
|
}
|
|
131
|
-
else if ('jimp' in lib && typeof
|
|
132
|
-
const
|
|
133
|
-
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);
|
|
134
119
|
const dimensions = {
|
|
135
|
-
width: jimp.
|
|
136
|
-
height: jimp.
|
|
120
|
+
width: jimp.width,
|
|
121
|
+
height: jimp.height
|
|
137
122
|
};
|
|
138
|
-
const buffer = await jimp
|
|
123
|
+
const buffer = await jimp
|
|
124
|
+
.resize({ w: width, mode: lib.jimp.ResizeStrategy.BILINEAR })
|
|
125
|
+
.getBuffer('image/jpeg', { quality: 50 });
|
|
139
126
|
return {
|
|
140
127
|
buffer,
|
|
141
128
|
original: dimensions
|
|
142
129
|
};
|
|
143
130
|
}
|
|
144
131
|
else {
|
|
145
|
-
throw new
|
|
132
|
+
throw new Boom('No image processing library available');
|
|
146
133
|
}
|
|
147
134
|
};
|
|
148
|
-
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
const
|
|
152
|
-
var _a, _b;
|
|
153
|
-
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 || {};
|
|
154
139
|
if (Buffer.isBuffer(mediaUpload)) {
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
else if ('url' in mediaUpload) {
|
|
158
|
-
bufferOrFilePath = mediaUpload.url.toString();
|
|
140
|
+
buffer = mediaUpload;
|
|
159
141
|
}
|
|
160
142
|
else {
|
|
161
|
-
|
|
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);
|
|
162
147
|
}
|
|
163
148
|
const lib = await getImageProcessingLibrary();
|
|
164
149
|
let img;
|
|
165
|
-
if ('sharp' in lib && typeof
|
|
150
|
+
if ('sharp' in lib && typeof lib.sharp?.default === 'function') {
|
|
166
151
|
img = lib.sharp
|
|
167
|
-
.default(
|
|
168
|
-
.resize(
|
|
152
|
+
.default(buffer)
|
|
153
|
+
.resize(w, h)
|
|
169
154
|
.jpeg({
|
|
170
155
|
quality: 50
|
|
171
156
|
})
|
|
172
157
|
.toBuffer();
|
|
173
158
|
}
|
|
174
|
-
else if ('jimp' in lib && typeof
|
|
175
|
-
const
|
|
176
|
-
const
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
img = cropped.quality(50).resize(640, 640, RESIZE_BILINEAR).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 });
|
|
180
164
|
}
|
|
181
165
|
else {
|
|
182
|
-
throw new
|
|
166
|
+
throw new Boom('No image processing library available');
|
|
183
167
|
}
|
|
184
168
|
return {
|
|
185
169
|
img: await img
|
|
186
170
|
};
|
|
187
171
|
};
|
|
188
|
-
exports.generateProfilePicture = generateProfilePicture;
|
|
189
172
|
/** gets the SHA256 of the given media message */
|
|
190
|
-
const mediaMessageSHA256B64 = (message) => {
|
|
173
|
+
export const mediaMessageSHA256B64 = (message) => {
|
|
191
174
|
const media = Object.values(message)[0];
|
|
192
|
-
return
|
|
175
|
+
return media?.fileSha256 && Buffer.from(media.fileSha256).toString('base64');
|
|
193
176
|
};
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const musicMetadata = await Promise.resolve().then(() => __importStar(require('music-metadata')));
|
|
177
|
+
export async function getAudioDuration(buffer) {
|
|
178
|
+
const musicMetadata = await import('music-metadata');
|
|
197
179
|
let metadata;
|
|
198
180
|
const options = {
|
|
199
181
|
duration: true
|
|
@@ -212,19 +194,20 @@ async function getAudioDuration(buffer) {
|
|
|
212
194
|
/**
|
|
213
195
|
referenced from and modifying https://github.com/wppconnect-team/wa-js/blob/main/src/chat/functions/prepareAudioWaveform.ts
|
|
214
196
|
*/
|
|
215
|
-
async function getAudioWaveform(buffer, logger) {
|
|
197
|
+
export async function getAudioWaveform(buffer, logger) {
|
|
216
198
|
try {
|
|
217
|
-
|
|
199
|
+
// @ts-ignore
|
|
200
|
+
const { default: decoder } = await import('audio-decode');
|
|
218
201
|
let audioData;
|
|
219
202
|
if (Buffer.isBuffer(buffer)) {
|
|
220
203
|
audioData = buffer;
|
|
221
204
|
}
|
|
222
205
|
else if (typeof buffer === 'string') {
|
|
223
|
-
const rStream =
|
|
224
|
-
audioData = await
|
|
206
|
+
const rStream = createReadStream(buffer);
|
|
207
|
+
audioData = await toBuffer(rStream);
|
|
225
208
|
}
|
|
226
209
|
else {
|
|
227
|
-
audioData = await
|
|
210
|
+
audioData = await toBuffer(buffer);
|
|
228
211
|
}
|
|
229
212
|
const audioBuffer = await decoder(audioData);
|
|
230
213
|
const rawData = audioBuffer.getChannelData(0); // We only need to work with one channel of data
|
|
@@ -247,17 +230,16 @@ async function getAudioWaveform(buffer, logger) {
|
|
|
247
230
|
return waveform;
|
|
248
231
|
}
|
|
249
232
|
catch (e) {
|
|
250
|
-
logger
|
|
233
|
+
logger?.debug('Failed to generate waveform: ' + e);
|
|
251
234
|
}
|
|
252
235
|
}
|
|
253
|
-
const toReadable = (buffer) => {
|
|
254
|
-
const readable = new
|
|
236
|
+
export const toReadable = (buffer) => {
|
|
237
|
+
const readable = new Readable({ read: () => { } });
|
|
255
238
|
readable.push(buffer);
|
|
256
239
|
readable.push(null);
|
|
257
240
|
return readable;
|
|
258
241
|
};
|
|
259
|
-
|
|
260
|
-
const toBuffer = async (stream) => {
|
|
242
|
+
export const toBuffer = async (stream) => {
|
|
261
243
|
const chunks = [];
|
|
262
244
|
for await (const chunk of stream) {
|
|
263
245
|
chunks.push(chunk);
|
|
@@ -265,27 +247,29 @@ const toBuffer = async (stream) => {
|
|
|
265
247
|
stream.destroy();
|
|
266
248
|
return Buffer.concat(chunks);
|
|
267
249
|
};
|
|
268
|
-
|
|
269
|
-
const getStream = async (item, opts) => {
|
|
250
|
+
export const getStream = async (item, opts) => {
|
|
270
251
|
if (Buffer.isBuffer(item)) {
|
|
271
|
-
return { stream:
|
|
252
|
+
return { stream: toReadable(item), type: 'buffer' };
|
|
272
253
|
}
|
|
273
254
|
if ('stream' in item) {
|
|
274
255
|
return { stream: item.stream, type: 'readable' };
|
|
275
256
|
}
|
|
276
|
-
|
|
277
|
-
|
|
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' };
|
|
261
|
+
}
|
|
262
|
+
if (urlStr.startsWith('http://') || urlStr.startsWith('https://')) {
|
|
263
|
+
return { stream: await getHttpStream(item.url, opts), type: 'remote' };
|
|
278
264
|
}
|
|
279
|
-
return { stream:
|
|
265
|
+
return { stream: createReadStream(item.url), type: 'file' };
|
|
280
266
|
};
|
|
281
|
-
exports.getStream = getStream;
|
|
282
267
|
/** generates a thumbnail for a given media, if required */
|
|
283
|
-
async function generateThumbnail(file, mediaType, options) {
|
|
284
|
-
var _a;
|
|
268
|
+
export async function generateThumbnail(file, mediaType, options) {
|
|
285
269
|
let thumbnail;
|
|
286
270
|
let originalImageDimensions;
|
|
287
271
|
if (mediaType === 'image') {
|
|
288
|
-
const { buffer, original } = await
|
|
272
|
+
const { buffer, original } = await extractImageThumb(file);
|
|
289
273
|
thumbnail = buffer.toString('base64');
|
|
290
274
|
if (original.width && original.height) {
|
|
291
275
|
originalImageDimensions = {
|
|
@@ -295,15 +279,15 @@ async function generateThumbnail(file, mediaType, options) {
|
|
|
295
279
|
}
|
|
296
280
|
}
|
|
297
281
|
else if (mediaType === 'video') {
|
|
298
|
-
const imgFilename =
|
|
282
|
+
const imgFilename = join(getTmpFilesDirectory(), generateMessageIDV2() + '.jpg');
|
|
299
283
|
try {
|
|
300
284
|
await extractVideoThumb(file, imgFilename, '00:00:00', { width: 32, height: 32 });
|
|
301
|
-
const buff = await
|
|
285
|
+
const buff = await fs.readFile(imgFilename);
|
|
302
286
|
thumbnail = buff.toString('base64');
|
|
303
|
-
await
|
|
287
|
+
await fs.unlink(imgFilename);
|
|
304
288
|
}
|
|
305
289
|
catch (err) {
|
|
306
|
-
|
|
290
|
+
options.logger?.debug('could not generate video thumb: ' + err);
|
|
307
291
|
}
|
|
308
292
|
}
|
|
309
293
|
return {
|
|
@@ -311,24 +295,22 @@ async function generateThumbnail(file, mediaType, options) {
|
|
|
311
295
|
originalImageDimensions
|
|
312
296
|
};
|
|
313
297
|
}
|
|
314
|
-
const getHttpStream = async (url, options = {}) => {
|
|
315
|
-
const fetched = await
|
|
298
|
+
export const getHttpStream = async (url, options = {}) => {
|
|
299
|
+
const fetched = await axios.get(url.toString(), { ...options, responseType: 'stream' });
|
|
316
300
|
return fetched.data;
|
|
317
301
|
};
|
|
318
|
-
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
const { stream, type } = await (0, exports.getStream)(media, opts);
|
|
322
|
-
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');
|
|
323
305
|
const mediaKey = Crypto.randomBytes(32);
|
|
324
306
|
const { cipherKey, iv, macKey } = await getMediaKeys(mediaKey, mediaType);
|
|
325
|
-
const encFilePath =
|
|
326
|
-
const encFileWriteStream =
|
|
307
|
+
const encFilePath = join(getTmpFilesDirectory(), mediaType + generateMessageIDV2() + '-enc');
|
|
308
|
+
const encFileWriteStream = createWriteStream(encFilePath);
|
|
327
309
|
let originalFileStream;
|
|
328
310
|
let originalFilePath;
|
|
329
311
|
if (saveOriginalFileIfRequired) {
|
|
330
|
-
originalFilePath =
|
|
331
|
-
originalFileStream =
|
|
312
|
+
originalFilePath = join(getTmpFilesDirectory(), mediaType + generateMessageIDV2() + '-original');
|
|
313
|
+
originalFileStream = createWriteStream(originalFilePath);
|
|
332
314
|
}
|
|
333
315
|
let fileLength = 0;
|
|
334
316
|
const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv);
|
|
@@ -343,14 +325,14 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
343
325
|
try {
|
|
344
326
|
for await (const data of stream) {
|
|
345
327
|
fileLength += data.length;
|
|
346
|
-
if (type === 'remote' &&
|
|
347
|
-
throw new
|
|
328
|
+
if (type === 'remote' && opts?.maxContentLength && fileLength + data.length > opts.maxContentLength) {
|
|
329
|
+
throw new Boom(`content length exceeded when encrypting "${type}"`, {
|
|
348
330
|
data: { media, type }
|
|
349
331
|
});
|
|
350
332
|
}
|
|
351
333
|
if (originalFileStream) {
|
|
352
334
|
if (!originalFileStream.write(data)) {
|
|
353
|
-
await
|
|
335
|
+
await once(originalFileStream, 'drain');
|
|
354
336
|
}
|
|
355
337
|
}
|
|
356
338
|
sha256Plain.update(data);
|
|
@@ -363,9 +345,9 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
363
345
|
const fileEncSha256 = sha256Enc.digest();
|
|
364
346
|
encFileWriteStream.write(mac);
|
|
365
347
|
encFileWriteStream.end();
|
|
366
|
-
|
|
348
|
+
originalFileStream?.end?.();
|
|
367
349
|
stream.destroy();
|
|
368
|
-
logger
|
|
350
|
+
logger?.debug('encrypted data successfully');
|
|
369
351
|
return {
|
|
370
352
|
mediaKey,
|
|
371
353
|
originalFilePath,
|
|
@@ -379,43 +361,44 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
379
361
|
catch (error) {
|
|
380
362
|
// destroy all streams with error
|
|
381
363
|
encFileWriteStream.destroy();
|
|
382
|
-
|
|
364
|
+
originalFileStream?.destroy?.();
|
|
383
365
|
aes.destroy();
|
|
384
366
|
hmac.destroy();
|
|
385
367
|
sha256Plain.destroy();
|
|
386
368
|
sha256Enc.destroy();
|
|
387
369
|
stream.destroy();
|
|
388
370
|
try {
|
|
389
|
-
await
|
|
371
|
+
await fs.unlink(encFilePath);
|
|
390
372
|
if (originalFilePath) {
|
|
391
|
-
await
|
|
373
|
+
await fs.unlink(originalFilePath);
|
|
392
374
|
}
|
|
393
375
|
}
|
|
394
376
|
catch (err) {
|
|
395
|
-
logger
|
|
377
|
+
logger?.error({ err }, 'failed deleting tmp files');
|
|
396
378
|
}
|
|
397
379
|
throw error;
|
|
398
380
|
}
|
|
399
381
|
};
|
|
400
|
-
exports.encryptedStream = encryptedStream;
|
|
401
382
|
const DEF_HOST = 'mmg.whatsapp.net';
|
|
402
383
|
const AES_CHUNK_SIZE = 16;
|
|
403
384
|
const toSmallestChunkSize = (num) => {
|
|
404
385
|
return Math.floor(num / AES_CHUNK_SIZE) * AES_CHUNK_SIZE;
|
|
405
386
|
};
|
|
406
|
-
const getUrlFromDirectPath = (directPath) => `https://${DEF_HOST}${directPath}`;
|
|
407
|
-
|
|
408
|
-
const
|
|
409
|
-
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
|
+
}
|
|
410
394
|
const keys = await getMediaKeys(mediaKey, type);
|
|
411
|
-
return
|
|
395
|
+
return downloadEncryptedContent(downloadUrl, keys, opts);
|
|
412
396
|
};
|
|
413
|
-
exports.downloadContentFromMessage = downloadContentFromMessage;
|
|
414
397
|
/**
|
|
415
398
|
* Decrypts and downloads an AES256-CBC encrypted file given the keys.
|
|
416
399
|
* Assumes the SHA256 of the plaintext is appended to the end of the ciphertext
|
|
417
400
|
* */
|
|
418
|
-
const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startByte, endByte, options } = {}) => {
|
|
401
|
+
export const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startByte, endByte, options } = {}) => {
|
|
419
402
|
let bytesFetched = 0;
|
|
420
403
|
let startChunk = 0;
|
|
421
404
|
let firstBlockIsIV = false;
|
|
@@ -430,8 +413,8 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
|
|
|
430
413
|
}
|
|
431
414
|
const endChunk = endByte ? toSmallestChunkSize(endByte || 0) + AES_CHUNK_SIZE : undefined;
|
|
432
415
|
const headers = {
|
|
433
|
-
...(
|
|
434
|
-
Origin:
|
|
416
|
+
...(options?.headers || {}),
|
|
417
|
+
Origin: DEFAULT_ORIGIN
|
|
435
418
|
};
|
|
436
419
|
if (startChunk || endChunk) {
|
|
437
420
|
headers.Range = `bytes=${startChunk}-`;
|
|
@@ -440,7 +423,7 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
|
|
|
440
423
|
}
|
|
441
424
|
}
|
|
442
425
|
// download the message
|
|
443
|
-
const fetched = await
|
|
426
|
+
const fetched = await getHttpStream(downloadUrl, {
|
|
444
427
|
...(options || {}),
|
|
445
428
|
headers,
|
|
446
429
|
maxBodyLength: Infinity,
|
|
@@ -459,7 +442,7 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
|
|
|
459
442
|
push(bytes);
|
|
460
443
|
}
|
|
461
444
|
};
|
|
462
|
-
const output = new
|
|
445
|
+
const output = new Transform({
|
|
463
446
|
transform(chunk, _, callback) {
|
|
464
447
|
let data = Buffer.concat([remainingBytes, chunk]);
|
|
465
448
|
const decryptLength = toSmallestChunkSize(data.length);
|
|
@@ -498,9 +481,8 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
|
|
|
498
481
|
});
|
|
499
482
|
return fetched.pipe(output, { end: true });
|
|
500
483
|
};
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
const getExtension = (mimetype) => mimetype.split(';')[0].split('/')[1];
|
|
484
|
+
export function extensionForMediaMessage(message) {
|
|
485
|
+
const getExtension = (mimetype) => mimetype.split(';')[0]?.split('/')[1];
|
|
504
486
|
const type = Object.keys(message)[0];
|
|
505
487
|
let extension;
|
|
506
488
|
if (type === 'locationMessage' || type === 'liveLocationMessage' || type === 'productMessage') {
|
|
@@ -512,28 +494,27 @@ function extensionForMediaMessage(message) {
|
|
|
512
494
|
}
|
|
513
495
|
return extension;
|
|
514
496
|
}
|
|
515
|
-
const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
497
|
+
export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
516
498
|
return async (filePath, { mediaType, fileEncSha256B64, timeoutMs }) => {
|
|
517
|
-
var _a, _b;
|
|
518
499
|
// send a query JSON to obtain the url & auth token to upload our media
|
|
519
500
|
let uploadInfo = await refreshMediaConn(false);
|
|
520
501
|
let urls;
|
|
521
502
|
const hosts = [...customUploadHosts, ...uploadInfo.hosts];
|
|
522
|
-
fileEncSha256B64 =
|
|
503
|
+
fileEncSha256B64 = encodeBase64EncodedStringForUpload(fileEncSha256B64);
|
|
523
504
|
for (const { hostname } of hosts) {
|
|
524
505
|
logger.debug(`uploading to "${hostname}"`);
|
|
525
506
|
const auth = encodeURIComponent(uploadInfo.auth); // the auth token
|
|
526
|
-
const url = `https://${hostname}${
|
|
507
|
+
const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
|
|
527
508
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
528
509
|
let result;
|
|
529
510
|
try {
|
|
530
|
-
const body = await
|
|
511
|
+
const body = await axios.post(url, createReadStream(filePath), {
|
|
531
512
|
...options,
|
|
532
513
|
maxRedirects: 0,
|
|
533
514
|
headers: {
|
|
534
515
|
...(options.headers || {}),
|
|
535
516
|
'Content-Type': 'application/octet-stream',
|
|
536
|
-
Origin:
|
|
517
|
+
Origin: DEFAULT_ORIGIN
|
|
537
518
|
},
|
|
538
519
|
httpsAgent: fetchAgent,
|
|
539
520
|
timeout: timeoutMs,
|
|
@@ -542,7 +523,7 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
|
|
|
542
523
|
maxContentLength: Infinity
|
|
543
524
|
});
|
|
544
525
|
result = body.data;
|
|
545
|
-
if (
|
|
526
|
+
if (result?.url || result?.directPath) {
|
|
546
527
|
urls = {
|
|
547
528
|
mediaUrl: result.url,
|
|
548
529
|
directPath: result.direct_path
|
|
@@ -555,37 +536,36 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
|
|
|
555
536
|
}
|
|
556
537
|
}
|
|
557
538
|
catch (error) {
|
|
558
|
-
if (
|
|
559
|
-
result =
|
|
539
|
+
if (axios.isAxiosError(error)) {
|
|
540
|
+
result = error.response?.data;
|
|
560
541
|
}
|
|
561
|
-
const isLast = hostname ===
|
|
542
|
+
const isLast = hostname === hosts[uploadInfo.hosts.length - 1]?.hostname;
|
|
562
543
|
logger.warn({ trace: error.stack, uploadResult: result }, `Error in uploading to ${hostname} ${isLast ? '' : ', retrying...'}`);
|
|
563
544
|
}
|
|
564
545
|
}
|
|
565
546
|
if (!urls) {
|
|
566
|
-
throw new
|
|
547
|
+
throw new Boom('Media upload failed on all hosts', { statusCode: 500 });
|
|
567
548
|
}
|
|
568
549
|
return urls;
|
|
569
550
|
};
|
|
570
551
|
};
|
|
571
|
-
exports.getWAUploadToServer = getWAUploadToServer;
|
|
572
552
|
const getMediaRetryKey = (mediaKey) => {
|
|
573
|
-
return
|
|
553
|
+
return hkdf(mediaKey, 32, { info: 'WhatsApp Media Retry Notification' });
|
|
574
554
|
};
|
|
575
555
|
/**
|
|
576
556
|
* Generate a binary node that will request the phone to re-upload the media & return the newly uploaded URL
|
|
577
557
|
*/
|
|
578
|
-
const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
|
|
558
|
+
export const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
|
|
579
559
|
const recp = { stanzaId: key.id };
|
|
580
|
-
const recpBuffer =
|
|
560
|
+
const recpBuffer = proto.ServerErrorReceipt.encode(recp).finish();
|
|
581
561
|
const iv = Crypto.randomBytes(12);
|
|
582
562
|
const retryKey = await getMediaRetryKey(mediaKey);
|
|
583
|
-
const ciphertext =
|
|
563
|
+
const ciphertext = aesEncryptGCM(recpBuffer, retryKey, iv, Buffer.from(key.id));
|
|
584
564
|
const req = {
|
|
585
565
|
tag: 'receipt',
|
|
586
566
|
attrs: {
|
|
587
567
|
id: key.id,
|
|
588
|
-
to:
|
|
568
|
+
to: jidNormalizedUser(meId),
|
|
589
569
|
type: 'server-error'
|
|
590
570
|
},
|
|
591
571
|
content: [
|
|
@@ -613,9 +593,8 @@ const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
|
|
|
613
593
|
};
|
|
614
594
|
return req;
|
|
615
595
|
};
|
|
616
|
-
|
|
617
|
-
const
|
|
618
|
-
const rmrNode = (0, WABinary_1.getBinaryNodeChild)(node, 'rmr');
|
|
596
|
+
export const decodeMediaRetryNode = (node) => {
|
|
597
|
+
const rmrNode = getBinaryNodeChild(node, 'rmr');
|
|
619
598
|
const event = {
|
|
620
599
|
key: {
|
|
621
600
|
id: node.attrs.id,
|
|
@@ -624,39 +603,37 @@ const decodeMediaRetryNode = (node) => {
|
|
|
624
603
|
participant: rmrNode.attrs.participant
|
|
625
604
|
}
|
|
626
605
|
};
|
|
627
|
-
const errorNode =
|
|
606
|
+
const errorNode = getBinaryNodeChild(node, 'error');
|
|
628
607
|
if (errorNode) {
|
|
629
608
|
const errorCode = +errorNode.attrs.code;
|
|
630
|
-
event.error = new
|
|
609
|
+
event.error = new Boom(`Failed to re-upload media (${errorCode})`, {
|
|
631
610
|
data: errorNode.attrs,
|
|
632
|
-
statusCode:
|
|
611
|
+
statusCode: getStatusCodeForMediaRetry(errorCode)
|
|
633
612
|
});
|
|
634
613
|
}
|
|
635
614
|
else {
|
|
636
|
-
const encryptedInfoNode =
|
|
637
|
-
const ciphertext =
|
|
638
|
-
const iv =
|
|
615
|
+
const encryptedInfoNode = getBinaryNodeChild(node, 'encrypt');
|
|
616
|
+
const ciphertext = getBinaryNodeChildBuffer(encryptedInfoNode, 'enc_p');
|
|
617
|
+
const iv = getBinaryNodeChildBuffer(encryptedInfoNode, 'enc_iv');
|
|
639
618
|
if (ciphertext && iv) {
|
|
640
619
|
event.media = { ciphertext, iv };
|
|
641
620
|
}
|
|
642
621
|
else {
|
|
643
|
-
event.error = new
|
|
622
|
+
event.error = new Boom('Failed to re-upload media (missing ciphertext)', { statusCode: 404 });
|
|
644
623
|
}
|
|
645
624
|
}
|
|
646
625
|
return event;
|
|
647
626
|
};
|
|
648
|
-
|
|
649
|
-
const decryptMediaRetryData = async ({ ciphertext, iv }, mediaKey, msgId) => {
|
|
627
|
+
export const decryptMediaRetryData = async ({ ciphertext, iv }, mediaKey, msgId) => {
|
|
650
628
|
const retryKey = await getMediaRetryKey(mediaKey);
|
|
651
|
-
const plaintext =
|
|
652
|
-
return
|
|
629
|
+
const plaintext = aesDecryptGCM(ciphertext, retryKey, iv, Buffer.from(msgId));
|
|
630
|
+
return proto.MediaRetryNotification.decode(plaintext);
|
|
653
631
|
};
|
|
654
|
-
|
|
655
|
-
const getStatusCodeForMediaRetry = (code) => MEDIA_RETRY_STATUS_MAP[code];
|
|
656
|
-
exports.getStatusCodeForMediaRetry = getStatusCodeForMediaRetry;
|
|
632
|
+
export const getStatusCodeForMediaRetry = (code) => MEDIA_RETRY_STATUS_MAP[code];
|
|
657
633
|
const MEDIA_RETRY_STATUS_MAP = {
|
|
658
|
-
[
|
|
659
|
-
[
|
|
660
|
-
[
|
|
661
|
-
[
|
|
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
|
|
662
638
|
};
|
|
639
|
+
//# sourceMappingURL=messages-media.js.map
|