whalibmob 5.9.0 → 5.9.2
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 +1 -0
- package/cli.js +7 -0
- package/lib/Client.js +105 -104
- package/lib/DeviceManager.js +25 -26
- package/lib/MediaService.js +2 -2
- package/lib/MediaThumbnail.js +5 -7
- package/lib/auth-utils.js +11 -13
- package/lib/messages/MessageSender.js +60 -72
- package/lib/messages/ReportingToken.js +4 -6
- package/lib/messages/TcTokenStore.js +9 -15
- package/lib/noise.js +3 -4
- package/lib/proto/MessageProto.js +24 -14
- package/lib/signal/SignalProtocol.js +4 -4
- package/lib/signal/SignalStore.js +2 -2
- package/package.json +1 -1
package/lib/noise.js
CHANGED
|
@@ -449,10 +449,9 @@ class NoiseSocket extends EventEmitter {
|
|
|
449
449
|
// for a bug in the client; the credentials were rejected by the
|
|
450
450
|
// server, which is a different thing and has different remedies.
|
|
451
451
|
//
|
|
452
|
-
//
|
|
453
|
-
//
|
|
454
|
-
//
|
|
455
|
-
// the session is finished and retrying with it is pointless.
|
|
452
|
+
// WhatsApp publishes none of this, so the meanings below come from
|
|
453
|
+
// observing the server. Codes marked "wipe" mean the session is
|
|
454
|
+
// finished and retrying with it is pointless.
|
|
456
455
|
const FAILURE = {
|
|
457
456
|
'400': { wipe: false, text: 'generic failure.' },
|
|
458
457
|
'401': { wipe: true, text: 'logged out. The session was unpaired ' +
|
|
@@ -226,10 +226,10 @@ function encodePollOption(name) {
|
|
|
226
226
|
// PollCreationMessage { encKey=1, name=2, options=3, selectableOptionsCount=4 }
|
|
227
227
|
//
|
|
228
228
|
// The 32-byte secret was being written to encKey, inside the poll itself.
|
|
229
|
-
//
|
|
230
|
-
// Message.messageContextInfo.messageSecret
|
|
231
|
-
//
|
|
232
|
-
//
|
|
229
|
+
// encKey has to stay unset; the secret belongs in
|
|
230
|
+
// Message.messageContextInfo.messageSecret, which is the copy a voter derives
|
|
231
|
+
// their vote key from. In the wrong place it reached nobody, so the poll could
|
|
232
|
+
// not be voted on.
|
|
233
233
|
function encodePollCreationMessage(opts) {
|
|
234
234
|
const messageSecret = opts.messageSecret || opts.encKey ||
|
|
235
235
|
require('crypto').randomBytes(32);
|
|
@@ -672,28 +672,38 @@ function decodeMessageContainer(buf) {
|
|
|
672
672
|
try {
|
|
673
673
|
const pm = _decodeFields(f[12]);
|
|
674
674
|
const pmType = pm[2];
|
|
675
|
+
// ProtocolMessage.Type. These are not the field numbers the payloads
|
|
676
|
+
// live in and the two must not be confused: HISTORY_SYNC_NOTIFICATION
|
|
677
|
+
// is type 5 carried in field 6, APP_STATE_SYNC_KEY_SHARE is type 6
|
|
678
|
+
// carried in field 7. Having those two the wrong way round meant a key
|
|
679
|
+
// share was read as a history notification, looked in the field it does
|
|
680
|
+
// not use, found nothing, and was dropped — so app state could never be
|
|
681
|
+
// decrypted at all.
|
|
675
682
|
const typeNames = {
|
|
676
683
|
0: 'revoke',
|
|
677
684
|
3: 'ephemeral',
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
685
|
+
4: 'ephemeral_sync_response',
|
|
686
|
+
5: 'history_sync',
|
|
687
|
+
6: 'app_state_sync_key_share',
|
|
688
|
+
7: 'app_state_sync_key_request',
|
|
689
|
+
9: 'initial_security_notification_setting_sync',
|
|
690
|
+
10: 'app_state_fatal_exception',
|
|
691
|
+
11: 'share_phone_number',
|
|
692
|
+
14: 'message_edit'
|
|
681
693
|
};
|
|
682
694
|
const subtype = typeNames[pmType] || String(pmType);
|
|
683
695
|
msgResult = { type: 'protocol', subtype };
|
|
684
696
|
|
|
685
|
-
//
|
|
686
|
-
//
|
|
687
|
-
|
|
697
|
+
// The payloads are read by the field they occupy rather than by the
|
|
698
|
+
// type that announced them, so a type number this list does not know
|
|
699
|
+
// about still delivers what it carried.
|
|
700
|
+
if (pm[6] && Buffer.isBuffer(pm[6])) {
|
|
688
701
|
try {
|
|
689
702
|
const { decodeHistorySyncNotification } = require('../HistorySyncHandler');
|
|
690
703
|
msgResult.historySyncNotification = decodeHistorySyncNotification(pm[6]);
|
|
691
704
|
} catch (_hse) {}
|
|
692
705
|
}
|
|
693
|
-
|
|
694
|
-
// ── APP_STATE_SYNC_KEY_SHARE (pmType=5) ──────────────────────────────
|
|
695
|
-
// ProtocolMessage field 7 holds the AppStateSyncKeyShare bytes.
|
|
696
|
-
if (pmType === 5 && pm[7] && Buffer.isBuffer(pm[7])) {
|
|
706
|
+
if (pm[7] && Buffer.isBuffer(pm[7])) {
|
|
697
707
|
try {
|
|
698
708
|
const { decodeAppStateSyncKeyShare } = require('../HistorySyncHandler');
|
|
699
709
|
msgResult.appStateSyncKeyShare = decodeAppStateSyncKeyShare(pm[7]);
|
|
@@ -278,15 +278,15 @@ class SignalProtocol {
|
|
|
278
278
|
|
|
279
279
|
// ─── SenderKey group encrypt / decrypt ────────────────────────────────────
|
|
280
280
|
//
|
|
281
|
-
// Uses WaSignalGroup GroupCipher/GroupSessionBuilder
|
|
281
|
+
// Uses WaSignalGroup GroupCipher/GroupSessionBuilder.
|
|
282
282
|
// SenderKeyName format: groupId::senderId::0 (device 0 for group identity).
|
|
283
283
|
|
|
284
284
|
_senderKeyName(groupId, senderId) {
|
|
285
285
|
// A SenderKey belongs to a device, not to an account. Every device that
|
|
286
286
|
// posts to a group distributes its own key, so the name has to carry the
|
|
287
|
-
// device index
|
|
288
|
-
//
|
|
289
|
-
//
|
|
287
|
+
// device index — otherwise two devices of the same person share one slot
|
|
288
|
+
// and the second one to speak overwrites the first, leaving its messages
|
|
289
|
+
// undecryptable.
|
|
290
290
|
//
|
|
291
291
|
// Bare JIDs still resolve to device 0, so everything already on disk keeps
|
|
292
292
|
// the exact same key string.
|
|
@@ -209,8 +209,8 @@ class SignalStore {
|
|
|
209
209
|
// SessionCipher.encrypt — which throws "No open session". bulkEncryptForDevices
|
|
210
210
|
// drops whatever it cannot encrypt, so the stanza went out with a <to> entry
|
|
211
211
|
// missing for that device and the server nacked the whole send with ack 479.
|
|
212
|
-
//
|
|
213
|
-
//
|
|
212
|
+
// The fix is to validate the record itself on every check rather than
|
|
213
|
+
// trusting that a cached entry still holds an open session.
|
|
214
214
|
hasSession(encodedAddress) {
|
|
215
215
|
if (!this._openSessionMemo) this._openSessionMemo = new Map();
|
|
216
216
|
const data = this._sessions[encodedAddress];
|