violetics 7.0.1-alpha → 7.0.2-alpha

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 (114) hide show
  1. package/LICENSE +3 -2
  2. package/README.md +1001 -232
  3. package/WAProto/index.js +75379 -142631
  4. package/engine-requirements.js +11 -8
  5. package/lib/Defaults/index.js +132 -146
  6. package/lib/Signal/Group/ciphertext-message.js +2 -6
  7. package/lib/Signal/Group/group-session-builder.js +7 -42
  8. package/lib/Signal/Group/group_cipher.js +37 -52
  9. package/lib/Signal/Group/index.js +11 -57
  10. package/lib/Signal/Group/keyhelper.js +7 -45
  11. package/lib/Signal/Group/sender-chain-key.js +7 -16
  12. package/lib/Signal/Group/sender-key-distribution-message.js +8 -12
  13. package/lib/Signal/Group/sender-key-message.js +9 -13
  14. package/lib/Signal/Group/sender-key-name.js +2 -6
  15. package/lib/Signal/Group/sender-key-record.js +9 -22
  16. package/lib/Signal/Group/sender-key-state.js +27 -43
  17. package/lib/Signal/Group/sender-message-key.js +4 -8
  18. package/lib/Signal/libsignal.js +319 -94
  19. package/lib/Signal/lid-mapping.js +224 -139
  20. package/lib/Socket/Client/index.js +2 -19
  21. package/lib/Socket/Client/types.js +10 -0
  22. package/lib/Socket/Client/websocket.js +53 -0
  23. package/lib/Socket/business.js +162 -44
  24. package/lib/Socket/chats.js +477 -418
  25. package/lib/Socket/communities.js +430 -0
  26. package/lib/Socket/groups.js +110 -99
  27. package/lib/Socket/index.js +10 -10
  28. package/lib/Socket/messages-recv.js +884 -561
  29. package/lib/Socket/messages-send.js +859 -428
  30. package/lib/Socket/mex.js +41 -0
  31. package/lib/Socket/newsletter.js +195 -390
  32. package/lib/Socket/socket.js +465 -315
  33. package/lib/Store/index.js +3 -10
  34. package/lib/Store/make-in-memory-store.js +73 -79
  35. package/lib/Store/make-ordered-dictionary.js +4 -7
  36. package/lib/Store/object-repository.js +2 -6
  37. package/lib/Types/Auth.js +1 -2
  38. package/lib/Types/Bussines.js +1 -0
  39. package/lib/Types/Call.js +1 -2
  40. package/lib/Types/Chat.js +7 -4
  41. package/lib/Types/Contact.js +1 -2
  42. package/lib/Types/Events.js +1 -2
  43. package/lib/Types/GroupMetadata.js +1 -2
  44. package/lib/Types/Label.js +2 -5
  45. package/lib/Types/LabelAssociation.js +2 -5
  46. package/lib/Types/Message.js +17 -9
  47. package/lib/Types/Newsletter.js +33 -38
  48. package/lib/Types/Product.js +1 -2
  49. package/lib/Types/Signal.js +1 -2
  50. package/lib/Types/Socket.js +2 -2
  51. package/lib/Types/State.js +12 -2
  52. package/lib/Types/USync.js +1 -2
  53. package/lib/Types/index.js +14 -31
  54. package/lib/Utils/auth-utils.js +228 -152
  55. package/lib/Utils/browser-utils.js +28 -0
  56. package/lib/Utils/business.js +66 -70
  57. package/lib/Utils/chat-utils.js +331 -249
  58. package/lib/Utils/crypto.js +57 -91
  59. package/lib/Utils/decode-wa-message.js +168 -84
  60. package/lib/Utils/event-buffer.js +138 -80
  61. package/lib/Utils/generics.js +180 -297
  62. package/lib/Utils/history.js +83 -49
  63. package/lib/Utils/identity-change-handler.js +48 -0
  64. package/lib/Utils/index.js +19 -33
  65. package/lib/Utils/link-preview.js +14 -23
  66. package/lib/Utils/logger.js +2 -7
  67. package/lib/Utils/lt-hash.js +2 -46
  68. package/lib/Utils/make-mutex.js +24 -47
  69. package/lib/Utils/message-retry-manager.js +224 -0
  70. package/lib/Utils/messages-media.js +501 -496
  71. package/lib/Utils/messages.js +1428 -362
  72. package/lib/Utils/noise-handler.js +145 -100
  73. package/lib/Utils/pre-key-manager.js +105 -0
  74. package/lib/Utils/process-message.js +356 -150
  75. package/lib/Utils/reporting-utils.js +257 -0
  76. package/lib/Utils/signal.js +78 -73
  77. package/lib/Utils/sync-action-utils.js +47 -0
  78. package/lib/Utils/tc-token-utils.js +17 -0
  79. package/lib/Utils/use-multi-file-auth-state.js +35 -45
  80. package/lib/Utils/validate-connection.js +91 -107
  81. package/lib/WABinary/constants.js +1300 -1304
  82. package/lib/WABinary/decode.js +26 -48
  83. package/lib/WABinary/encode.js +109 -155
  84. package/lib/WABinary/generic-utils.js +161 -149
  85. package/lib/WABinary/index.js +5 -21
  86. package/lib/WABinary/jid-utils.js +73 -40
  87. package/lib/WABinary/types.js +1 -2
  88. package/lib/WAM/BinaryInfo.js +2 -6
  89. package/lib/WAM/constants.js +19070 -11568
  90. package/lib/WAM/encode.js +17 -23
  91. package/lib/WAM/index.js +3 -19
  92. package/lib/WAUSync/Protocols/USyncContactProtocol.js +8 -12
  93. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +11 -15
  94. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +9 -13
  95. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +9 -14
  96. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +20 -23
  97. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +13 -9
  98. package/lib/WAUSync/Protocols/index.js +4 -20
  99. package/lib/WAUSync/USyncQuery.js +40 -36
  100. package/lib/WAUSync/USyncUser.js +2 -6
  101. package/lib/WAUSync/index.js +3 -19
  102. package/lib/index.js +11 -44
  103. package/package.json +74 -107
  104. package/lib/Defaults/baileys-version.json +0 -3
  105. package/lib/Defaults/phonenumber-mcc.json +0 -223
  106. package/lib/Signal/Group/queue-job.js +0 -57
  107. package/lib/Socket/Client/abstract-socket-client.js +0 -13
  108. package/lib/Socket/Client/mobile-socket-client.js +0 -65
  109. package/lib/Socket/Client/web-socket-client.js +0 -118
  110. package/lib/Socket/groupStatus.js +0 -637
  111. package/lib/Socket/registration.js +0 -166
  112. package/lib/Socket/usync.js +0 -70
  113. package/lib/Store/make-cache-manager-store.js +0 -83
  114. package/lib/Utils/baileys-event-stream.js +0 -63
