whalibmob 5.5.73 → 5.5.77
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/DeviceManager.js +49 -15
- package/lib/messages/MessageSender.js +41 -35
- package/package.json +1 -1
package/lib/DeviceManager.js
CHANGED
|
@@ -44,12 +44,18 @@ function jidStrToObj(jidStr) {
|
|
|
44
44
|
if (server === 's.whatsapp.net' && device > 0) {
|
|
45
45
|
return { user, agent: 0, device, server, toString() { return self; } };
|
|
46
46
|
}
|
|
47
|
-
// @lid multi-device (e.g. "112713111982325:2@lid"):
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
47
|
+
// @lid multi-device (e.g. "112713111982325:2@lid"): AD_JID with the domain in
|
|
48
|
+
// the agent byte — 1 for lid, matching Baileys' writeJid, which emits AD_JID
|
|
49
|
+
// with domainType whenever a device is present.
|
|
50
|
+
//
|
|
51
|
+
// This previously packed the device into the user string as a JID_PAIR
|
|
52
|
+
// ("112713111982325:2"), a workaround from when the encoder could not express
|
|
53
|
+
// a LID agent at all and would otherwise have flattened the JID to device 0.
|
|
54
|
+
// The server does not recognise that shape: a prekey IQ addressed with it got
|
|
55
|
+
// no reply whatsoever and timed out, so no session was ever built for the
|
|
56
|
+
// contact's linked devices and sends failed with NO_OPEN_SESSION.
|
|
51
57
|
if (server === 'lid' && device > 0) {
|
|
52
|
-
return { user:
|
|
58
|
+
return { user, agent: 1, device, server, toString() { return self; } };
|
|
53
59
|
}
|
|
54
60
|
// JID_PAIR: used for @lid device-0, @g.us, and primary (device-0) @s.whatsapp.net
|
|
55
61
|
return { user, server, toString() { return self; } };
|
|
@@ -749,8 +755,37 @@ class DeviceManager {
|
|
|
749
755
|
}
|
|
750
756
|
|
|
751
757
|
if (allowPkmsg && fetchJids.length > 0) {
|
|
752
|
-
|
|
753
|
-
|
|
758
|
+
// Ask for the bundles by phone JID. The encrypt IQ is not answered at all
|
|
759
|
+
// when its <user> entries are @lid — it just times out — while the same
|
|
760
|
+
// request in phone form comes back in full. Translate through the known
|
|
761
|
+
// LID→PN mapping, keeping a link back so each bundle is installed under
|
|
762
|
+
// the LID address the participants node will use.
|
|
763
|
+
const pnForLid = this._client._lidToPn && this._client._lidToPn.get(lidUser);
|
|
764
|
+
const wireToLid = new Map();
|
|
765
|
+
let wireJids = fetchJids;
|
|
766
|
+
if (pnForLid) {
|
|
767
|
+
wireJids = fetchJids.map(j => {
|
|
768
|
+
const at = j.indexOf('@');
|
|
769
|
+
const base = at >= 0 ? j.slice(0, at) : j;
|
|
770
|
+
const colon = base.indexOf(':');
|
|
771
|
+
const dev = colon >= 0 ? (parseInt(base.slice(colon + 1), 10) || 0) : 0;
|
|
772
|
+
const wire = makeDeviceJid(pnForLid, dev, 's.whatsapp.net');
|
|
773
|
+
wireToLid.set(wire, j);
|
|
774
|
+
return wire;
|
|
775
|
+
});
|
|
776
|
+
_whaDbg('[DBG] LID_BUNDLE_VIA_PN lid=' + lidUser + ' pn=' + pnForLid +
|
|
777
|
+
' jids=[' + wireJids.join(',') + ']\n');
|
|
778
|
+
} else {
|
|
779
|
+
_whaDbg('[DBG] LID_BUNDLE_NO_PN lid=' + lidUser + ' — requesting by LID\n');
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
const bundles = await this.fetchBundles(wireJids);
|
|
783
|
+
for (const [wireJid, bundle] of bundles) {
|
|
784
|
+
// Install under the @lid address: that is what the outgoing
|
|
785
|
+
// participants node — and therefore the encrypt step — looks the
|
|
786
|
+
// session up by. Stored under the phone user it is a different Signal
|
|
787
|
+
// address and would never be found.
|
|
788
|
+
const jid = wireToLid.get(wireJid) || wireJid;
|
|
754
789
|
try {
|
|
755
790
|
await signalProto.buildSessionFromBundle(jid, bundle);
|
|
756
791
|
// ── CRITICAL: remap bundle JID back to @lid format ────────────────────
|
|
@@ -760,14 +795,13 @@ class DeviceManager {
|
|
|
760
795
|
// nodes to also use @lid format — mixing @s.whatsapp.net participants with
|
|
761
796
|
// a @lid routing address causes the server to close the connection.
|
|
762
797
|
//
|
|
763
|
-
//
|
|
764
|
-
//
|
|
765
|
-
//
|
|
766
|
-
//
|
|
767
|
-
//
|
|
768
|
-
//
|
|
769
|
-
//
|
|
770
|
-
// "112713111982325:2@s.whatsapp.net" → "112713111982325:2@lid"
|
|
798
|
+
// A Signal address is (user, device) with the @server stripped — but
|
|
799
|
+
// the user of a LID and the user of a phone JID are different strings,
|
|
800
|
+
// so a session is NOT reachable under both. That assumption is what
|
|
801
|
+
// left sends failing: bundles fetched in phone form were stored under
|
|
802
|
+
// the phone user while the participants node looked them up by LID.
|
|
803
|
+
// The session is installed under the @lid address above; this only
|
|
804
|
+
// normalises the JID pushed into readyJids.
|
|
771
805
|
const jidBase = jid.replace(/@(?:s\.whatsapp\.net|lid)$/, '');
|
|
772
806
|
const lidJidForDevice = jidBase + '@lid';
|
|
773
807
|
readyJids.push(lidJidForDevice);
|
|
@@ -42,12 +42,12 @@ function phoneFromJid(jid) {
|
|
|
42
42
|
return colon >= 0 ? user.slice(0, colon) : user;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
// ───
|
|
45
|
+
// ─── ADVSignedDeviceIdentity ─────────────────────────────────────────────────
|
|
46
46
|
//
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
47
|
+
// Received from the server in the pair-success IQ when a companion device is
|
|
48
|
+
// linked. A primary device registered over SMS never gets one and must not
|
|
49
|
+
// invent one — see _buildOrGetAdvIdentity. The encoders below remain for
|
|
50
|
+
// working with a real identity when the server does supply it.
|
|
51
51
|
//
|
|
52
52
|
// ADVDeviceIdentityDetails (protobuf):
|
|
53
53
|
// field 1 (rawId, uint32): registration ID
|
|
@@ -110,33 +110,26 @@ function _getCurve() {
|
|
|
110
110
|
// Returns Buffer of encoded proto WITH accountSignatureKey included.
|
|
111
111
|
// Result is cached in store.advIdentity so we only build it once per registration.
|
|
112
112
|
function _buildOrGetAdvIdentity(store) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const adv = _encodeADVSignedIdentity(details, pub32, acctSig, devSig);
|
|
133
|
-
store.advIdentity = adv;
|
|
134
|
-
_whaDbg('[DBG] ADV_BUILT from primary iOS keys (' + adv.length + 'b)\n');
|
|
135
|
-
return adv;
|
|
136
|
-
} catch (e) {
|
|
137
|
-
_whaDbg('[DBG] ADV_BUILD_ERR: ' + e.message);
|
|
138
|
-
return null;
|
|
113
|
+
// Only ever return an identity the server actually issued.
|
|
114
|
+
//
|
|
115
|
+
// ADVSignedDeviceIdentity is minted during companion pairing: it proves a
|
|
116
|
+
// linked device's identity key was authorised by the primary, and its
|
|
117
|
+
// accountSignature is made with the primary's key. This client registers
|
|
118
|
+
// over SMS as the primary, so no pairing IQ ever runs and there is nothing
|
|
119
|
+
// to attach — which is what the comment above allowPkmsg already says
|
|
120
|
+
// primaries do.
|
|
121
|
+
//
|
|
122
|
+
// This used to fabricate one by self-signing with our own identity key when
|
|
123
|
+
// the store had none. That identity cannot validate: nothing authorised it.
|
|
124
|
+
// Attaching it to every pkmsg is a plausible cause of the server rejecting
|
|
125
|
+
// sends with ack 479 while still delivering messages to us, and it
|
|
126
|
+
// contradicted the documented behaviour a few lines up. If a real
|
|
127
|
+
// device-identity is ever received on <success> it is stored and used here;
|
|
128
|
+
// otherwise the node is simply omitted.
|
|
129
|
+
if (store && store.advIdentity && store.advIdentity.length > 0) {
|
|
130
|
+
return store.advIdentity;
|
|
139
131
|
}
|
|
132
|
+
return null;
|
|
140
133
|
}
|
|
141
134
|
|
|
142
135
|
function makeJid(input, server) {
|
|
@@ -716,14 +709,27 @@ class MessageSender {
|
|
|
716
709
|
// For LID-migrated accounts, the message `to` field AND Signal participants
|
|
717
710
|
// must use the LID JID. Phone-JID messages are silently accepted by the
|
|
718
711
|
// server but never delivered to the recipient's LID-registered device.
|
|
719
|
-
|
|
720
|
-
|
|
712
|
+
//
|
|
713
|
+
// WA_DM_ROUTE overrides the choice for diagnosis, because both routes have
|
|
714
|
+
// been observed failing in different ways and only a live account can tell
|
|
715
|
+
// them apart:
|
|
716
|
+
// pn — always address the phone JID (how this worked before LID JIDs
|
|
717
|
+
// started being decoded at all)
|
|
718
|
+
// lid — always address the LID when one is known (the default below)
|
|
719
|
+
// auto — same as lid; the default
|
|
720
|
+
const routeMode = (process.env.WA_DM_ROUTE || 'auto').toLowerCase();
|
|
721
|
+
const lidUser = this._client._pnToLid && this._client._pnToLid.get(recipientPhone);
|
|
722
|
+
const useLidRoute = lidUser && routeMode !== 'pn';
|
|
723
|
+
const routingToJid = useLidRoute ? `${lidUser}@lid` : toJid;
|
|
721
724
|
|
|
722
725
|
_whaDbg('[DBG] DM_ROUTE phone=' + recipientPhone +
|
|
723
|
-
' routing=' + routingToJid + (
|
|
726
|
+
' routing=' + routingToJid + (useLidRoute ? ' (LID)' : ' (PN)') +
|
|
727
|
+
' mode=' + routeMode);
|
|
724
728
|
|
|
725
729
|
let otherJids;
|
|
726
|
-
|
|
730
|
+
// Follow the same address family as the routing JID — the participants and
|
|
731
|
+
// the `to` must agree, so WA_DM_ROUTE=pn has to switch both.
|
|
732
|
+
if (useLidRoute) {
|
|
727
733
|
// Fetch bundle + build Signal session for the LID JID.
|
|
728
734
|
// skipUsync=true: we already know the LID from _pnToLid — skip a second
|
|
729
735
|
// 15 s usync round-trip and go straight to bundle fetch (device 0 primary).
|