arn-browser 0.1.32 → 0.1.33
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arn-browser",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.33",
|
|
4
4
|
"description": "A lightweight, browser autmation helper.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -20,14 +20,14 @@
|
|
|
20
20
|
"dotenv": "^17.2.3",
|
|
21
21
|
"fingerprint-generator": "^2.1.78",
|
|
22
22
|
"fingerprint-injector": "^2.1.78",
|
|
23
|
-
"https-proxy-agent": "^
|
|
23
|
+
"https-proxy-agent": "^9.0.0",
|
|
24
24
|
"node-cache": "^5.1.2",
|
|
25
25
|
"node-fetch": "^3.3.2",
|
|
26
26
|
"playwright-core": "1.42.1",
|
|
27
27
|
"proxy-chain": "^2.6.0",
|
|
28
28
|
"puppeteer-core": "^24.40.0",
|
|
29
29
|
"randomstring": "^1.3.1",
|
|
30
|
-
"socks-proxy-agent": "^
|
|
30
|
+
"socks-proxy-agent": "^10.0.0",
|
|
31
31
|
"speakeasy": "^2.0.0",
|
|
32
32
|
"superagent": "^10.2.3"
|
|
33
33
|
},
|
|
@@ -268,7 +268,24 @@ export interface PwLaunchOptions {
|
|
|
268
268
|
humanize_options?: HumanizeOptions;
|
|
269
269
|
|
|
270
270
|
// ========================================================================
|
|
271
|
-
// 6.
|
|
271
|
+
// 6. NOTIFICATIONS
|
|
272
|
+
// ========================================================================
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* List of hostnames to auto-grant notification permissions for.
|
|
276
|
+
* Pass plain hostnames — they are auto-converted to `https://host:443` internally.
|
|
277
|
+
*
|
|
278
|
+
* If empty (default), Chrome's default "Ask" behavior is used.
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
* notification_hosts: ["web.whatsapp.com", "messages.google.com"]
|
|
282
|
+
*
|
|
283
|
+
* Default: []
|
|
284
|
+
*/
|
|
285
|
+
notification_hosts?: string[];
|
|
286
|
+
|
|
287
|
+
// ========================================================================
|
|
288
|
+
// 7. LOGGING
|
|
272
289
|
// ========================================================================
|
|
273
290
|
|
|
274
291
|
/**
|
|
@@ -71,7 +71,8 @@ function resolveProfilePath(nameOrPath, browserName) {
|
|
|
71
71
|
|
|
72
72
|
let prefix = browserName.toLowerCase();
|
|
73
73
|
if (prefix.includes("brave")) prefix = "brave";
|
|
74
|
-
else if (prefix.includes("
|
|
74
|
+
else if (prefix.includes("chromium")) prefix = "chromium";
|
|
75
|
+
else if (prefix.includes("chrome")) prefix = "chrome";
|
|
75
76
|
else if (prefix.includes("firefox")) prefix = "firefox";
|
|
76
77
|
else if (prefix.includes("camoufox")) prefix = "camoufox";
|
|
77
78
|
|
|
@@ -114,6 +115,31 @@ function writeProfileMeta(dirPath, type, cleanupMinutes) {
|
|
|
114
115
|
}
|
|
115
116
|
}
|
|
116
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Writes per-host notification permissions into the Chrome Preferences object.
|
|
120
|
+
* Accepts plain hostnames (e.g. "web.whatsapp.com") and converts them
|
|
121
|
+
* to Chrome's internal format: "https://host:443,*" with setting=1 (Allow).
|
|
122
|
+
* If hosts array is empty, does nothing (Chrome default "Ask" behavior).
|
|
123
|
+
*/
|
|
124
|
+
function writeNotificationPermissions(prefs, hosts) {
|
|
125
|
+
if (!hosts || hosts.length === 0) return;
|
|
126
|
+
|
|
127
|
+
if (!prefs.profile) prefs.profile = {};
|
|
128
|
+
if (!prefs.profile.content_settings) prefs.profile.content_settings = {};
|
|
129
|
+
if (!prefs.profile.content_settings.exceptions) prefs.profile.content_settings.exceptions = {};
|
|
130
|
+
if (!prefs.profile.content_settings.exceptions.notifications) prefs.profile.content_settings.exceptions.notifications = {};
|
|
131
|
+
|
|
132
|
+
const now = String(Date.now());
|
|
133
|
+
for (const host of hosts) {
|
|
134
|
+
const origin = host.startsWith("http") ? host : `https://${host}:443`;
|
|
135
|
+
const key = `${origin},*`;
|
|
136
|
+
prefs.profile.content_settings.exceptions.notifications[key] = {
|
|
137
|
+
last_modified: now,
|
|
138
|
+
setting: 1, // 1 = Allow
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
117
143
|
/**
|
|
118
144
|
* Scans both persistent and temp profile directories.
|
|
119
145
|
* Deletes profiles whose `_profile_meta.json` indicates they are expired.
|
|
@@ -278,6 +304,10 @@ export async function pwLaunch({
|
|
|
278
304
|
camoufox_options = {}, // { geoip, humanize, ... }
|
|
279
305
|
multilogin_options = {}, // { profileId, os_type, canvas_noise, ... }
|
|
280
306
|
|
|
307
|
+
// Notifications — per-host allow list
|
|
308
|
+
// Pass plain hostnames: ["web.whatsapp.com", "messages.google.com"]
|
|
309
|
+
notification_hosts = [],
|
|
310
|
+
|
|
281
311
|
// Logging
|
|
282
312
|
launch_logs = false,
|
|
283
313
|
cleanup_logs = false,
|
|
@@ -325,6 +355,7 @@ export async function pwLaunch({
|
|
|
325
355
|
spoof_fingerprint,
|
|
326
356
|
cleanupMinutes: effectiveCleanupMinutes,
|
|
327
357
|
browserType: which_browser, // "chrome" or "chromium"
|
|
358
|
+
notification_hosts,
|
|
328
359
|
});
|
|
329
360
|
break;
|
|
330
361
|
case "firefox":
|
|
@@ -347,6 +378,7 @@ export async function pwLaunch({
|
|
|
347
378
|
humanize_options: effectiveHumanizeOptions,
|
|
348
379
|
spoof_fingerprint,
|
|
349
380
|
cleanupMinutes: effectiveCleanupMinutes,
|
|
381
|
+
notification_hosts,
|
|
350
382
|
});
|
|
351
383
|
break;
|
|
352
384
|
case "camoufox":
|
|
@@ -382,7 +414,7 @@ export async function pwLaunch({
|
|
|
382
414
|
// ==========================================================================
|
|
383
415
|
// 4. ENGINE: CHROMIUM
|
|
384
416
|
// ==========================================================================
|
|
385
|
-
async function chromiumLauncher({ profilePath, proxy, timezoneId, CapSolver, humanize_options, spoof_fingerprint, cleanupMinutes, browserType = "chromium" }) {
|
|
417
|
+
async function chromiumLauncher({ profilePath, proxy, timezoneId, CapSolver, humanize_options, spoof_fingerprint, cleanupMinutes, browserType = "chromium", notification_hosts = [] }) {
|
|
386
418
|
const isPersistent = !!profilePath;
|
|
387
419
|
|
|
388
420
|
// 1. Determine Path (Temp needs it for fingerprint storage, Persistent needs it for data)
|
|
@@ -411,6 +443,8 @@ async function chromiumLauncher({ profilePath, proxy, timezoneId, CapSolver, hum
|
|
|
411
443
|
// --- Silence & Networking ---
|
|
412
444
|
"--disable-background-networking",
|
|
413
445
|
"--disable-background-timer-throttling",
|
|
446
|
+
"--disable-backgrounding-occluded-windows",
|
|
447
|
+
"--disable-renderer-backgrounding",
|
|
414
448
|
"--disable-breakpad",
|
|
415
449
|
"--disable-crash-reporter",
|
|
416
450
|
"--disable-component-update",
|
|
@@ -498,6 +532,7 @@ async function chromiumLauncher({ profilePath, proxy, timezoneId, CapSolver, hum
|
|
|
498
532
|
|
|
499
533
|
if (!prefs.profile) prefs.profile = {};
|
|
500
534
|
prefs.profile.exit_type = "Normal";
|
|
535
|
+
writeNotificationPermissions(prefs, notification_hosts);
|
|
501
536
|
|
|
502
537
|
if (!prefs.session) prefs.session = {};
|
|
503
538
|
prefs.session.restore_on_startup = 4;
|
|
@@ -631,7 +666,7 @@ async function firefoxLauncher({ profilePath, proxy, timezoneId, humanize_option
|
|
|
631
666
|
// ==========================================================================
|
|
632
667
|
// 6. ENGINE: BRAVE
|
|
633
668
|
// ==========================================================================
|
|
634
|
-
async function braveLauncher({ profilePath, proxy, CapSolver, timezoneId, humanize_options, spoof_fingerprint, cleanupMinutes }) {
|
|
669
|
+
async function braveLauncher({ profilePath, proxy, CapSolver, timezoneId, humanize_options, spoof_fingerprint, cleanupMinutes, notification_hosts = [] }) {
|
|
635
670
|
const isPersistent = !!profilePath;
|
|
636
671
|
const activePath = isPersistent ? profilePath : path.join(TEMP_DIR, crypto.randomUUID());
|
|
637
672
|
|
|
@@ -706,6 +741,7 @@ async function braveLauncher({ profilePath, proxy, CapSolver, timezoneId, humani
|
|
|
706
741
|
// Prevent tab restore (saves proxy bandwidth)
|
|
707
742
|
if (!prefs.profile) prefs.profile = {};
|
|
708
743
|
prefs.profile.exit_type = "Normal";
|
|
744
|
+
writeNotificationPermissions(prefs, notification_hosts);
|
|
709
745
|
|
|
710
746
|
if (!prefs.session) prefs.session = {};
|
|
711
747
|
prefs.session.restore_on_startup = 4;
|
|
@@ -759,6 +795,8 @@ async function braveLauncher({ profilePath, proxy, CapSolver, timezoneId, humani
|
|
|
759
795
|
// --- Silence & Networking ---
|
|
760
796
|
"--disable-background-networking",
|
|
761
797
|
"--disable-background-timer-throttling",
|
|
798
|
+
"--disable-backgrounding-occluded-windows",
|
|
799
|
+
"--disable-renderer-backgrounding",
|
|
762
800
|
"--disable-breakpad",
|
|
763
801
|
"--disable-crash-reporter",
|
|
764
802
|
"--disable-component-update",
|
|
@@ -180,7 +180,24 @@ export interface PpLaunchOptions {
|
|
|
180
180
|
};
|
|
181
181
|
|
|
182
182
|
// ========================================================================
|
|
183
|
-
// 8.
|
|
183
|
+
// 8. NOTIFICATIONS
|
|
184
|
+
// ========================================================================
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* List of hostnames to auto-grant notification permissions for.
|
|
188
|
+
* Pass plain hostnames — they are auto-converted to `https://host:443` internally.
|
|
189
|
+
*
|
|
190
|
+
* If empty (default), Chrome's default "Ask" behavior is used.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* notification_hosts: ["web.whatsapp.com", "messages.google.com"]
|
|
194
|
+
*
|
|
195
|
+
* Default: []
|
|
196
|
+
*/
|
|
197
|
+
notification_hosts?: string[];
|
|
198
|
+
|
|
199
|
+
// ========================================================================
|
|
200
|
+
// 9. LOGGING
|
|
184
201
|
// ========================================================================
|
|
185
202
|
|
|
186
203
|
/**
|
|
@@ -128,7 +128,8 @@ function resolveProfilePath(nameOrPath, browserName) {
|
|
|
128
128
|
|
|
129
129
|
let prefix = browserName.toLowerCase();
|
|
130
130
|
if (prefix.includes("brave")) prefix = "brave";
|
|
131
|
-
else if (prefix.includes("
|
|
131
|
+
else if (prefix.includes("chromium")) prefix = "chromium";
|
|
132
|
+
else if (prefix.includes("chrome")) prefix = "chrome";
|
|
132
133
|
|
|
133
134
|
const folderName = `${prefix}_${nameOrPath}`;
|
|
134
135
|
return path.join(PERSISTENT_DIR, folderName);
|
|
@@ -163,6 +164,31 @@ function writeProfileMeta(dirPath, type, cleanupMinutes) {
|
|
|
163
164
|
}
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Writes per-host notification permissions into the Chrome Preferences object.
|
|
169
|
+
* Accepts plain hostnames (e.g. "web.whatsapp.com") and converts them
|
|
170
|
+
* to Chrome's internal format: "https://host:443,*" with setting=1 (Allow).
|
|
171
|
+
* If hosts array is empty, does nothing (Chrome default "Ask" behavior).
|
|
172
|
+
*/
|
|
173
|
+
function writeNotificationPermissions(prefs, hosts) {
|
|
174
|
+
if (!hosts || hosts.length === 0) return;
|
|
175
|
+
|
|
176
|
+
if (!prefs.profile) prefs.profile = {};
|
|
177
|
+
if (!prefs.profile.content_settings) prefs.profile.content_settings = {};
|
|
178
|
+
if (!prefs.profile.content_settings.exceptions) prefs.profile.content_settings.exceptions = {};
|
|
179
|
+
if (!prefs.profile.content_settings.exceptions.notifications) prefs.profile.content_settings.exceptions.notifications = {};
|
|
180
|
+
|
|
181
|
+
const now = String(Date.now());
|
|
182
|
+
for (const host of hosts) {
|
|
183
|
+
const origin = host.startsWith("http") ? host : `https://${host}:443`;
|
|
184
|
+
const key = `${origin},*`;
|
|
185
|
+
prefs.profile.content_settings.exceptions.notifications[key] = {
|
|
186
|
+
last_modified: now,
|
|
187
|
+
setting: 1, // 1 = Allow
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
166
192
|
/**
|
|
167
193
|
* Scans profile directories and deletes expired profiles.
|
|
168
194
|
*/
|
|
@@ -262,6 +288,10 @@ export async function ppLaunch({
|
|
|
262
288
|
// Multilogin
|
|
263
289
|
multilogin_options = {},
|
|
264
290
|
|
|
291
|
+
// Notifications — per-host allow list
|
|
292
|
+
// Pass plain hostnames: ["web.whatsapp.com", "messages.google.com"]
|
|
293
|
+
notification_hosts = [],
|
|
294
|
+
|
|
265
295
|
// Logging
|
|
266
296
|
launch_logs = false,
|
|
267
297
|
cleanup_logs = false,
|
|
@@ -295,6 +325,7 @@ export async function ppLaunch({
|
|
|
295
325
|
spoof_fingerprint,
|
|
296
326
|
cleanupMinutes: effectiveCleanupMinutes,
|
|
297
327
|
browserType: "chrome",
|
|
328
|
+
notification_hosts,
|
|
298
329
|
});
|
|
299
330
|
break;
|
|
300
331
|
case "chromium":
|
|
@@ -306,6 +337,7 @@ export async function ppLaunch({
|
|
|
306
337
|
spoof_fingerprint,
|
|
307
338
|
cleanupMinutes: effectiveCleanupMinutes,
|
|
308
339
|
browserType: "chromium",
|
|
340
|
+
notification_hosts,
|
|
309
341
|
});
|
|
310
342
|
break;
|
|
311
343
|
case "brave":
|
|
@@ -316,6 +348,7 @@ export async function ppLaunch({
|
|
|
316
348
|
extraArgs,
|
|
317
349
|
spoof_fingerprint,
|
|
318
350
|
cleanupMinutes: effectiveCleanupMinutes,
|
|
351
|
+
notification_hosts,
|
|
319
352
|
});
|
|
320
353
|
break;
|
|
321
354
|
case "multilogin":
|
|
@@ -339,7 +372,7 @@ export async function ppLaunch({
|
|
|
339
372
|
// 4. ENGINE: CHROME (CDP)
|
|
340
373
|
// ==========================================================================
|
|
341
374
|
|
|
342
|
-
async function chromeLauncher({ profilePath, proxy, timezoneId, extraArgs, spoof_fingerprint, cleanupMinutes, browserType = "chrome" }) {
|
|
375
|
+
async function chromeLauncher({ profilePath, proxy, timezoneId, extraArgs, spoof_fingerprint, cleanupMinutes, browserType = "chrome", notification_hosts = [] }) {
|
|
343
376
|
const isPersistent = !!profilePath;
|
|
344
377
|
const activePath = isPersistent ? profilePath : path.join(TEMP_DIR, crypto.randomUUID());
|
|
345
378
|
|
|
@@ -357,6 +390,7 @@ async function chromeLauncher({ profilePath, proxy, timezoneId, extraArgs, spoof
|
|
|
357
390
|
extraArgs,
|
|
358
391
|
spoof_fingerprint,
|
|
359
392
|
browserLabel: browserType === "chromium" ? "Chromium" : "Chrome",
|
|
393
|
+
notification_hosts,
|
|
360
394
|
});
|
|
361
395
|
}
|
|
362
396
|
|
|
@@ -364,7 +398,7 @@ async function chromeLauncher({ profilePath, proxy, timezoneId, extraArgs, spoof
|
|
|
364
398
|
// 5. ENGINE: BRAVE (CDP)
|
|
365
399
|
// ==========================================================================
|
|
366
400
|
|
|
367
|
-
async function braveLauncher({ profilePath, proxy, timezoneId, extraArgs, spoof_fingerprint, cleanupMinutes }) {
|
|
401
|
+
async function braveLauncher({ profilePath, proxy, timezoneId, extraArgs, spoof_fingerprint, cleanupMinutes, notification_hosts = [] }) {
|
|
368
402
|
const isPersistent = !!profilePath;
|
|
369
403
|
const activePath = isPersistent ? profilePath : path.join(TEMP_DIR, crypto.randomUUID());
|
|
370
404
|
|
|
@@ -391,6 +425,7 @@ async function braveLauncher({ profilePath, proxy, timezoneId, extraArgs, spoof_
|
|
|
391
425
|
// Prevent tab restore (saves proxy bandwidth)
|
|
392
426
|
if (!prefs.profile) prefs.profile = {};
|
|
393
427
|
prefs.profile.exit_type = "Normal";
|
|
428
|
+
writeNotificationPermissions(prefs, notification_hosts);
|
|
394
429
|
|
|
395
430
|
if (!prefs.session) prefs.session = {};
|
|
396
431
|
prefs.session.restore_on_startup = 4;
|
|
@@ -438,6 +473,7 @@ async function braveLauncher({ profilePath, proxy, timezoneId, extraArgs, spoof_
|
|
|
438
473
|
extraArgs: [...braveArgs, ...extraArgs],
|
|
439
474
|
spoof_fingerprint,
|
|
440
475
|
browserLabel: "Brave",
|
|
476
|
+
notification_hosts,
|
|
441
477
|
});
|
|
442
478
|
}
|
|
443
479
|
|
|
@@ -445,7 +481,7 @@ async function braveLauncher({ profilePath, proxy, timezoneId, extraArgs, spoof_
|
|
|
445
481
|
// 6. CDP SPAWN & CONNECT (Shared between Chrome & Brave)
|
|
446
482
|
// ==========================================================================
|
|
447
483
|
|
|
448
|
-
async function spawnAndConnect({ binaryPath, profilePath, isPersistent, proxy, timezoneId = null, extraArgs = [], spoof_fingerprint = false, browserLabel = "Browser" }) {
|
|
484
|
+
async function spawnAndConnect({ binaryPath, profilePath, isPersistent, proxy, timezoneId = null, extraArgs = [], spoof_fingerprint = false, browserLabel = "Browser", notification_hosts = [] }) {
|
|
449
485
|
let browser;
|
|
450
486
|
let closing = false;
|
|
451
487
|
let signalHandler;
|
|
@@ -468,6 +504,7 @@ async function spawnAndConnect({ binaryPath, profilePath, isPersistent, proxy, t
|
|
|
468
504
|
// Prevent "Restore pages?" prompt after crash
|
|
469
505
|
if (!prefs.profile) prefs.profile = {};
|
|
470
506
|
prefs.profile.exit_type = "Normal";
|
|
507
|
+
writeNotificationPermissions(prefs, notification_hosts);
|
|
471
508
|
|
|
472
509
|
// Set startup to open about:blank instead of restoring tabs
|
|
473
510
|
if (!prefs.session) prefs.session = {};
|
|
@@ -508,6 +545,8 @@ async function spawnAndConnect({ binaryPath, profilePath, isPersistent, proxy, t
|
|
|
508
545
|
// --- Silence & Networking ---
|
|
509
546
|
"--disable-background-networking",
|
|
510
547
|
"--disable-background-timer-throttling",
|
|
548
|
+
"--disable-backgrounding-occluded-windows",
|
|
549
|
+
"--disable-renderer-backgrounding",
|
|
511
550
|
"--disable-breakpad",
|
|
512
551
|
"--disable-crash-reporter",
|
|
513
552
|
"--disable-component-update",
|