@heavstaltech/baileys 2.3.4 → 3.2.4

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 (133) hide show
  1. package/README.md +226 -53
  2. package/WAProto/index.js +14270 -302
  3. package/engine-requirements.js +10 -0
  4. package/lib/Defaults/baileys-version.json +1 -1
  5. package/lib/Defaults/index.js +118 -79
  6. package/lib/Defaults/phonenumber-mcc.json +223 -0
  7. package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
  8. package/lib/Signal/Group/ciphertext-message.js +15 -0
  9. package/lib/Signal/Group/group-session-builder.d.ts +14 -0
  10. package/lib/Signal/Group/group-session-builder.js +64 -0
  11. package/lib/Signal/Group/group_cipher.d.ts +17 -0
  12. package/lib/Signal/Group/group_cipher.js +96 -0
  13. package/lib/Signal/Group/index.d.ts +11 -0
  14. package/lib/Signal/Group/index.js +57 -0
  15. package/lib/Signal/Group/keyhelper.d.ts +10 -0
  16. package/lib/Signal/Group/keyhelper.js +55 -0
  17. package/lib/Signal/Group/queue-job.d.ts +1 -0
  18. package/lib/Signal/Group/queue-job.js +57 -0
  19. package/lib/Signal/Group/sender-chain-key.d.ts +13 -0
  20. package/lib/Signal/Group/sender-chain-key.js +34 -0
  21. package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -0
  22. package/lib/Signal/Group/sender-key-distribution-message.js +66 -0
  23. package/lib/Signal/Group/sender-key-message.d.ts +18 -0
  24. package/lib/Signal/Group/sender-key-message.js +69 -0
  25. package/lib/Signal/Group/sender-key-name.d.ts +17 -0
  26. package/lib/Signal/Group/sender-key-name.js +51 -0
  27. package/lib/Signal/Group/sender-key-record.d.ts +30 -0
  28. package/lib/Signal/Group/sender-key-record.js +53 -0
  29. package/lib/Signal/Group/sender-key-state.d.ts +38 -0
  30. package/lib/Signal/Group/sender-key-state.js +99 -0
  31. package/lib/Signal/Group/sender-message-key.d.ts +11 -0
  32. package/{WASignalGroup/sender_message_key.js → lib/Signal/Group/sender-message-key.js} +6 -16
  33. package/lib/Signal/libsignal.js +51 -29
  34. package/lib/Socket/business.d.ts +43 -42
  35. package/lib/Socket/chats.d.ts +222 -36
  36. package/lib/Socket/chats.js +186 -153
  37. package/lib/Socket/dugong.d.ts +254 -0
  38. package/lib/Socket/dugong.js +484 -0
  39. package/lib/Socket/groups.d.ts +7 -7
  40. package/lib/Socket/groups.js +37 -35
  41. package/lib/Socket/index.d.ts +52 -51
  42. package/lib/Socket/index.js +1 -0
  43. package/lib/Socket/messages-recv.d.ts +37 -34
  44. package/lib/Socket/messages-recv.js +175 -37
  45. package/lib/Socket/messages-send.d.ts +12 -18
  46. package/lib/Socket/messages-send.js +396 -574
  47. package/lib/Socket/newsletter.d.ts +28 -26
  48. package/lib/Socket/newsletter.js +140 -25
  49. package/lib/Socket/registration.d.ts +52 -49
  50. package/lib/Socket/registration.js +7 -7
  51. package/lib/Socket/socket.d.ts +0 -1
  52. package/lib/Socket/socket.js +47 -198
  53. package/lib/Socket/usync.d.ts +10 -11
  54. package/lib/Store/make-cache-manager-store.d.ts +1 -2
  55. package/lib/Store/make-in-memory-store.d.ts +2 -2
  56. package/lib/Store/make-in-memory-store.js +1 -5
  57. package/lib/Store/make-ordered-dictionary.js +2 -2
  58. package/lib/Types/Auth.d.ts +1 -0
  59. package/lib/Types/Call.d.ts +1 -1
  60. package/lib/Types/Chat.d.ts +7 -12
  61. package/lib/Types/Events.d.ts +2 -17
  62. package/lib/Types/GroupMetadata.d.ts +2 -3
  63. package/lib/Types/Label.d.ts +0 -11
  64. package/lib/Types/Label.js +1 -1
  65. package/lib/Types/LabelAssociation.js +1 -1
  66. package/lib/Types/Message.d.ts +10 -170
  67. package/lib/Types/Newsletter.d.ts +97 -86
  68. package/lib/Types/Newsletter.js +38 -32
  69. package/lib/Types/Socket.d.ts +2 -7
  70. package/lib/Types/index.d.ts +0 -9
  71. package/lib/Types/index.js +1 -1
  72. package/lib/Utils/auth-utils.js +14 -35
  73. package/lib/Utils/business.d.ts +1 -1
  74. package/lib/Utils/business.js +2 -2
  75. package/lib/Utils/chat-utils.d.ts +12 -11
  76. package/lib/Utils/chat-utils.js +36 -52
  77. package/lib/Utils/crypto.d.ts +16 -15
  78. package/lib/Utils/crypto.js +26 -74
  79. package/lib/Utils/decode-wa-message.d.ts +0 -17
  80. package/lib/Utils/decode-wa-message.js +17 -53
  81. package/lib/Utils/event-buffer.js +7 -10
  82. package/lib/Utils/generics.d.ts +17 -13
  83. package/lib/Utils/generics.js +79 -58
  84. package/lib/Utils/history.d.ts +2 -6
  85. package/lib/Utils/history.js +6 -4
  86. package/lib/Utils/logger.d.ts +3 -1
  87. package/lib/Utils/lt-hash.js +12 -12
  88. package/lib/Utils/make-mutex.d.ts +2 -2
  89. package/lib/Utils/messages-media.d.ts +28 -25
  90. package/lib/Utils/messages-media.js +201 -103
  91. package/lib/Utils/messages.js +36 -473
  92. package/lib/Utils/noise-handler.d.ts +5 -4
  93. package/lib/Utils/noise-handler.js +14 -19
  94. package/lib/Utils/process-message.d.ts +5 -5
  95. package/lib/Utils/process-message.js +23 -75
  96. package/lib/Utils/signal.d.ts +1 -2
  97. package/lib/Utils/signal.js +26 -32
  98. package/lib/Utils/use-multi-file-auth-state.d.ts +1 -0
  99. package/lib/Utils/use-multi-file-auth-state.js +66 -242
  100. package/lib/Utils/validate-connection.d.ts +1 -1
  101. package/lib/Utils/validate-connection.js +88 -64
  102. package/lib/WABinary/constants.d.ts +27 -24
  103. package/lib/WABinary/decode.d.ts +2 -1
  104. package/lib/WABinary/decode.js +11 -23
  105. package/lib/WABinary/encode.d.ts +2 -1
  106. package/lib/WABinary/encode.js +147 -134
  107. package/lib/WABinary/generic-utils.d.ts +5 -2
  108. package/lib/WABinary/generic-utils.js +125 -37
  109. package/lib/WABinary/jid-utils.d.ts +1 -1
  110. package/lib/WAM/BinaryInfo.d.ts +11 -2
  111. package/lib/WAM/encode.d.ts +2 -1
  112. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +3 -3
  113. package/lib/WAUSync/USyncUser.d.ts +2 -0
  114. package/lib/index.d.ts +12 -0
  115. package/lib/index.js +12 -0
  116. package/package.json +102 -98
  117. package/WAProto/index.d.ts +0 -50383
  118. package/WASignalGroup/GroupProtocol.js +0 -1697
  119. package/WASignalGroup/ciphertext_message.js +0 -16
  120. package/WASignalGroup/group_cipher.js +0 -120
  121. package/WASignalGroup/group_session_builder.js +0 -46
  122. package/WASignalGroup/index.js +0 -5
  123. package/WASignalGroup/keyhelper.js +0 -21
  124. package/WASignalGroup/protobufs.js +0 -3
  125. package/WASignalGroup/queue_job.js +0 -69
  126. package/WASignalGroup/sender_chain_key.js +0 -50
  127. package/WASignalGroup/sender_key_distribution_message.js +0 -78
  128. package/WASignalGroup/sender_key_message.js +0 -92
  129. package/WASignalGroup/sender_key_name.js +0 -70
  130. package/WASignalGroup/sender_key_record.js +0 -56
  131. package/WASignalGroup/sender_key_state.js +0 -129
  132. package/lib/Utils/use-single-file-auth-state.d.ts +0 -12
  133. package/lib/Utils/use-single-file-auth-state.js +0 -75