@@ -1,44 +1,37 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.processSyncAction = exports.chatModificationToAppPatch = exports.decodePatches = exports.decodeSyncdSnapshot = exports.downloadExternalPatch = exports.downloadExternalBlob = exports.extractSyncdPatches = exports.decodeSyncdPatch = exports.decodeSyncdMutations = exports.encodeSyncdPatch = exports.newLTHashState = void 0;
4
- const boom_1 = require("@hapi/boom");
5
- const WAProto_1 = require("../../WAProto");
6
- const LabelAssociation_1 = require("../Types/LabelAssociation");
7
- const WABinary_1 = require("../WABinary");
8
- const crypto_1 = require("./crypto");
9
- const generics_1 = require("./generics");
10
- const lt_hash_1 = require("./lt-hash");
11
- const messages_media_1 = require("./messages-media");
1
+ import { Boom } from '@hapi/boom';
2
+ import { expandAppStateKeys } from 'whatsapp-rust-bridge';
3
+ import { proto } from '../../WAProto/index.js';
4
+ import { LabelAssociationType } from '../Types/LabelAssociation.js';
5
+ import { getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidNormalizedUser } from '../WABinary/index.js';
6
+ import { aesDecrypt, aesEncrypt, hmacSign } from './crypto.js';
7
+ import { toNumber } from './generics.js';
8
+ import { LT_HASH_ANTI_TAMPERING } from './lt-hash.js';
9
+ import { downloadContentFromMessage } from './messages-media.js';
10
+ import { emitSyncActionResults, processContactAction } from './sync-action-utils.js';
12
11
  const mutationKeys = (keydata) => {
13
- const expanded = (0, crypto_1.hkdf)(keydata, 160, { info: 'WhatsApp Mutation Keys' });
12
+ const keys = expandAppStateKeys(keydata);
14
13
  return {
15
- indexKey: expanded.slice(0, 32),
16
- valueEncryptionKey: expanded.slice(32, 64),
17
- valueMacKey: expanded.slice(64, 96),
18
- snapshotMacKey: expanded.slice(96, 128),
19
- patchMacKey: expanded.slice(128, 160)
14
+ indexKey: keys.indexKey,
15
+ valueEncryptionKey: keys.valueEncryptionKey,
16
+ valueMacKey: keys.valueMacKey,
17
+ snapshotMacKey: keys.snapshotMacKey,
18
+ patchMacKey: keys.patchMacKey
20
19
  };
21
20
  };
22
21
  const generateMac = (operation, data, keyId, key) => {
23
- const getKeyData = () => {
24
- let r;
25
- switch (operation) {
26
- case WAProto_1.proto.SyncdMutation.SyncdOperation.SET:
27
- r = 0x01;
28
- break;
29
- case WAProto_1.proto.SyncdMutation.SyncdOperation.REMOVE:
30
- r = 0x02;
31
- break;
32
- }
33
- const buff = Buffer.from([r]);
34
- return Buffer.concat([buff, Buffer.from(keyId, 'base64')]);
35
- };
36
- const keyData = getKeyData();
37
- const last = Buffer.alloc(8); // 8 bytes
38
- last.set([keyData.length], last.length - 1);
39
- const total = Buffer.concat([keyData, data, last]);
40
- const hmac = (0, crypto_1.hmacSign)(total, key, 'sha512');
41
- return hmac.slice(0, 32);
22
+ const opByte = operation === proto.SyncdMutation.SyncdOperation.SET ? 0x01 : 0x02;
23
+ const keyIdBuffer = typeof keyId === 'string' ? Buffer.from(keyId, 'base64') : keyId;
24
+ const keyData = new Uint8Array(1 + keyIdBuffer.length);
25
+ keyData[0] = opByte;
26
+ keyData.set(keyIdBuffer, 1);
27
+ const last = new Uint8Array(8);
28
+ last[7] = keyData.length;
29
+ const total = new Uint8Array(keyData.length + data.length + last.length);
30
+ total.set(keyData, 0);
31
+ total.set(data, keyData.length);
32
+ total.set(last, keyData.length + data.length);
33
+ const hmac = hmacSign(total, key, 'sha512');
34
+ return hmac.subarray(0, 32);
42
35
  };
