@fer2809fl/baileys 1.4.5

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.
Files changed (205) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +424 -0
  3. package/WAProto/GenerateStatics.sh +4 -0
  4. package/WAProto/WAProto.proto +4775 -0
  5. package/WAProto/index.d.ts +55057 -0
  6. package/WAProto/index.js +169661 -0
  7. package/WAProto/index.ts.ts +53473 -0
  8. package/WAProto/n +1 -0
  9. package/lib/Defaults/baileys-version.json +3 -0
  10. package/lib/Defaults/index.d.ts +62 -0
  11. package/lib/Defaults/index.js +117 -0
  12. package/lib/Defaults/n +1 -0
  13. package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
  14. package/lib/Signal/Group/ciphertext-message.js +15 -0
  15. package/lib/Signal/Group/group-session-builder.d.ts +14 -0
  16. package/lib/Signal/Group/group-session-builder.js +64 -0
  17. package/lib/Signal/Group/group_cipher.d.ts +17 -0
  18. package/lib/Signal/Group/group_cipher.js +96 -0
  19. package/lib/Signal/Group/index.d.ts +11 -0
  20. package/lib/Signal/Group/index.js +57 -0
  21. package/lib/Signal/Group/keyhelper.d.ts +10 -0
  22. package/lib/Signal/Group/keyhelper.js +55 -0
  23. package/lib/Signal/Group/queue-job.d.ts +1 -0
  24. package/lib/Signal/Group/queue-job.js +57 -0
  25. package/lib/Signal/Group/sender-chain-key.d.ts +13 -0
  26. package/lib/Signal/Group/sender-chain-key.js +34 -0
  27. package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -0
  28. package/lib/Signal/Group/sender-key-distribution-message.js +66 -0
  29. package/lib/Signal/Group/sender-key-message.d.ts +18 -0
  30. package/lib/Signal/Group/sender-key-message.js +69 -0
  31. package/lib/Signal/Group/sender-key-name.d.ts +17 -0
  32. package/lib/Signal/Group/sender-key-name.js +51 -0
  33. package/lib/Signal/Group/sender-key-record.d.ts +30 -0
  34. package/lib/Signal/Group/sender-key-record.js +53 -0
  35. package/lib/Signal/Group/sender-key-state.d.ts +38 -0
  36. package/lib/Signal/Group/sender-key-state.js +99 -0
  37. package/lib/Signal/Group/sender-message-key.d.ts +11 -0
  38. package/lib/Signal/Group/sender-message-key.js +29 -0
  39. package/lib/Signal/libsignal.d.ts +3 -0
  40. package/lib/Signal/libsignal.js +174 -0
  41. package/lib/Signal/n +1 -0
  42. package/lib/Socket/Client/index.d.ts +2 -0
  43. package/lib/Socket/Client/index.js +18 -0
  44. package/lib/Socket/Client/n +1 -0
  45. package/lib/Socket/Client/types.d.ts +16 -0
  46. package/lib/Socket/Client/types.js +13 -0
  47. package/lib/Socket/Client/websocket.d.ts +13 -0
  48. package/lib/Socket/Client/websocket.js +111 -0
  49. package/lib/Socket/business.d.ts +172 -0
  50. package/lib/Socket/business.js +260 -0
  51. package/lib/Socket/chats.d.ts +82 -0
  52. package/lib/Socket/chats.js +871 -0
  53. package/lib/Socket/groups.d.ts +124 -0
  54. package/lib/Socket/groups.js +332 -0
  55. package/lib/Socket/index.d.ts +172 -0
  56. package/lib/Socket/index.js +10 -0
  57. package/lib/Socket/messages-recv.d.ts +161 -0
  58. package/lib/Socket/messages-recv.js +1054 -0
  59. package/lib/Socket/messages-send.d.ts +151 -0
  60. package/lib/Socket/messages-send.js +1057 -0
  61. package/lib/Socket/n +1 -0
  62. package/lib/Socket/newsletter.d.ts +136 -0
  63. package/lib/Socket/newsletter.js +268 -0
  64. package/lib/Socket/setup.js +480 -0
  65. package/lib/Socket/setup.ts +622 -0
  66. package/lib/Socket/socket.d.ts +270 -0
  67. package/lib/Socket/socket.js +534 -0
  68. package/lib/Socket/usync.d.ts +36 -0
  69. package/lib/Socket/usync.js +70 -0
  70. package/lib/Store/index.d.ts +2 -0
  71. package/lib/Store/index.js +8 -0
  72. package/lib/Store/make-in-memory-store.d.ts +118 -0
  73. package/lib/Store/make-in-memory-store.js +439 -0
  74. package/lib/Store/make-ordered-dictionary.d.ts +13 -0
  75. package/lib/Store/make-ordered-dictionary.js +81 -0
  76. package/lib/Store/n +1 -0
  77. package/lib/Store/object-repository.d.ts +10 -0
  78. package/lib/Store/object-repository.js +27 -0
  79. package/lib/Types/Auth.d.ts +103 -0
  80. package/lib/Types/Auth.js +2 -0
  81. package/lib/Types/Call.d.ts +13 -0
  82. package/lib/Types/Call.js +2 -0
  83. package/lib/Types/Chat.d.ts +109 -0
  84. package/lib/Types/Chat.js +4 -0
  85. package/lib/Types/Contact.d.ts +23 -0
  86. package/lib/Types/Contact.js +2 -0
  87. package/lib/Types/Events.d.ts +199 -0
  88. package/lib/Types/Events.js +2 -0
  89. package/lib/Types/GroupMetadata.d.ts +64 -0
  90. package/lib/Types/GroupMetadata.js +2 -0
  91. package/lib/Types/Label.d.ts +35 -0
  92. package/lib/Types/Label.js +27 -0
  93. package/lib/Types/LabelAssociation.d.ts +29 -0
  94. package/lib/Types/LabelAssociation.js +9 -0
  95. package/lib/Types/Message.d.ts +400 -0
  96. package/lib/Types/Message.js +7 -0
  97. package/lib/Types/Newsletter.d.ts +79 -0
  98. package/lib/Types/Newsletter.js +18 -0
  99. package/lib/Types/Product.d.ts +78 -0
  100. package/lib/Types/Product.js +2 -0
  101. package/lib/Types/Signal.d.ts +57 -0
  102. package/lib/Types/Signal.js +2 -0
  103. package/lib/Types/Socket.d.ts +119 -0
  104. package/lib/Types/Socket.js +2 -0
  105. package/lib/Types/State.d.ts +27 -0
  106. package/lib/Types/State.js +2 -0
  107. package/lib/Types/USync.d.ts +25 -0
  108. package/lib/Types/USync.js +2 -0
  109. package/lib/Types/index.d.ts +64 -0
  110. package/lib/Types/index.js +42 -0
  111. package/lib/Types/n +1 -0
  112. package/lib/Utils/auth-utils.d.ts +18 -0
  113. package/lib/Utils/auth-utils.js +199 -0
  114. package/lib/Utils/baileys-event-stream.d.ts +16 -0
  115. package/lib/Utils/baileys-event-stream.js +63 -0
  116. package/lib/Utils/business.d.ts +22 -0
  117. package/lib/Utils/business.js +234 -0
  118. package/lib/Utils/chat-utils.d.ts +70 -0
  119. package/lib/Utils/chat-utils.js +730 -0
  120. package/lib/Utils/crypto.d.ts +40 -0
  121. package/lib/Utils/crypto.js +193 -0
  122. package/lib/Utils/decode-wa-message.d.ts +35 -0
  123. package/lib/Utils/decode-wa-message.js +207 -0
  124. package/lib/Utils/event-buffer.d.ts +35 -0
  125. package/lib/Utils/event-buffer.js +518 -0
  126. package/lib/Utils/generics.d.ts +89 -0
  127. package/lib/Utils/generics.js +441 -0
  128. package/lib/Utils/history.d.ts +19 -0
  129. package/lib/Utils/history.js +94 -0
  130. package/lib/Utils/index.d.ts +17 -0
  131. package/lib/Utils/index.js +33 -0
  132. package/lib/Utils/link-preview.d.ts +21 -0
  133. package/lib/Utils/link-preview.js +126 -0
  134. package/lib/Utils/logger.d.ts +11 -0
  135. package/lib/Utils/logger.js +10 -0
  136. package/lib/Utils/lt-hash.d.ts +12 -0
  137. package/lib/Utils/lt-hash.js +51 -0
  138. package/lib/Utils/make-mutex.d.ts +7 -0
  139. package/lib/Utils/make-mutex.js +43 -0
  140. package/lib/Utils/messages-media.d.ts +120 -0
  141. package/lib/Utils/messages-media.js +980 -0
  142. package/lib/Utils/messages.d.ts +80 -0
  143. package/lib/Utils/messages.js +1101 -0
  144. package/lib/Utils/n +1 -0
  145. package/lib/Utils/noise-handler.d.ts +19 -0
  146. package/lib/Utils/noise-handler.js +150 -0
  147. package/lib/Utils/process-message.d.ts +42 -0
  148. package/lib/Utils/process-message.js +404 -0
  149. package/lib/Utils/signal.d.ts +33 -0
  150. package/lib/Utils/signal.js +153 -0
  151. package/lib/Utils/use-multi-file-auth-state.d.ts +12 -0
  152. package/lib/Utils/use-multi-file-auth-state.js +125 -0
  153. package/lib/Utils/validate-connection.d.ts +10 -0
  154. package/lib/Utils/validate-connection.js +229 -0
  155. package/lib/WABinary/constants.d.ts +27 -0
  156. package/lib/WABinary/constants.js +1303 -0
  157. package/lib/WABinary/decode.d.ts +6 -0
  158. package/lib/WABinary/decode.js +265 -0
  159. package/lib/WABinary/encode.d.ts +2 -0
  160. package/lib/WABinary/encode.js +250 -0
  161. package/lib/WABinary/generic-utils.d.ts +14 -0
  162. package/lib/WABinary/generic-utils.js +110 -0
  163. package/lib/WABinary/index.d.ts +5 -0
  164. package/lib/WABinary/index.js +21 -0
  165. package/lib/WABinary/jid-utils.d.ts +37 -0
  166. package/lib/WABinary/jid-utils.js +85 -0
  167. package/lib/WABinary/jid-utils.js.bak +83 -0
  168. package/lib/WABinary/n +1 -0
  169. package/lib/WABinary/types.d.ts +18 -0
  170. package/lib/WABinary/types.js +2 -0
  171. package/lib/WAM/BinaryInfo.d.ts +8 -0
  172. package/lib/WAM/BinaryInfo.js +13 -0
  173. package/lib/WAM/constants.d.ts +38 -0
  174. package/lib/WAM/constants.js +15350 -0
  175. package/lib/WAM/encode.d.ts +2 -0
  176. package/lib/WAM/encode.js +155 -0
  177. package/lib/WAM/index.d.ts +3 -0
  178. package/lib/WAM/index.js +19 -0
  179. package/lib/WAM/n +1 -0
  180. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -0
  181. package/lib/WAUSync/Protocols/USyncContactProtocol.js +32 -0
  182. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -0
  183. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
  184. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
  185. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
  186. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
  187. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
  188. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +25 -0
  189. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +53 -0
  190. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +8 -0
  191. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +24 -0
  192. package/lib/WAUSync/Protocols/index.d.ts +4 -0
  193. package/lib/WAUSync/Protocols/index.js +20 -0
  194. package/lib/WAUSync/Protocols/n +1 -0
  195. package/lib/WAUSync/USyncQuery.d.ts +28 -0
  196. package/lib/WAUSync/USyncQuery.js +89 -0
  197. package/lib/WAUSync/USyncUser.d.ts +12 -0
  198. package/lib/WAUSync/USyncUser.js +26 -0
  199. package/lib/WAUSync/index.d.ts +3 -0
  200. package/lib/WAUSync/index.js +19 -0
  201. package/lib/WAUSync/n +1 -0
  202. package/lib/index.d.ts +16 -0
  203. package/lib/index.js +48 -0
  204. package/lib/n +1 -0
  205. package/package.json +103 -0
