aunubaileys 1.0.16 → 1.0.17

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/README.md CHANGED
@@ -64,6 +64,10 @@ Everything else is pure upstream. When upstream moves, we rebase the patch layer
64
64
 
65
65
 
66
66
 
67
+ ### 🆕 What's new in 1.0.17 / Baru di 1.0.17
68
+
69
+ - 👥 **Group sender-key heal** — the 1.0.14 failure counter now covers group messages too: after 3 consecutive group decrypt failures from the same author in the same group, the stale sender-key record is deleted (new `signalRepository.deleteSenderKey`), so the next retry makes the author resend with a fresh distribution message and the group cipher rebuilds from scratch. One rotten sender-key record can no longer mute a group member forever.
70
+
67
71
  ### 🆕 What's new in 1.0.16 / Baru di 1.0.16
68
72
 
69
73
  - 🪪 **Identity changes are handled, not just logged** — when WhatsApp notifies that a contact's identity changed (new phone / reinstall / recycled number), upstream Baileys logs “identity changed” and does nothing, leaving your stored session bound to the old identity so that contact's messages keep failing. AunuBaileys now deletes the stored session for that JID on the spot, so the next exchange re-initiates cleanly against the new identity.
@@ -66,6 +66,10 @@ export function makeLibSignalRepository(auth) {
66
66
  senderKeyDistributionMessage: senderKeyDistributionMessage.serialize()
67
67
  };
68
68
  },
69
+ async deleteSenderKey(group, authorJid) {
70
+ const senderNameStr = jidToSignalSenderKeyName(group, authorJid).toString();
71
+ await auth.keys.set({ 'sender-key': { [senderNameStr]: null } });
72
+ },
69
73
  async deleteSession(jid) {
70
74
  const addr = jidToSignalProtocolAddress(jid).toString();
71
75
  await auth.keys.set({ session: { [addr]: null } });
@@ -677,18 +677,26 @@ export const makeMessagesRecvSocket = (config) => {
677
677
  }
678
678
  const encNode = getBinaryNodeChild(node, 'enc');
679
679
  let forceIncludeKeys = !encNode;
680
- if (!isJidGroup(msg.key.remoteJid) && author) {
680
+ if (author) {
681
681
  try {
682
+ const isGroupMsg = isJidGroup(msg.key.remoteJid);
682
683
  const addr = signalRepository.jidToSignalProtocolAddress(author);
683
- const fails = (decryptFailCounts.get(addr) || 0) + 1;
684
+ const failKey = isGroupMsg ? `sk:${msg.key.remoteJid}:${addr}` : addr;
685
+ const fails = (decryptFailCounts.get(failKey) || 0) + 1;
684
686
  if (fails >= DECRYPT_FAIL_SESSION_RESET_LIMIT) {
685
- await signalRepository.deleteSession(author);
686
- decryptFailCounts.delete(addr);
687
+ if (isGroupMsg) {
688
+ await signalRepository.deleteSenderKey(msg.key.remoteJid, author);
689
+ logger.warn({ author, group: msg.key.remoteJid }, 'aunu: deleted stale sender-key record after repeated group decrypt failures; retry request asks the author to resend with a fresh distribution message');
690
+ }
691
+ else {
692
+ await signalRepository.deleteSession(author);
693
+ logger.warn({ author, addr }, 'aunu: deleted stale E2E session after repeated decrypt failures (Bad MAC self-heal); retry receipt carries fresh keys');
694
+ }
695
+ decryptFailCounts.delete(failKey);
687
696
  forceIncludeKeys = true;
688
- logger.warn({ author, addr }, 'aunu: deleted stale E2E session after repeated decrypt failures (Bad MAC self-heal); retry receipt carries fresh keys');
689
697
  }
690
698
  else {
691
- decryptFailCounts.set(addr, fails);
699
+ decryptFailCounts.set(failKey, fails);
692
700
  }
693
701
  }
694
702
  catch (healErr) {
@@ -708,7 +716,9 @@ export const makeMessagesRecvSocket = (config) => {
708
716
  else {
709
717
  if (author) {
710
718
  try {
711
- decryptFailCounts.delete(signalRepository.jidToSignalProtocolAddress(author));
719
+ const addr = signalRepository.jidToSignalProtocolAddress(author);
720
+ decryptFailCounts.delete(addr);
721
+ decryptFailCounts.delete(`sk:${msg.key.remoteJid}:${addr}`);
712
722
  }
713
723
  catch { }
714
724
  }
@@ -54,6 +54,8 @@ export type SignalRepository = {
54
54
  injectE2ESession(opts: E2ESessionOpts): Promise<void>;
55
55
  /** AunuBaileys: delete the stored E2E session for a JID (used by the Bad MAC self-heal). */
56
56
  deleteSession(jid: string): Promise<void>;
57
+ /** AunuBaileys: delete the stored sender-key record for a group author (stale group session heal). */
58
+ deleteSenderKey(group: string, authorJid: string): Promise<void>;
57
59
  jidToSignalProtocolAddress(jid: string): string;
58
60
  };
59
61
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "aunubaileys",
3
3
  "type": "module",
4
- "version": "1.0.16",
4
+ "version": "1.0.17",
5
5
  "description": "AunuBaileys \u2014 a WhatsApp Web API for bots that never sleep. Full upstream power with the beloved in-memory store restored and pairing that just works. Forged by AunuCore.",
6
6
  "keywords": [
7
7
  "whatsapp",