43
36
  const to64BitNetworkOrder = (e) => {
44
37
  const buff = Buffer.alloc(8);
@@ -53,71 +46,59 @@ const makeLtHashGenerator = ({ indexValueMap, hash }) => {
53
46
  mix: ({ indexMac, valueMac, operation }) => {
54
47
  const indexMacBase64 = Buffer.from(indexMac).toString('base64');
55
48
  const prevOp = indexValueMap[indexMacBase64];
56
- if (operation === WAProto_1.proto.SyncdMutation.SyncdOperation.REMOVE) {
49
+ if (operation === proto.SyncdMutation.SyncdOperation.REMOVE) {
57
50
  if (!prevOp) {
58
- throw new boom_1.Boom('tried remove, but no previous op', { data: { indexMac, valueMac } });
51
+ throw new Boom('tried remove, but no previous op', { data: { indexMac, valueMac } });
59
52
  }
60
53
  // remove from index value mac, since this mutation is erased
61
54
  delete indexValueMap[indexMacBase64];
62
55
  }
63
56
  else {
64
- addBuffs.push(new Uint8Array(valueMac).buffer);
57
+ addBuffs.push(valueMac);
65
58
  // add this index into the history map
66
59
  indexValueMap[indexMacBase64] = { valueMac };
67
60
  }
68
61
  if (prevOp) {
69
- subBuffs.push(new Uint8Array(prevOp.valueMac).buffer);
62
+ subBuffs.push(prevOp.valueMac);
70
63
  }
71
64
  },
72
65
  finish: () => {
73
- const hashArrayBuffer = new Uint8Array(hash).buffer;
74
- const result = lt_hash_1.LT_HASH_ANTI_TAMPERING.subtractThenAdd(hashArrayBuffer, addBuffs, subBuffs);
75
- const buffer = Buffer.from(result);
66
+ const result = LT_HASH_ANTI_TAMPERING.subtractThenAdd(hash, subBuffs, addBuffs);
76
67
  return {
77
- hash: buffer,
68
+ hash: Buffer.from(result),
78
69
  indexValueMap
79
70
  };
80
71
  }
81
72
  };
82
73
  };
83
74
  const generateSnapshotMac = (lthash, version, name, key) => {
84
- const total = Buffer.concat([
85
- lthash,
86
- to64BitNetworkOrder(version),
87
- Buffer.from(name, 'utf-8')
88
- ]);
89
- return (0, crypto_1.hmacSign)(total, key, 'sha256');
75
+ const total = Buffer.concat([lthash, to64BitNetworkOrder(version), Buffer.from(name, 'utf-8')]);
76
+ return hmacSign(total, key, 'sha256');
90
77
  };
91
78
  const generatePatchMac = (snapshotMac, valueMacs, version, type, key) => {
92
- const total = Buffer.concat([
93
- snapshotMac,
94
- ...valueMacs,
95
- to64BitNetworkOrder(version),
96
- Buffer.from(type, 'utf-8')
97
- ]);
98
- return (0, crypto_1.hmacSign)(total, key);
79
+ const total = Buffer.concat([snapshotMac, ...valueMacs, to64BitNetworkOrder(version), Buffer.from(type, 'utf-8')]);
80
+ return hmacSign(total, key);
99
81
  };
100
- const newLTHashState = () => ({ version: 0, hash: Buffer.alloc(128), indexValueMap: {} });
101
- exports.newLTHashState = newLTHashState;
102
- const encodeSyncdPatch = async ({ type, index, syncAction, apiVersion, operation }, myAppStateKeyId, state, getAppStateSyncKey) => {
82
+ export const newLTHashState = () => ({ version: 0, hash: Buffer.alloc(128), indexValueMap: {} });
83
+ export const encodeSyncdPatch = async ({ type, index, syncAction, apiVersion, operation }, myAppStateKeyId, state, getAppStateSyncKey) => {
103
84
  const key = !!myAppStateKeyId ? await getAppStateSyncKey(myAppStateKeyId) : undefined;
104
85
  if (!key) {
105
- throw new boom_1.Boom(`myAppStateKey ("${myAppStateKeyId}") not present`, { statusCode: 404 });
86
+ throw new Boom(`myAppStateKey ("${myAppStateKeyId}") not present`, { statusCode: 404 });
106
87
  }
107
88
  const encKeyId = Buffer.from(myAppStateKeyId, 'base64');
108
89
  state = { ...state, indexValueMap: { ...state.indexValueMap } };
109
90
  const indexBuffer = Buffer.from(JSON.stringify(index));
110
- const dataProto = WAProto_1.proto.SyncActionData.fromObject({
91
+ const dataProto = proto.SyncActionData.fromObject({
111
92
  index: indexBuffer,
112
93
  value: syncAction,
113
94
  padding: new Uint8Array(0),
114
95
  version: apiVersion
115
96
  });
116
- const encoded = WAProto_1.proto.SyncActionData.encode(dataProto).finish();
97
+ const encoded = proto.SyncActionData.encode(dataProto).finish();
117
98
  const keyValue = mutationKeys(key.keyData);
118
- const encValue = (0, crypto_1.aesEncrypt)(encoded, keyValue.valueEncryptionKey);
99
+ const encValue = aesEncrypt(encoded, keyValue.valueEncryptionKey);
119
100
  const valueMac = generateMac(operation, encValue, encKeyId, keyValue.valueMacKey);
120
- const indexMac = (0, crypto_1.hmacSign)(indexBuffer, keyValue.indexKey);
101
+ const indexMac = hmacSign(indexBuffer, keyValue.indexKey);
121
102
  // update LT hash
122
103
  const generator = makeLtHashGenerator(state);
123
104
  generator.mix({ indexMac, valueMac, operation });
@@ -147,33 +128,33 @@ const encodeSyncdPatch = async ({ type, index, syncAction, apiVersion, operation
147
128
  state.indexValueMap[base64Index] = { valueMac };
148
129
  return { patch, state };
149
130
  };
150
- exports.encodeSyncdPatch = encodeSyncdPatch;
151
- const decodeSyncdMutations = async (msgMutations, initialState, getAppStateSyncKey, onMutation, validateMacs) => {
131
+ export const decodeSyncdMutations = async (msgMutations, initialState, getAppStateSyncKey, onMutation, validateMacs) => {
152
132
  const ltGenerator = makeLtHashGenerator(initialState);
133
+ const derivedKeyCache = new Map();
153
134
  // indexKey used to HMAC sign record.index.blob
154
135
  // valueEncryptionKey used to AES-256-CBC encrypt record.value.blob[0:-32]
155
136
  // the remaining record.value.blob[0:-32] is the mac, it the HMAC sign of key.keyId + decoded proto data + length of bytes in keyId
156
137
  for (const msgMutation of msgMutations) {
157
138
  // if it's a syncdmutation, get the operation property
158
139
  // otherwise, if it's only a record -- it'll be a SET mutation
159
- const operation = 'operation' in msgMutation ? msgMutation.operation : WAProto_1.proto.SyncdMutation.SyncdOperation.SET;
160
- const record = ('record' in msgMutation && !!msgMutation.record) ? msgMutation.record : msgMutation;
140
+ const operation = 'operation' in msgMutation ? msgMutation.operation : proto.SyncdMutation.SyncdOperation.SET;
141
+ const record = 'record' in msgMutation && !!msgMutation.record ? msgMutation.record : msgMutation;
161
142
  const key = await getKey(record.keyId.id);
162
- const content = Buffer.from(record.value.blob);
163
- const encContent = content.slice(0, -32);
164
- const ogValueMac = content.slice(-32);
143
+ const content = record.value.blob;
144
+ const encContent = content.subarray(0, -32);
145
+ const ogValueMac = content.subarray(-32);
165
146
  if (validateMacs) {
166
147
  const contentHmac = generateMac(operation, encContent, record.keyId.id, key.valueMacKey);
167
148
  if (Buffer.compare(contentHmac, ogValueMac) !== 0) {
168
- throw new boom_1.Boom('HMAC content verification failed');
149
+ throw new Boom('HMAC content verification failed');
169
150
  }
170
151
  }
171
- const result = (0, crypto_1.aesDecrypt)(encContent, key.valueEncryptionKey);
172
- const syncAction = WAProto_1.proto.SyncActionData.decode(result);
152
+ const result = aesDecrypt(encContent, key.valueEncryptionKey);
153
+ const syncAction = proto.SyncActionData.decode(result);
173
154
  if (validateMacs) {
174
- const hmac = (0, crypto_1.hmacSign)(syncAction.index, key.indexKey);
155
+ const hmac = hmacSign(syncAction.index, key.indexKey);
175
156
  if (Buffer.compare(hmac, record.index.blob) !== 0) {
176
- throw new boom_1.Boom('HMAC index verification failed');
157
+ throw new Boom('HMAC index verification failed');
177
158
  }
178
159
  }
179
160
  const indexStr = Buffer.from(syncAction.index).toString();
@@ -187,40 +168,47 @@ const decodeSyncdMutations = async (msgMutations, initialState, getAppStateSyncK
187
168
  return ltGenerator.finish();
188
169
  async function getKey(keyId) {
189
170
  const base64Key = Buffer.from(keyId).toString('base64');
171
+ const cached = derivedKeyCache.get(base64Key);
172
+ if (cached) {
173
+ return cached;
174
+ }
190
175
  const keyEnc = await getAppStateSyncKey(base64Key);
191
176
  if (!keyEnc) {
192
- throw new boom_1.Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 404, data: { msgMutations } });
177
+ throw new Boom(`failed to find key "${base64Key}" to decode mutation`, {
178
+ statusCode: 404,
179
+ data: { msgMutations }
180
+ });
193
181
  }
194
- return mutationKeys(keyEnc.keyData);
182
+ const keys = mutationKeys(keyEnc.keyData);
183
+ derivedKeyCache.set(base64Key, keys);
184
+ return keys;
195
185
  }
196
186
  };
197
- exports.decodeSyncdMutations = decodeSyncdMutations;
198
- const decodeSyncdPatch = async (msg, name, initialState, getAppStateSyncKey, onMutation, validateMacs) => {
187
+ export const decodeSyncdPatch = async (msg, name, initialState, getAppStateSyncKey, onMutation, validateMacs) => {
199
188
  if (validateMacs) {
200
189
  const base64Key = Buffer.from(msg.keyId.id).toString('base64');
201
190
  const mainKeyObj = await getAppStateSyncKey(base64Key);
202
191
  if (!mainKeyObj) {
203
- throw new boom_1.Boom(`failed to find key "${base64Key}" to decode patch`, { statusCode: 404, data: { msg } });
192
+ throw new Boom(`failed to find key "${base64Key}" to decode patch`, { statusCode: 404, data: { msg } });
204
193
  }
205
194
  const mainKey = mutationKeys(mainKeyObj.keyData);
206
195
  const mutationmacs = msg.mutations.map(mutation => mutation.record.value.blob.slice(-32));
207
- const patchMac = generatePatchMac(msg.snapshotMac, mutationmacs, (0, generics_1.toNumber)(msg.version.version), name, mainKey.patchMacKey);
196
+ const patchMac = generatePatchMac(msg.snapshotMac, mutationmacs, toNumber(msg.version.version), name, mainKey.patchMacKey);
208
197
  if (Buffer.compare(patchMac, msg.patchMac) !== 0) {
209
- throw new boom_1.Boom('Invalid patch mac');
198
+ throw new Boom('Invalid patch mac');
210
199
  }
211
200
  }
212
- const result = await (0, exports.decodeSyncdMutations)(msg.mutations, initialState, getAppStateSyncKey, onMutation, validateMacs);
201
+ const result = await decodeSyncdMutations(msg.mutations, initialState, getAppStateSyncKey, onMutation, validateMacs);
213
202
  return result;
214
203
  };
215
- exports.decodeSyncdPatch = decodeSyncdPatch;
216
- const extractSyncdPatches = async (result, options) => {
217
- const syncNode = (0, WABinary_1.getBinaryNodeChild)(result, 'sync');
218
- const collectionNodes = (0, WABinary_1.getBinaryNodeChildren)(syncNode, 'collection');
204
+ export const extractSyncdPatches = async (result, options) => {
205
+ const syncNode = getBinaryNodeChild(result, 'sync');
206
+ const collectionNodes = getBinaryNodeChildren(syncNode, 'collection');
219
207
  const final = {};
220
208
  await Promise.all(collectionNodes.map(async (collectionNode) => {
221
- const patchesNode = (0, WABinary_1.getBinaryNodeChild)(collectionNode, 'patches');
222
- const patches = (0, WABinary_1.getBinaryNodeChildren)(patchesNode || collectionNode, 'patch');
223
- const snapshotNode = (0, WABinary_1.getBinaryNodeChild)(collectionNode, 'snapshot');
209
+ const patchesNode = getBinaryNodeChild(collectionNode, 'patches');
210
+ const patches = getBinaryNodeChildren(patchesNode || collectionNode, 'patch');
211
+ const snapshotNode = getBinaryNodeChild(collectionNode, 'snapshot');
224
212
  const syncds = [];
225
213
  const name = collectionNode.attrs.name;
226
214
  const hasMorePatches = collectionNode.attrs.has_more_patches === 'true';
@@ -229,16 +217,16 @@ const extractSyncdPatches = async (result, options) => {
229
217
  if (!Buffer.isBuffer(snapshotNode)) {
230
218
  snapshotNode.content = Buffer.from(Object.values(snapshotNode.content));
231
219
  }
232
- const blobRef = WAProto_1.proto.ExternalBlobReference.decode(snapshotNode.content);
233
- const data = await (0, exports.downloadExternalBlob)(blobRef, options);
234
- snapshot = WAProto_1.proto.SyncdSnapshot.decode(data);
220
+ const blobRef = proto.ExternalBlobReference.decode(snapshotNode.content);
221
+ const data = await downloadExternalBlob(blobRef, options);
222
+ snapshot = proto.SyncdSnapshot.decode(data);
235
223
  }
236
224
  for (let { content } of patches) {
237
225
  if (content) {
238
226
  if (!Buffer.isBuffer(content)) {
239
227
  content = Buffer.from(Object.values(content));
240
228
  }
241
- const syncd = WAProto_1.proto.SyncdPatch.decode(content);
229
+ const syncd = proto.SyncdPatch.decode(content);
242
230
  if (!syncd.version) {
243
231
  syncd.version = { version: +collectionNode.attrs.version + 1 };
244
232
  }
@@ -249,32 +237,27 @@ const extractSyncdPatches = async (result, options) => {
249
237
  }));
250
238
  return final;
251
239
  };
252
- exports.extractSyncdPatches = extractSyncdPatches;
253
- const downloadExternalBlob = async (blob, options) => {
254
- const stream = await (0, messages_media_1.downloadContentFromMessage)(blob, 'md-app-state', { options });
240
+ export const downloadExternalBlob = async (blob, options) => {
241
+ const stream = await downloadContentFromMessage(blob, 'md-app-state', { options });
255
242
  const bufferArray = [];
256
243
  for await (const chunk of stream) {
257
244
  bufferArray.push(chunk);
258
245
  }
259
246
  return Buffer.concat(bufferArray);
260
247
  };
261
- exports.downloadExternalBlob = downloadExternalBlob;
262
- const downloadExternalPatch = async (blob, options) => {
263
- const buffer = await (0, exports.downloadExternalBlob)(blob, options);
264
- const syncData = WAProto_1.proto.SyncdMutations.decode(buffer);
248
+ export const downloadExternalPatch = async (blob, options) => {
249
+ const buffer = await downloadExternalBlob(blob, options);
250
+ const syncData = proto.SyncdMutations.decode(buffer);
265
251
  return syncData;
266
252
  };
267
- exports.downloadExternalPatch = downloadExternalPatch;
268
- const decodeSyncdSnapshot = async (name, snapshot, getAppStateSyncKey, minimumVersionNumber, validateMacs = true) => {
269
- const newState = (0, exports.newLTHashState)();
270
- newState.version = (0, generics_1.toNumber)(snapshot.version.version);
253
+ export const decodeSyncdSnapshot = async (name, snapshot, getAppStateSyncKey, minimumVersionNumber, validateMacs = true) => {
254
+ const newState = newLTHashState();
255
+ newState.version = toNumber(snapshot.version.version);
271
256
  const mutationMap = {};
272
- const areMutationsRequired = typeof minimumVersionNumber === 'undefined'
273
- || newState.version > minimumVersionNumber;
274
- const { hash, indexValueMap } = await (0, exports.decodeSyncdMutations)(snapshot.records, newState, getAppStateSyncKey, areMutationsRequired
275
- ? (mutation) => {
276
- var _a;
277
- const index = (_a = mutation.syncAction.index) === null || _a === void 0 ? void 0 : _a.toString();
257
+ const areMutationsRequired = typeof minimumVersionNumber === 'undefined' || newState.version > minimumVersionNumber;
258
+ const { hash, indexValueMap } = await decodeSyncdMutations(snapshot.records, newState, getAppStateSyncKey, areMutationsRequired
259
+ ? mutation => {
260
+ const index = mutation.syncAction.index?.toString();
278
261
  mutationMap[index] = mutation;
279
262
  }
280
263
  : () => { }, validateMacs);
@@ -284,12 +267,12 @@ const decodeSyncdSnapshot = async (name, snapshot, getAppStateSyncKey, minimumVe
284
267
  const base64Key = Buffer.from(snapshot.keyId.id).toString('base64');
285
268
  const keyEnc = await getAppStateSyncKey(base64Key);
286
269
  if (!keyEnc) {
287
- throw new boom_1.Boom(`failed to find key "${base64Key}" to decode mutation`);
270
+ throw new Boom(`failed to find key "${base64Key}" to decode mutation`);
288
271
  }
289
272
  const result = mutationKeys(keyEnc.keyData);
290
273
  const computedSnapshotMac = generateSnapshotMac(newState.hash, newState.version, name, result.snapshotMacKey);
291
274
  if (Buffer.compare(snapshot.mac, computedSnapshotMac) !== 0) {
292
- throw new boom_1.Boom(`failed to verify LTHash at ${newState.version} of ${name} from snapshot`);
275
+ throw new Boom(`failed to verify LTHash at ${newState.version} of ${name} from snapshot`);
293
276
  }
294
277
  }
295
278
  return {
@@ -297,45 +280,41 @@ const decodeSyncdSnapshot = async (name, snapshot, getAppStateSyncKey, minimumVe
297
280
  mutationMap
298
281
  };
299
282
  };
300
- exports.decodeSyncdSnapshot = decodeSyncdSnapshot;
301
- const decodePatches = async (name, syncds, initial, getAppStateSyncKey, options, minimumVersionNumber, logger, validateMacs = true) => {
302
- var _a;
283
+ export const decodePatches = async (name, syncds, initial, getAppStateSyncKey, options, minimumVersionNumber, logger, validateMacs = true) => {
303
284
  const newState = {
304
285
  ...initial,
305
286
  indexValueMap: { ...initial.indexValueMap }
306
287
  };
307
288
  const mutationMap = {};
308
- for (let i = 0; i < syncds.length; i++) {
309
- const syncd = syncds[i];
289
+ for (const syncd of syncds) {
310
290
  const { version, keyId, snapshotMac } = syncd;
311
291
  if (syncd.externalMutations) {
312
- logger === null || logger === void 0 ? void 0 : logger.trace({ name, version }, 'downloading external patch');
313
- const ref = await (0, exports.downloadExternalPatch)(syncd.externalMutations, options);
314
- logger === null || logger === void 0 ? void 0 : logger.debug({ name, version, mutations: ref.mutations.length }, 'downloaded external patch');
315
- (_a = syncd.mutations) === null || _a === void 0 ? void 0 : _a.push(...ref.mutations);
292
+ logger?.trace({ name, version }, 'downloading external patch');
293
+ const ref = await downloadExternalPatch(syncd.externalMutations, options);
294
+ logger?.debug({ name, version, mutations: ref.mutations.length }, 'downloaded external patch');
295
+ syncd.mutations?.push(...ref.mutations);
316
296
  }
317
- const patchVersion = (0, generics_1.toNumber)(version.version);
297
+ const patchVersion = toNumber(version.version);
318
298
  newState.version = patchVersion;
319
299
  const shouldMutate = typeof minimumVersionNumber === 'undefined' || patchVersion > minimumVersionNumber;
320
- const decodeResult = await (0, exports.decodeSyncdPatch)(syncd, name, newState, getAppStateSyncKey, shouldMutate
300
+ const decodeResult = await decodeSyncdPatch(syncd, name, newState, getAppStateSyncKey, shouldMutate
321
301
  ? mutation => {
322
- var _a;
323
- const index = (_a = mutation.syncAction.index) === null || _a === void 0 ? void 0 : _a.toString();
302
+ const index = mutation.syncAction.index?.toString();
324
303
  mutationMap[index] = mutation;
325
304
  }
326
- : (() => { }), true);
305
+ : () => { }, true);
327
306
  newState.hash = decodeResult.hash;
328
307
  newState.indexValueMap = decodeResult.indexValueMap;
329
308
  if (validateMacs) {
330
309
  const base64Key = Buffer.from(keyId.id).toString('base64');
331
310
  const keyEnc = await getAppStateSyncKey(base64Key);
332
311
  if (!keyEnc) {
333
- throw new boom_1.Boom(`failed to find key "${base64Key}" to decode mutation`);
312
+ throw new Boom(`failed to find key "${base64Key}" to decode mutation`);
334
313
  }
335
314
  const result = mutationKeys(keyEnc.keyData);
336
315
  const computedSnapshotMac = generateSnapshotMac(newState.hash, newState.version, name, result.snapshotMacKey);
337
316
  if (Buffer.compare(snapshotMac, computedSnapshotMac) !== 0) {
338
- throw new boom_1.Boom(`failed to verify LTHash at ${newState.version} of ${name}`);
317
+ throw new Boom(`failed to verify LTHash at ${newState.version} of ${name}`);
339
318
  }
340
319
  }
341
320
  // clear memory used up by the mutations
@@ -343,31 +322,31 @@ const decodePatches = async (name, syncds, initial, getAppStateSyncKey, options,
343
322
  }
344
323
  return { state: newState, mutationMap };
345
324
  };
346
- exports.decodePatches = decodePatches;
347
- const chatModificationToAppPatch = (mod, jid) => {
348
- const OP = WAProto_1.proto.SyncdMutation.SyncdOperation;
325
+ export const chatModificationToAppPatch = (mod, jid) => {
326
+ const OP = proto.SyncdMutation.SyncdOperation;
349
327
  const getMessageRange = (lastMessages) => {
350
328
  let messageRange;
351
329
  if (Array.isArray(lastMessages)) {
352
330
  const lastMsg = lastMessages[lastMessages.length - 1];
353
331
  messageRange = {
354
- lastMessageTimestamp: lastMsg === null || lastMsg === void 0 ? void 0 : lastMsg.messageTimestamp,
355
- messages: (lastMessages === null || lastMessages === void 0 ? void 0 : lastMessages.length) ? lastMessages.map(m => {
356
- var _a, _b;
357
- if (!((_a = m.key) === null || _a === void 0 ? void 0 : _a.id) || !((_b = m.key) === null || _b === void 0 ? void 0 : _b.remoteJid)) {
358
- throw new boom_1.Boom('Incomplete key', { statusCode: 400, data: m });
359
- }
360
- if ((0, WABinary_1.isJidGroup)(m.key.remoteJid) && !m.key.fromMe && !m.key.participant) {
361
- throw new boom_1.Boom('Expected not from me message to have participant', { statusCode: 400, data: m });
362
- }
363
- if (!m.messageTimestamp || !(0, generics_1.toNumber)(m.messageTimestamp)) {
364
- throw new boom_1.Boom('Missing timestamp in last message list', { statusCode: 400, data: m });
365
- }
366
- if (m.key.participant) {
367
- m.key.participant = (0, WABinary_1.jidNormalizedUser)(m.key.participant);
368
- }
369
- return m;
370
- }) : undefined
332
+ lastMessageTimestamp: lastMsg?.messageTimestamp,
333
+ messages: lastMessages?.length
334
+ ? lastMessages.map(m => {
335
+ if (!m.key?.id || !m.key?.remoteJid) {
336
+ throw new Boom('Incomplete key', { statusCode: 400, data: m });
337
+ }
338
+ if (isJidGroup(m.key.remoteJid) && !m.key.fromMe && !m.key.participant) {
339
+ throw new Boom('Expected not from me message to have participant', { statusCode: 400, data: m });
340
+ }
341
+ if (!m.messageTimestamp || !toNumber(m.messageTimestamp)) {
342
+ throw new Boom('Missing timestamp in last message list', { statusCode: 400, data: m });
343
+ }
344
+ if (m.key.participant) {
345
+ m.key.participant = jidNormalizedUser(m.key.participant);
346
+ }
347
+ return m;
348
+ })
349
+ : undefined
371
350
  };
372
351
  }
373
352
  else {
@@ -418,25 +397,33 @@ const chatModificationToAppPatch = (mod, jid) => {
418
397
  operation: OP.SET
419
398
  };
420
399
  }
400
+ else if ('deleteForMe' in mod) {
401
+ const { timestamp, key, deleteMedia } = mod.deleteForMe;
402
+ patch = {
403
+ syncAction: {
404
+ deleteMessageForMeAction: {
405
+ deleteMedia,
406
+ messageTimestamp: timestamp
407
+ }
408
+ },
409
+ index: ['deleteMessageForMe', jid, key.id, key.fromMe ? '1' : '0', '0'],
410
+ type: 'regular_high',
411
+ apiVersion: 3,
412
+ operation: OP.SET
413
+ };
414
+ }
421
415
  else if ('clear' in mod) {
422
- if (mod.clear === 'all') {
423
- throw new boom_1.Boom('not supported');
424
- }
425
- else {
426
- const key = mod.clear.messages[0];
427
- patch = {
428
- syncAction: {
429
- deleteMessageForMeAction: {
430
- deleteMedia: false,
431
- messageTimestamp: key.timestamp
432
- }
433
- },
434
- index: ['deleteMessageForMe', jid, key.id, key.fromMe ? '1' : '0', '0'],
435
- type: 'regular_high',
436
- apiVersion: 3,
437
- operation: OP.SET
438
- };
439
- }
416
+ patch = {
417
+ syncAction: {
418
+ clearChatAction: {
419
+ messageRange: getMessageRange(mod.lastMessages)
420
+ }
421
+ },
422
+ index: ['clearChat', jid, '1' /*the option here is 0 when keep starred messages is enabled*/, '0'],
423
+ type: 'regular_high',
424
+ apiVersion: 6,
425
+ operation: OP.SET
426
+ };
440
427
  }
441
428
  else if ('pin' in mod) {
442
429
  patch = {
@@ -451,6 +438,28 @@ const chatModificationToAppPatch = (mod, jid) => {
451
438
  operation: OP.SET
452
439
  };
453
440
  }
441
+ else if ('contact' in mod) {
442
+ patch = {
443
+ syncAction: {
444
+ contactAction: mod.contact || {}
445
+ },
446
+ index: ['contact', jid],
447
+ type: 'critical_unblock_low',
448
+ apiVersion: 2,
449
+ operation: mod.contact ? OP.SET : OP.REMOVE
450
+ };
451
+ }
452
+ else if ('disableLinkPreviews' in mod) {
453
+ patch = {
454
+ syncAction: {
455
+ privacySettingDisableLinkPreviewsAction: mod.disableLinkPreviews || {}
456
+ },
457
+ index: ['setting_disableLinkPreviews'],
458
+ type: 'regular',
459
+ apiVersion: 8,
460
+ operation: OP.SET
461
+ };
462
+ }
454
463
  else if ('star' in mod) {
455
464
  const key = mod.star.messages[0];
456
465
  patch = {
@@ -469,7 +478,7 @@ const chatModificationToAppPatch = (mod, jid) => {
469
478
  patch = {
470
479
  syncAction: {
471
480
  deleteChatAction: {
472
- messageRange: getMessageRange(mod.lastMessages),
481
+ messageRange: getMessageRange(mod.lastMessages)
473
482
  }
474
483
  },
475
484
  index: ['deleteChat', jid, '1'],
@@ -488,64 +497,90 @@ const chatModificationToAppPatch = (mod, jid) => {
488
497
  index: ['setting_pushName'],
489
498
  type: 'critical_block',
490
499
  apiVersion: 1,
491
- operation: OP.SET,
500
+ operation: OP.SET
501
+ };
502
+ }
503
+ else if ('quickReply' in mod) {
504
+ patch = {
505
+ syncAction: {
506
+ quickReplyAction: {
507
+ count: 0,
508
+ deleted: mod.quickReply.deleted || false,
509
+ keywords: [],
510
+ message: mod.quickReply.message || '',
511
+ shortcut: mod.quickReply.shortcut || ''
512
+ }
513
+ },
514
+ index: ['quick_reply', mod.quickReply.timestamp || String(Math.floor(Date.now() / 1000))],
515
+ type: 'regular',
516
+ apiVersion: 2,
517
+ operation: OP.SET
518
+ };
519
+ }
520
+ else if ('addLabel' in mod) {
521
+ patch = {
522
+ syncAction: {
523
+ labelEditAction: {
524
+ name: mod.addLabel.name,
525
+ color: mod.addLabel.color,
526
+ predefinedId: mod.addLabel.predefinedId,
527
+ deleted: mod.addLabel.deleted
528
+ }
529
+ },
530
+ index: ['label_edit', mod.addLabel.id],
531
+ type: 'regular',
532
+ apiVersion: 3,
533
+ operation: OP.SET
492
534
  };
493
535
  }
494
536
  else if ('addChatLabel' in mod) {
495
537
  patch = {
496
538
  syncAction: {
497
539
  labelAssociationAction: {
498
- labeled: true,
540
+ labeled: true
499
541
  }
500
542
  },
501
- index: [LabelAssociation_1.LabelAssociationType.Chat, mod.addChatLabel.labelId, jid],
543
+ index: [LabelAssociationType.Chat, mod.addChatLabel.labelId, jid],
502
544
  type: 'regular',
503
545
  apiVersion: 3,
504
- operation: OP.SET,
546
+ operation: OP.SET
505
547
  };
506
548
  }
507
549
  else if ('removeChatLabel' in mod) {
508
550
  patch = {
509
551
  syncAction: {
510
552
  labelAssociationAction: {
511
- labeled: false,
553
+ labeled: false
512
554
  }
513
555
  },
514
- index: [LabelAssociation_1.LabelAssociationType.Chat, mod.removeChatLabel.labelId, jid],
556
+ index: [LabelAssociationType.Chat, mod.removeChatLabel.labelId, jid],
515
557
  type: 'regular',
516
558
  apiVersion: 3,
517
- operation: OP.SET,
559
+ operation: OP.SET
518
560
  };
519
561
  }
520
562
  else if ('addMessageLabel' in mod) {
521
563
  patch = {
522
564
  syncAction: {
523
565
  labelAssociationAction: {
524
- labeled: true,
566
+ labeled: true
525
567
  }
526
568
  },
527
- index: [
528
- LabelAssociation_1.LabelAssociationType.Message,
529
- mod.addMessageLabel.labelId,
530
- jid,
531
- mod.addMessageLabel.messageId,
532
- '0',
533
- '0'
534
- ],
569
+ index: [LabelAssociationType.Message, mod.addMessageLabel.labelId, jid, mod.addMessageLabel.messageId, '0', '0'],
535
570
  type: 'regular',
536
571
  apiVersion: 3,
537
- operation: OP.SET,
572
+ operation: OP.SET
538
573
  };
539
574
  }
540
575
  else if ('removeMessageLabel' in mod) {
541
576
  patch = {
542
577
  syncAction: {
543
578
  labelAssociationAction: {
544
- labeled: false,
579
+ labeled: false
545
580
  }
546
581
  },
547
582
  index: [
548
- LabelAssociation_1.LabelAssociationType.Message,
583
+ LabelAssociationType.Message,
549
584
  mod.removeMessageLabel.labelId,
550
585
  jid,
551
586
  mod.removeMessageLabel.messageId,
@@ -554,34 +589,30 @@ const chatModificationToAppPatch = (mod, jid) => {
554
589
  ],
555
590
  type: 'regular',
556
591
  apiVersion: 3,
557
- operation: OP.SET,
592
+ operation: OP.SET
558
593
  };
559
594
  }
560
595
  else {
561
- throw new boom_1.Boom('not supported');
596
+ throw new Boom('not supported');
562
597
  }
563
598
  patch.syncAction.timestamp = Date.now();
564
599
  return patch;
565
600
  };
566
- exports.chatModificationToAppPatch = chatModificationToAppPatch;
567
- const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) => {
568
- var _a, _b, _c, _d;
601
+ export const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) => {
569
602
  const isInitialSync = !!initialSyncOpts;
570
- const accountSettings = initialSyncOpts === null || initialSyncOpts === void 0 ? void 0 : initialSyncOpts.accountSettings;
571
- logger === null || logger === void 0 ? void 0 : logger.trace({ syncAction, initialSync: !!initialSyncOpts }, 'processing sync action');
603
+ const accountSettings = initialSyncOpts?.accountSettings;
604
+ logger?.trace({ syncAction, initialSync: !!initialSyncOpts }, 'processing sync action');
572
605
  const { syncAction: { value: action }, index: [type, id, msgId, fromMe] } = syncAction;
573
- if (action === null || action === void 0 ? void 0 : action.muteAction) {
606
+ if (action?.muteAction) {
574
607
  ev.emit('chats.update', [
575
608
  {
576
609
  id,
577
- muteEndTime: ((_a = action.muteAction) === null || _a === void 0 ? void 0 : _a.muted)
578
- ? (0, generics_1.toNumber)(action.muteAction.muteEndTimestamp)
579
- : null,
610
+ muteEndTime: action.muteAction?.muted ? toNumber(action.muteAction.muteEndTimestamp) : null,
580
611
  conditional: getChatUpdateConditional(id, undefined)
581
612
  }
582
613
  ]);
583
614
  }
584
- else if ((action === null || action === void 0 ? void 0 : action.archiveChatAction) || type === 'archive' || type === 'unarchive') {
615
+ else if (action?.archiveChatAction || type === 'archive' || type === 'unarchive') {
585
616
  // okay so we've to do some annoying computation here
586
617
  // when we're initially syncing the app state
587
618
  // there are a few cases we need to handle
@@ -592,36 +623,38 @@ const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) => {
592
623
  // we compare the timestamp of latest message from the other person to determine this
593
624
  // 2. if the account unarchiveChats setting is false -- then it doesn't matter,
594
625
  // it'll always take an app state action to mark in unarchived -- which we'll get anyway
595
- const archiveAction = action === null || action === void 0 ? void 0 : action.archiveChatAction;
596
- const isArchived = archiveAction
597
- ? archiveAction.archived
598
- : type === 'archive';
626
+ const archiveAction = action?.archiveChatAction;
627
+ const isArchived = archiveAction ? archiveAction.archived : type === 'archive';
599
628
  // // basically we don't need to fire an "archive" update if the chat is being marked unarchvied
600
629
  // // this only applies for the initial sync
601
630
  // if(isInitialSync && !isArchived) {
602
631
  // isArchived = false
603
632
  // }
604
- const msgRange = !(accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.unarchiveChats) ? undefined : archiveAction === null || archiveAction === void 0 ? void 0 : archiveAction.messageRange;
633
+ const msgRange = !accountSettings?.unarchiveChats ? undefined : archiveAction?.messageRange;
605
634
  // logger?.debug({ chat: id, syncAction }, 'message range archive')
606
- ev.emit('chats.update', [{
635
+ ev.emit('chats.update', [
636
+ {
607
637
  id,
608
638
  archived: isArchived,
609
639
  conditional: getChatUpdateConditional(id, msgRange)
610
- }]);
640
+ }
641
+ ]);
611
642
  }
612
- else if (action === null || action === void 0 ? void 0 : action.markChatAsReadAction) {
643
+ else if (action?.markChatAsReadAction) {
613
644
  const markReadAction = action.markChatAsReadAction;
614
645
  // basically we don't need to fire an "read" update if the chat is being marked as read
615
646
  // because the chat is read by default
616
647
  // this only applies for the initial sync
617
648
  const isNullUpdate = isInitialSync && markReadAction.read;
618
- ev.emit('chats.update', [{
649
+ ev.emit('chats.update', [
650
+ {
619
651
  id,
620
- unreadCount: isNullUpdate ? null : !!(markReadAction === null || markReadAction === void 0 ? void 0 : markReadAction.read) ? 0 : -1,
621
- conditional: getChatUpdateConditional(id, markReadAction === null || markReadAction === void 0 ? void 0 : markReadAction.messageRange)
622
- }]);
652
+ unreadCount: isNullUpdate ? null : !!markReadAction?.read ? 0 : -1,
653
+ conditional: getChatUpdateConditional(id, markReadAction?.messageRange)
654
+ }
655
+ ]);
623
656
  }
624
- else if ((action === null || action === void 0 ? void 0 : action.deleteMessageForMeAction) || type === 'deleteMessageForMe') {
657
+ else if (action?.deleteMessageForMeAction || type === 'deleteMessageForMe') {
625
658
  ev.emit('messages.delete', {
626
659
  keys: [
627
660
  {
@@ -632,37 +665,35 @@ const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) => {
632
665
  ]
633
666
  });
634
667
  }
635
- else if (action === null || action === void 0 ? void 0 : action.contactAction) {
636
- ev.emit('contacts.upsert', [{
637
- id: id,
638
- name: action.contactAction.fullName,
639
- lid: action.contactAction.lidJid || undefined,
640
- jid: (0, WABinary_1.isJidUser)(id) ? id : undefined
641
- }]);
642
- }
643
- else if (action === null || action === void 0 ? void 0 : action.pushNameSetting) {
644
- const name = (_b = action === null || action === void 0 ? void 0 : action.pushNameSetting) === null || _b === void 0 ? void 0 : _b.name;
645
- if (name && (me === null || me === void 0 ? void 0 : me.name) !== name) {
668
+ else if (action?.contactAction) {
669
+ const results = processContactAction(action.contactAction, id, logger);
670
+ emitSyncActionResults(ev, results);
671
+ }
672
+ else if (action?.pushNameSetting) {
673
+ const name = action?.pushNameSetting?.name;
674
+ if (name && me?.name !== name) {
646
675
  ev.emit('creds.update', { me: { ...me, name } });
647
676
  }
648
677
  }
649
- else if (action === null || action === void 0 ? void 0 : action.pinAction) {
650
- ev.emit('chats.update', [{
678
+ else if (action?.pinAction) {
679
+ ev.emit('chats.update', [
680
+ {
651
681
  id,
652
- pinned: ((_c = action.pinAction) === null || _c === void 0 ? void 0 : _c.pinned) ? (0, generics_1.toNumber)(action.timestamp) : null,
682
+ pinned: action.pinAction?.pinned ? toNumber(action.timestamp) : null,
653
683
  conditional: getChatUpdateConditional(id, undefined)
654
- }]);
684
+ }
685
+ ]);
655
686
  }
656
- else if (action === null || action === void 0 ? void 0 : action.unarchiveChatsSetting) {
687
+ else if (action?.unarchiveChatsSetting) {
657
688
  const unarchiveChats = !!action.unarchiveChatsSetting.unarchiveChats;
658
689
  ev.emit('creds.update', { accountSettings: { unarchiveChats } });
659
- logger === null || logger === void 0 ? void 0 : logger.info(`archive setting updated => '${action.unarchiveChatsSetting.unarchiveChats}'`);
690
+ logger?.info(`archive setting updated => '${action.unarchiveChatsSetting.unarchiveChats}'`);
660
691
  if (accountSettings) {
661
692
  accountSettings.unarchiveChats = unarchiveChats;
662
693
  }
663
694
  }
664
- else if ((action === null || action === void 0 ? void 0 : action.starAction) || type === 'star') {
665
- let starred = (_d = action === null || action === void 0 ? void 0 : action.starAction) === null || _d === void 0 ? void 0 : _d.starred;
695
+ else if (action?.starAction || type === 'star') {
696
+ let starred = action?.starAction?.starred;
666
697
  if (typeof starred !== 'boolean') {
667
698
  starred = syncAction.index[syncAction.index.length - 1] === '1';
668
699
  }
@@ -673,46 +704,98 @@ const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) => {
673
704
  }
674
705
  ]);
675
706
  }
676
- else if ((action === null || action === void 0 ? void 0 : action.deleteChatAction) || type === 'deleteChat') {
707
+ else if (action?.deleteChatAction || type === 'deleteChat') {
677
708
  if (!isInitialSync) {
678
709
  ev.emit('chats.delete', [id]);
679
710
  }
680
711
  }
681
- else if (action === null || action === void 0 ? void 0 : action.labelEditAction) {
712
+ else if (action?.labelEditAction) {
682
713
  const { name, color, deleted, predefinedId } = action.labelEditAction;
683
714
  ev.emit('labels.edit', {
684
- id,
715
+ id: id,
685
716
  name: name,
686
717
  color: color,
687
718
  deleted: deleted,
688
719
  predefinedId: predefinedId ? String(predefinedId) : undefined
689
720
  });
690
721
  }
691
- else if (action === null || action === void 0 ? void 0 : action.labelAssociationAction) {
722
+ else if (action?.labelAssociationAction) {
692
723
  ev.emit('labels.association', {
693
- type: action.labelAssociationAction.labeled
694
- ? 'add'
695
- : 'remove',
696
- association: type === LabelAssociation_1.LabelAssociationType.Chat
724
+ type: action.labelAssociationAction.labeled ? 'add' : 'remove',
725
+ association: type === LabelAssociationType.Chat
697
726
  ? {
698
- type: LabelAssociation_1.LabelAssociationType.Chat,
727
+ type: LabelAssociationType.Chat,
699
728
  chatId: syncAction.index[2],
700
729
  labelId: syncAction.index[1]
701
730
  }
702
731
  : {
703
- type: LabelAssociation_1.LabelAssociationType.Message,
732
+ type: LabelAssociationType.Message,
704
733
  chatId: syncAction.index[2],
705
734
  messageId: syncAction.index[3],
706
735
  labelId: syncAction.index[1]
707
736
  }
708
737
  });
709
738
  }
739
+ else if (action?.localeSetting?.locale) {
740
+ ev.emit('settings.update', { setting: 'locale', value: action.localeSetting.locale });
741
+ }
742
+ else if (action?.timeFormatAction) {
743
+ ev.emit('settings.update', { setting: 'timeFormat', value: action.timeFormatAction });
744
+ }
745
+ else if (action?.pnForLidChatAction) {
746
+ if (action.pnForLidChatAction.pnJid) {
747
+ ev.emit('lid-mapping.update', { lid: id, pn: action.pnForLidChatAction.pnJid });
748
+ }
749
+ }
750
+ else if (action?.privacySettingRelayAllCalls) {
751
+ ev.emit('settings.update', {
752
+ setting: 'privacySettingRelayAllCalls',
753
+ value: action.privacySettingRelayAllCalls
754
+ });
755
+ }
756
+ else if (action?.statusPrivacy) {
757
+ ev.emit('settings.update', { setting: 'statusPrivacy', value: action.statusPrivacy });
758
+ }
759
+ else if (action?.lockChatAction) {
760
+ ev.emit('chats.lock', { id: id, locked: !!action.lockChatAction.locked });
761
+ }
762
+ else if (action?.privacySettingDisableLinkPreviewsAction) {
763
+ ev.emit('settings.update', {
764
+ setting: 'disableLinkPreviews',
765
+ value: action.privacySettingDisableLinkPreviewsAction
766
+ });
767
+ }
768
+ else if (action?.notificationActivitySettingAction?.notificationActivitySetting) {
769
+ ev.emit('settings.update', {
770
+ setting: 'notificationActivitySetting',
771
+ value: action.notificationActivitySettingAction.notificationActivitySetting
772
+ });
773
+ }
774
+ else if (action?.lidContactAction) {
775
+ ev.emit('contacts.upsert', [
776
+ {
777
+ id: id,
778
+ name: action.lidContactAction.fullName ||
779
+ action.lidContactAction.firstName ||
780
+ action.lidContactAction.username ||
781
+ undefined,
782
+ lid: id,
783
+ phoneNumber: undefined
784
+ }
785
+ ]);
786
+ }
787
+ else if (action?.privacySettingChannelsPersonalisedRecommendationAction) {
788
+ ev.emit('settings.update', {
789
+ setting: 'channelsPersonalisedRecommendation',
790
+ value: action.privacySettingChannelsPersonalisedRecommendationAction
791
+ });
792
+ }
710
793
  else {
711
- logger === null || logger === void 0 ? void 0 : logger.debug({ syncAction, id }, 'unprocessable update');
794
+ logger?.debug({ syncAction, id }, 'unprocessable update');
712
795
  }
713
796
  function getChatUpdateConditional(id, msgRange) {
714
797
  return isInitialSync
715
- ? (data) => {
798
+ ? data => {
716
799
  const chat = data.historySets.chats[id] || data.chatUpserts[id];
717
800
  if (chat) {
718
801
  return msgRange ? isValidPatchBasedOnMessageRange(chat, msgRange) : true;
@@ -721,9 +804,8 @@ const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) => {
721
804
  : undefined;
722
805
  }
723
806
  function isValidPatchBasedOnMessageRange(chat, msgRange) {
724
- const lastMsgTimestamp = Number((msgRange === null || msgRange === void 0 ? void 0 : msgRange.lastMessageTimestamp) || (msgRange === null || msgRange === void 0 ? void 0 : msgRange.lastSystemMessageTimestamp) || 0);
725
- const chatLastMsgTimestamp = Number((chat === null || chat === void 0 ? void 0 : chat.lastMessageRecvTimestamp) || 0);
807
+ const lastMsgTimestamp = Number(msgRange?.lastMessageTimestamp || msgRange?.lastSystemMessageTimestamp || 0);
808
+ const chatLastMsgTimestamp = Number(chat?.lastMessageRecvTimestamp || 0);
726
809
  return lastMsgTimestamp >= chatLastMsgTimestamp;
727
810
  }
728
- };
729
- exports.processSyncAction = processSyncAction;
811
+ };