lordceaser-baileys 1.0.20 → 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 +22 -6
- 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 +78 -79
- package/lib/Socket/groups.d.ts +29 -30
- package/lib/Socket/groups.js +3 -4
- 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 +44 -98
- package/lib/Socket/messages-send.d.ts +31 -33
- package/lib/Socket/messages-send.js +70 -82
- 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 +23 -28
- 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 +3 -1
- 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 +31 -36
- 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 +19 -23
- 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 +29 -33
- package/lib/Utils/history.d.ts +2 -2
- package/lib/Utils/history.js +1 -1
- 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 +76 -79
- package/lib/Utils/messages.d.ts +9 -7
- package/lib/Utils/messages.js +30 -29
- package/lib/Utils/noise-handler.d.ts +11 -9
- package/lib/Utils/noise-handler.js +22 -17
- package/lib/Utils/process-message.d.ts +5 -4
- package/lib/Utils/process-message.js +40 -68
- package/lib/Utils/signal.d.ts +1 -2
- package/lib/Utils/signal.js +19 -11
- package/lib/Utils/use-multi-file-auth-state.js +14 -46
- package/lib/Utils/validate-connection.d.ts +3 -2
- package/lib/Utils/validate-connection.js +46 -16
- 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 +3 -3
- 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 +2 -2
- 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/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
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.mobileRegisterFetch = exports.mobileRegisterEncrypt = exports.mobileRegister = exports.mobileRegisterExists = exports.mobileRegisterCode = exports.registrationParams = exports.makeRegistrationSocket = void 0;
|
|
7
|
+
/* eslint-disable camelcase */
|
|
8
|
+
const axios_1 = __importDefault(require("axios"));
|
|
9
|
+
const Defaults_1 = require("../Defaults");
|
|
10
|
+
const crypto_1 = require("../Utils/crypto");
|
|
11
|
+
const WABinary_1 = require("../WABinary");
|
|
12
|
+
const business_1 = require("./business");
|
|
13
|
+
function urlencode(str) {
|
|
14
|
+
return str.replace(/-/g, '%2d').replace(/_/g, '%5f').replace(/~/g, '%7e');
|
|
15
|
+
}
|
|
16
|
+
const validRegistrationOptions = (config) => (config === null || config === void 0 ? void 0 : config.phoneNumberCountryCode) &&
|
|
17
|
+
config.phoneNumberNationalNumber &&
|
|
18
|
+
config.phoneNumberMobileCountryCode;
|
|
19
|
+
const makeRegistrationSocket = (config) => {
|
|
20
|
+
const sock = (0, business_1.makeBusinessSocket)(config);
|
|
21
|
+
const register = async (code) => {
|
|
22
|
+
if (!validRegistrationOptions(config.auth.creds.registration)) {
|
|
23
|
+
throw new Error('please specify the registration options');
|
|
24
|
+
}
|
|
25
|
+
const result = await mobileRegister({ ...sock.authState.creds, ...sock.authState.creds.registration, code }, config.options);
|
|
26
|
+
sock.authState.creds.me = {
|
|
27
|
+
id: (0, WABinary_1.jidEncode)(result.login, 's.whatsapp.net'),
|
|
28
|
+
name: '~'
|
|
29
|
+
};
|
|
30
|
+
sock.authState.creds.registered = true;
|
|
31
|
+
sock.ev.emit('creds.update', sock.authState.creds);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
const requestRegistrationCode = async (registrationOptions) => {
|
|
35
|
+
registrationOptions = registrationOptions || config.auth.creds.registration;
|
|
36
|
+
if (!validRegistrationOptions(registrationOptions)) {
|
|
37
|
+
throw new Error('Invalid registration options');
|
|
38
|
+
}
|
|
39
|
+
sock.authState.creds.registration = registrationOptions;
|
|
40
|
+
sock.ev.emit('creds.update', sock.authState.creds);
|
|
41
|
+
return mobileRegisterCode({ ...config.auth.creds, ...registrationOptions }, config.options);
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
...sock,
|
|
45
|
+
register,
|
|
46
|
+
requestRegistrationCode,
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
exports.makeRegistrationSocket = makeRegistrationSocket;
|
|
50
|
+
function convertBufferToUrlHex(buffer) {
|
|
51
|
+
var id = '';
|
|
52
|
+
buffer.forEach((x) => {
|
|
53
|
+
// encode random identity_id buffer as percentage url encoding
|
|
54
|
+
id += `%${x.toString(16).padStart(2, '0').toLowerCase()}`;
|
|
55
|
+
});
|
|
56
|
+
return id;
|
|
57
|
+
}
|
|
58
|
+
function registrationParams(params) {
|
|
59
|
+
const e_regid = Buffer.alloc(4);
|
|
60
|
+
e_regid.writeInt32BE(params.registrationId);
|
|
61
|
+
const e_skey_id = Buffer.alloc(3);
|
|
62
|
+
e_skey_id.writeInt16BE(params.signedPreKey.keyId);
|
|
63
|
+
params.phoneNumberCountryCode = params.phoneNumberCountryCode.replace('+', '').trim();
|
|
64
|
+
params.phoneNumberNationalNumber = params.phoneNumberNationalNumber.replace(/[/-\s)(]/g, '').trim();
|
|
65
|
+
return {
|
|
66
|
+
cc: params.phoneNumberCountryCode,
|
|
67
|
+
in: params.phoneNumberNationalNumber,
|
|
68
|
+
Rc: '0',
|
|
69
|
+
lg: 'en',
|
|
70
|
+
lc: 'GB',
|
|
71
|
+
mistyped: '6',
|
|
72
|
+
authkey: Buffer.from(params.noiseKey.public).toString('base64url'),
|
|
73
|
+
e_regid: e_regid.toString('base64url'),
|
|
74
|
+
e_keytype: 'BQ',
|
|
75
|
+
e_ident: Buffer.from(params.signedIdentityKey.public).toString('base64url'),
|
|
76
|
+
// e_skey_id: e_skey_id.toString('base64url'),
|
|
77
|
+
e_skey_id: 'AAAA',
|
|
78
|
+
e_skey_val: Buffer.from(params.signedPreKey.keyPair.public).toString('base64url'),
|
|
79
|
+
e_skey_sig: Buffer.from(params.signedPreKey.signature).toString('base64url'),
|
|
80
|
+
fdid: params.phoneId,
|
|
81
|
+
network_ratio_type: '1',
|
|
82
|
+
expid: params.deviceId,
|
|
83
|
+
simnum: '1',
|
|
84
|
+
hasinrc: '1',
|
|
85
|
+
pid: Math.floor(Math.random() * 1000).toString(),
|
|
86
|
+
id: convertBufferToUrlHex(params.identityId),
|
|
87
|
+
backup_token: convertBufferToUrlHex(params.backupToken),
|
|
88
|
+
token: (0, crypto_1.md5)(Buffer.concat([Defaults_1.MOBILE_TOKEN, Buffer.from(params.phoneNumberNationalNumber)])).toString('hex'),
|
|
89
|
+
fraud_checkpoint_code: params.captcha,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
exports.registrationParams = registrationParams;
|
|
93
|
+
/**
|
|
94
|
+
* Requests a registration code for the given phone number.
|
|
95
|
+
*/
|
|
96
|
+
function mobileRegisterCode(params, fetchOptions) {
|
|
97
|
+
return mobileRegisterFetch('/code', {
|
|
98
|
+
params: {
|
|
99
|
+
...registrationParams(params),
|
|
100
|
+
mcc: `${params.phoneNumberMobileCountryCode}`.padStart(3, '0'),
|
|
101
|
+
mnc: `${params.phoneNumberMobileNetworkCode || '001'}`.padStart(3, '0'),
|
|
102
|
+
sim_mcc: '000',
|
|
103
|
+
sim_mnc: '000',
|
|
104
|
+
method: (params === null || params === void 0 ? void 0 : params.method) || 'sms',
|
|
105
|
+
reason: '',
|
|
106
|
+
hasav: '1'
|
|
107
|
+
},
|
|
108
|
+
...fetchOptions,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
exports.mobileRegisterCode = mobileRegisterCode;
|
|
112
|
+
function mobileRegisterExists(params, fetchOptions) {
|
|
113
|
+
return mobileRegisterFetch('/exist', {
|
|
114
|
+
params: registrationParams(params),
|
|
115
|
+
...fetchOptions
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
exports.mobileRegisterExists = mobileRegisterExists;
|
|
119
|
+
/**
|
|
120
|
+
* Registers the phone number on whatsapp with the received OTP code.
|
|
121
|
+
*/
|
|
122
|
+
async function mobileRegister(params, fetchOptions) {
|
|
123
|
+
//const result = await mobileRegisterFetch(`/reg_onboard_abprop?cc=${params.phoneNumberCountryCode}&in=${params.phoneNumberNationalNumber}&rc=0`)
|
|
124
|
+
return mobileRegisterFetch('/register', {
|
|
125
|
+
params: { ...registrationParams(params), code: params.code.replace('-', '') },
|
|
126
|
+
...fetchOptions,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
exports.mobileRegister = mobileRegister;
|
|
130
|
+
/**
|
|
131
|
+
* Encrypts the given string as AEAD aes-256-gcm with the public whatsapp key and a random keypair.
|
|
132
|
+
*/
|
|
133
|
+
function mobileRegisterEncrypt(data) {
|
|
134
|
+
const keypair = crypto_1.Curve.generateKeyPair();
|
|
135
|
+
const key = crypto_1.Curve.sharedKey(keypair.private, Defaults_1.REGISTRATION_PUBLIC_KEY);
|
|
136
|
+
const buffer = (0, crypto_1.aesEncryptGCM)(Buffer.from(data), new Uint8Array(key), Buffer.alloc(12), Buffer.alloc(0));
|
|
137
|
+
return Buffer.concat([Buffer.from(keypair.public), buffer]).toString('base64url');
|
|
138
|
+
}
|
|
139
|
+
exports.mobileRegisterEncrypt = mobileRegisterEncrypt;
|
|
140
|
+
async function mobileRegisterFetch(path, opts = {}) {
|
|
141
|
+
let url = `${Defaults_1.MOBILE_REGISTRATION_ENDPOINT}${path}`;
|
|
142
|
+
if (opts.params) {
|
|
143
|
+
const parameter = [];
|
|
144
|
+
for (const param in opts.params) {
|
|
145
|
+
if (opts.params[param] !== null && opts.params[param] !== undefined) {
|
|
146
|
+
parameter.push(param + '=' + urlencode(opts.params[param]));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
url += `?${parameter.join('&')}`;
|
|
150
|
+
delete opts.params;
|
|
151
|
+
}
|
|
152
|
+
if (!opts.headers) {
|
|
153
|
+
opts.headers = {};
|
|
154
|
+
}
|
|
155
|
+
opts.headers['User-Agent'] = Defaults_1.MOBILE_USERAGENT;
|
|
156
|
+
const response = await (0, axios_1.default)(url, opts);
|
|
157
|
+
var json = response.data;
|
|
158
|
+
if (response.status > 300 || json.reason) {
|
|
159
|
+
throw json;
|
|
160
|
+
}
|
|
161
|
+
if (json.status && !['ok', 'sent'].includes(json.status)) {
|
|
162
|
+
throw json;
|
|
163
|
+
}
|
|
164
|
+
return json;
|
|
165
|
+
}
|
|
166
|
+
exports.mobileRegisterFetch = mobileRegisterFetch;
|
package/lib/Socket/socket.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { Boom } from '@hapi/boom';
|
|
2
3
|
import { SocketConfig } from '../Types';
|
|
3
4
|
import { BinaryNode } from '../WABinary';
|
|
4
|
-
import { WebSocketClient } from './Client';
|
|
5
5
|
/**
|
|
6
6
|
* Connects to WA servers and performs:
|
|
7
7
|
* - simple queries (no retry mechanism, wait for connection establishment)
|
|
@@ -10,12 +10,12 @@ import { WebSocketClient } from './Client';
|
|
|
10
10
|
*/
|
|
11
11
|
export declare const makeSocket: (config: SocketConfig) => {
|
|
12
12
|
type: "md";
|
|
13
|
-
ws:
|
|
13
|
+
ws: any;
|
|
14
14
|
ev: import("../Types").BaileysEventEmitter & {
|
|
15
|
-
process(handler: (events: Partial<import("../Types").BaileysEventMap>) => void | Promise<void>): (
|
|
15
|
+
process(handler: (events: Partial<import("../Types").BaileysEventMap>) => void | Promise<void>): () => void;
|
|
16
16
|
buffer(): void;
|
|
17
|
-
createBufferedFunction<A extends any[], T>(work: (...args: A) => Promise<T>): (
|
|
18
|
-
flush(force?: boolean): boolean;
|
|
17
|
+
createBufferedFunction<A extends any[], T>(work: (...args: A) => Promise<T>): (...args: A) => Promise<T>;
|
|
18
|
+
flush(force?: boolean | undefined): boolean;
|
|
19
19
|
isBuffering(): boolean;
|
|
20
20
|
};
|
|
21
21
|
authState: {
|
|
@@ -25,8 +25,8 @@ export declare const makeSocket: (config: SocketConfig) => {
|
|
|
25
25
|
signalRepository: import("../Types").SignalRepository;
|
|
26
26
|
readonly user: import("../Types").Contact | undefined;
|
|
27
27
|
generateMessageTag: () => string;
|
|
28
|
-
query: (node: BinaryNode, timeoutMs?: number) => Promise<
|
|
29
|
-
waitForMessage: <
|
|
28
|
+
query: (node: BinaryNode, timeoutMs?: number) => Promise<BinaryNode>;
|
|
29
|
+
waitForMessage: <T_1>(msgId: string, timeoutMs?: number | undefined) => Promise<T_1>;
|
|
30
30
|
waitForSocketOpen: () => Promise<void>;
|
|
31
31
|
sendRawMessage: (data: Uint8Array | Buffer) => Promise<void>;
|
|
32
32
|
sendNode: (frame: BinaryNode) => Promise<void>;
|
|
@@ -37,6 +37,7 @@ export declare const makeSocket: (config: SocketConfig) => {
|
|
|
37
37
|
uploadPreKeysToServerIfRequired: () => Promise<void>;
|
|
38
38
|
requestPairingCode: (phoneNumber: string) => Promise<string>;
|
|
39
39
|
/** Waits for the connection to WA to reach a state */
|
|
40
|
-
waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) =>
|
|
41
|
-
sendWAMBuffer: (wamBuffer: Buffer) => Promise<
|
|
40
|
+
waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
|
|
41
|
+
sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>;
|
|
42
42
|
};
|
|
43
|
+
export type Socket = ReturnType<typeof makeSocket>;
|
package/lib/Socket/socket.js
CHANGED
|
@@ -5,7 +5,7 @@ const boom_1 = require("@hapi/boom");
|
|
|
5
5
|
const crypto_1 = require("crypto");
|
|
6
6
|
const url_1 = require("url");
|
|
7
7
|
const util_1 = require("util");
|
|
8
|
-
const WAProto_1 = require("
|
|
8
|
+
const WAProto_1 = require("../../WAProto");
|
|
9
9
|
const Defaults_1 = require("../Defaults");
|
|
10
10
|
const Types_1 = require("../Types");
|
|
11
11
|
const Utils_1 = require("../Utils");
|
|
@@ -20,17 +20,15 @@ const Client_1 = require("./Client");
|
|
|
20
20
|
const makeSocket = (config) => {
|
|
21
21
|
var _a, _b;
|
|
22
22
|
const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, browser, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository, } = config;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (config.mobile || url.protocol === 'tcp:') {
|
|
28
|
-
throw new boom_1.Boom('Mobile API is not supported anymore', { statusCode: Types_1.DisconnectReason.loggedOut });
|
|
23
|
+
let url = typeof waWebSocketUrl === 'string' ? new url_1.URL(waWebSocketUrl) : waWebSocketUrl;
|
|
24
|
+
config.mobile = config.mobile || url.protocol === 'tcp:';
|
|
25
|
+
if (config.mobile && url.protocol !== 'tcp:') {
|
|
26
|
+
url = new url_1.URL(`tcp://${Defaults_1.MOBILE_ENDPOINT}:${Defaults_1.MOBILE_PORT}`);
|
|
29
27
|
}
|
|
30
|
-
if (url.protocol === 'wss' && ((_a = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _a === void 0 ? void 0 : _a.routingInfo)) {
|
|
28
|
+
if (!config.mobile && url.protocol === 'wss' && ((_a = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _a === void 0 ? void 0 : _a.routingInfo)) {
|
|
31
29
|
url.searchParams.append('ED', authState.creds.routingInfo.toString('base64url'));
|
|
32
30
|
}
|
|
33
|
-
const ws = new Client_1.WebSocketClient(url, config);
|
|
31
|
+
const ws = config.socket ? config.socket : config.mobile ? new Client_1.MobileSocketClient(url, config) : new Client_1.WebSocketClient(url, config);
|
|
34
32
|
ws.connect();
|
|
35
33
|
const ev = (0, Utils_1.makeEventBuffer)(logger);
|
|
36
34
|
/** ephemeral key pair used to encrypt/decrypt communication. Unique for each connection */
|
|
@@ -38,7 +36,8 @@ const makeSocket = (config) => {
|
|
|
38
36
|
/** WA noise protocol wrapper */
|
|
39
37
|
const noise = (0, Utils_1.makeNoiseHandler)({
|
|
40
38
|
keyPair: ephemeralKeyPair,
|
|
41
|
-
NOISE_HEADER: Defaults_1.NOISE_WA_HEADER,
|
|
39
|
+
NOISE_HEADER: config.mobile ? Defaults_1.MOBILE_NOISE_HEADER : Defaults_1.NOISE_WA_HEADER,
|
|
40
|
+
mobile: config.mobile,
|
|
42
41
|
logger,
|
|
43
42
|
routingInfo: (_b = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _b === void 0 ? void 0 : _b.routingInfo
|
|
44
43
|
});
|
|
@@ -117,7 +116,7 @@ const makeSocket = (config) => {
|
|
|
117
116
|
let onRecv;
|
|
118
117
|
let onErr;
|
|
119
118
|
try {
|
|
120
|
-
|
|
119
|
+
return await (0, Utils_1.promiseTimeout)(timeoutMs, (resolve, reject) => {
|
|
121
120
|
onRecv = resolve;
|
|
122
121
|
onErr = err => {
|
|
123
122
|
reject(err || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }));
|
|
@@ -126,7 +125,6 @@ const makeSocket = (config) => {
|
|
|
126
125
|
ws.on('close', onErr); // if the socket closes, you'll never receive the message
|
|
127
126
|
ws.off('error', onErr);
|
|
128
127
|
});
|
|
129
|
-
return result;
|
|
130
128
|
}
|
|
131
129
|
finally {
|
|
132
130
|
ws.off(`TAG:${msgId}`, onRecv);
|
|
@@ -140,10 +138,9 @@ const makeSocket = (config) => {
|
|
|
140
138
|
node.attrs.id = generateMessageTag();
|
|
141
139
|
}
|
|
142
140
|
const msgId = node.attrs.id;
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
]);
|
|
141
|
+
const wait = waitForMessage(msgId, timeoutMs);
|
|
142
|
+
await sendNode(node);
|
|
143
|
+
const result = await wait;
|
|
147
144
|
if ('tag' in result) {
|
|
148
145
|
(0, WABinary_1.assertNodeErrorFree)(result);
|
|
149
146
|
}
|
|
@@ -160,9 +157,12 @@ const makeSocket = (config) => {
|
|
|
160
157
|
const result = await awaitNextMessage(init);
|
|
161
158
|
const handshake = WAProto_1.proto.HandshakeMessage.decode(result);
|
|
162
159
|
logger.trace({ handshake }, 'handshake recv from WA');
|
|
163
|
-
const keyEnc =
|
|
160
|
+
const keyEnc = noise.processHandshake(handshake, creds.noiseKey);
|
|
164
161
|
let node;
|
|
165
|
-
if (
|
|
162
|
+
if (config.mobile) {
|
|
163
|
+
node = (0, Utils_1.generateMobileNode)(config);
|
|
164
|
+
}
|
|
165
|
+
else if (!creds.me) {
|
|
166
166
|
node = (0, Utils_1.generateRegistrationNode)(creds, config);
|
|
167
167
|
logger.info({ node }, 'not logged in, attempting registration...');
|
|
168
168
|
}
|
|
@@ -232,11 +232,11 @@ const makeSocket = (config) => {
|
|
|
232
232
|
const l0 = frame.tag;
|
|
233
233
|
const l1 = frame.attrs || {};
|
|
234
234
|
const l2 = Array.isArray(frame.content) ? (_a = frame.content[0]) === null || _a === void 0 ? void 0 : _a.tag : '';
|
|
235
|
-
|
|
235
|
+
Object.keys(l1).forEach(key => {
|
|
236
236
|
anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, frame) || anyTriggered;
|
|
237
237
|
anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, frame) || anyTriggered;
|
|
238
238
|
anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}`, frame) || anyTriggered;
|
|
239
|
-
}
|
|
239
|
+
});
|
|
240
240
|
anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},,${l2}`, frame) || anyTriggered;
|
|
241
241
|
anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0}`, frame) || anyTriggered;
|
|
242
242
|
if (!anyTriggered && logger.level === 'debug') {
|
|
@@ -531,14 +531,6 @@ const makeSocket = (config) => {
|
|
|
531
531
|
ws.on('CB:ib,,downgrade_webclient', () => {
|
|
532
532
|
end(new boom_1.Boom('Multi-device beta not joined', { statusCode: Types_1.DisconnectReason.multideviceMismatch }));
|
|
533
533
|
});
|
|
534
|
-
ws.on('CB:ib,,offline_preview', (node) => {
|
|
535
|
-
logger.info('offline preview received', JSON.stringify(node));
|
|
536
|
-
sendNode({
|
|
537
|
-
tag: 'ib',
|
|
538
|
-
attrs: {},
|
|
539
|
-
content: [{ tag: 'offline_batch', attrs: { count: '100' } }]
|
|
540
|
-
});
|
|
541
|
-
});
|
|
542
534
|
ws.on('CB:ib,,edge_routing', (node) => {
|
|
543
535
|
const edgeRoutingNode = (0, WABinary_1.getBinaryNodeChild)(node, 'edge_routing');
|
|
544
536
|
const routingInfo = (0, WABinary_1.getBinaryNodeChild)(edgeRoutingNode, 'routing_info');
|
|
@@ -586,6 +578,9 @@ const makeSocket = (config) => {
|
|
|
586
578
|
}
|
|
587
579
|
Object.assign(creds, update);
|
|
588
580
|
});
|
|
581
|
+
if (printQRInTerminal) {
|
|
582
|
+
(0, Utils_1.printQRIfNecessaryListener)(ev, logger);
|
|
583
|
+
}
|
|
589
584
|
return {
|
|
590
585
|
type: 'md',
|
|
591
586
|
ws,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.makeCacheManagerAuthState = exports.makeInMemoryStore = void 0;
|
|
7
|
+
const make_cache_manager_store_1 = __importDefault(require("./make-cache-manager-store"));
|
|
8
|
+
exports.makeCacheManagerAuthState = make_cache_manager_store_1.default;
|
|
9
|
+
const make_in_memory_store_1 = __importDefault(require("./make-in-memory-store"));
|
|
10
|
+
exports.makeInMemoryStore = make_in_memory_store_1.default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Store } from 'cache-manager';
|
|
2
|
+
import { AuthenticationCreds } from '../Types';
|
|
3
|
+
declare const makeCacheManagerAuthState: (store: Store, sessionKey: string) => Promise<{
|
|
4
|
+
clearState: () => Promise<void>;
|
|
5
|
+
saveCreds: () => Promise<void>;
|
|
6
|
+
state: {
|
|
7
|
+
creds: AuthenticationCreds;
|
|
8
|
+
keys: {
|
|
9
|
+
get: (type: string, ids: string[]) => Promise<{}>;
|
|
10
|
+
set: (data: any) => Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
}>;
|
|
14
|
+
export default makeCacheManagerAuthState;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const cache_manager_1 = require("cache-manager");
|
|
7
|
+
const WAProto_1 = require("../../WAProto");
|
|
8
|
+
const Utils_1 = require("../Utils");
|
|
9
|
+
const logger_1 = __importDefault(require("../Utils/logger"));
|
|
10
|
+
const makeCacheManagerAuthState = async (store, sessionKey) => {
|
|
11
|
+
const defaultKey = (file) => `${sessionKey}:${file}`;
|
|
12
|
+
const databaseConn = await (0, cache_manager_1.caching)(store);
|
|
13
|
+
const writeData = async (file, data) => {
|
|
14
|
+
let ttl = undefined;
|
|
15
|
+
if (file === 'creds') {
|
|
16
|
+
ttl = 63115200; // 2 years
|
|
17
|
+
}
|
|
18
|
+
await databaseConn.set(defaultKey(file), JSON.stringify(data, Utils_1.BufferJSON.replacer), ttl);
|
|
19
|
+
};
|
|
20
|
+
const readData = async (file) => {
|
|
21
|
+
try {
|
|
22
|
+
const data = await databaseConn.get(defaultKey(file));
|
|
23
|
+
if (data) {
|
|
24
|
+
return JSON.parse(data, Utils_1.BufferJSON.reviver);
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
logger_1.default.error(error);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const removeData = async (file) => {
|
|
34
|
+
try {
|
|
35
|
+
return await databaseConn.del(defaultKey(file));
|
|
36
|
+
}
|
|
37
|
+
catch (_a) {
|
|
38
|
+
logger_1.default.error(`Error removing ${file} from session ${sessionKey}`);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const clearState = async () => {
|
|
42
|
+
try {
|
|
43
|
+
const result = await databaseConn.store.keys(`${sessionKey}*`);
|
|
44
|
+
await Promise.all(result.map(async (key) => await databaseConn.del(key)));
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const creds = (await readData('creds')) || (0, Utils_1.initAuthCreds)();
|
|
50
|
+
return {
|
|
51
|
+
clearState,
|
|
52
|
+
saveCreds: () => writeData('creds', creds),
|
|
53
|
+
state: {
|
|
54
|
+
creds,
|
|
55
|
+
keys: {
|
|
56
|
+
get: async (type, ids) => {
|
|
57
|
+
const data = {};
|
|
58
|
+
await Promise.all(ids.map(async (id) => {
|
|
59
|
+
let value = await readData(`${type}-${id}`);
|
|
60
|
+
if (type === 'app-state-sync-key' && value) {
|
|
61
|
+
value = WAProto_1.proto.Message.AppStateSyncKeyData.fromObject(value);
|
|
62
|
+
}
|
|
63
|
+
data[id] = value;
|
|
64
|
+
}));
|
|
65
|
+
return data;
|
|
66
|
+
},
|
|
67
|
+
set: async (data) => {
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
|
+
const tasks = [];
|
|
70
|
+
for (const category in data) {
|
|
71
|
+
for (const id in data[category]) {
|
|
72
|
+
const value = data[category][id];
|
|
73
|
+
const key = `${category}-${id}`;
|
|
74
|
+
tasks.push(value ? writeData(key, value) : removeData(key));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
await Promise.all(tasks);
|
|
78
|
+
},
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
exports.default = makeCacheManagerAuthState;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type KeyedDB from '@adiwajshing/keyed-db';
|
|
2
|
+
import type { Comparable } from '@adiwajshing/keyed-db/lib/Types';
|
|
3
|
+
import type { Logger } from 'pino';
|
|
4
|
+
import { proto } from '../../WAProto';
|
|
5
|
+
import type makeMDSocket from '../Socket';
|
|
6
|
+
import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, PresenceData, WAMessage, WAMessageCursor, WAMessageKey } from '../Types';
|
|
7
|
+
import { Label } from '../Types/Label';
|
|
8
|
+
import { LabelAssociation } from '../Types/LabelAssociation';
|
|
9
|
+
import { ObjectRepository } from './object-repository';
|
|
10
|
+
type WASocket = ReturnType<typeof makeMDSocket>;
|
|
11
|
+
export declare const waChatKey: (pin: boolean) => {
|
|
12
|
+
key: (c: Chat) => string;
|
|
13
|
+
compare: (k1: string, k2: string) => number;
|
|
14
|
+
};
|
|
15
|
+
export declare const waMessageID: (m: WAMessage) => string;
|
|
16
|
+
export declare const waLabelAssociationKey: Comparable<LabelAssociation, string>;
|
|
17
|
+
export type BaileysInMemoryStoreConfig = {
|
|
18
|
+
chatKey?: Comparable<Chat, string>;
|
|
19
|
+
labelAssociationKey?: Comparable<LabelAssociation, string>;
|
|
20
|
+
logger?: Logger;
|
|
21
|
+
socket?: WASocket;
|
|
22
|
+
};
|
|
23
|
+
declare const _default: (config: BaileysInMemoryStoreConfig) => {
|
|
24
|
+
chats: KeyedDB<Chat, string>;
|
|
25
|
+
contacts: {
|
|
26
|
+
[_: string]: Contact;
|
|
27
|
+
};
|
|
28
|
+
messages: {
|
|
29
|
+
[_: string]: {
|
|
30
|
+
array: proto.IWebMessageInfo[];
|
|
31
|
+
get: (id: string) => proto.IWebMessageInfo | undefined;
|
|
32
|
+
upsert: (item: proto.IWebMessageInfo, mode: "append" | "prepend") => void;
|
|
33
|
+
update: (item: proto.IWebMessageInfo) => boolean;
|
|
34
|
+
remove: (item: proto.IWebMessageInfo) => boolean;
|
|
35
|
+
updateAssign: (id: string, update: Partial<proto.IWebMessageInfo>) => boolean;
|
|
36
|
+
clear: () => void;
|
|
37
|
+
filter: (contain: (item: proto.IWebMessageInfo) => boolean) => void;
|
|
38
|
+
toJSON: () => proto.IWebMessageInfo[];
|
|
39
|
+
fromJSON: (newItems: proto.IWebMessageInfo[]) => void;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
groupMetadata: {
|
|
43
|
+
[_: string]: GroupMetadata;
|
|
44
|
+
};
|
|
45
|
+
state: ConnectionState;
|
|
46
|
+
presences: {
|
|
47
|
+
[id: string]: {
|
|
48
|
+
[participant: string]: PresenceData;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
labels: ObjectRepository<Label>;
|
|
52
|
+
labelAssociations: KeyedDB<LabelAssociation, string>;
|
|
53
|
+
bind: (ev: BaileysEventEmitter) => void;
|
|
54
|
+
/** loads messages from the store, if not found -- uses the legacy connection */
|
|
55
|
+
loadMessages: (jid: string, count: number, cursor: WAMessageCursor) => Promise<proto.IWebMessageInfo[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Get all available labels for profile
|
|
58
|
+
*
|
|
59
|
+
* Keep in mind that the list is formed from predefined tags and tags
|
|
60
|
+
* that were "caught" during their editing.
|
|
61
|
+
*/
|
|
62
|
+
getLabels: () => ObjectRepository<Label>;
|
|
63
|
+
/**
|
|
64
|
+
* Get labels for chat
|
|
65
|
+
*
|
|
66
|
+
* @returns Label IDs
|
|
67
|
+
**/
|
|
68
|
+
getChatLabels: (chatId: string) => LabelAssociation[];
|
|
69
|
+
/**
|
|
70
|
+
* Get labels for message
|
|
71
|
+
*
|
|
72
|
+
* @returns Label IDs
|
|
73
|
+
**/
|
|
74
|
+
getMessageLabels: (messageId: string) => string[];
|
|
75
|
+
loadMessage: (jid: string, id: string) => Promise<proto.IWebMessageInfo | undefined>;
|
|
76
|
+
mostRecentMessage: (jid: string) => Promise<proto.IWebMessageInfo>;
|
|
77
|
+
fetchImageUrl: (jid: string, sock: WASocket | undefined) => Promise<string | null | undefined>;
|
|
78
|
+
fetchGroupMetadata: (jid: string, sock: WASocket | undefined) => Promise<GroupMetadata>;
|
|
79
|
+
fetchMessageReceipts: ({ remoteJid, id }: WAMessageKey) => Promise<proto.IUserReceipt[] | null | undefined>;
|
|
80
|
+
toJSON: () => {
|
|
81
|
+
chats: KeyedDB<Chat, string>;
|
|
82
|
+
contacts: {
|
|
83
|
+
[_: string]: Contact;
|
|
84
|
+
};
|
|
85
|
+
messages: {
|
|
86
|
+
[_: string]: {
|
|
87
|
+
array: proto.IWebMessageInfo[];
|
|
88
|
+
get: (id: string) => proto.IWebMessageInfo | undefined;
|
|
89
|
+
upsert: (item: proto.IWebMessageInfo, mode: "append" | "prepend") => void;
|
|
90
|
+
update: (item: proto.IWebMessageInfo) => boolean;
|
|
91
|
+
remove: (item: proto.IWebMessageInfo) => boolean;
|
|
92
|
+
updateAssign: (id: string, update: Partial<proto.IWebMessageInfo>) => boolean;
|
|
93
|
+
clear: () => void;
|
|
94
|
+
filter: (contain: (item: proto.IWebMessageInfo) => boolean) => void;
|
|
95
|
+
toJSON: () => proto.IWebMessageInfo[];
|
|
96
|
+
fromJSON: (newItems: proto.IWebMessageInfo[]) => void;
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
labels: ObjectRepository<Label>;
|
|
100
|
+
labelAssociations: KeyedDB<LabelAssociation, string>;
|
|
101
|
+
};
|
|
102
|
+
fromJSON: (json: {
|
|
103
|
+
chats: Chat[];
|
|
104
|
+
contacts: {
|
|
105
|
+
[id: string]: Contact;
|
|
106
|
+
};
|
|
107
|
+
messages: {
|
|
108
|
+
[id: string]: proto.IWebMessageInfo[];
|
|
109
|
+
};
|
|
110
|
+
labels: {
|
|
111
|
+
[labelId: string]: Label;
|
|
112
|
+
};
|
|
113
|
+
labelAssociations: LabelAssociation[];
|
|
114
|
+
}) => void;
|
|
115
|
+
writeToFile: (path: string) => void;
|
|
116
|
+
readFromFile: (path: string) => void;
|
|
117
|
+
};
|
|
118
|
+
export default _default;
|