@@ -0,0 +1,534 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeSocket = void 0;
4
+ const boom_1 = require("@hapi/boom");
5
+ const crypto_1 = require("crypto");
6
+ const url_1 = require("url");
7
+ const util_1 = require("util");
8
+ const WAProto_1 = require("../../WAProto");
9
+ const Defaults_1 = require("../Defaults");
10
+ const Types_1 = require("../Types");
11
+ const Utils_1 = require("../Utils");
12
+ const WABinary_1 = require("../WABinary");
13
+ const Client_1 = require("./Client");
14
+
15
+ const makeSocket = (config) => {
16
+ var _a, _b;
17
+ const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, browser, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository, } = config;
18
+ const url = typeof waWebSocketUrl === 'string' ? new url_1.URL(waWebSocketUrl) : waWebSocketUrl;
19
+ if (config.mobile || url.protocol === 'tcp:') {
20
+ throw new boom_1.Boom('Mobile API is not supported anymore', { statusCode: Types_1.DisconnectReason.loggedOut });
21
+ }
22
+ if (url.protocol === 'wss' && ((_a = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _a === void 0 ? void 0 : _a.routingInfo)) {
23
+ url.searchParams.append('ED', authState.creds.routingInfo.toString('base64url'));
24
+ }
25
+ const ws = new Client_1.WebSocketClient(url, config);
26
+ ws.connect();
27
+ const ev = (0, Utils_1.makeEventBuffer)(logger);
28
+ const ephemeralKeyPair = Utils_1.Curve.generateKeyPair();
29
+ const noise = (0, Utils_1.makeNoiseHandler)({
30
+ keyPair: ephemeralKeyPair,
31
+ NOISE_HEADER: Defaults_1.NOISE_WA_HEADER,
32
+ logger,
33
+ routingInfo: (_b = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _b === void 0 ? void 0 : _b.routingInfo
34
+ });
35
+ const { creds } = authState;
36
+ const keys = (0, Utils_1.addTransactionCapability)(authState.keys, logger, transactionOpts);
37
+ const signalRepository = makeSignalRepository({ creds, keys });
38
+ let lastDateRecv;
39
+ let epoch = 1;
40
+ let keepAliveReq;
41
+ let qrTimer;
42
+ let closed = false;
43
+ const uqTagId = (0, Utils_1.generateMdTagPrefix)();
44
+ const generateMessageTag = () => `${uqTagId}${epoch++}`;
45
+ const sendPromise = (0, util_1.promisify)(ws.send);
46
+
47
+ const sendRawMessage = async (data) => {
48
+ try {
49
+ if (!ws.isOpen) {
50
+ throw new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed });
51
+ }
52
+ const bytes = noise.encodeFrame(data);
53
+ await (0, Utils_1.promiseTimeout)(connectTimeoutMs, async (resolve, reject) => {
54
+ try {
55
+ await sendPromise.call(ws, bytes);
56
+ resolve();
57
+ }
58
+ catch (error) {
59
+ reject(error || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }));
60
+ }
61
+ });
62
+ } catch (err) {
63
+ logger.error({ err }, 'Error in sendRawMessage');
64
+ throw err;
65
+ }
66
+ };
67
+
68
+ const sendNode = (frame) => {
69
+ try {
70
+ if (logger.level === 'trace') {
71
+ logger.trace({ xml: (0, WABinary_1.binaryNodeToString)(frame), msg: 'xml send' });
72
+ }
73
+ const buff = (0, WABinary_1.encodeBinaryNode)(frame);
74
+ return sendRawMessage(buff);
75
+ } catch (error) {
76
+ logger.error({ error }, 'Error sending node');
77
+ }
78
+ };
79
+
80
+ const onUnexpectedError = (err, msg) => {
81
+ logger.error({ err }, `unexpected error in '${msg}'`);
82
+ const message = (err && ((err.stack || err.message) || String(err))).toLowerCase();
83
+ if (message.includes('bad mac') || (message.includes('mac') && message.includes('invalid'))) {
84
+ try {
85
+ uploadPreKeysToServerIfRequired(true)
86
+ .catch(e => logger.warn({ e }, 'failed to re-upload prekeys after bad mac'));
87
+ }
88
+ catch (_e) { }
89
+ }
90
+ if (message.includes('429') || message.includes('rate limit')) {
91
+ const wait = Math.min(30000, (config.backoffDelayMs || 5000));
92
+ logger.info({ wait }, 'backing off due to rate limit');
93
+ setTimeout(() => { }, wait);
94
+ }
95
+ };
96
+
97
+ const awaitNextMessage = async (sendMsg) => {
98
+ if (!ws.isOpen) {
99
+ throw new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed });
100
+ }
101
+ let onOpen;
102
+ let onClose;
103
+ const result = (0, Utils_1.promiseTimeout)(connectTimeoutMs, (resolve, reject) => {
104
+ onOpen = resolve;
105
+ onClose = mapWebSocketError(reject);
106
+ ws.on('frame', onOpen);
107
+ ws.on('close', onClose);
108
+ ws.on('error', onClose);
109
+ })
110
+ .finally(() => {
111
+ ws.off('frame', onOpen);
112
+ ws.off('close', onClose);
113
+ ws.off('error', onClose);
114
+ });
115
+ if (sendMsg) {
116
+ sendRawMessage(sendMsg).catch(err => {
117
+ if (onClose) onClose(err);
118
+ });
119
+ }
120
+ return result;
121
+ };
122
+
123
+ const waitForMessage = async (msgId, timeoutMs = defaultQueryTimeoutMs) => {
124
+ let onRecv;
125
+ let onErr;
126
+ try {
127
+ const result = await (0, Utils_1.promiseTimeout)(timeoutMs, (resolve, reject) => {
128
+ onRecv = resolve;
129
+ onErr = err => {
130
+ reject(err || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }));
131
+ };
132
+ ws.on(`TAG:${msgId}`, onRecv);
133
+ ws.on('close', onErr);
134
+ ws.on('error', onErr);
135
+ });
136
+ return result;
137
+ }
138
+ finally {
139
+ ws.off(`TAG:${msgId}`, onRecv);
140
+ ws.off('close', onErr);
141
+ ws.off('error', onErr);
142
+ }
143
+ };
144
+
145
+ const query = async (node, timeoutMs) => {
146
+ if (!node.attrs.id) {
147
+ node.attrs.id = generateMessageTag();
148
+ }
149
+ const msgId = node.attrs.id;
150
+ try {
151
+ const [result] = await Promise.all([
152
+ waitForMessage(msgId, timeoutMs),
153
+ sendNode(node)
154
+ ]);
155
+ if (result && 'tag' in result) {
156
+ (0, WABinary_1.assertNodeErrorFree)(result);
157
+ }
158
+ return result;
159
+ } catch (error) {
160
+ throw error;
161
+ }
162
+ };
163
+
164
+ const validateConnection = async () => {
165
+ try {
166
+ let helloMsg = { clientHello: { ephemeral: ephemeralKeyPair.public } };
167
+ helloMsg = WAProto_1.proto.HandshakeMessage.fromObject(helloMsg);
168
+ logger.info({ browser, helloMsg }, 'connected to WA');
169
+ const init = WAProto_1.proto.HandshakeMessage.encode(helloMsg).finish();
170
+ const result = await awaitNextMessage(init);
171
+ const handshake = WAProto_1.proto.HandshakeMessage.decode(result);
172
+ logger.trace({ handshake }, 'handshake recv from WA');
173
+ const keyEnc = await noise.processHandshake(handshake, creds.noiseKey);
174
+ let node;
175
+ if (!creds.me) {
176
+ node = (0, Utils_1.generateRegistrationNode)(creds, config);
177
+ logger.info({ node }, 'not logged in, attempting registration...');
178
+ }
179
+ else {
180
+ node = (0, Utils_1.generateLoginNode)(creds.me.id, config);
181
+ logger.info({ node }, 'logging in...');
182
+ }
183
+ const payloadEnc = noise.encrypt(WAProto_1.proto.ClientPayload.encode(node).finish());
184
+ await sendRawMessage(WAProto_1.proto.HandshakeMessage.encode({
185
+ clientFinish: { static: keyEnc, payload: payloadEnc },
186
+ }).finish());
187
+ noise.finishInit();
188
+ startKeepAliveRequest();
189
+ } catch (err) {
190
+ logger.error({ err }, 'error in validating connection');
191
+ end(err);
192
+ }
193
+ };
194
+
195
+ const getAvailablePreKeysOnServer = async () => {
196
+ const result = await query({
197
+ tag: 'iq',
198
+ attrs: {
199
+ id: generateMessageTag(),
200
+ xmlns: 'encrypt',
201
+ type: 'get',
202
+ to: WABinary_1.S_WHATSAPP_NET
203
+ },
204
+ content: [{ tag: 'count', attrs: {} }]
205
+ });
206
+ const countChild = (0, WABinary_1.getBinaryNodeChild)(result, 'count');
207
+ return +countChild.attrs.value;
208
+ };
209
+
210
+ const uploadPreKeys = async (count = Defaults_1.INITIAL_PREKEY_COUNT) => {
211
+ await keys.transaction(async () => {
212
+ logger.info({ count }, 'uploading pre-keys');
213
+ const { update, node } = await (0, Utils_1.getNextPreKeysNode)({ creds, keys }, count);
214
+ await query(node);
215
+ ev.emit('creds.update', update);
216
+ logger.info({ count }, 'uploaded pre-keys');
217
+ });
218
+ };
219
+
220
+ const uploadPreKeysToServerIfRequired = async () => {
221
+ const preKeyCount = await getAvailablePreKeysOnServer();
222
+ logger.info(`${preKeyCount} pre-keys found on server`);
223
+ if (preKeyCount <= Defaults_1.MIN_PREKEY_COUNT) {
224
+ await uploadPreKeys();
225
+ }
226
+ };
227
+
228
+ const onMessageReceived = (data) => {
229
+ noise.decodeFrame(data, frame => {
230
+ var _a;
231
+ lastDateRecv = new Date();
232
+ let anyTriggered = false;
233
+ anyTriggered = ws.emit('frame', frame);
234
+ if (!(frame instanceof Uint8Array)) {
235
+ const msgId = frame.attrs.id;
236
+ if (logger.level === 'trace') {
237
+ logger.trace({ xml: (0, WABinary_1.binaryNodeToString)(frame), msg: 'recv xml' });
238
+ }
239
+ anyTriggered = ws.emit(`${Defaults_1.DEF_TAG_PREFIX}${msgId}`, frame) || anyTriggered;
240
+ const l0 = frame.tag;
241
+ const l1 = frame.attrs || {};
242
+ const l2 = Array.isArray(frame.content) ? (_a = frame.content[0]) === null || _a === void 0 ? void 0 : _a.tag : '';
243
+ for (const key of Object.keys(l1)) {
244
+ anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, frame) || anyTriggered;
245
+ anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, frame) || anyTriggered;
246
+ anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}`, frame) || anyTriggered;
247
+ }
248
+ anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},,${l2}`, frame) || anyTriggered;
249
+ anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0}`, frame) || anyTriggered;
250
+ if (!anyTriggered && logger.level === 'debug') {
251
+ logger.debug({ unhandled: true, msgId, fromMe: false, frame }, 'communication recv');
252
+ }
253
+ }
254
+ });
255
+ };
256
+
257
+ const end = (error) => {
258
+ if (closed) return;
259
+ closed = true;
260
+ logger.info({ trace: error === null || error === void 0 ? void 0 : error.stack }, error ? 'connection errored' : 'connection closed');
261
+ clearInterval(keepAliveReq);
262
+ clearTimeout(qrTimer);
263
+ ws.removeAllListeners('close');
264
+ ws.removeAllListeners('error');
265
+ ws.removeAllListeners('open');
266
+ ws.removeAllListeners('message');
267
+ if (!ws.isClosed && !ws.isClosing) {
268
+ try { ws.close(); } catch (_a) { }
269
+ }
270
+ ev.emit('connection.update', {
271
+ connection: 'close',
272
+ lastDisconnect: { error, date: new Date() }
273
+ });
274
+ ev.removeAllListeners('connection.update');
275
+ };
276
+
277
+ const waitForSocketOpen = async () => {
278
+ if (ws.isOpen) return;
279
+ if (ws.isClosed || ws.isClosing) {
280
+ throw new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed });
281
+ }
282
+ let onOpen;
283
+ let onClose;
284
+ await new Promise((resolve, reject) => {
285
+ onOpen = () => resolve(undefined);
286
+ onClose = mapWebSocketError(reject);
287
+ ws.on('open', onOpen);
288
+ ws.on('close', onClose);
289
+ ws.on('error', onClose);
290
+ })
291
+ .finally(() => {
292
+ ws.off('open', onOpen);
293
+ ws.off('close', onClose);
294
+ ws.off('error', onClose);
295
+ });
296
+ };
297
+
298
+ const startKeepAliveRequest = () => (keepAliveReq = setInterval(() => {
299
+ if (!lastDateRecv) lastDateRecv = new Date();
300
+ const diff = Date.now() - lastDateRecv.getTime();
301
+ if (diff > keepAliveIntervalMs + 5000) {
302
+ end(new boom_1.Boom('Connection was lost', { statusCode: Types_1.DisconnectReason.connectionLost }));
303
+ }
304
+ else if (ws.isOpen) {
305
+ query({
306
+ tag: 'iq',
307
+ attrs: {
308
+ id: generateMessageTag(),
309
+ to: WABinary_1.S_WHATSAPP_NET,
310
+ type: 'get',
311
+ xmlns: 'w:p',
312
+ },
313
+ content: [{ tag: 'ping', attrs: {} }]
314
+ }).catch(err => {
315
+ logger.error({ trace: err.stack }, 'error in sending keep alive');
316
+ });
317
+ }
318
+ }, keepAliveIntervalMs));
319
+
320
+ const sendPassiveIq = (tag) => (query({
321
+ tag: 'iq',
322
+ attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'passive', type: 'set' },
323
+ content: [{ tag, attrs: {} }]
324
+ }));
325
+
326
+ const logout = async (msg) => {
327
+ var _a;
328
+ const jid = (_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id;
329
+ if (jid) {
330
+ await sendNode({
331
+ tag: 'iq',
332
+ attrs: { to: WABinary_1.S_WHATSAPP_NET, type: 'set', id: generateMessageTag(), xmlns: 'md' },
333
+ content: [{ tag: 'remove-companion-device', attrs: { jid, reason: 'user_initiated' } }]
334
+ });
335
+ }
336
+ end(new boom_1.Boom(msg || 'Intentional Logout', { statusCode: Types_1.DisconnectReason.loggedOut }));
337
+ };
338
+
339
+ const requestPairingCode = async (phoneNumber, pairKey) => {
340
+ try {
341
+ if (!pairKey) {
342
+ const randomSuffix = (0, crypto_1.randomBytes)(2).toString('hex').toUpperCase().slice(0, 4);
343
+ pairKey = `ASTA${randomSuffix}`;
344
+ }
345
+ authState.creds.pairingCode = pairKey.toUpperCase();
346
+ authState.creds.me = {
347
+ id: (0, WABinary_1.jidEncode)(phoneNumber, 's.whatsapp.net'),
348
+ name: '~'
349
+ };
350
+ ev.emit('creds.update', authState.creds);
351
+ await sendNode({
352
+ tag: 'iq',
353
+ attrs: { to: WABinary_1.S_WHATSAPP_NET, type: 'set', id: generateMessageTag(), xmlns: 'md' },
354
+ content: [
355
+ {
356
+ tag: 'link_code_companion_reg',
357
+ attrs: {
358
+ jid: authState.creds.me.id,
359
+ stage: 'companion_hello',
360
+ should_show_push_notification: 'true'
361
+ },
362
+ content: [
363
+ { tag: 'link_code_pairing_wrapped_companion_ephemeral_pub', attrs: {}, content: await generatePairingKey() },
364
+ { tag: 'companion_server_auth_key_pub', attrs: {}, content: authState.creds.noiseKey.public },
365
+ { tag: 'companion_platform_id', attrs: {}, content: (0, Utils_1.getPlatformId)(browser[1]) },
366
+ { tag: 'companion_platform_display', attrs: {}, content: `${browser[1]} (${browser[0]})` },
367
+ { tag: 'link_code_pairing_nonce', attrs: {}, content: '0' }
368
+ ]
369
+ }
370
+ ]
371
+ });
372
+ return authState.creds.pairingCode;
373
+ } catch (error) {
374
+ logger.error({ error }, 'Error requesting pairing code');
375
+ throw error;
376
+ }
377
+ };
378
+
379
+ async function generatePairingKey() {
380
+ const salt = (0, crypto_1.randomBytes)(32);
381
+ const randomIv = (0, crypto_1.randomBytes)(16);
382
+ const key = await (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
383
+ const ciphered = (0, Utils_1.aesEncryptCTR)(authState.creds.pairingEphemeralKeyPair.public, key, randomIv);
384
+ return Buffer.concat([salt, randomIv, ciphered]);
385
+ }
386
+
387
+ const sendWAMBuffer = (wamBuffer) => {
388
+ return query({
389
+ tag: 'iq',
390
+ attrs: { to: WABinary_1.S_WHATSAPP_NET, id: generateMessageTag(), xmlns: 'w:stats' },
391
+ content: [{ tag: 'add', attrs: {}, content: wamBuffer }]
392
+ });
393
+ };
394
+
395
+ ws.on('message', onMessageReceived);
396
+ ws.on('open', async () => {
397
+ try { await validateConnection(); }
398
+ catch (err) {
399
+ logger.error({ err }, 'error in validating connection');
400
+ end(err);
401
+ }
402
+ });
403
+ ws.on('error', mapWebSocketError(end));
404
+ ws.on('close', () => end(new boom_1.Boom('Connection Terminated', { statusCode: Types_1.DisconnectReason.connectionClosed })));
405
+ ws.on('CB:xmlstreamend', () => end(new boom_1.Boom('Connection Terminated by Server', { statusCode: Types_1.DisconnectReason.connectionClosed })));
406
+
407
+ ws.on('CB:iq,type:set,pair-device', async (stanza) => {
408
+ const iq = { tag: 'iq', attrs: { to: WABinary_1.S_WHATSAPP_NET, type: 'result', id: stanza.attrs.id } };
409
+ await sendNode(iq);
410
+ const pairDeviceNode = (0, WABinary_1.getBinaryNodeChild)(stanza, 'pair-device');
411
+ const refNodes = (0, WABinary_1.getBinaryNodeChildren)(pairDeviceNode, 'ref');
412
+ const noiseKeyB64 = Buffer.from(creds.noiseKey.public).toString('base64');
413
+ const identityKeyB64 = Buffer.from(creds.signedIdentityKey.public).toString('base64');
414
+ const advB64 = creds.advSecretKey;
415
+ let qrMs = qrTimeout || 60000;
416
+ const genPairQR = () => {
417
+ if (!ws.isOpen) return;
418
+ const refNode = refNodes.shift();
419
+ if (!refNode) {
420
+ end(new boom_1.Boom('QR refs attempts ended', { statusCode: Types_1.DisconnectReason.timedOut }));
421
+ return;
422
+ }
423
+ const ref = refNode.content.toString('utf-8');
424
+ const qr = [ref, noiseKeyB64, identityKeyB64, advB64].join(',');
425
+ ev.emit('connection.update', { qr });
426
+ qrTimer = setTimeout(genPairQR, qrMs);
427
+ qrMs = qrTimeout || 20000;
428
+ };
429
+ genPairQR();
430
+ });
431
+
432
+ ws.on('CB:iq,,pair-success', async (stanza) => {
433
+ try {
434
+ const { reply, creds: updatedCreds } = (0, Utils_1.configureSuccessfulPairing)(stanza, creds);
435
+ ev.emit('creds.update', updatedCreds);
436
+ ev.emit('connection.update', { isNewLogin: true, qr: undefined });
437
+ await sendNode(reply);
438
+ }
439
+ catch (error) {
440
+ end(error);
441
+ }
442
+ });
443
+
444
+ ws.on('CB:success', async (node) => {
445
+ try {
446
+ await uploadPreKeysToServerIfRequired();
447
+ await sendPassiveIq('active');
448
+ clearTimeout(qrTimer);
449
+ ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } });
450
+ ev.emit('connection.update', { connection: 'open' });
451
+ }
452
+ catch (err) {
453
+ end(err);
454
+ }
455
+ });
456
+
457
+ ws.on('CB:stream:error', (node) => {
458
+ const { reason, statusCode } = (0, Utils_1.getErrorCodeFromStreamError)(node);
459
+ end(new boom_1.Boom(`Stream Errored (${reason})`, { statusCode, data: node }));
460
+ });
461
+
462
+ ws.on('CB:failure', (node) => {
463
+ const reason = +(node.attrs.reason || 500);
464
+ end(new boom_1.Boom('Connection Failure', { statusCode: reason, data: node.attrs }));
465
+ });
466
+
467
+ ws.on('CB:ib,,edge_routing', (node) => {
468
+ const edgeRoutingNode = (0, WABinary_1.getBinaryNodeChild)(node, 'edge_routing');
469
+ const routingInfo = (0, WABinary_1.getBinaryNodeChild)(edgeRoutingNode, 'routing_info');
470
+ if (routingInfo === null || routingInfo === void 0 ? void 0 : routingInfo.content) {
471
+ authState.creds.routingInfo = Buffer.from(routingInfo === null || routingInfo === void 0 ? void 0 : routingInfo.content);
472
+ ev.emit('creds.update', authState.creds);
473
+ }
474
+ });
475
+
476
+ let didStartBuffer = false;
477
+ process.nextTick(() => {
478
+ var _a;
479
+ if ((_a = creds.me) === null || _a === void 0 ? void 0 : _a.id) {
480
+ ev.buffer();
481
+ didStartBuffer = true;
482
+ }
483
+ ev.emit('connection.update', { connection: 'connecting', receivedPendingNotifications: false, qr: undefined });
484
+ });
485
+
486
+ ws.on('CB:ib,,offline', (node) => {
487
+ const child = (0, WABinary_1.getBinaryNodeChild)(node, 'offline');
488
+ const offlineNotifs = +((child === null || child === void 0 ? void 0 : child.attrs.count) || 0);
489
+ if (didStartBuffer) ev.flush();
490
+ ev.emit('connection.update', { receivedPendingNotifications: true });
491
+ });
492
+
493
+ ev.on('creds.update', update => {
494
+ var _a, _b;
495
+ const name = (_a = update.me) === null || _a === void 0 ? void 0 : _a.name;
496
+ if (((_b = creds.me) === null || _b === void 0 ? void 0 : _b.name) !== name) {
497
+ sendNode({ tag: 'presence', attrs: { name: name } })
498
+ .catch(err => logger.warn({ trace: err.stack }, 'presence error'));
499
+ }
500
+ Object.assign(creds, update);
501
+ });
502
+
503
+ if (printQRInTerminal) (0, Utils_1.printQRIfNecessaryListener)(ev, logger);
504
+
505
+ return {
506
+ type: 'md',
507
+ ws,
508
+ ev,
509
+ authState: { creds, keys },
510
+ signalRepository,
511
+ get user() { return authState.creds.me; },
512
+ generateMessageTag,
513
+ query,
514
+ waitForMessage,
515
+ waitForSocketOpen,
516
+ sendRawMessage,
517
+ sendNode,
518
+ logout,
519
+ end,
520
+ onUnexpectedError,
521
+ uploadPreKeys,
522
+ uploadPreKeysToServerIfRequired,
523
+ requestPairingCode,
524
+ waitForConnectionUpdate: (0, Utils_1.bindWaitForConnectionUpdate)(ev),
525
+ sendWAMBuffer,
526
+ };
527
+ };
528
+ exports.makeSocket = makeSocket;
529
+
530
+ function mapWebSocketError(handler) {
531
+ return (error) => {
532
+ handler(new boom_1.Boom(`WebSocket Error (${error === null || error === void 0 ? void 0 : error.message})`, { statusCode: (0, Utils_1.getCodeFromWSError)(error), data: error }));
533
+ };
534
+ }
@@ -0,0 +1,36 @@
1
+ import { Boom } from '@hapi/boom';
2
+ import { SocketConfig } from '../Types';
3
+ import { BinaryNode } from '../WABinary';
4
+ import { USyncQuery } from '../WAUSync';
5
+ export declare const makeUSyncSocket: (config: SocketConfig) => {
6
+ executeUSyncQuery: (usyncQuery: USyncQuery) => Promise<import("../WAUSync").USyncQueryResult | undefined>;
7
+ type: "md";
8
+ ws: import("./Client").WebSocketClient;
9
+ ev: import("../Types").BaileysEventEmitter & {
10
+ process(handler: (events: Partial<import("../Types").BaileysEventMap>) => void | Promise<void>): (() => void);
11
+ buffer(): void;
12
+ createBufferedFunction<A extends any[], T>(work: (...args: A) => Promise<T>): ((...args: A) => Promise<T>);
13
+ flush(force?: boolean): boolean;
14
+ isBuffering(): boolean;
15
+ };
16
+ authState: {
17
+ creds: import("../Types").AuthenticationCreds;
18
+ keys: import("../Types").SignalKeyStoreWithTransaction;
19
+ };
20
+ signalRepository: import("../Types").SignalRepository;
21
+ user: import("../Types").Contact | undefined;
22
+ generateMessageTag: () => string;
23
+ query: (node: BinaryNode, timeoutMs?: number) => Promise<any>;
24
+ waitForMessage: <T>(msgId: string, timeoutMs?: number | undefined) => Promise<any>;
25
+ waitForSocketOpen: () => Promise<void>;
26
+ sendRawMessage: (data: Uint8Array | Buffer) => Promise<void>;
27
+ sendNode: (frame: BinaryNode) => Promise<void>;
28
+ logout: (msg?: string) => Promise<void>;
29
+ end: (error: Error | undefined) => void;
30
+ onUnexpectedError: (err: Error | Boom, msg: string) => void;
31
+ uploadPreKeys: (count?: number) => Promise<void>;
32
+ uploadPreKeysToServerIfRequired: () => Promise<void>;
33
+ requestPairingCode: (phoneNumber: any, pairKey?: string) => Promise<string>;
34
+ waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => Promise<boolean | undefined>, timeoutMs?: number) => Promise<void>;
35
+ sendWAMBuffer: (wamBuffer: Buffer) => Promise<any>;
36
+ };
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeUSyncSocket = void 0;
4
+ const boom_1 = require("@hapi/boom");
5
+ const WABinary_1 = require("../WABinary");
6
+ const socket_1 = require("./socket");
7
+ const makeUSyncSocket = (config) => {
8
+ const sock = (0, socket_1.makeSocket)(config);
9
+ const { generateMessageTag, query, } = sock;
10
+ const executeUSyncQuery = async (usyncQuery) => {
11
+ if (usyncQuery.protocols.length === 0) {
12
+ throw new boom_1.Boom('USyncQuery must have at least one protocol');
13
+ }
14
+ // todo: validate users, throw WARNING on no valid users
15
+ // variable below has only validated users
16
+ const validUsers = usyncQuery.users;
17
+ const userNodes = validUsers.map((user) => {
18
+ return {
19
+ tag: 'user',
20
+ attrs: {
21
+ jid: !user.phone ? user.id : undefined,
22
+ },
23
+ content: usyncQuery.protocols
24
+ .map((a) => a.getUserElement(user))
25
+ .filter(a => a !== null)
26
+ };
27
+ });
28
+ const listNode = {
29
+ tag: 'list',
30
+ attrs: {},
31
+ content: userNodes
32
+ };
33
+ const queryNode = {
34
+ tag: 'query',
35
+ attrs: {},
36
+ content: usyncQuery.protocols.map((a) => a.getQueryElement())
37
+ };
38
+ const iq = {
39
+ tag: 'iq',
40
+ attrs: {
41
+ to: WABinary_1.S_WHATSAPP_NET,
42
+ type: 'get',
43
+ xmlns: 'usync',
44
+ },
45
+ content: [
46
+ {
47
+ tag: 'usync',
48
+ attrs: {
49
+ context: usyncQuery.context,
50
+ mode: usyncQuery.mode,
51
+ sid: generateMessageTag(),
52
+ last: 'true',
53
+ index: '0',
54
+ },
55
+ content: [
56
+ queryNode,
57
+ listNode
58
+ ]
59
+ }
60
+ ],
61
+ };
62
+ const result = await query(iq);
63
+ return usyncQuery.parseUSyncQueryResult(result);
64
+ };
65
+ return {
66
+ ...sock,
67
+ executeUSyncQuery,
68
+ };
69
+ };
70
+ exports.makeUSyncSocket = makeUSyncSocket;
@@ -0,0 +1,2 @@
1
+ import makeInMemoryStore from './make-in-memory-store';
2
+ export { makeInMemoryStore };
@@ -0,0 +1,8 @@
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.makeInMemoryStore = void 0;
7
+ const make_in_memory_store_1 = __importDefault(require("./make-in-memory-store"));
8
+ exports.makeInMemoryStore = make_in_memory_store_1.default;