whalibmob 5.7.2 → 5.7.3
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 +37 -2
- package/lib/messages/TcTokenStore.js +44 -0
- package/package.json +1 -1
package/lib/Client.js
CHANGED
|
@@ -1904,8 +1904,43 @@ class WhalibmobClient extends EventEmitter {
|
|
|
1904
1904
|
const { normalizeJidForTcToken } = require('./messages/TcTokenStore');
|
|
1905
1905
|
const norm = normalizeJidForTcToken(jid);
|
|
1906
1906
|
if (norm.endsWith('@lid')) return norm;
|
|
1907
|
-
|
|
1908
|
-
|
|
1907
|
+
|
|
1908
|
+
const pnUser = norm.split('@')[0];
|
|
1909
|
+
let lidUser = this._pnToLid && this._pnToLid.get(pnUser);
|
|
1910
|
+
|
|
1911
|
+
// The in-memory map starts empty and is filled by usync and by incoming
|
|
1912
|
+
// messages, so a send early in a process — or one that hits a warm device
|
|
1913
|
+
// cache and never runs usync — could find nothing and fall back to the
|
|
1914
|
+
// phone JID. The mapping is on disk in the Signal store either way, which
|
|
1915
|
+
// is the same place whatsmeow reads it from, so consult that before giving
|
|
1916
|
+
// up. The consequence of not doing so is not cosmetic: the lookup lands on
|
|
1917
|
+
// a key with no token while a live one sits under the LID, and the message
|
|
1918
|
+
// goes out without one.
|
|
1919
|
+
if (!lidUser) {
|
|
1920
|
+
const store = this._signal && this._signal.store;
|
|
1921
|
+
const persisted = store && typeof store.getLidMappings === 'function'
|
|
1922
|
+
? store.getLidMappings() : null;
|
|
1923
|
+
const fromDisk = persisted && persisted[pnUser];
|
|
1924
|
+
if (fromDisk) {
|
|
1925
|
+
lidUser = String(fromDisk);
|
|
1926
|
+
if (this._pnToLid) this._pnToLid.set(pnUser, lidUser);
|
|
1927
|
+
if (this._lidToPn) this._lidToPn.set(lidUser, pnUser);
|
|
1928
|
+
_whaDbg('[DBG] TCTOKEN_LID_FROM_DISK pn=' + pnUser + ' lid=' + lidUser);
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
if (!lidUser) return norm;
|
|
1933
|
+
|
|
1934
|
+
const lidJid = lidUser + '@lid';
|
|
1935
|
+
|
|
1936
|
+
// Anything already filed under the phone JID belongs with the LID entry.
|
|
1937
|
+
// Left split, the two halves each hold part of the state and neither is
|
|
1938
|
+
// complete. Cheap when there is nothing to move, which is the usual case.
|
|
1939
|
+
if (this._tcTokenStore && this._tcTokenStore.mergeEntry(norm, lidJid)) {
|
|
1940
|
+
_whaDbg('[DBG] TCTOKEN_MERGED ' + norm + ' → ' + lidJid);
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1943
|
+
return lidJid;
|
|
1909
1944
|
}
|
|
1910
1945
|
|
|
1911
1946
|
// The JID a token is *issued* to, which is not the JID it is *stored* under.
|
|
@@ -166,6 +166,50 @@ class TcTokenStore {
|
|
|
166
166
|
return true;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Fold an entry filed under one JID into the entry for another.
|
|
171
|
+
*
|
|
172
|
+
* The same contact can end up with two entries — one under their phone JID
|
|
173
|
+
* and one under their LID — when a send happens before the LID mapping is
|
|
174
|
+
* known. That is not just untidy: whichever key the next send resolves to is
|
|
175
|
+
* the only one it looks at, so a live token under the LID goes unused and the
|
|
176
|
+
* message ships without one.
|
|
177
|
+
*
|
|
178
|
+
* The live token wins, newest first. The sender timestamp takes the newer of
|
|
179
|
+
* the two, since an older one would say we are due to issue again when we are
|
|
180
|
+
* not.
|
|
181
|
+
*
|
|
182
|
+
* @returns {boolean} whether anything was moved
|
|
183
|
+
*/
|
|
184
|
+
mergeEntry(fromJid, toJid) {
|
|
185
|
+
const fromKey = normalizeJidForTcToken(fromJid);
|
|
186
|
+
const toKey = normalizeJidForTcToken(toJid);
|
|
187
|
+
if (fromKey === toKey) return false;
|
|
188
|
+
|
|
189
|
+
const from = this._map.get(fromKey);
|
|
190
|
+
if (!from) return false;
|
|
191
|
+
|
|
192
|
+
const to = this._map.get(toKey) || {};
|
|
193
|
+
|
|
194
|
+
const fromLive = !!(from.token && from.token.length) && !tcTokenExpired(from.timestamp);
|
|
195
|
+
const toLive = !!(to.token && to.token.length) && !tcTokenExpired(to.timestamp);
|
|
196
|
+
|
|
197
|
+
let token = to.token != null ? to.token : null;
|
|
198
|
+
let timestamp = to.timestamp != null ? to.timestamp : null;
|
|
199
|
+
if (fromLive && (!toLive || Number(from.timestamp) > Number(to.timestamp || 0))) {
|
|
200
|
+
token = from.token;
|
|
201
|
+
timestamp = from.timestamp;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const senderTimestamp =
|
|
205
|
+
Math.max(Number(to.senderTimestamp || 0), Number(from.senderTimestamp || 0)) || null;
|
|
206
|
+
|
|
207
|
+
this._map.set(toKey, { token, timestamp, senderTimestamp });
|
|
208
|
+
this._map.delete(fromKey);
|
|
209
|
+
this._save();
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
|
|
169
213
|
clearToken(jid) {
|
|
170
214
|
const key = normalizeJidForTcToken(jid);
|
|
171
215
|
const existing = this._map.get(key) || {};
|