whalibmob 5.33.28 → 5.33.29
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/Registration.js +20 -10
- package/lib/Store.js +7 -2
- package/package.json +1 -1
package/lib/Registration.js
CHANGED
|
@@ -1593,6 +1593,16 @@ function toBase64Url(buf) {
|
|
|
1593
1593
|
return buf.toString('base64').replace(/\+/g, '-').replace(/\//g, '_');
|
|
1594
1594
|
}
|
|
1595
1595
|
|
|
1596
|
+
// The native client encodes the Signal-key and expid wire parameters with
|
|
1597
|
+
// Base64.encodeToString(bytes, 11) = URL_SAFE | NO_WRAP | NO_PADDING: authkey
|
|
1598
|
+
// (43 chars), e_ident/e_skey_val (43), e_skey_sig (86), e_regid (6), e_keytype,
|
|
1599
|
+
// e_skey_id (4), expid (22) — never a trailing '='. The padded form still
|
|
1600
|
+
// decodes server-side, but the bare '=' is a wire tell no real device emits.
|
|
1601
|
+
// The ENC envelope and the vname certificate keep their own encoder above.
|
|
1602
|
+
function toBase64UrlNoPad(buf) {
|
|
1603
|
+
return toBase64Url(buf).replace(/=+$/, '');
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1596
1606
|
// ---------- vname: the Business verified-name certificate ----------
|
|
1597
1607
|
//
|
|
1598
1608
|
// A Business registration carries one extra form field, `vname`, and a consumer
|
|
@@ -1712,18 +1722,18 @@ async function buildPayload(store, waVersion, useToken, extraPairs, path) {
|
|
|
1712
1722
|
'rc', String(RELEASE_CHANNEL),
|
|
1713
1723
|
'lg', meta.lg,
|
|
1714
1724
|
'lc', meta.lc,
|
|
1715
|
-
'authkey',
|
|
1725
|
+
'authkey', toBase64UrlNoPad(stripKeyPrefix(store.noiseKeyPair.public)),
|
|
1716
1726
|
// Business only; buildForm drops a null, so a consumer registration sends
|
|
1717
1727
|
// the same body it always has.
|
|
1718
1728
|
'vname', buildVerifiedNameCertificate(store, device),
|
|
1719
|
-
'e_regid',
|
|
1720
|
-
'e_keytype',
|
|
1721
|
-
'e_ident',
|
|
1722
|
-
'e_skey_id',
|
|
1723
|
-
'e_skey_val',
|
|
1724
|
-
'e_skey_sig',
|
|
1729
|
+
'e_regid', toBase64UrlNoPad(intToBytes(store.registrationId, 4)),
|
|
1730
|
+
'e_keytype', toBase64UrlNoPad(Buffer.from([SIGNAL_KEY_TYPE])),
|
|
1731
|
+
'e_ident', toBase64UrlNoPad(stripKeyPrefix(store.identityKeyPair.public)),
|
|
1732
|
+
'e_skey_id', toBase64UrlNoPad(intToBytes(store.signedPreKey.id, 3)),
|
|
1733
|
+
'e_skey_val', toBase64UrlNoPad(stripKeyPrefix(store.signedPreKey.public)),
|
|
1734
|
+
'e_skey_sig', toBase64UrlNoPad(store.signedPreKey.signature),
|
|
1725
1735
|
'fdid', fdid,
|
|
1726
|
-
'expid',
|
|
1736
|
+
'expid', toBase64UrlNoPad(store.deviceId),
|
|
1727
1737
|
'id', toUrlHex(store.identityId),
|
|
1728
1738
|
'access_session_id', getAccessSessionId(store),
|
|
1729
1739
|
'token', token,
|
|
@@ -1920,7 +1930,7 @@ async function sendFunnelLog(store, waVersion, currentScreen, actionTaken, event
|
|
|
1920
1930
|
'in', national,
|
|
1921
1931
|
'lg', 'en',
|
|
1922
1932
|
'lc', 'US',
|
|
1923
|
-
'expid',
|
|
1933
|
+
'expid', toBase64UrlNoPad(store.deviceId),
|
|
1924
1934
|
'fdid', fdid,
|
|
1925
1935
|
'id', toUrlHex(store.identityId),
|
|
1926
1936
|
'current_screen', currentScreen,
|
|
@@ -1952,7 +1962,7 @@ async function sendPrePnFunnelLog(store, waVersion, actionTaken, eventName) {
|
|
|
1952
1962
|
const body = buildForm([
|
|
1953
1963
|
'lg', 'en',
|
|
1954
1964
|
'lc', 'US',
|
|
1955
|
-
'expid',
|
|
1965
|
+
'expid', toBase64UrlNoPad(store.deviceId),
|
|
1956
1966
|
'fdid', fdid,
|
|
1957
1967
|
'id', toUrlHex(store.identityId),
|
|
1958
1968
|
'current_screen', 'enter_number',
|
package/lib/Store.js
CHANGED
|
@@ -82,7 +82,11 @@ function createNewStore(phoneNumber, opts) {
|
|
|
82
82
|
|
|
83
83
|
const registrationId = (crypto.randomBytes(2).readUInt16BE(0) & 0x3fff) + 1;
|
|
84
84
|
const fdid = uuidv4();
|
|
85
|
-
|
|
85
|
+
// expid goes on the wire as a UUID and WhatsApp reads its version/variant
|
|
86
|
+
// nibbles (the native client builds it with UUID.nameUUIDFromBytes/randomUUID).
|
|
87
|
+
// 16 fully random bytes land on a valid UUID shape only ~1 time in 16, so the
|
|
88
|
+
// server sees a malformed UUID; take the 16 bytes of a real v4 UUID instead.
|
|
89
|
+
const deviceId = Buffer.from(uuidv4().replace(/-/g, ''), 'hex');
|
|
86
90
|
const identityId = crypto.randomBytes(16);
|
|
87
91
|
// Device fingerprint fields the native client sends on /code (see
|
|
88
92
|
// Registration.js): advertising id (UUID) and the 20-byte backup token.
|
|
@@ -358,7 +362,8 @@ function fromSixParts(sixParts) {
|
|
|
358
362
|
},
|
|
359
363
|
registrationId: (crypto.randomBytes(2).readUInt16BE(0) & 0x3fff) + 1,
|
|
360
364
|
fdid: uuidv4(),
|
|
361
|
-
|
|
365
|
+
// expid must be a valid UUID on the wire — see createNewStore above.
|
|
366
|
+
deviceId: Buffer.from(uuidv4().replace(/-/g, ''), 'hex'),
|
|
362
367
|
identityId,
|
|
363
368
|
advertisingId: uuidv4(),
|
|
364
369
|
backupToken: crypto.randomBytes(20),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "whalibmob",
|
|
3
|
-
"version": "5.33.
|
|
3
|
+
"version": "5.33.29",
|
|
4
4
|
"description": "Node.js library for WhatsApp — register a number over SMS, or link as a companion by QR. Signal E2E encryption, media, groups, channels.",
|
|
5
5
|
"author": "Kunboruto20",
|
|
6
6
|
"main": "index.js",
|