@@ -1,295 +1,119 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.useMultiFileAuthState = void 0;
7
- const async_lock_1 = __importDefault(require("async-lock"));
4
+ const async_mutex_1 = require("async-mutex");
8
5
  const promises_1 = require("fs/promises");
9
6
  const path_1 = require("path");
10
7
  const WAProto_1 = require("../../WAProto");
11
8
  const auth_utils_1 = require("./auth-utils");
12
9
  const generics_1 = require("./generics");
13
- const node_cache_1 = __importDefault(require("node-cache"));
14
- const Defaults_1 = require("../Defaults");
15
-
16
- // Enhanced locking mechanism
17
- const fileLock = new async_lock_1.default({
18
- maxPending: Infinity,
19
- timeout: 5000 // 5s timeout to prevent deadlocks
20
- });
21
- const globalAuthLock = new async_lock_1.default(); // Additional global lock
22
-
23
- // Debugging utilities
24
- let AUTH_DEBUG = false;
25
- function authDebug(...args) {
26
- if (AUTH_DEBUG) {
27
- console.log('[AUTH DEBUG]', new Date().toISOString(), ...args);
10
+ const fileLocks = new Map();
11
+ const getFileLock = (path) => {
12
+ let mutex = fileLocks.get(path);
13
+ if (!mutex) {
14
+ mutex = new async_mutex_1.Mutex();
15
+ fileLocks.set(path, mutex);
28
16
  }
29
- }
30
-
17
+ return mutex;
18
+ };
31
19
  /**
32
- * Enhanced multi-file auth state storage with:
33
- * - Better error handling
34
- * - Additional locking
35
- * - Data validation
36
- * - Auto-repair mechanisms
37
- */
38
- const useMultiFileAuthState = async (folder, options = {}) => {
39
- AUTH_DEBUG = options.authDebug ?? false;
40
- const cache = options.syncCache ? new node_cache_1.default({
41
- stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.SIGNAL_STORE,
42
- useClones: false,
43
- deleteOnExpire: true,
44
- checkperiod: 120
45
- }) : null;
46
- // Validate and prepare folder
47
- const prepareFolder = async () => {
48
- try {
49
- const folderInfo = await (0, promises_1.stat)(folder).catch(() => null);
50
-
51
- if (folderInfo) {
52
- if (!folderInfo.isDirectory()) {
53
- throw new Error(`Path exists but is not a directory: ${folder}`);
54
- }
55
- } else {
56
- authDebug('Creating auth folder:', folder);
57
- await (0, promises_1.mkdir)(folder, { recursive: true });
58
- }
59
-
60
- // Verify folder is writable
61
- await testFolderAccess();
62
- } catch (error) {
63
- authDebug('Folder preparation failed:', error);
64
- throw new Error(`Auth folder initialization failed: ${error.message}`);
65
- }
66
- };
67
-
68
- const testFolderAccess = async () => {
69
- const testFile = (0, path_1.join)(folder, '.temp_test');
70
- try {
71
- await (0, promises_1.writeFile)(testFile, 'test');
72
- await (0, promises_1.unlink)(testFile);
73
- } catch (error) {
74
- throw new Error(`Folder not writable: ${error.message}`);
75
- }
76
- };
77
-
78
- const fixFileName = (file) => {
79
- if (!file) return file;
80
- return file.replace(/\//g, '__').replace(/:/g, '-');
81
- };
82
-
83
- function getUniqueId(type, id) {
84
- return `${type}.${id}`;
85
- }
86
-
87
- // Enhanced write with retries
20
+ * stores the full authentication state in a single folder.
21
+ * Far more efficient than singlefileauthstate
22
+ *
23
+ * Again, I wouldn't endorse this for any production level use other than perhaps a bot.
24
+ * Would recommend writing an auth state for use with a proper SQL or No-SQL DB
25
+ * */
26
+ const useMultiFileAuthState = async (folder) => {
88
27
  const writeData = async (data, file) => {
89
- return globalAuthLock.acquire('write', async () => {
90
- const filePath = (0, path_1.join)(folder, fixFileName(file));
91
- let attempts = 0;
92
- const maxAttempts = 3;
93
-
94
- while (attempts < maxAttempts) {
95
- attempts++;
96
- try {
97
- await fileLock.acquire(filePath, async () => {
98
- const serialized = JSON.stringify(data, generics_1.BufferJSON.replacer);
99
- await (0, promises_1.writeFile)(filePath, serialized);
100
- authDebug('Write successful:', file);
101
- });
102
- return;
103
- } catch (error) {
104
- authDebug(`Write attempt ${attempts} failed for ${file}:`, error);
105
- if (attempts >= maxAttempts) {
106
- throw new Error(`Failed to write after ${maxAttempts} attempts: ${error.message}`);
107
- }
108
- await new Promise(resolve => setTimeout(resolve, 100 * attempts));
109
- }
28
+ const filePath = (0, path_1.join)(folder, fixFileName(file));
29
+ const mutex = getFileLock(filePath);
30
+ return mutex.acquire().then(async (release) => {
31
+ try {
32
+ await (0, promises_1.writeFile)(filePath, JSON.stringify(data, generics_1.BufferJSON.replacer));
33
+ }
34
+ finally {
35
+ release();
110
36
  }
111
37
  });
112
38
  };
113
-
114
- // Enhanced read with validation
115
39
  const readData = async (file) => {
116
- return globalAuthLock.acquire('read', async () => {
40
+ try {
117
41
  const filePath = (0, path_1.join)(folder, fixFileName(file));
118
-
119
- try {
120
- const data = await fileLock.acquire(filePath, async () => {
121
- const content = await (0, promises_1.readFile)(filePath, { encoding: 'utf-8' });
122
- authDebug('Read successful:', file);
123
- return content;
124
- });
125
-
126
- const parsed = JSON.parse(data, generics_1.BufferJSON.reviver);
127
-
128
- // Basic data validation
129
- if (file === 'creds.json' && !parsed.me) {
130
- authDebug('Invalid creds data detected');
131
- return null;
42
+ const mutex = getFileLock(filePath);
43
+ return await mutex.acquire().then(async (release) => {
44
+ try {
45
+ const data = await (0, promises_1.readFile)(filePath, { encoding: 'utf-8' });
46
+ return JSON.parse(data, generics_1.BufferJSON.reviver);
132
47
  }
133
-
134
- return parsed;
135
- } catch (error) {
136
- if (error.code !== 'ENOENT') { // Ignore "file not found" errors
137
- authDebug('Read error:', file, error);
48
+ finally {
49
+ release();
138
50
  }
139
- return null;
140
- }
141
- });
51
+ });
52
+ }
53
+ catch (error) {
54
+ return null;
55
+ }
142
56
  };
143
-
144
- // Safe removal
145
57
  const removeData = async (file) => {
146
- return globalAuthLock.acquire('remove', async () => {
58
+ try {
147
59
  const filePath = (0, path_1.join)(folder, fixFileName(file));
148
-
149
- try {
150
- await fileLock.acquire(filePath, async () => {
60
+ const mutex = getFileLock(filePath);
61
+ return mutex.acquire().then(async (release) => {
62
+ try {
151
63
  await (0, promises_1.unlink)(filePath);
152
- authDebug('Removed:', file);
153
- });
154
- } catch (error) {
155
- if (error.code !== 'ENOENT') { // Ignore "file not found" errors
156
- authDebug('Remove error:', file, error);
157
64
  }
158
- }
159
- });
160
- };
161
-
162
- // Initialize
163
- await prepareFolder();
164
-
165
- // Load or initialize credentials
166
- let creds = await readData('creds.json');
167
- if (!creds) {
168
- authDebug('No existing creds found, initializing new ones');
169
- creds = (0, auth_utils_1.initAuthCreds)();
170
- await writeData(creds, 'creds.json');
171
- }
172
-
173
- async function warmUpCache() {
174
- try {
175
- const files = await promises_1.readdir(folder);
176
- for (const file of files) {
177
- if (file.endsWith('.json') && file !== 'creds.json') {
178
- const parts = file.split('-');
179
- if (parts.length === 2) {
180
- const type = parts[0];
181
- const id = parts[1].replace('.json', '');
182
- const data = await readData(file);
183
- if (data) {
184
- cache.set(getUniqueId(type, id), data);
185
- authDebug(`Cache warmed: ${type}-${id}`);
186
- }
187
- }
188
- }
65
+ catch (_a) {
66
+ }
67
+ finally {
68
+ release();
69
+ }
70
+ });
189
71
  }
190
- } catch (error) {
191
- authDebug('Cache warm-up failed:', error);
192
- }
193
- }
194
-
195
- if (cache) warmUpCache();
196
-
197
- // Auto-save mechanism
198
- let saveTimeout;
199
- const scheduleSave = () => {
200
- if (saveTimeout) clearTimeout(saveTimeout);
201
- saveTimeout = setTimeout(() => {
202
- saveCreds().catch(error => {
203
- authDebug('Auto-save failed, retrying sooner:', error);
204
- setTimeout(scheduleSave, 60000);
205
- });
206
- }, 180000);
207
- };
208
- // Enhanced save function
209
- const saveCreds = async () => {
210
- try {
211
- await writeData(creds, 'creds.json');
212
- scheduleSave();
213
- } catch (error) {
214
- authDebug('Critical: Creds save failed:', error);
215
- throw error;
72
+ catch (_a) {
216
73
  }
217
74
  };
218
-
219
- process.on('beforeExit', async () => {
220
- if (saveTimeout) clearTimeout(saveTimeout);
221
- await saveCreds().catch(error => {
222
- authDebug('Emergency save failed:', error);
223
- });
224
- });
225
-
226
- process.on('uncaughtException', async (error) => {
227
- authDebug('Uncaught exception, attempting emergency save:', error);
228
- if (saveTimeout) clearTimeout(saveTimeout);
229
- await saveCreds().catch(e => {
230
- authDebug('Emergency save failed:', e);
231
- });
232
- process.exit(1);
233
- });
234
- // Start auto-save loop
235
- scheduleSave();
236
-
75
+ const folderInfo = await (0, promises_1.stat)(folder).catch(() => { });
76
+ if (folderInfo) {
77
+ if (!folderInfo.isDirectory()) {
78
+ throw new Error(`found something that is not a directory at ${folder}, either delete it or specify a different location`);
79
+ }
80
+ }
81
+ else {
82
+ await (0, promises_1.mkdir)(folder, { recursive: true });
83
+ }
84
+ const fixFileName = (file) => { var _a; return (_a = file === null || file === void 0 ? void 0 : file.replace(/\//g, '__')) === null || _a === void 0 ? void 0 : _a.replace(/:/g, '-'); };
85
+ const creds = await readData('creds.json') || (0, auth_utils_1.initAuthCreds)();
237
86
  return {
238
87
  state: {
239
88
  creds,
240
89
  keys: {
241
90
  get: async (type, ids) => {
242
91
  const data = {};
243
-
244
92
  await Promise.all(ids.map(async (id) => {
245
93
  let value = await readData(`${type}-${id}.json`);
246
-
247
94
  if (type === 'app-state-sync-key' && value) {
248
- try {
249
- value = WAProto_1.proto.Message.AppStateSyncKeyData.fromObject(value);
250
- } catch (error) {
251
- authDebug('Key conversion failed:', type, id, error);
252
- value = null;
253
- }
95
+ value = WAProto_1.proto.Message.AppStateSyncKeyData.fromObject(value);
254
96
  }
255
-
256
97
  data[id] = value;
257
98
  }));
258
-
259
99
  return data;
260
100
  },
261
101
  set: async (data) => {
262
102
  const tasks = [];
263
-
264
103
  for (const category in data) {
265
104
  for (const id in data[category]) {
266
105
  const value = data[category][id];
267
106
  const file = `${category}-${id}.json`;
268
-
269
- if (value) {
270
- tasks.push(writeData(value, file));
271
- } else {
272
- tasks.push(removeData(file));
273
- }
107
+ tasks.push(value ? writeData(value, file) : removeData(file));
274
108
  }
275
109
  }
276
-
277
- try {
278
- await Promise.all(tasks);
279
- } catch (error) {
280
- authDebug('Bulk key update failed:', error);
281
- throw error;
282
- }
110
+ await Promise.all(tasks);
283
111
  }
284
112
  }
285
113
  },
286
- saveCreds,
287
- // Additional maintenance API
288
- cleanup: async () => {
289
- if (saveTimeout) clearTimeout(saveTimeout);
290
- await saveCreds();
291
- },
292
- cache
114
+ saveCreds: async () => {
115
+ return writeData(creds, 'creds.json');
116
+ }
293
117
  };
294
118
  };
295
- exports.useMultiFileAuthState = useMultiFileAuthState;
119
+ exports.useMultiFileAuthState = useMultiFileAuthState;
@@ -7,5 +7,5 @@ export declare const generateRegistrationNode: ({ registrationId, signedPreKey,
7
7
  export declare const configureSuccessfulPairing: (stanza: BinaryNode, { advSecretKey, signedIdentityKey, signalIdentities }: Pick<AuthenticationCreds, 'advSecretKey' | 'signedIdentityKey' | 'signalIdentities'>) => {
8
8
  creds: Partial<AuthenticationCreds>;
9
9
  reply: BinaryNode;
10
- };
10
+ };
11
11
  export declare const encodeSignedDeviceIdentity: (account: proto.IADVSignedDeviceIdentity, includeSignatureKey: boolean) => Uint8Array;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.encodeSignedDeviceIdentity = exports.configureSuccessfulPairing = exports.generateRegistrationNode = exports.generateLoginNode = exports.generateMobileNode = void 0;
3
+ exports.encodeSignedDeviceIdentity = exports.configureSuccessfulPairing = exports.generateRegistrationNode = exports.generateLoginNode = void 0;
4
4
  const boom_1 = require("@hapi/boom");
5
5
  const crypto_1 = require("crypto");
6
6
  const WAProto_1 = require("../../WAProto");
@@ -9,106 +9,107 @@ const WABinary_1 = require("../WABinary");
9
9
  const crypto_2 = require("./crypto");
10
10
  const generics_1 = require("./generics");
11
11
  const signal_1 = require("./signal");
12
+
12
13
  const getUserAgent = (config) => {
13
- var _a, _b;
14
- const osVersion = config.mobile ? '15.3.1' : '0.1';
15
- const version = config.mobile ? [2, 24, 6] : config.version;
16
- const device = config.mobile ? 'iPhone_7' : 'Desktop';
17
- const manufacturer = config.mobile ? 'Apple' : '';
18
- const platform = config.mobile ? WAProto_1.proto.ClientPayload.UserAgent.Platform.IOS : WAProto_1.proto.ClientPayload.UserAgent.Platform.WEB;
19
- const phoneId = config.mobile ? { phoneId: config.auth.creds.phoneId } : {};
20
14
  return {
21
15
  appVersion: {
22
- primary: version[0],
23
- secondary: version[1],
24
- tertiary: version[2],
16
+ primary: config.version[0],
17
+ secondary: config.version[1],
18
+ tertiary: config.version[2],
25
19
  },
26
- platform,
20
+ platform: WAProto_1.proto.ClientPayload.UserAgent.Platform.WEB,
27
21
  releaseChannel: WAProto_1.proto.ClientPayload.UserAgent.ReleaseChannel.RELEASE,
28
- mcc: ((_a = config.auth.creds.registration) === null || _a === void 0 ? void 0 : _a.phoneNumberMobileCountryCode) || '000',
29
- mnc: ((_b = config.auth.creds.registration) === null || _b === void 0 ? void 0 : _b.phoneNumberMobileNetworkCode) || '000',
30
- osVersion: osVersion,
31
- manufacturer,
32
- device,
33
- osBuildNumber: osVersion,
22
+ osVersion: '0.1',
23
+ device: 'Desktop',
24
+ osBuildNumber: '0.1',
34
25
  localeLanguageIso6391: 'en',
35
- localeCountryIso31661Alpha2: 'US',
36
- ...phoneId
26
+ mnc: '000',
27
+ mcc: '000',
28
+ localeCountryIso31661Alpha2: config.countryCode || 'US'
37
29
  };
38
30
  };
31
+
39
32
  const PLATFORM_MAP = {
40
33
  'Mac OS': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.DARWIN,
41
34
  'Windows': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WIN32
42
35
  };
36
+
43
37
  const getWebInfo = (config) => {
44
38
  let webSubPlatform = WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER;
45
- if (config.syncFullHistory && PLATFORM_MAP[config.browser[0]]) {
39
+ if (config.syncFullHistory && PLATFORM_MAP[config.browser[0]] && config.browser[1] === 'Desktop') {
46
40
  webSubPlatform = PLATFORM_MAP[config.browser[0]];
47
41
  }
48
42
  return { webSubPlatform };
49
43
  };
44
+
50
45
  const getClientPayload = (config) => {
51
46
  const payload = {
52
47
  connectType: WAProto_1.proto.ClientPayload.ConnectType.WIFI_UNKNOWN,
53
48
  connectReason: WAProto_1.proto.ClientPayload.ConnectReason.USER_ACTIVATED,
54
49
  userAgent: getUserAgent(config),
55
50
  };
56
- if (!config.mobile) {
57
- payload.webInfo = getWebInfo(config);
58
- }
51
+ payload.webInfo = getWebInfo(config);
59
52
  return payload;
60
53
  };
61
- const generateMobileNode = (config) => {
62
- if (!config.auth.creds) {
63
- throw new boom_1.Boom('No registration data found', { data: config });
64
- }
65
- const payload = {
66
- ...getClientPayload(config),
67
- sessionId: Math.floor(Math.random() * 999999999 + 1),
68
- shortConnect: true,
69
- connectAttemptCount: 0,
70
- device: 0,
71
- dnsSource: {
72
- appCached: false,
73
- dnsMethod: WAProto_1.proto.ClientPayload.DNSSource.DNSResolutionMethod.SYSTEM,
74
- },
75
- passive: false,
76
- pushName: 'test',
77
- username: Number(`${config.auth.creds.registration.phoneNumberCountryCode}${config.auth.creds.registration.phoneNumberNationalNumber}`),
78
- };
79
- return WAProto_1.proto.ClientPayload.fromObject(payload);
80
- };
81
- exports.generateMobileNode = generateMobileNode;
54
+
82
55
  const generateLoginNode = (userJid, config) => {
83
56
  const { user, device } = (0, WABinary_1.jidDecode)(userJid);
84
57
  const payload = {
85
58
  ...getClientPayload(config),
86
59
  passive: true,
60
+ pull: true,
87
61
  username: +user,
88
62
  device: device,
63
+ lidDbMigrated: false
89
64
  };
90
65
  return WAProto_1.proto.ClientPayload.fromObject(payload);
91
66
  };
92
67
  exports.generateLoginNode = generateLoginNode;
68
+
93
69
  const getPlatformType = (platform) => {
94
70
  const platformType = platform.toUpperCase();
95
- return WAProto_1.proto.DeviceProps.PlatformType[platformType] || WAProto_1.proto.DeviceProps.PlatformType.DESKTOP;
71
+ return WAProto_1.proto.DeviceProps.PlatformType[platformType] || WAProto_1.proto.DeviceProps.PlatformType.CHROME;
96
72
  };
73
+
97
74
  const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentityKey }, config) => {
98
- // the app version needs to be md5 hashed
99
- // and passed in
100
75
  const appVersionBuf = (0, crypto_1.createHash)('md5')
101
- .update(config.version.join('.')) // join as string
76
+ .update(config.version.join('.'))
102
77
  .digest();
78
+
103
79
  const companion = {
104
80
  os: config.browser[0],
105
81
  platformType: getPlatformType(config.browser[1]),
106
82
  requireFullSync: config.syncFullHistory,
83
+ historySyncConfig: {
84
+ storageQuotaMb: 10240,
85
+ inlineInitialPayloadInE2EeMsg: true,
86
+ recentSyncDaysLimit: undefined,
87
+ supportCallLogHistory: false,
88
+ supportBotUserAgentChatHistory: true,
89
+ supportCagReactionsAndPolls: true,
90
+ supportBizHostedMsg: true,
91
+ supportRecentSyncChunkMessageCountTuning: true,
92
+ supportHostedGroupMsg: true,
93
+ supportFbidBotChatHistory: true,
94
+ supportAddOnHistorySyncMigration: undefined,
95
+ supportMessageAssociation: true,
96
+ supportGroupHistory: false,
97
+ onDemandReady: undefined,
98
+ supportGuestChat: undefined
99
+ },
100
+ version: {
101
+ primary: 10,
102
+ secondary: 15,
103
+ tertiary: 7
104
+ }
107
105
  };
106
+
108
107
  const companionProto = WAProto_1.proto.DeviceProps.encode(companion).finish();
108
+
109
109
  const registerPayload = {
110
110
  ...getClientPayload(config),
111
111
  passive: false,
112
+ pull: false,
112
113
  devicePairingData: {
113
114
  buildHash: appVersionBuf,
114
115
  deviceProps: companionProto,
@@ -123,6 +124,7 @@ const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentity
123
124
  return WAProto_1.proto.ClientPayload.fromObject(registerPayload);
124
125
  };
125
126
  exports.generateRegistrationNode = generateRegistrationNode;
127
+
126
128
  const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, signalIdentities }) => {
127
129
  const msgId = stanza.attrs.id;
128
130
  const pairSuccessNode = (0, WABinary_1.getBinaryNodeChild)(stanza, 'pair-success');
@@ -130,30 +132,52 @@ const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, s
130
132
  const platformNode = (0, WABinary_1.getBinaryNodeChild)(pairSuccessNode, 'platform');
131
133
  const deviceNode = (0, WABinary_1.getBinaryNodeChild)(pairSuccessNode, 'device');
132
134
  const businessNode = (0, WABinary_1.getBinaryNodeChild)(pairSuccessNode, 'biz');
135
+
133
136
  if (!deviceIdentityNode || !deviceNode) {
134
137
  throw new boom_1.Boom('Missing device-identity or device in pair success node', { data: stanza });
135
138
  }
136
- const bizName = businessNode === null || businessNode === void 0 ? void 0 : businessNode.attrs.name;
139
+
140
+ const bizName = businessNode?.attrs.name;
137
141
  const jid = deviceNode.attrs.jid;
138
- const { details, hmac } = WAProto_1.proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentityNode.content);
139
- // check HMAC matches
140
- const advSign = (0, crypto_2.hmacSign)(details, Buffer.from(advSecretKey, 'base64'));
142
+ const lid = deviceNode.attrs.lid;
143
+
144
+ const { details, hmac, accountType } = WAProto_1.proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentityNode.content);
145
+
146
+ let hmacPrefix = Buffer.from([]);
147
+ if (accountType !== undefined && accountType === WAProto_1.proto.ADVEncryptionType.HOSTED) {
148
+ hmacPrefix = Buffer.from([0x06, 0x05]);
149
+ }
150
+
151
+ const advSign = (0, crypto_2.hmacSign)(Buffer.concat([hmacPrefix, details]), Buffer.from(advSecretKey, 'base64'));
141
152
  if (Buffer.compare(hmac, advSign) !== 0) {
142
153
  throw new boom_1.Boom('Invalid account signature');
143
154
  }
155
+
144
156
  const account = WAProto_1.proto.ADVSignedDeviceIdentity.decode(details);
145
157
  const { accountSignatureKey, accountSignature, details: deviceDetails } = account;
146
- // verify the device signature matches
147
- const accountMsg = Buffer.concat([Buffer.from([6, 0]), deviceDetails, signedIdentityKey.public]);
158
+
159
+ const deviceIdentity = WAProto_1.proto.ADVDeviceIdentity.decode(deviceDetails);
160
+
161
+ const accountSignaturePrefix = deviceIdentity.deviceType === WAProto_1.proto.ADVEncryptionType.HOSTED
162
+ ? Buffer.from([0x06, 0x05])
163
+ : Buffer.from([0x06, 0x00]);
164
+ const accountMsg = Buffer.concat([accountSignaturePrefix, deviceDetails, signedIdentityKey.public]);
165
+
148
166
  if (!crypto_2.Curve.verify(accountSignatureKey, accountMsg, accountSignature)) {
149
167
  throw new boom_1.Boom('Failed to verify account signature');
150
168
  }
151
- // sign the details with our identity key
152
- const deviceMsg = Buffer.concat([Buffer.from([6, 1]), deviceDetails, signedIdentityKey.public, accountSignatureKey]);
169
+
170
+ const deviceMsg = Buffer.concat([
171
+ Buffer.from([0x06, 0x01]),
172
+ deviceDetails,
173
+ signedIdentityKey.public,
174
+ accountSignatureKey
175
+ ]);
153
176
  account.deviceSignature = crypto_2.Curve.sign(signedIdentityKey.private, deviceMsg);
177
+
154
178
  const identity = (0, signal_1.createSignalIdentity)(jid, accountSignatureKey);
155
179
  const accountEnc = (0, exports.encodeSignedDeviceIdentity)(account, false);
156
- const deviceIdentity = WAProto_1.proto.ADVDeviceIdentity.decode(account.details);
180
+
157
181
  const reply = {
158
182
  tag: 'iq',
159
183
  attrs: {
@@ -175,27 +199,27 @@ const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, s
175
199
  }
176
200
  ]
177
201
  };
202
+
178
203
  const authUpdate = {
179
204
  account,
180
- me: { id: jid, name: bizName },
205
+ me: { id: jid, name: bizName, lid },
181
206
  signalIdentities: [
182
207
  ...(signalIdentities || []),
183
208
  identity
184
209
  ],
185
- platform: platformNode === null || platformNode === void 0 ? void 0 : platformNode.attrs.name
210
+ platform: platformNode?.attrs.name
186
211
  };
212
+
187
213
  return {
188
214
  creds: authUpdate,
189
215
  reply
190
216
  };
191
217
  };
192
218
  exports.configureSuccessfulPairing = configureSuccessfulPairing;
219
+
193
220
  const encodeSignedDeviceIdentity = (account, includeSignatureKey) => {
194
- var _a;
195
221
  account = { ...account };
196
- // set to null if we are not to include the signature key
197
- // or if we are including the signature key but it is empty
198
- if (!includeSignatureKey || !((_a = account.accountSignatureKey) === null || _a === void 0 ? void 0 : _a.length)) {
222
+ if (!includeSignatureKey || !account.accountSignatureKey?.length) {
199
223
  account.accountSignatureKey = null;
200
224
  }
201
225
  return WAProto_1.proto.ADVSignedDeviceIdentity