whalibmob 5.29.5 → 5.29.6

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 CHANGED
@@ -1866,9 +1866,19 @@ requesting sms code for +919634847671...
1866
1866
  status sent
1867
1867
  ```
1868
1868
 
1869
- It happens once. Every later registration reads the file. `WA_NO_APK_DOWNLOAD=1`
1870
- turns the fetch off if you would rather it never pulled a hundred megabytes
1871
- unasked, and `wa apk-material` below does the same job by hand.
1869
+ It happens once. Every later registration reads the file — from the session
1870
+ directory you are using, wherever that is. `WA_NO_APK_DOWNLOAD=1` turns the
1871
+ fetch off if you would rather it never pulled a hundred megabytes unasked, and
1872
+ `wa apk-material` below does the same job by hand.
1873
+
1874
+ > [!NOTE]
1875
+ > The download goes through the Aurora OSS token dispenser, a free third-party
1876
+ > service that mints an anonymous Play account. It refuses with **HTTP 403**
1877
+ > when it is rate limiting and **5xx** when it is having a bad minute, so the
1878
+ > request is retried a few times with a growing wait before giving up.
1879
+ > `WA_PLAY_RETRY_DELAY_MS` sets that wait (default `2000`, doubling each time).
1880
+ > If it still refuses, nothing is wrong with your setup — pass an APK path to
1881
+ > `wa apk-material` instead, which is the same thing without the middleman.
1872
1882
 
1873
1883
  The rest of this section is what happens behind that one command, and how to
1874
1884
  drive each part yourself.
package/cli.js CHANGED
@@ -2833,6 +2833,16 @@ async function main() {
2833
2833
  // first question land in the wrong prompt.
2834
2834
  _sessDir = await askSessionDir(cmd, flags.session);
2835
2835
 
2836
+ // One source of truth for the rest of the run. The library resolves the files
2837
+ // that belong to the installation rather than to a number — the Android token
2838
+ // material above all — through SessionPaths.defaultBaseDir(), which reads
2839
+ // WA_SESSION_DIR. The CLI, though, can arrive at its directory three other
2840
+ // ways: --session, the folder remembered from the setup prompt, or the home
2841
+ // default. Without publishing the answer here, `wa apk-material` wrote into
2842
+ // the resolved directory while registration went looking in ~/.waSession and
2843
+ // reported no material at all.
2844
+ process.env.WA_SESSION_DIR = _sessDir;
2845
+
2836
2846
  await askDebugMode(cmd);
2837
2847
  await askDonation(cmd);
2838
2848
 
package/lib/PlayStore.js CHANGED
@@ -158,19 +158,68 @@ function _request(url, opts) {
158
158
 
159
159
  // ─── Auth ─────────────────────────────────────────────────────────────────────
160
160
 
161
+ // How often the dispenser is asked before giving up, and how long between tries.
162
+ //
163
+ // The dispenser is a free service shared by everyone who uses it, and the way it
164
+ // sheds load is to refuse — 403 when it is rate limiting, 5xx when it is having
165
+ // a bad minute. Both are usually over in seconds, so one refusal is not an
166
+ // answer worth reporting to the caller. The waits grow so a dispenser that is
167
+ // genuinely busy is not hammered: roughly 2s, then 4s, then 8s.
168
+ const DISPENSER_ATTEMPTS = 4;
169
+ const DISPENSER_BASE_DELAY = 2000;
170
+
171
+ // The wait, overridable. Someone behind a dispenser that is having a long day
172
+ // may want to wait longer between tries, and the test suite wants not to wait
173
+ // at all. 0 is valid and means retry immediately.
174
+ function _dispenserDelay() {
175
+ const n = Number(process.env.WA_PLAY_RETRY_DELAY_MS);
176
+ return Number.isFinite(n) && n >= 0 ? n : DISPENSER_BASE_DELAY;
177
+ }
178
+
179
+ // Worth asking again, or not. A refusal that says "too many, come back" is; a
180
+ // 400 saying the request itself is malformed never will be, and retrying it
181
+ // only makes the caller wait three times as long for the same error.
182
+ function _dispenserRetryable(status) {
183
+ return status === 403 || status === 408 || status === 429 || status >= 500;
184
+ }
185
+
186
+ const _sleep = (ms) => new Promise(r => setTimeout(r, ms));
187
+
161
188
  async function fetchAnonymousAuth() {
162
189
  const body = JSON.stringify(DEVICE_PROFILE);
163
- const res = await _request(AURORA_DISPENSER_URL, {
164
- method: 'POST',
165
- headers: {
166
- 'Content-Type': 'application/json',
167
- 'User-Agent': AURORA_USER_AGENT,
168
- 'Content-Length': Buffer.byteLength(body)
169
- },
170
- body
171
- });
190
+ const headers = {
191
+ 'Content-Type': 'application/json',
192
+ 'User-Agent': AURORA_USER_AGENT,
193
+ 'Content-Length': Buffer.byteLength(body)
194
+ };
195
+
196
+ let res = null;
197
+ let lastErr = null;
198
+ for (let attempt = 1; attempt <= DISPENSER_ATTEMPTS; attempt++) {
199
+ try {
200
+ res = await _request(AURORA_DISPENSER_URL, { method: 'POST', headers, body });
201
+ lastErr = null;
202
+ if (res.status === 200) break;
203
+ if (!_dispenserRetryable(res.status) || attempt === DISPENSER_ATTEMPTS) break;
204
+ _whaDbg('[DBG] PLAY dispenser HTTP ' + res.status + ' — attempt ' +
205
+ attempt + '/' + DISPENSER_ATTEMPTS + ', retrying');
206
+ } catch (e) {
207
+ // A dropped connection or a timeout is the same kind of transient as a
208
+ // 5xx, so it is retried on the same schedule rather than thrown at once.
209
+ lastErr = e;
210
+ res = null;
211
+ if (attempt === DISPENSER_ATTEMPTS) break;
212
+ _whaDbg('[DBG] PLAY dispenser ' + (e && e.message) + ' — attempt ' +
213
+ attempt + '/' + DISPENSER_ATTEMPTS + ', retrying');
214
+ }
215
+ await _sleep(_dispenserDelay() * Math.pow(2, attempt - 1));
216
+ }
217
+
218
+ if (lastErr) throw lastErr;
219
+
172
220
  if (res.status !== 200) {
173
221
  throw new Error('the Aurora token dispenser answered HTTP ' + res.status +
222
+ ' after ' + DISPENSER_ATTEMPTS + ' attempts' +
174
223
  ' — it is a free third-party service and this is what it does when it is ' +
175
224
  'down or rate limiting. Nothing is wrong with your setup; either try again ' +
176
225
  'later or pass an APK path instead.');
@@ -384,3 +433,9 @@ module.exports = {
384
433
  AURORA_DISPENSER_URL,
385
434
  PERSONAL_PACKAGE
386
435
  };
436
+
437
+ // Dispenser retry internals, exposed for tests. Not part of the public API.
438
+ module.exports._retry = {
439
+ dispenserRetryable: _dispenserRetryable,
440
+ DISPENSER_ATTEMPTS
441
+ };
@@ -957,7 +957,27 @@ function androidMaterialPath(device) {
957
957
  const name = (device && device.business)
958
958
  ? 'android-apk-material-business.json'
959
959
  : 'android-apk-material.json';
960
- return path.join(os.homedir(), '.waSession', name);
960
+
961
+ // The session directory, wherever it actually is — not a hardcoded
962
+ // ~/.waSession. `wa apk-material` writes the file into the directory the CLI
963
+ // resolved (--session, WA_SESSION_DIR, or the one remembered from the setup
964
+ // prompt), while this read it from the home default and reported "no
965
+ // material" for anything else. Anyone who moved their sessions had to set
966
+ // WA_ANDROID_APK_MATERIAL by hand to make registration find a file that was
967
+ // already there. SessionPaths.defaultBaseDir() is the same resolver the
968
+ // writer goes through, and SHARED_FILES there already names both of these as
969
+ // belonging to the base directory.
970
+ const { defaultBaseDir } = require('./SessionPaths');
971
+ const primary = path.join(defaultBaseDir(), name);
972
+
973
+ // Material extracted before the directory could be moved still sits in
974
+ // ~/.waSession. If the configured directory has none but the old default
975
+ // does, read that rather than claiming there is no material at all.
976
+ if (!fs.existsSync(primary)) {
977
+ const legacy = path.join(os.homedir(), '.waSession', name);
978
+ if (legacy !== primary && fs.existsSync(legacy)) return legacy;
979
+ }
980
+ return primary;
961
981
  }
962
982
 
963
983
  const _androidMaterial = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whalibmob",
3
- "version": "5.29.5",
3
+ "version": "5.29.6",
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",