whalibmob 5.33.20 → 5.33.22
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 +26 -1
- package/cli.js +3 -3
- package/lib/Attestation.js +25 -2
- package/lib/Registration.js +6 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ code, and bring the account into being. Both transports, one API.
|
|
|
19
19
|
|
|
20
20
|
### Start here
|
|
21
21
|
|
|
22
|
-
[](#register-a-new-number)
|
|
23
23
|
[](#linking-to-an-existing-account-pairing-code-or-qr)
|
|
24
24
|
[](#cli--getting-started)
|
|
25
25
|
|
|
@@ -439,6 +439,9 @@ wa registration --request-code 919634847671 --method wa_old
|
|
|
439
439
|
|
|
440
440
|
# via flash call — WhatsApp rings the number and hangs up (Android only)
|
|
441
441
|
WA_OS=android wa registration --request-code 919634847671 --method flash
|
|
442
|
+
|
|
443
|
+
# via email — WhatsApp sends a 6-digit code to the email address linked to the number
|
|
444
|
+
wa registration --request-code 919634847671 --method email_otp
|
|
442
445
|
```
|
|
443
446
|
|
|
444
447
|
**Flash call** sends no code anywhere. WhatsApp rings the number from a
|
|
@@ -471,6 +474,28 @@ Three things to know before choosing it:
|
|
|
471
474
|
Set `WA_FLASH_CODE_LEN` if a number's server expects a different length than the
|
|
472
475
|
six digits the app defaults to.
|
|
473
476
|
|
|
477
|
+
**Email OTP** sends a 6-digit verification code to the email address that the
|
|
478
|
+
phone number's WhatsApp account has associated. This method only works when the
|
|
479
|
+
number already has an email linked to its WhatsApp account — if there is no email
|
|
480
|
+
on file, the server returns an error and you should fall back to `sms` or `voice`.
|
|
481
|
+
|
|
482
|
+
```sh
|
|
483
|
+
# request via email
|
|
484
|
+
wa registration --request-code 919634847671 --method email_otp
|
|
485
|
+
|
|
486
|
+
# then confirm with the 6-digit code WhatsApp emailed
|
|
487
|
+
wa registration --register 919634847671 --code 123456
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
Two things to know before choosing it:
|
|
491
|
+
|
|
492
|
+
- **Email must be linked.** If the number has never had an email associated in
|
|
493
|
+
WhatsApp Settings → Account → Email address, the server rejects the request.
|
|
494
|
+
Use `sms` or `voice` instead.
|
|
495
|
+
- **Falls back to SMS.** When `email_otp` fails (no email on file or email
|
|
496
|
+
delivery issue), whalibmob automatically retries with `sms` so the attempt is
|
|
497
|
+
not wasted.
|
|
498
|
+
|
|
474
499
|
**Set the account's display name while registering** with `--name`. This is the
|
|
475
500
|
name people who have *not* saved your number see next to it — in group
|
|
476
501
|
participant lists, in notifications, and beside your messages. Quote it if it
|
package/cli.js
CHANGED
|
@@ -673,7 +673,7 @@ const HELP = `
|
|
|
673
673
|
|
|
674
674
|
Registration
|
|
675
675
|
/reg check <phone> check if number has WhatsApp
|
|
676
|
-
/reg code <phone> [sms|voice|wa_old|flash]
|
|
676
|
+
/reg code <phone> [sms|voice|wa_old|flash|email_otp] request verification code
|
|
677
677
|
/reg push <phone> [sms|voice] request code and receive it over push
|
|
678
678
|
/reg confirm <phone> <code> complete registration
|
|
679
679
|
|
|
@@ -2400,7 +2400,7 @@ async function handleLine(line) {
|
|
|
2400
2400
|
const ph = normalizePhone(p[2]);
|
|
2401
2401
|
const method = (p[3] || 'sms').toLowerCase();
|
|
2402
2402
|
if (!ph) {
|
|
2403
|
-
fail('usage: /reg code <phone> [sms|voice|wa_old|flash] [--name "Your Name"]');
|
|
2403
|
+
fail('usage: /reg code <phone> [sms|voice|wa_old|flash|email_otp] [--name "Your Name"]');
|
|
2404
2404
|
out(' --name sets the display name the account registers with — what people');
|
|
2405
2405
|
out(' who have not saved your number see. It can be changed later with /name.');
|
|
2406
2406
|
break;
|
|
@@ -2788,7 +2788,7 @@ options:
|
|
|
2788
2788
|
--out <file> where apk-material writes (default: <session dir>/android-apk-material.json)
|
|
2789
2789
|
--sms connect by registering this number over SMS
|
|
2790
2790
|
--pair connect by linking to an existing account (8-digit code)
|
|
2791
|
-
--method sms | voice | wa_old | flash (default: sms)
|
|
2791
|
+
--method sms | voice | wa_old | flash | email_otp (default: sms)
|
|
2792
2792
|
flash: WhatsApp rings the number and hangs up; the code is
|
|
2793
2793
|
read from the calling number automatically (Android only)
|
|
2794
2794
|
--business register/connect as WhatsApp Business (same as WA_BUSINESS=1)
|
package/lib/Attestation.js
CHANGED
|
@@ -55,6 +55,27 @@ const GS_SERVER_KEY = Buffer.from(
|
|
|
55
55
|
// Base stat codes for the 13 path checks; +1000 when stat() fails.
|
|
56
56
|
const GS_BASE_CODES = [10, 11, 0, 100, 101, 102, 103, 104, 1, 105, 106, 107, 108];
|
|
57
57
|
|
|
58
|
+
// ─── _ge: environment security flags ─────────────────────────────────────────
|
|
59
|
+
// sb=false (no security bypass), sv=false (not security-verified by TEE).
|
|
60
|
+
// Always false on a headless client — matching a device that passed basic
|
|
61
|
+
// checks but has no hardware-backed verification.
|
|
62
|
+
function generateGeToken() {
|
|
63
|
+
return encodeURIComponent('{"sb":false,"sv":false}');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ─── _ga: app analytics envelope ─────────────────────────────────────────────
|
|
67
|
+
// bi = SHA-512 of the session nonce (deterministic per session, unique per
|
|
68
|
+
// device); ap/ai/ae are numeric constants observed across Android builds;
|
|
69
|
+
// mp/mu are multi-profile/multi-user booleans (false on a single-user install).
|
|
70
|
+
function generateGaToken(nonceB64) {
|
|
71
|
+
const nonceBuf = Buffer.from(
|
|
72
|
+
(nonceB64 || '').replace(/-/g, '+').replace(/_/g, '/'), 'base64'
|
|
73
|
+
);
|
|
74
|
+
const bi = crypto.createHash('sha512').update(nonceBuf).digest('base64');
|
|
75
|
+
const json = '{"bi":"' + bi + '","ap":247444,"ai":145847,"mp":false,"ae":128383,"mu":false}';
|
|
76
|
+
return encodeURIComponent(json);
|
|
77
|
+
}
|
|
78
|
+
|
|
58
79
|
function generateGsToken() {
|
|
59
80
|
const nowMs = Date.now();
|
|
60
81
|
const sec = Math.floor(nowMs / 1000);
|
|
@@ -246,14 +267,16 @@ async function attestationFields(device, nonceB64, opts) {
|
|
|
246
267
|
if (device && device.os === 'android') {
|
|
247
268
|
const a = await androidIntegrity(nonceB64 || '', device);
|
|
248
269
|
const gs = generateGsToken();
|
|
270
|
+
const ge = generateGeToken();
|
|
271
|
+
const ga = generateGaToken(nonceB64 || '');
|
|
249
272
|
_ok('_gs field generated (WASafe envelope, ' + gs.length + ' encoded chars)');
|
|
250
273
|
return [
|
|
251
274
|
'gpia', orNull(a.gpia),
|
|
252
275
|
'_gg', orNull(a.gg),
|
|
253
276
|
'_gi', orNull(a.gi),
|
|
254
277
|
'_gp', orNull(a.gp),
|
|
255
|
-
'_ge',
|
|
256
|
-
'_ga',
|
|
278
|
+
'_ge', ge,
|
|
279
|
+
'_ga', ga,
|
|
257
280
|
'_gs', gs,
|
|
258
281
|
'push_token', pushToken
|
|
259
282
|
];
|
package/lib/Registration.js
CHANGED
|
@@ -1389,7 +1389,7 @@ function getRequestVerificationCodeParameters(store, method, meta, device, attem
|
|
|
1389
1389
|
'reason', '',
|
|
1390
1390
|
'mcc', meta.mcc,
|
|
1391
1391
|
'mnc', meta.mnc,
|
|
1392
|
-
'feo2_query_status', '
|
|
1392
|
+
'feo2_query_status', 'success_get_client_capabilities',
|
|
1393
1393
|
'db', '1',
|
|
1394
1394
|
'sim_type', '1',
|
|
1395
1395
|
'recaptcha', '%7B%22stage%22%3A%22ABPROP_DISABLED%22%7D',
|
|
@@ -2216,8 +2216,11 @@ async function requestSmsCode(store, method, opts) {
|
|
|
2216
2216
|
}
|
|
2217
2217
|
|
|
2218
2218
|
// Auto-fallback: if the primary method gets no_routes, try the alternate once.
|
|
2219
|
-
// sms → wa_old, wa_old → sms, voice → sms.
|
|
2220
|
-
const fallbackMethod = method === 'wa_old' ? 'sms'
|
|
2219
|
+
// sms → wa_old, wa_old → sms, voice → sms, email_otp → sms.
|
|
2220
|
+
const fallbackMethod = method === 'wa_old' ? 'sms'
|
|
2221
|
+
: (method === 'sms' ? 'wa_old'
|
|
2222
|
+
: (method === 'email_otp' ? 'sms'
|
|
2223
|
+
: 'sms'));
|
|
2221
2224
|
let autoFallbackDone = false;
|
|
2222
2225
|
|
|
2223
2226
|
// Derive real MCC/MNC from the phone number being registered.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "whalibmob",
|
|
3
|
-
"version": "5.33.
|
|
3
|
+
"version": "5.33.22",
|
|
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",
|