whalibmob 5.14.18 → 5.16.0
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 +75 -2
- package/index.js +9 -0
- package/lib/Client.js +447 -56
- package/lib/HistorySyncHandler.js +58 -10
- package/lib/OfflineNodeProcessor.js +100 -0
- package/lib/SessionPaths.js +30 -0
- package/lib/WAM/BinaryInfo.js +19 -0
- package/lib/WAM/constants.js +22868 -0
- package/lib/WAM/encode.js +161 -0
- package/lib/WAM/index.js +18 -0
- package/lib/messages/MessageSender.js +11 -0
- package/lib/proto/MessageProto.js +72 -1
- package/lib/signal/SignalProtocol.js +99 -10
- package/lib/signal/SignalStore.js +312 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2149,7 +2149,8 @@ History arrives in chunks over the first minute or so after linking, largest fir
|
|
|
2149
2149
|
| File | Holds |
|
|
2150
2150
|
|---|---|
|
|
2151
2151
|
| `<phone>.web.json` | link state — keys, `advSecretKey`, the device slot you were given |
|
|
2152
|
-
| `<phone>.web.signal.json` | Signal sessions
|
|
2152
|
+
| `<phone>.web.signal.json` | Signal sessions, signed pre-key, identities, LID map, pre-key counters |
|
|
2153
|
+
| `<phone>.web.pre-key-<id>.json` | one one-time pre-key — 812 of them |
|
|
2153
2154
|
| `<phone>.web.sk.json` | group SenderKeys |
|
|
2154
2155
|
| `<phone>.web.tctoken.json` | privacy tokens |
|
|
2155
2156
|
| `<phone>.web.appState.json` | app-state version and hash per collection |
|
|
@@ -2538,7 +2539,11 @@ whalibmob_auth/
|
|
|
2538
2539
|
├── android-apk-material-business.json
|
|
2539
2540
|
├── 919634847671/
|
|
2540
2541
|
│ ├── 919634847671.json ← the store: keys, device, version
|
|
2541
|
-
│ ├── 919634847671.signal.json ← Signal sessions
|
|
2542
|
+
│ ├── 919634847671.signal.json ← Signal sessions, signed pre-key, identities
|
|
2543
|
+
│ ├── 919634847671.pre-key-1.json ← one-time pre-keys, one file each
|
|
2544
|
+
│ ├── 919634847671.pre-key-2.json
|
|
2545
|
+
│ ├── … 812 of them
|
|
2546
|
+
│ ├── 919634847671.pre-key-812.json
|
|
2542
2547
|
│ ├── 919634847671.sk.json ← sender keys
|
|
2543
2548
|
│ ├── 919634847671.tctoken.json
|
|
2544
2549
|
│ ├── 919634847671.device-cache.json
|
|
@@ -2566,6 +2571,66 @@ of a pile by prefix.
|
|
|
2566
2571
|
> is moved unless you ask — `wa migrate-sessions` does that, one number or all
|
|
2567
2572
|
> of them, and re-running it is safe.
|
|
2568
2573
|
|
|
2574
|
+
### One-time Pre-keys
|
|
2575
|
+
|
|
2576
|
+
A pre-key is a one-shot Diffie-Hellman key the account leaves with the server so
|
|
2577
|
+
somebody who wants to message it can open a Signal session without it being
|
|
2578
|
+
online. Each one is handed out once and then gone. Run out and nobody can start
|
|
2579
|
+
a conversation with the number at all — the messages are not delayed, they are
|
|
2580
|
+
never sent, and nothing anywhere reports it.
|
|
2581
|
+
|
|
2582
|
+
whalibmob keeps a pool of **812**, generated the moment a session is created and
|
|
2583
|
+
written one key per file, in whatever authentication folder you gave it:
|
|
2584
|
+
|
|
2585
|
+
```
|
|
2586
|
+
~/.waSession/919634847671/
|
|
2587
|
+
├── 919634847671.pre-key-1.json
|
|
2588
|
+
├── 919634847671.pre-key-2.json
|
|
2589
|
+
└── … 919634847671.pre-key-812.json
|
|
2590
|
+
```
|
|
2591
|
+
|
|
2592
|
+
A companion link for the same number keeps its own pool beside it as
|
|
2593
|
+
`919634847671.web.pre-key-<id>.json`. The two are never shared: they are
|
|
2594
|
+
separate devices with separate identity keys, and a key offered under the wrong
|
|
2595
|
+
one cannot be answered.
|
|
2596
|
+
|
|
2597
|
+
The file is the same shape the reference client writes — the raw 32-byte public
|
|
2598
|
+
key and the private key, both BufferJSON:
|
|
2599
|
+
|
|
2600
|
+
```json
|
|
2601
|
+
{"private":{"type":"Buffer","data":"…"},"public":{"type":"Buffer","data":"…"}}
|
|
2602
|
+
```
|
|
2603
|
+
|
|
2604
|
+
**Keeping the server stocked.** Three things drive it, and all of them ask the
|
|
2605
|
+
server what it is actually holding rather than guessing from the local pool —
|
|
2606
|
+
the two drift apart, because the server spends a key on every bundle it hands
|
|
2607
|
+
out and none of that reaches this side.
|
|
2608
|
+
|
|
2609
|
+
| When | What it does |
|
|
2610
|
+
|---|---|
|
|
2611
|
+
| on login | asks the server for its count; **0** there means a full 812 goes up, anything low means a top-up of 5 |
|
|
2612
|
+
| when the server says it is running low | same check, same batch |
|
|
2613
|
+
| every 30 minutes | same check — for the session that stays up long enough to be drained without a word |
|
|
2614
|
+
|
|
2615
|
+
A batch is the next ids the server has not been sent, never the whole pool
|
|
2616
|
+
again, and only counts as sent once the server has acknowledged it — a rejected
|
|
2617
|
+
upload is retried four times with backoff and then left for the next check, with
|
|
2618
|
+
the same keys still queued. Ids are never reused, even after the key under one
|
|
2619
|
+
has been spent.
|
|
2620
|
+
|
|
2621
|
+
After the login upload the account also asks for the server's **key bundle
|
|
2622
|
+
digest** and compares the identity key and signed pre-key it is being served
|
|
2623
|
+
against the ones this session holds. A mismatch there is the failure that used
|
|
2624
|
+
to need the number registering again to clear.
|
|
2625
|
+
|
|
2626
|
+
None of this needs calling: `init()` and `connectWeb()` both do it, identically.
|
|
2627
|
+
|
|
2628
|
+
> [!NOTE]
|
|
2629
|
+
> **Sessions written before 5.14.19 keep every key they had.** Pre-keys used to
|
|
2630
|
+
> live inside `<phone>.signal.json`; on the first start they are moved out into
|
|
2631
|
+
> files of their own and the aggregate copy is dropped. The keys themselves do
|
|
2632
|
+
> not change, so the bundles the server has already handed out stay answerable.
|
|
2633
|
+
|
|
2569
2634
|
### Where the folder comes from
|
|
2570
2635
|
|
|
2571
2636
|
| order | source |
|
|
@@ -2720,6 +2785,14 @@ Creates a fresh credential store for the given phone number — the key pairs, r
|
|
|
2720
2785
|
|
|
2721
2786
|
It returns everything `createNewStore` does, plus a few fields kept for application code that expects them: `nextPreKeyId`, `firstUnuploadedPreKeyId`, `accountSyncCounter`, `accountSettings`, `processedHistoryMessages` and `advSecretKey`. Those extras live on the object only — `saveStore` does not write them, so they are not there again after a reload. Nothing in the library reads them; treat them as a convenience, not as state.
|
|
2722
2787
|
|
|
2788
|
+
> [!NOTE]
|
|
2789
|
+
> The two pre-key counters the library actually runs on are the ones in the
|
|
2790
|
+
> `SignalStore` — `nextPreKeyId()` and `firstUnuploadedPreKeyId()`, persisted in
|
|
2791
|
+
> `<phone>.signal.json`. They live there rather than in the store because a
|
|
2792
|
+
> number's mobile half and its companion half have a `SignalStore` each and must
|
|
2793
|
+
> never share a pre-key id space. The fields above are the same names on a
|
|
2794
|
+
> different object and do not drive anything.
|
|
2795
|
+
|
|
2723
2796
|
```js
|
|
2724
2797
|
const { initAuthCreds, saveStore } = require('whalibmob')
|
|
2725
2798
|
const path = require('path')
|
package/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const SessionPaths = require('./lib/SessionPaths');
|
|
|
7
7
|
const { createNewStore, saveStore, loadStore, toSixParts, fromSixParts, storeToJson, storeFromJson } = require('./lib/Store');
|
|
8
8
|
const { checkIfRegistered, requestSmsCode, verifyCode } = require('./lib/Registration');
|
|
9
9
|
const { SignalProtocol } = require('./lib/signal/SignalProtocol');
|
|
10
|
+
const WAM = require('./lib/WAM');
|
|
10
11
|
const { SignalStore } = require('./lib/signal/SignalStore');
|
|
11
12
|
const { SenderKeyStore, SenderKeyCrypto } = require('./lib/signal/SenderKey');
|
|
12
13
|
const { DeviceManager } = require('./lib/DeviceManager');
|
|
@@ -103,6 +104,14 @@ module.exports = {
|
|
|
103
104
|
encodeCompanionRegisterPayload,
|
|
104
105
|
encodeCompanionLoginPayload,
|
|
105
106
|
fetchWaWebVersion,
|
|
107
|
+
// WAM — the web client's stats channel: the event/global tables, the binary
|
|
108
|
+
// encoder and the BinaryInfo holder, all as the reference client defines
|
|
109
|
+
// them. See client.wamBuffer / client.sendWAMBuffer().
|
|
110
|
+
WAM,
|
|
111
|
+
encodeWAM: WAM.encodeWAM,
|
|
112
|
+
BinaryInfo: WAM.BinaryInfo,
|
|
113
|
+
WEB_EVENTS: WAM.WEB_EVENTS,
|
|
114
|
+
WEB_GLOBALS: WAM.WEB_GLOBALS,
|
|
106
115
|
// Signal / encryption internals
|
|
107
116
|
SignalProtocol,
|
|
108
117
|
SignalStore,
|