whalibmob 5.5.70 → 5.5.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/Client.js CHANGED
@@ -877,9 +877,16 @@ class WhalibmobClient extends EventEmitter {
877
877
  return;
878
878
  }
879
879
 
880
- const fromStr = attrs.from ? String(attrs.from) : '';
881
- // Extract bare phone number: "40756469325@s.whatsapp.net" → "40756469325"
882
- const recipientPhone = fromStr.split('@')[0].split('.')[0];
880
+ const fromStr = attrs.from ? String(attrs.from) : '';
881
+ const isGroup = fromStr.endsWith('@g.us');
882
+
883
+ // On a group retry `from` is the group and `participant` is the device that
884
+ // failed to decrypt. Keying off `from` there would have targeted the group
885
+ // id as if it were a contact and cleared nothing.
886
+ const targetJid = isGroup && attrs.participant
887
+ ? String(attrs.participant)
888
+ : fromStr;
889
+ const recipientPhone = targetJid.split('@')[0].split(':')[0].split('.')[0];
883
890
 
884
891
  _whaDbg('[DBG] RETRY_RECV msgId=' + msgId + ' from=' + fromStr + ' — clearing session + resending\n');
885
892
 
@@ -900,7 +907,24 @@ class WhalibmobClient extends EventEmitter {
900
907
  this._devMgr.clearCache([recipientPhone]);
901
908
  }
902
909
 
903
- // Re-send the message — will create fresh pre-key (pkmsg) sessions
910
+ // Re-send the message — will create fresh pre-key (pkmsg) sessions.
911
+ // A group resend must go back through the group path: it needs a fresh
912
+ // SenderKey distribution, which only _sendGroupMessage builds. Drop the
913
+ // "already distributed" record first, or the resend would carry the same
914
+ // bare skmsg the recipient just told us it could not read.
915
+ const resendId = generateMessageId();
916
+ if (cached.isGroup) {
917
+ if (this._signal && this._signal.senderKeyStore) {
918
+ this._signal.senderKeyStore.invalidateSKDM(cached.toJid);
919
+ }
920
+ this._sender._sendGroupMessage(
921
+ cached.toJid, resendId, cached.plaintext, cached.mediaType, cached.options
922
+ )
923
+ .then(r => _whaDbg('[DBG] RETRY_RESEND group ok id=' + (r && r.id) + '\n'))
924
+ .catch(e => _whaDbg('[DBG] RETRY_RESEND_ERR: ' + e.message));
925
+ return;
926
+ }
927
+
904
928
  this._sender._sendDMMessage(
905
929
  cached.toJid, cached.msgId, cached.plaintext, cached.mediaType, cached.options
906
930
  )
@@ -305,30 +305,15 @@ class DeviceManager {
305
305
  async fetchBundles(jids) {
306
306
  if (!jids || jids.length === 0) return new Map();
307
307
 
308
- // Convert a string JID like "user@server" or "user:device@server" into
309
- // a proper JID object so the binary encoder uses JID_PAIR / AD_JID format.
310
- // Raw UTF-8 strings are NOT recognised by the WA server for @lid JIDs — the
311
- // server silently ignores unknown JIDs and returns an empty bundle list.
312
- const toJidObj = jidStr => {
313
- const str = typeof jidStr === 'string' ? jidStr : String(jidStr);
314
- const at = str.indexOf('@');
315
- const raw = at >= 0 ? str.slice(0, at) : str;
316
- const server = at >= 0 ? str.slice(at + 1) : 's.whatsapp.net';
317
- const colon = raw.indexOf(':');
318
- const user = colon >= 0 ? raw.slice(0, colon) : raw;
319
- const device = colon >= 0 ? (parseInt(raw.slice(colon + 1), 10) || 0) : 0;
320
- const self = str;
321
- // AD_JID binary format is for @s.whatsapp.net with device > 0.
322
- // JID_PAIR binary format is used for @lid and for device-0 @s.whatsapp.net.
323
- if (server === 's.whatsapp.net' && device > 0) {
324
- // AD_JID: agent=0, device=N
325
- return { user, agent: 0, device, server, toString() { return self; } };
326
- }
327
- // JID_PAIR: user@server — server may be 'lid' or 's.whatsapp.net'
328
- return { user, server, toString() { return self; } };
329
- };
330
-
331
- const userNodes = jids.map(jid => new BinaryNode('user', { jid: toJidObj(jid) }, null));
308
+ // Use the shared converter. The local copy this replaced dropped the device
309
+ // suffix on @lid JIDs: it split "112713111982325:49@lid" into user and
310
+ // device, then fell through to a JID_PAIR built from `user` alone, so every
311
+ // device of a contact encoded to the identical "112713111982325@lid". The
312
+ // server saw one repeated JID, returned a single device-0 bundle, and no
313
+ // session was ever built for the other devices — leaving them unable to
314
+ // decrypt anything we sent. jidStrToObj keeps the colon inside the user
315
+ // part for @lid, which is what the server expects.
316
+ const userNodes = jids.map(jid => new BinaryNode('user', { jid: jidStrToObj(jid) }, null));
332
317
  const iqId = this._client._genMsgId();
333
318
  const iqNode = new BinaryNode('iq',
334
319
  { id: iqId, xmlns: 'encrypt', type: 'get', to: 's.whatsapp.net' },
@@ -973,6 +973,21 @@ class MessageSender {
973
973
  };
974
974
  if (options.edit) stanzaAttrs.edit = String(options.edit);
975
975
 
976
+ // Cache the plaintext here too, not just on the DM path. A group recipient
977
+ // that cannot decrypt sends a retry receipt exactly like a DM recipient
978
+ // does, and without this the client had nothing to re-send and dropped it
979
+ // with "no cached plaintext" — so the message was acked by the server and
980
+ // then silently never arrived.
981
+ if (this._client._sentMsgCache) {
982
+ this._client._sentMsgCache.set(msgId, {
983
+ plaintext, toJid: groupJid, msgId, mediaType, options, isGroup: true
984
+ });
985
+ if (this._client._sentMsgCache.size > 200) {
986
+ const firstKey = this._client._sentMsgCache.keys().next().value;
987
+ this._client._sentMsgCache.delete(firstKey);
988
+ }
989
+ }
990
+
976
991
  const msgNode = new BinaryNode('message', stanzaAttrs, msgContent);
977
992
  return this._dispatchAndAck(msgNode, msgId);
978
993
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whalibmob",
3
- "version": "5.5.70",
3
+ "version": "5.5.71",
4
4
  "description": "WhatsApp library for interaction with WhatsApp Mobile API no web",
5
5
  "author": "Kunboruto50",
6
6
  "main": "index.js",