lordceaser-baileys 1.0.19 → 1.0.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/lib/Defaults/baileys-version.json +1 -1
- package/lib/Defaults/index.d.ts +235 -3
- package/lib/Defaults/index.js +23 -7
- package/lib/Defaults/phonenumber-mcc.json +223 -0
- package/lib/Signal/libsignal.js +9 -18
- package/lib/Socket/Client/{types.d.ts → abstract-socket-client.d.ts} +2 -0
- package/lib/Socket/Client/index.d.ts +3 -2
- package/lib/Socket/Client/index.js +3 -2
- package/lib/Socket/Client/mobile-socket-client.d.ts +13 -0
- package/lib/Socket/Client/mobile-socket-client.js +65 -0
- package/lib/Socket/Client/{websocket.d.ts → web-socket-client.d.ts} +1 -1
- package/lib/Socket/Client/{websocket.js → web-socket-client.js} +2 -2
- package/lib/Socket/business.d.ts +40 -38
- package/lib/Socket/chats.d.ts +23 -25
- package/lib/Socket/chats.js +77 -78
- package/lib/Socket/groups.d.ts +29 -30
- package/lib/Socket/groups.js +2 -3
- package/lib/Socket/index.d.ts +48 -44
- package/lib/Socket/index.js +2 -2
- package/lib/Socket/messages-recv.d.ts +37 -37
- package/lib/Socket/messages-recv.js +43 -97
- package/lib/Socket/messages-send.d.ts +31 -33
- package/lib/Socket/messages-send.js +69 -81
- package/lib/Socket/registration.d.ts +242 -0
- package/lib/Socket/registration.js +166 -0
- package/lib/Socket/socket.d.ts +10 -9
- package/lib/Socket/socket.js +22 -27
- package/lib/Store/index.d.ts +3 -0
- package/lib/Store/index.js +10 -0
- package/lib/Store/make-cache-manager-store.d.ts +14 -0
- package/lib/Store/make-cache-manager-store.js +83 -0
- package/lib/Store/make-in-memory-store.d.ts +118 -0
- package/lib/Store/make-in-memory-store.js +422 -0
- package/lib/Store/make-ordered-dictionary.d.ts +13 -0
- package/lib/Store/make-ordered-dictionary.js +81 -0
- package/lib/Store/object-repository.d.ts +10 -0
- package/lib/Store/object-repository.js +27 -0
- package/lib/Types/Auth.d.ts +7 -0
- package/lib/Types/Chat.d.ts +7 -12
- package/lib/Types/Contact.d.ts +1 -1
- package/lib/Types/GroupMetadata.d.ts +0 -2
- package/lib/Types/Label.js +1 -1
- package/lib/Types/LabelAssociation.js +1 -1
- package/lib/Types/Message.d.ts +10 -9
- package/lib/Types/Message.js +2 -0
- package/lib/Types/Socket.d.ts +11 -16
- package/lib/Types/index.js +1 -1
- package/lib/Utils/auth-utils.d.ts +3 -3
- package/lib/Utils/auth-utils.js +13 -7
- package/lib/Utils/business.js +5 -13
- package/lib/Utils/chat-utils.d.ts +14 -13
- package/lib/Utils/chat-utils.js +30 -35
- package/lib/Utils/crypto.d.ts +15 -14
- package/lib/Utils/crypto.js +30 -70
- package/lib/Utils/decode-wa-message.d.ts +2 -18
- package/lib/Utils/decode-wa-message.js +18 -22
- package/lib/Utils/event-buffer.d.ts +2 -2
- package/lib/Utils/event-buffer.js +7 -7
- package/lib/Utils/generics.d.ts +14 -15
- package/lib/Utils/generics.js +28 -32
- package/lib/Utils/history.d.ts +2 -2
- package/lib/Utils/link-preview.d.ts +2 -2
- package/lib/Utils/link-preview.js +1 -34
- package/lib/Utils/logger.d.ts +3 -10
- package/lib/Utils/lt-hash.d.ts +2 -2
- package/lib/Utils/lt-hash.js +6 -6
- package/lib/Utils/make-mutex.d.ts +2 -2
- package/lib/Utils/make-mutex.js +0 -1
- package/lib/Utils/messages-media.d.ts +24 -20
- package/lib/Utils/messages-media.js +75 -78
- package/lib/Utils/messages.d.ts +9 -7
- package/lib/Utils/messages.js +29 -28
- package/lib/Utils/noise-handler.d.ts +11 -9
- package/lib/Utils/noise-handler.js +21 -16
- package/lib/Utils/process-message.d.ts +5 -4
- package/lib/Utils/process-message.js +39 -67
- package/lib/Utils/signal.d.ts +1 -2
- package/lib/Utils/signal.js +19 -11
- package/lib/Utils/use-multi-file-auth-state.js +13 -45
- package/lib/Utils/validate-connection.d.ts +3 -2
- package/lib/Utils/validate-connection.js +45 -15
- package/lib/WABinary/constants.js +5 -5
- package/lib/WABinary/decode.d.ts +3 -2
- package/lib/WABinary/decode.js +9 -20
- package/lib/WABinary/encode.d.ts +2 -1
- package/lib/WABinary/encode.js +18 -38
- package/lib/WABinary/generic-utils.d.ts +2 -1
- package/lib/WABinary/generic-utils.js +2 -2
- package/lib/WABinary/jid-utils.d.ts +3 -7
- package/lib/WABinary/jid-utils.js +2 -9
- package/lib/WAM/BinaryInfo.d.ts +11 -2
- package/lib/WAM/constants.d.ts +2 -3
- package/lib/WAM/encode.d.ts +2 -1
- package/lib/WAM/encode.js +2 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/package.json +3 -3
- package/WAProto/index.d.ts +0 -53473
- package/WAProto/index.js +0 -165029
- package/lib/Socket/usync.d.ts +0 -36
- package/lib/Socket/usync.js +0 -70
- package/lib/Types/USync.d.ts +0 -25
- package/lib/Types/USync.js +0 -2
- package/lib/WAProto/index.d.ts +0 -53473
- package/lib/WAProto/index.js +0 -165029
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +0 -9
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +0 -32
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +0 -22
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +0 -57
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +0 -12
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +0 -30
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +0 -12
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +0 -42
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +0 -25
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +0 -53
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +0 -8
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +0 -24
- package/lib/WAUSync/Protocols/index.d.ts +0 -4
- package/lib/WAUSync/Protocols/index.js +0 -20
- package/lib/WAUSync/USyncQuery.d.ts +0 -28
- package/lib/WAUSync/USyncQuery.js +0 -89
- package/lib/WAUSync/USyncUser.d.ts +0 -12
- package/lib/WAUSync/USyncUser.js +0 -26
- package/lib/WAUSync/index.d.ts +0 -3
- package/lib/WAUSync/index.js +0 -19
- /package/lib/Socket/Client/{types.js → abstract-socket-client.js} +0 -0
package/lib/Utils/lt-hash.js
CHANGED
|
@@ -30,15 +30,15 @@ class d {
|
|
|
30
30
|
var n = this;
|
|
31
31
|
return n.add(n.subtract(e, r), t);
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
_addSingle(e, t) {
|
|
34
34
|
var r = this;
|
|
35
|
-
const n = new Uint8Array(
|
|
36
|
-
return r.performPointwiseWithOverflow(
|
|
35
|
+
const n = new Uint8Array((0, crypto_1.hkdf)(Buffer.from(t), o, { info: r.salt })).buffer;
|
|
36
|
+
return r.performPointwiseWithOverflow(e, n, ((e, t) => e + t));
|
|
37
37
|
}
|
|
38
|
-
|
|
38
|
+
_subtractSingle(e, t) {
|
|
39
39
|
var r = this;
|
|
40
|
-
const n = new Uint8Array(
|
|
41
|
-
return r.performPointwiseWithOverflow(
|
|
40
|
+
const n = new Uint8Array((0, crypto_1.hkdf)(Buffer.from(t), o, { info: r.salt })).buffer;
|
|
41
|
+
return r.performPointwiseWithOverflow(e, n, ((e, t) => e - t));
|
|
42
42
|
}
|
|
43
43
|
performPointwiseWithOverflow(e, t, r) {
|
|
44
44
|
const n = new DataView(e), i = new DataView(t), a = new ArrayBuffer(n.byteLength), s = new DataView(a);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare const makeMutex: () => {
|
|
2
|
-
mutex<T>(code: () =>
|
|
2
|
+
mutex<T>(code: () => T | Promise<T>): Promise<T>;
|
|
3
3
|
};
|
|
4
4
|
export type Mutex = ReturnType<typeof makeMutex>;
|
|
5
5
|
export declare const makeKeyedMutex: () => {
|
|
6
|
-
mutex<T>(key: string, task: () =>
|
|
6
|
+
mutex<T>(key: string, task: () => T | Promise<T>): Promise<T>;
|
|
7
7
|
};
|
package/lib/Utils/make-mutex.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.makeKeyedMutex = exports.makeMutex = void 0;
|
|
4
4
|
const makeMutex = () => {
|
|
5
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
5
|
let task = Promise.resolve();
|
|
7
6
|
let taskTimeout;
|
|
8
7
|
return {
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
1
4
|
import { Boom } from '@hapi/boom';
|
|
2
5
|
import { AxiosRequestConfig } from 'axios';
|
|
6
|
+
import type { Logger } from 'pino';
|
|
3
7
|
import { Readable, Transform } from 'stream';
|
|
4
8
|
import { URL } from 'url';
|
|
5
9
|
import { proto } from '../../WAProto';
|
|
6
10
|
import { DownloadableMessage, MediaConnInfo, MediaDecryptionKeyInfo, MediaType, SocketConfig, WAMediaUpload, WAMediaUploadFunction, WAMessageContent } from '../Types';
|
|
7
11
|
import { BinaryNode } from '../WABinary';
|
|
8
|
-
import { ILogger } from './logger';
|
|
9
12
|
export declare const hkdfInfoKey: (type: MediaType) => string;
|
|
10
13
|
/** generates all the keys required to encrypt/decrypt & sign a media message */
|
|
11
|
-
export declare function getMediaKeys(buffer: Uint8Array | string | null | undefined, mediaType: MediaType):
|
|
14
|
+
export declare function getMediaKeys(buffer: Uint8Array | string | null | undefined, mediaType: MediaType): MediaDecryptionKeyInfo;
|
|
12
15
|
export declare const extractImageThumb: (bufferOrFilePath: Readable | Buffer | string, width?: number) => Promise<{
|
|
13
|
-
buffer: Buffer
|
|
16
|
+
buffer: Buffer;
|
|
14
17
|
original: {
|
|
15
18
|
width: number | undefined;
|
|
16
19
|
height: number | undefined;
|
|
@@ -18,7 +21,7 @@ export declare const extractImageThumb: (bufferOrFilePath: Readable | Buffer | s
|
|
|
18
21
|
}>;
|
|
19
22
|
export declare const encodeBase64EncodedStringForUpload: (b64: string) => string;
|
|
20
23
|
export declare const generateProfilePicture: (mediaUpload: WAMediaUpload) => Promise<{
|
|
21
|
-
img: Buffer
|
|
24
|
+
img: Buffer;
|
|
22
25
|
}>;
|
|
23
26
|
/** gets the SHA256 of the given media message */
|
|
24
27
|
export declare const mediaMessageSHA256B64: (message: WAMessageContent) => string | null | undefined;
|
|
@@ -26,9 +29,9 @@ export declare function getAudioDuration(buffer: Buffer | string | Readable): Pr
|
|
|
26
29
|
/**
|
|
27
30
|
referenced from and modifying https://github.com/wppconnect-team/wa-js/blob/main/src/chat/functions/prepareAudioWaveform.ts
|
|
28
31
|
*/
|
|
29
|
-
export declare function getAudioWaveform(buffer: Buffer | string | Readable, logger?:
|
|
32
|
+
export declare function getAudioWaveform(buffer: Buffer | string | Readable, logger?: Logger): Promise<Uint8Array | undefined>;
|
|
30
33
|
export declare const toReadable: (buffer: Buffer) => Readable;
|
|
31
|
-
export declare const toBuffer: (stream: Readable) => Promise<Buffer
|
|
34
|
+
export declare const toBuffer: (stream: Readable) => Promise<Buffer>;
|
|
32
35
|
export declare const getStream: (item: WAMediaUpload, opts?: AxiosRequestConfig) => Promise<{
|
|
33
36
|
readonly stream: Readable;
|
|
34
37
|
readonly type: "buffer";
|
|
@@ -44,7 +47,7 @@ export declare const getStream: (item: WAMediaUpload, opts?: AxiosRequestConfig)
|
|
|
44
47
|
}>;
|
|
45
48
|
/** generates a thumbnail for a given media, if required */
|
|
46
49
|
export declare function generateThumbnail(file: string, mediaType: 'video' | 'image', options: {
|
|
47
|
-
logger?:
|
|
50
|
+
logger?: Logger;
|
|
48
51
|
}): Promise<{
|
|
49
52
|
thumbnail: string | undefined;
|
|
50
53
|
originalImageDimensions: {
|
|
@@ -57,22 +60,23 @@ export declare const getHttpStream: (url: string | URL, options?: AxiosRequestCo
|
|
|
57
60
|
}) => Promise<Readable>;
|
|
58
61
|
type EncryptedStreamOptions = {
|
|
59
62
|
saveOriginalFileIfRequired?: boolean;
|
|
60
|
-
logger?:
|
|
63
|
+
logger?: Logger;
|
|
61
64
|
opts?: AxiosRequestConfig;
|
|
62
65
|
};
|
|
63
66
|
export declare const encryptedStream: (media: WAMediaUpload, mediaType: MediaType, { logger, saveOriginalFileIfRequired, opts }?: EncryptedStreamOptions) => Promise<{
|
|
64
|
-
mediaKey: Buffer
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
mac: Buffer
|
|
68
|
-
fileEncSha256: Buffer
|
|
69
|
-
fileSha256: Buffer
|
|
67
|
+
mediaKey: Buffer;
|
|
68
|
+
encWriteStream: Readable;
|
|
69
|
+
bodyPath: string | undefined;
|
|
70
|
+
mac: Buffer;
|
|
71
|
+
fileEncSha256: Buffer;
|
|
72
|
+
fileSha256: Buffer;
|
|
70
73
|
fileLength: number;
|
|
74
|
+
didSaveToTmpPath: boolean;
|
|
71
75
|
}>;
|
|
72
76
|
export type MediaDownloadOptions = {
|
|
73
77
|
startByte?: number;
|
|
74
78
|
endByte?: number;
|
|
75
|
-
options?: AxiosRequestConfig<
|
|
79
|
+
options?: AxiosRequestConfig<any>;
|
|
76
80
|
};
|
|
77
81
|
export declare const getUrlFromDirectPath: (directPath: string) => string;
|
|
78
82
|
export declare const downloadContentFromMessage: ({ mediaKey, directPath, url }: DownloadableMessage, type: MediaType, opts?: MediaDownloadOptions) => Promise<Transform>;
|
|
@@ -86,18 +90,18 @@ export declare const getWAUploadToServer: ({ customUploadHosts, fetchAgent, logg
|
|
|
86
90
|
/**
|
|
87
91
|
* Generate a binary node that will request the phone to re-upload the media & return the newly uploaded URL
|
|
88
92
|
*/
|
|
89
|
-
export declare const encryptMediaRetryRequest: (key: proto.IMessageKey, mediaKey: Buffer | Uint8Array, meId: string) =>
|
|
93
|
+
export declare const encryptMediaRetryRequest: (key: proto.IMessageKey, mediaKey: Buffer | Uint8Array, meId: string) => BinaryNode;
|
|
90
94
|
export declare const decodeMediaRetryNode: (node: BinaryNode) => {
|
|
91
|
-
key:
|
|
95
|
+
key: proto.IMessageKey;
|
|
92
96
|
media?: {
|
|
93
97
|
ciphertext: Uint8Array;
|
|
94
98
|
iv: Uint8Array;
|
|
95
|
-
};
|
|
96
|
-
error?: Boom;
|
|
99
|
+
} | undefined;
|
|
100
|
+
error?: Boom<any> | undefined;
|
|
97
101
|
};
|
|
98
102
|
export declare const decryptMediaRetryData: ({ ciphertext, iv }: {
|
|
99
103
|
ciphertext: Uint8Array;
|
|
100
104
|
iv: Uint8Array;
|
|
101
|
-
}, mediaKey: Uint8Array, msgId: string) =>
|
|
105
|
+
}, mediaKey: Uint8Array, msgId: string) => proto.MediaRetryNotification;
|
|
102
106
|
export declare const getStatusCodeForMediaRetry: (code: number) => any;
|
|
103
107
|
export {};
|
|
@@ -15,33 +15,18 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) ||
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
})();
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
35
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
27
|
};
|
|
38
28
|
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;
|
|
29
|
+
exports.getStatusCodeForMediaRetry = exports.decryptMediaRetryData = exports.decodeMediaRetryNode = exports.encryptMediaRetryRequest = exports.getWAUploadToServer = exports.extensionForMediaMessage = exports.downloadEncryptedContent = exports.downloadContentFromMessage = exports.getUrlFromDirectPath = exports.encryptedStream = exports.getHttpStream = exports.generateThumbnail = exports.getStream = exports.toBuffer = exports.toReadable = exports.getAudioWaveform = exports.getAudioDuration = exports.mediaMessageSHA256B64 = exports.generateProfilePicture = exports.encodeBase64EncodedStringForUpload = exports.extractImageThumb = exports.getMediaKeys = exports.hkdfInfoKey = void 0;
|
|
45
30
|
const boom_1 = require("@hapi/boom");
|
|
46
31
|
const axios_1 = __importDefault(require("axios"));
|
|
47
32
|
const child_process_1 = require("child_process");
|
|
@@ -60,11 +45,13 @@ const getTmpFilesDirectory = () => (0, os_1.tmpdir)();
|
|
|
60
45
|
const getImageProcessingLibrary = async () => {
|
|
61
46
|
const [_jimp, sharp] = await Promise.all([
|
|
62
47
|
(async () => {
|
|
63
|
-
const jimp = await (
|
|
48
|
+
const jimp = await (import('jimp')
|
|
49
|
+
.catch(() => { }));
|
|
64
50
|
return jimp;
|
|
65
51
|
})(),
|
|
66
52
|
(async () => {
|
|
67
|
-
const sharp = await (
|
|
53
|
+
const sharp = await (import('sharp')
|
|
54
|
+
.catch(() => { }));
|
|
68
55
|
return sharp;
|
|
69
56
|
})()
|
|
70
57
|
]);
|
|
@@ -83,7 +70,7 @@ const hkdfInfoKey = (type) => {
|
|
|
83
70
|
};
|
|
84
71
|
exports.hkdfInfoKey = hkdfInfoKey;
|
|
85
72
|
/** generates all the keys required to encrypt/decrypt & sign a media message */
|
|
86
|
-
|
|
73
|
+
function getMediaKeys(buffer, mediaType) {
|
|
87
74
|
if (!buffer) {
|
|
88
75
|
throw new boom_1.Boom('Cannot derive from empty media key');
|
|
89
76
|
}
|
|
@@ -91,13 +78,14 @@ async function getMediaKeys(buffer, mediaType) {
|
|
|
91
78
|
buffer = Buffer.from(buffer.replace('data:;base64,', ''), 'base64');
|
|
92
79
|
}
|
|
93
80
|
// expand using HKDF to 112 bytes, also pass in the relevant app info
|
|
94
|
-
const expandedMediaKey =
|
|
81
|
+
const expandedMediaKey = (0, crypto_1.hkdf)(buffer, 112, { info: (0, exports.hkdfInfoKey)(mediaType) });
|
|
95
82
|
return {
|
|
96
83
|
iv: expandedMediaKey.slice(0, 16),
|
|
97
84
|
cipherKey: expandedMediaKey.slice(16, 48),
|
|
98
85
|
macKey: expandedMediaKey.slice(48, 80),
|
|
99
86
|
};
|
|
100
87
|
}
|
|
88
|
+
exports.getMediaKeys = getMediaKeys;
|
|
101
89
|
/** Extracts video thumb using FFMPEG */
|
|
102
90
|
const extractVideoThumb = async (path, destPath, time, size) => new Promise((resolve, reject) => {
|
|
103
91
|
const cmd = `ffmpeg -ss ${time} -i ${path} -y -vf scale=${size.width}:-1 -vframes 1 -f image2 ${destPath}`;
|
|
@@ -204,7 +192,7 @@ const mediaMessageSHA256B64 = (message) => {
|
|
|
204
192
|
};
|
|
205
193
|
exports.mediaMessageSHA256B64 = mediaMessageSHA256B64;
|
|
206
194
|
async function getAudioDuration(buffer) {
|
|
207
|
-
const musicMetadata = await
|
|
195
|
+
const musicMetadata = await import('music-metadata');
|
|
208
196
|
let metadata;
|
|
209
197
|
if (Buffer.isBuffer(buffer)) {
|
|
210
198
|
metadata = await musicMetadata.parseBuffer(buffer, undefined, { duration: true });
|
|
@@ -223,12 +211,13 @@ async function getAudioDuration(buffer) {
|
|
|
223
211
|
}
|
|
224
212
|
return metadata.format.duration;
|
|
225
213
|
}
|
|
214
|
+
exports.getAudioDuration = getAudioDuration;
|
|
226
215
|
/**
|
|
227
216
|
referenced from and modifying https://github.com/wppconnect-team/wa-js/blob/main/src/chat/functions/prepareAudioWaveform.ts
|
|
228
217
|
*/
|
|
229
218
|
async function getAudioWaveform(buffer, logger) {
|
|
230
219
|
try {
|
|
231
|
-
const
|
|
220
|
+
const audioDecode = (buffer) => import('audio-decode').then(({ default: audioDecode }) => audioDecode(buffer));
|
|
232
221
|
let audioData;
|
|
233
222
|
if (Buffer.isBuffer(buffer)) {
|
|
234
223
|
audioData = buffer;
|
|
@@ -240,7 +229,7 @@ async function getAudioWaveform(buffer, logger) {
|
|
|
240
229
|
else {
|
|
241
230
|
audioData = await (0, exports.toBuffer)(buffer);
|
|
242
231
|
}
|
|
243
|
-
const audioBuffer = await
|
|
232
|
+
const audioBuffer = await audioDecode(audioData);
|
|
244
233
|
const rawData = audioBuffer.getChannelData(0); // We only need to work with one channel of data
|
|
245
234
|
const samples = 64; // Number of samples we want to have in our final data set
|
|
246
235
|
const blockSize = Math.floor(rawData.length / samples); // the number of samples in each subdivision
|
|
@@ -264,6 +253,7 @@ async function getAudioWaveform(buffer, logger) {
|
|
|
264
253
|
logger === null || logger === void 0 ? void 0 : logger.debug('Failed to generate waveform: ' + e);
|
|
265
254
|
}
|
|
266
255
|
}
|
|
256
|
+
exports.getAudioWaveform = getAudioWaveform;
|
|
267
257
|
const toReadable = (buffer) => {
|
|
268
258
|
const readable = new stream_1.Readable({ read: () => { } });
|
|
269
259
|
readable.push(buffer);
|
|
@@ -309,7 +299,7 @@ async function generateThumbnail(file, mediaType, options) {
|
|
|
309
299
|
}
|
|
310
300
|
}
|
|
311
301
|
else if (mediaType === 'video') {
|
|
312
|
-
const imgFilename = (0, path_1.join)(getTmpFilesDirectory(), (0, generics_1.
|
|
302
|
+
const imgFilename = (0, path_1.join)(getTmpFilesDirectory(), (0, generics_1.generateMessageID)() + '.jpg');
|
|
313
303
|
try {
|
|
314
304
|
await extractVideoThumb(file, imgFilename, '00:00:00', { width: 32, height: 32 });
|
|
315
305
|
const buff = await fs_1.promises.readFile(imgFilename);
|
|
@@ -325,35 +315,34 @@ async function generateThumbnail(file, mediaType, options) {
|
|
|
325
315
|
originalImageDimensions
|
|
326
316
|
};
|
|
327
317
|
}
|
|
318
|
+
exports.generateThumbnail = generateThumbnail;
|
|
328
319
|
const getHttpStream = async (url, options = {}) => {
|
|
329
320
|
const fetched = await axios_1.default.get(url.toString(), { ...options, responseType: 'stream' });
|
|
330
321
|
return fetched.data;
|
|
331
322
|
};
|
|
332
323
|
exports.getHttpStream = getHttpStream;
|
|
333
324
|
const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
|
|
334
|
-
var _a, _b;
|
|
335
325
|
const { stream, type } = await (0, exports.getStream)(media, opts);
|
|
336
326
|
logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
|
|
337
327
|
const mediaKey = Crypto.randomBytes(32);
|
|
338
|
-
const { cipherKey, iv, macKey } =
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
let
|
|
342
|
-
let
|
|
343
|
-
if (
|
|
344
|
-
|
|
345
|
-
|
|
328
|
+
const { cipherKey, iv, macKey } = getMediaKeys(mediaKey, mediaType);
|
|
329
|
+
const encWriteStream = new stream_1.Readable({ read: () => { } });
|
|
330
|
+
let bodyPath;
|
|
331
|
+
let writeStream;
|
|
332
|
+
let didSaveToTmpPath = false;
|
|
333
|
+
if (type === 'file') {
|
|
334
|
+
bodyPath = media.url;
|
|
335
|
+
}
|
|
336
|
+
else if (saveOriginalFileIfRequired) {
|
|
337
|
+
bodyPath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageID)());
|
|
338
|
+
writeStream = (0, fs_1.createWriteStream)(bodyPath);
|
|
339
|
+
didSaveToTmpPath = true;
|
|
346
340
|
}
|
|
347
341
|
let fileLength = 0;
|
|
348
342
|
const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv);
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
const onChunk = (buff) => {
|
|
353
|
-
sha256Enc.update(buff);
|
|
354
|
-
hmac.update(buff);
|
|
355
|
-
encFileWriteStream.write(buff);
|
|
356
|
-
};
|
|
343
|
+
let hmac = Crypto.createHmac('sha256', macKey).update(iv);
|
|
344
|
+
let sha256Plain = Crypto.createHash('sha256');
|
|
345
|
+
let sha256Enc = Crypto.createHash('sha256');
|
|
357
346
|
try {
|
|
358
347
|
for await (const data of stream) {
|
|
359
348
|
fileLength += data.length;
|
|
@@ -364,54 +353,59 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
364
353
|
data: { media, type }
|
|
365
354
|
});
|
|
366
355
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
356
|
+
sha256Plain = sha256Plain.update(data);
|
|
357
|
+
if (writeStream) {
|
|
358
|
+
if (!writeStream.write(data)) {
|
|
359
|
+
await (0, events_1.once)(writeStream, 'drain');
|
|
370
360
|
}
|
|
371
361
|
}
|
|
372
|
-
sha256Plain.update(data);
|
|
373
362
|
onChunk(aes.update(data));
|
|
374
363
|
}
|
|
375
364
|
onChunk(aes.final());
|
|
376
365
|
const mac = hmac.digest().slice(0, 10);
|
|
377
|
-
sha256Enc.update(mac);
|
|
366
|
+
sha256Enc = sha256Enc.update(mac);
|
|
378
367
|
const fileSha256 = sha256Plain.digest();
|
|
379
368
|
const fileEncSha256 = sha256Enc.digest();
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
369
|
+
encWriteStream.push(mac);
|
|
370
|
+
encWriteStream.push(null);
|
|
371
|
+
writeStream === null || writeStream === void 0 ? void 0 : writeStream.end();
|
|
383
372
|
stream.destroy();
|
|
384
373
|
logger === null || logger === void 0 ? void 0 : logger.debug('encrypted data successfully');
|
|
385
374
|
return {
|
|
386
375
|
mediaKey,
|
|
387
|
-
|
|
388
|
-
|
|
376
|
+
encWriteStream,
|
|
377
|
+
bodyPath,
|
|
389
378
|
mac,
|
|
390
379
|
fileEncSha256,
|
|
391
380
|
fileSha256,
|
|
392
|
-
fileLength
|
|
381
|
+
fileLength,
|
|
382
|
+
didSaveToTmpPath
|
|
393
383
|
};
|
|
394
384
|
}
|
|
395
385
|
catch (error) {
|
|
396
386
|
// destroy all streams with error
|
|
397
|
-
|
|
398
|
-
|
|
387
|
+
encWriteStream.destroy();
|
|
388
|
+
writeStream === null || writeStream === void 0 ? void 0 : writeStream.destroy();
|
|
399
389
|
aes.destroy();
|
|
400
390
|
hmac.destroy();
|
|
401
391
|
sha256Plain.destroy();
|
|
402
392
|
sha256Enc.destroy();
|
|
403
393
|
stream.destroy();
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
394
|
+
if (didSaveToTmpPath) {
|
|
395
|
+
try {
|
|
396
|
+
await fs_1.promises.unlink(bodyPath);
|
|
397
|
+
}
|
|
398
|
+
catch (err) {
|
|
399
|
+
logger === null || logger === void 0 ? void 0 : logger.error({ err }, 'failed to save to tmp path');
|
|
408
400
|
}
|
|
409
|
-
}
|
|
410
|
-
catch (err) {
|
|
411
|
-
logger === null || logger === void 0 ? void 0 : logger.error({ err }, 'failed deleting tmp files');
|
|
412
401
|
}
|
|
413
402
|
throw error;
|
|
414
403
|
}
|
|
404
|
+
function onChunk(buff) {
|
|
405
|
+
sha256Enc = sha256Enc.update(buff);
|
|
406
|
+
hmac = hmac.update(buff);
|
|
407
|
+
encWriteStream.push(buff);
|
|
408
|
+
}
|
|
415
409
|
};
|
|
416
410
|
exports.encryptedStream = encryptedStream;
|
|
417
411
|
const DEF_HOST = 'mmg.whatsapp.net';
|
|
@@ -421,9 +415,9 @@ const toSmallestChunkSize = (num) => {
|
|
|
421
415
|
};
|
|
422
416
|
const getUrlFromDirectPath = (directPath) => `https://${DEF_HOST}${directPath}`;
|
|
423
417
|
exports.getUrlFromDirectPath = getUrlFromDirectPath;
|
|
424
|
-
const downloadContentFromMessage =
|
|
418
|
+
const downloadContentFromMessage = ({ mediaKey, directPath, url }, type, opts = {}) => {
|
|
425
419
|
const downloadUrl = url || (0, exports.getUrlFromDirectPath)(directPath);
|
|
426
|
-
const keys =
|
|
420
|
+
const keys = getMediaKeys(mediaKey, type);
|
|
427
421
|
return (0, exports.downloadEncryptedContent)(downloadUrl, keys, opts);
|
|
428
422
|
};
|
|
429
423
|
exports.downloadContentFromMessage = downloadContentFromMessage;
|
|
@@ -530,8 +524,9 @@ function extensionForMediaMessage(message) {
|
|
|
530
524
|
}
|
|
531
525
|
return extension;
|
|
532
526
|
}
|
|
527
|
+
exports.extensionForMediaMessage = extensionForMediaMessage;
|
|
533
528
|
const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
534
|
-
return async (
|
|
529
|
+
return async (stream, { mediaType, fileEncSha256B64, timeoutMs }) => {
|
|
535
530
|
var _a, _b;
|
|
536
531
|
// send a query JSON to obtain the url & auth token to upload our media
|
|
537
532
|
let uploadInfo = await refreshMediaConn(false);
|
|
@@ -542,12 +537,10 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
|
|
|
542
537
|
logger.debug(`uploading to "${hostname}"`);
|
|
543
538
|
const auth = encodeURIComponent(uploadInfo.auth); // the auth token
|
|
544
539
|
const url = `https://${hostname}${Defaults_1.MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
|
|
545
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
546
540
|
let result;
|
|
547
541
|
try {
|
|
548
|
-
const body = await axios_1.default.post(url,
|
|
542
|
+
const body = await axios_1.default.post(url, stream, {
|
|
549
543
|
...options,
|
|
550
|
-
maxRedirects: 0,
|
|
551
544
|
headers: {
|
|
552
545
|
...options.headers || {},
|
|
553
546
|
'Content-Type': 'application/octet-stream',
|
|
@@ -593,11 +586,11 @@ const getMediaRetryKey = (mediaKey) => {
|
|
|
593
586
|
/**
|
|
594
587
|
* Generate a binary node that will request the phone to re-upload the media & return the newly uploaded URL
|
|
595
588
|
*/
|
|
596
|
-
const encryptMediaRetryRequest =
|
|
589
|
+
const encryptMediaRetryRequest = (key, mediaKey, meId) => {
|
|
597
590
|
const recp = { stanzaId: key.id };
|
|
598
591
|
const recpBuffer = WAProto_1.proto.ServerErrorReceipt.encode(recp).finish();
|
|
599
592
|
const iv = Crypto.randomBytes(12);
|
|
600
|
-
const retryKey =
|
|
593
|
+
const retryKey = getMediaRetryKey(mediaKey);
|
|
601
594
|
const ciphertext = (0, crypto_1.aesEncryptGCM)(recpBuffer, retryKey, iv, Buffer.from(key.id));
|
|
602
595
|
const req = {
|
|
603
596
|
tag: 'receipt',
|
|
@@ -661,8 +654,8 @@ const decodeMediaRetryNode = (node) => {
|
|
|
661
654
|
return event;
|
|
662
655
|
};
|
|
663
656
|
exports.decodeMediaRetryNode = decodeMediaRetryNode;
|
|
664
|
-
const decryptMediaRetryData =
|
|
665
|
-
const retryKey =
|
|
657
|
+
const decryptMediaRetryData = ({ ciphertext, iv }, mediaKey, msgId) => {
|
|
658
|
+
const retryKey = getMediaRetryKey(mediaKey);
|
|
666
659
|
const plaintext = (0, crypto_1.aesDecryptGCM)(ciphertext, retryKey, iv, Buffer.from(msgId));
|
|
667
660
|
return WAProto_1.proto.MediaRetryNotification.decode(plaintext);
|
|
668
661
|
};
|
|
@@ -675,3 +668,7 @@ const MEDIA_RETRY_STATUS_MAP = {
|
|
|
675
668
|
[WAProto_1.proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
|
|
676
669
|
[WAProto_1.proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418,
|
|
677
670
|
};
|
|
671
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
672
|
+
function __importStar(arg0) {
|
|
673
|
+
throw new Error('Function not implemented.');
|
|
674
|
+
}
|
package/lib/Utils/messages.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { Logger } from 'pino';
|
|
1
4
|
import { type Transform } from 'stream';
|
|
2
5
|
import { proto } from '../../WAProto';
|
|
3
6
|
import { AnyMediaMessageContent, AnyMessageContent, MediaGenerationOptions, MessageContentGenerationOptions, MessageGenerationOptions, MessageGenerationOptionsFromContent, MessageUserReceipt, WAMessage, WAMessageContent, WAProto } from '../Types';
|
|
4
|
-
import { ILogger } from './logger';
|
|
5
7
|
import { MediaDownloadOptions } from './messages-media';
|
|
6
8
|
/**
|
|
7
9
|
* Uses a regex to test whether the string contains a URL, and returns the URL if it does.
|
|
@@ -9,7 +11,7 @@ import { MediaDownloadOptions } from './messages-media';
|
|
|
9
11
|
* @returns the URL, eg. https://google.com
|
|
10
12
|
*/
|
|
11
13
|
export declare const extractUrlFromText: (text: string) => string | undefined;
|
|
12
|
-
export declare const generateLinkPreviewIfRequired: (text: string, getUrlInfo: MessageGenerationOptions[
|
|
14
|
+
export declare const generateLinkPreviewIfRequired: (text: string, getUrlInfo: MessageGenerationOptions['getUrlInfo'], logger: MessageGenerationOptions['logger']) => Promise<import("../Types").WAUrlInfo | undefined>;
|
|
13
15
|
export declare const prepareWAMessageMedia: (message: AnyMediaMessageContent, options: MediaGenerationOptions) => Promise<proto.Message>;
|
|
14
16
|
export declare const prepareDisappearingMessageSettingContent: (ephemeralExpiration?: number) => proto.Message;
|
|
15
17
|
/**
|
|
@@ -40,11 +42,11 @@ export declare const extractMessageContent: (content: WAMessageContent | undefin
|
|
|
40
42
|
*/
|
|
41
43
|
export declare const getDevice: (id: string) => "android" | "unknown" | "web" | "ios" | "desktop";
|
|
42
44
|
/** Upserts a receipt in the message */
|
|
43
|
-
export declare const updateMessageWithReceipt: (msg: Pick<WAMessage,
|
|
45
|
+
export declare const updateMessageWithReceipt: (msg: Pick<WAMessage, 'userReceipt'>, receipt: MessageUserReceipt) => void;
|
|
44
46
|
/** Update the message with a new reaction */
|
|
45
|
-
export declare const updateMessageWithReaction: (msg: Pick<WAMessage,
|
|
47
|
+
export declare const updateMessageWithReaction: (msg: Pick<WAMessage, 'reactions'>, reaction: proto.IReaction) => void;
|
|
46
48
|
/** Update the message with a new poll update */
|
|
47
|
-
export declare const updateMessageWithPollUpdate: (msg: Pick<WAMessage,
|
|
49
|
+
export declare const updateMessageWithPollUpdate: (msg: Pick<WAMessage, 'pollUpdates'>, update: proto.IPollUpdate) => void;
|
|
48
50
|
type VoteAggregation = {
|
|
49
51
|
name: string;
|
|
50
52
|
voters: string[];
|
|
@@ -64,12 +66,12 @@ export declare const aggregateMessageKeysNotFromMe: (keys: proto.IMessageKey[])
|
|
|
64
66
|
}[];
|
|
65
67
|
type DownloadMediaMessageContext = {
|
|
66
68
|
reuploadRequest: (msg: WAMessage) => Promise<WAMessage>;
|
|
67
|
-
logger:
|
|
69
|
+
logger: Logger;
|
|
68
70
|
};
|
|
69
71
|
/**
|
|
70
72
|
* Downloads the given message. Throws an error if it's not a media message
|
|
71
73
|
*/
|
|
72
|
-
export declare const downloadMediaMessage: <Type extends "
|
|
74
|
+
export declare const downloadMediaMessage: <Type extends "stream" | "buffer">(message: WAMessage, type: Type, options: MediaDownloadOptions, ctx?: DownloadMediaMessageContext) => Promise<Type extends "buffer" ? Buffer : Transform>;
|
|
73
75
|
/** Checks whether the given message is a media message; if it is returns the inner content */
|
|
74
76
|
export declare const assertMediaContent: (content: proto.IMessage | null | undefined) => proto.Message.IVideoMessage | proto.Message.IImageMessage | proto.Message.IAudioMessage | proto.Message.IDocumentMessage | proto.Message.IStickerMessage;
|
|
75
77
|
export {};
|