gologin 2.2.7 → 2.2.9
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/CHANGELOG.md +10 -0
- package/examples/puppeter/cloud-browser.js +25 -14
- package/index.d.ts +63 -6
- package/package.json +1 -1
- package/src/browser/browser-checker.js +4 -1
- package/src/cookies/cookies-manager.js +0 -2
- package/src/gologin.js +198 -130
- package/src/utils/http.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
Combined changelog for GoLogin node.js SDK
|
|
4
4
|
|
|
5
|
+
## [2.2.9] 2026-06-08
|
|
6
|
+
|
|
7
|
+
### Fixes
|
|
8
|
+
|
|
9
|
+
* Disabled fonts downloading which was throwing errors
|
|
10
|
+
* Type fixes
|
|
11
|
+
* Added Proxy Error message to socks5 proxies check fails
|
|
12
|
+
* Added (Gologin) prefix where gologin proxies failed
|
|
13
|
+
* Profile start timing optimization
|
|
14
|
+
|
|
5
15
|
## [2.2.7] 2026-02-06
|
|
6
16
|
|
|
7
17
|
### Fixes
|
|
@@ -1,17 +1,31 @@
|
|
|
1
|
-
// Gologin provides a cloud browser that can be used to run puppeteer
|
|
2
|
-
// It will handle the browser start and close management - you just need to control the browser with
|
|
3
|
-
import
|
|
1
|
+
// Gologin provides a cloud browser that can be used to run puppeteer automation.
|
|
2
|
+
// It will handle the browser start and close management - you just need to control the browser with puppeteer
|
|
3
|
+
import puppeteer from 'puppeteer-core';
|
|
4
4
|
|
|
5
5
|
const token = process.env.GL_API_TOKEN || 'your dev token here';
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
}
|
|
6
|
+
const profileId = 'profile ID';
|
|
7
|
+
|
|
8
|
+
const CLOUD_BROWSER_URL = `https://cloudbrowser.gologin.com/connect?token=${token}&profile=${profileId}`;
|
|
9
|
+
const STOP_PROFILE_URL = `https://api.gologin.com/browser/${profileId}/web`;
|
|
10
|
+
|
|
11
|
+
async function stopProfile() {
|
|
12
|
+
await fetch(STOP_PROFILE_URL, {
|
|
13
|
+
method: 'DELETE',
|
|
14
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
15
|
+
});
|
|
16
|
+
}
|
|
9
17
|
|
|
10
18
|
async function main() {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
const response = await fetch(CLOUD_BROWSER_URL);
|
|
20
|
+
|
|
21
|
+
if (!response.ok) {
|
|
22
|
+
const errorReason = response.headers.get('X-Error-Reason');
|
|
23
|
+
throw new Error(`Failed to start cloud browser: ${errorReason ?? response.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const browser = await puppeteer.connect({
|
|
27
|
+
browserWSEndpoint: CLOUD_BROWSER_URL,
|
|
28
|
+
ignoreHTTPSErrors: true,
|
|
15
29
|
});
|
|
16
30
|
|
|
17
31
|
const page = await browser.newPage();
|
|
@@ -21,10 +35,7 @@ async function main() {
|
|
|
21
35
|
(elt) => elt?.innerText?.trim(),
|
|
22
36
|
);
|
|
23
37
|
|
|
24
|
-
console.log('status', status);
|
|
25
|
-
|
|
26
38
|
return status;
|
|
27
39
|
}
|
|
28
40
|
|
|
29
|
-
main().catch(console.error)
|
|
30
|
-
.finally(gologin.exit);
|
|
41
|
+
main().catch(console.error).finally(stopProfile);
|
package/index.d.ts
CHANGED
|
@@ -2,12 +2,12 @@ import { Browser } from 'puppeteer-core/lib/Browser';
|
|
|
2
2
|
|
|
3
3
|
import { CreateCustomBrowserValidation, BrowserProxyCreateValidation } from './types/profile-params';
|
|
4
4
|
|
|
5
|
-
export const OPERATING_SYSTEMS
|
|
6
|
-
win: 'win'
|
|
7
|
-
lin: 'lin'
|
|
8
|
-
mac: 'mac'
|
|
9
|
-
android: 'android'
|
|
10
|
-
}
|
|
5
|
+
export declare const OPERATING_SYSTEMS: {
|
|
6
|
+
readonly win: 'win';
|
|
7
|
+
readonly lin: 'lin';
|
|
8
|
+
readonly mac: 'mac';
|
|
9
|
+
readonly android: 'android';
|
|
10
|
+
};
|
|
11
11
|
export type OsType = (typeof OPERATING_SYSTEMS)[keyof typeof OPERATING_SYSTEMS];
|
|
12
12
|
|
|
13
13
|
type CloudLaunchParams = {
|
|
@@ -94,6 +94,63 @@ type GologinApiParams = {
|
|
|
94
94
|
token: string;
|
|
95
95
|
};
|
|
96
96
|
|
|
97
|
+
/** Options for the GoLogin class constructor (advanced usage, custom wrappers). */
|
|
98
|
+
export type GoLoginOptions = {
|
|
99
|
+
token?: string;
|
|
100
|
+
profile_id?: string;
|
|
101
|
+
password?: string;
|
|
102
|
+
extra_params?: string[];
|
|
103
|
+
executablePath?: string;
|
|
104
|
+
vncPort?: number;
|
|
105
|
+
tmpdir?: string;
|
|
106
|
+
waitWebsocket?: boolean;
|
|
107
|
+
isCloudHeadless?: boolean;
|
|
108
|
+
skipOrbitaHashChecking?: boolean;
|
|
109
|
+
uploadCookiesToServer?: boolean;
|
|
110
|
+
writeCookiesFromServer?: boolean;
|
|
111
|
+
remote_debugging_port?: number;
|
|
112
|
+
timezone?: { timezone: string; country?: string; city?: string; ip?: string; ll?: [number, number]; accuracy?: number, stateProv?: string, languages?: string };
|
|
113
|
+
args?: string[];
|
|
114
|
+
restoreLastSession?: boolean;
|
|
115
|
+
browserMajorVersion?: number;
|
|
116
|
+
proxyCheckTimeout?: number;
|
|
117
|
+
proxyCheckAttempts?: number;
|
|
118
|
+
autoUpdateBrowser?: boolean;
|
|
119
|
+
checkBrowserUpdate?: boolean;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/** Return type of GoLogin#start() — use wsUrl to connect with Puppeteer. */
|
|
123
|
+
export type GoLoginStartResult = {
|
|
124
|
+
status: 'success';
|
|
125
|
+
wsUrl: string;
|
|
126
|
+
resolution?: { width: number; height: number };
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* GoLogin class for advanced usage and custom wrappers.
|
|
131
|
+
* Use when you need direct control over the browser lifecycle (e.g. custom launchLocal,
|
|
132
|
+
* multiple instances, or access to wsUrl from start() for Puppeteer).
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* import { GoLogin } from 'gologin';
|
|
136
|
+
* const gologin = new GoLogin({ token: 'YOUR_TOKEN', profile_id: 'PROFILE_ID' });
|
|
137
|
+
* const { wsUrl } = await gologin.start();
|
|
138
|
+
* // connect with puppeteer.connect({ browserWSEndpoint: wsUrl })
|
|
139
|
+
* await gologin.stop();
|
|
140
|
+
*/
|
|
141
|
+
export declare class GoLogin {
|
|
142
|
+
constructor(options?: GoLoginOptions);
|
|
143
|
+
start(): Promise<GoLoginStartResult>;
|
|
144
|
+
stop(): Promise<void>;
|
|
145
|
+
startLocal(): Promise<{ status: string, wsUrl: string }>;
|
|
146
|
+
stopLocal(options?: { posting?: boolean }): Promise<void>;
|
|
147
|
+
setProfileId(profile_id: string): Promise<void>;
|
|
148
|
+
getProfile(profile_id?: string): Promise<Record<string, unknown>>;
|
|
149
|
+
quickCreateProfile(name?: string): Promise<{ id: string }>;
|
|
150
|
+
profilePath(): string;
|
|
151
|
+
commitProfile(): Promise<void>;
|
|
152
|
+
}
|
|
153
|
+
|
|
97
154
|
export declare function getDefaultParams(): {
|
|
98
155
|
token: string | undefined;
|
|
99
156
|
profile_id: string | undefined;
|
package/package.json
CHANGED
|
@@ -361,8 +361,11 @@ export class BrowserChecker {
|
|
|
361
361
|
|
|
362
362
|
getLatestBrowserVersion() {
|
|
363
363
|
const userOs = getOS();
|
|
364
|
+
const options = {
|
|
365
|
+
json: true,
|
|
366
|
+
};
|
|
364
367
|
|
|
365
|
-
return makeRequest(`${API_URL}/gologin-global-settings/latest-browser-info?os=${userOs}
|
|
368
|
+
return makeRequest(`${API_URL}/gologin-global-settings/latest-browser-info?os=${userOs}`, options);
|
|
366
369
|
}
|
|
367
370
|
|
|
368
371
|
get getOrbitaPath() {
|
|
@@ -128,8 +128,6 @@ export const loadCookiesFromFile = async (filePath, isSecondTry = false, profile
|
|
|
128
128
|
console.log('error in loadCookiesFromFile', error.message);
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
console.log(1);
|
|
132
|
-
|
|
133
131
|
try {
|
|
134
132
|
db = await getDB(filePath);
|
|
135
133
|
const cookiesRows = await db.all('select * from cookies');
|
package/src/gologin.js
CHANGED
|
@@ -80,11 +80,10 @@ export class GoLogin {
|
|
|
80
80
|
this.restoreLastSession = options.restoreLastSession || true;
|
|
81
81
|
this.processSpawned = null;
|
|
82
82
|
this.processKillTimeout = 1 * 1000;
|
|
83
|
-
this.browserMajorVersion = 0;
|
|
84
|
-
this.
|
|
83
|
+
this.browserMajorVersion = options.browserMajorVersion || 0;
|
|
84
|
+
this.newProxyOrbitaMajorVersion = 135;
|
|
85
85
|
this.proxyCheckTimeout = options.proxyCheckTimeout || 13 * 1000;
|
|
86
86
|
this.proxyCheckAttempts = options.proxyCheckAttempts || 3;
|
|
87
|
-
this.browserLatestMajorVersion = 137;
|
|
88
87
|
|
|
89
88
|
if (process.env.DISABLE_TELEMETRY !== 'true') {
|
|
90
89
|
Sentry.init({
|
|
@@ -329,7 +328,7 @@ export class GoLogin {
|
|
|
329
328
|
},
|
|
330
329
|
};
|
|
331
330
|
|
|
332
|
-
if (this.browserMajorVersion >= this.
|
|
331
|
+
if (this.browserMajorVersion >= this.newProxyOrbitaMajorVersion && profileData.proxy?.mode !== 'none') {
|
|
333
332
|
let proxyServer = `${profileData.proxy.mode}://`;
|
|
334
333
|
if (profileData.proxy.username) {
|
|
335
334
|
const encodedUsername = encodeURIComponent(profileData.proxy.username || '');
|
|
@@ -398,6 +397,7 @@ export class GoLogin {
|
|
|
398
397
|
async downloadProfileAndExtract(profile, local) {
|
|
399
398
|
let profile_folder;
|
|
400
399
|
const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
|
|
400
|
+
|
|
401
401
|
const profileZipExists = await access(this.profile_zip_path).then(() => true).catch(() => false);
|
|
402
402
|
|
|
403
403
|
if (!(local && profileZipExists)) {
|
|
@@ -458,26 +458,16 @@ export class GoLogin {
|
|
|
458
458
|
|
|
459
459
|
async createStartup(local = false) {
|
|
460
460
|
const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
461
|
+
|
|
462
|
+
const [profile] = await Promise.all([
|
|
463
|
+
this.getProfile(),
|
|
464
|
+
new Promise((resolve) => rimraf(profilePath, resolve)).then(() => debug('-', profilePath, 'dropped')),
|
|
465
|
+
]);
|
|
466
|
+
|
|
464
467
|
if (!profile) {
|
|
465
468
|
throw new Error('Error fetching profile data');
|
|
466
469
|
}
|
|
467
470
|
|
|
468
|
-
if (!this.executablePath) {
|
|
469
|
-
const { userAgent } = profile.navigator;
|
|
470
|
-
try {
|
|
471
|
-
const [browserMajorVersion] = userAgent.split('Chrome/')[1].split('.');
|
|
472
|
-
this.browserMajorVersion = Number(browserMajorVersion);
|
|
473
|
-
await this.checkBrowser(browserMajorVersion);
|
|
474
|
-
} catch (e) {
|
|
475
|
-
const latestVersionNumber = await this.getLatestBrowserVersion();
|
|
476
|
-
this.browserMajorVersion = latestVersionNumber;
|
|
477
|
-
await this.checkBrowser(latestVersionNumber);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
|
|
481
471
|
const { navigator = {}, fonts, os: profileOs } = profile;
|
|
482
472
|
this.fontsMasking = fonts?.enableMasking;
|
|
483
473
|
this.profileOs = profileOs;
|
|
@@ -488,10 +478,7 @@ export class GoLogin {
|
|
|
488
478
|
OS_PLATFORM === 'linux' && profileOs !== 'lin'
|
|
489
479
|
);
|
|
490
480
|
|
|
491
|
-
const {
|
|
492
|
-
resolution = '1920x1080',
|
|
493
|
-
} = navigator;
|
|
494
|
-
|
|
481
|
+
const { resolution = '1920x1080' } = navigator;
|
|
495
482
|
const [screenWidth, screenHeight] = resolution.split('x');
|
|
496
483
|
this.resolution = {
|
|
497
484
|
width: parseInt(screenWidth, 10),
|
|
@@ -499,87 +486,8 @@ export class GoLogin {
|
|
|
499
486
|
};
|
|
500
487
|
|
|
501
488
|
this.createCookiesTableQuery = profile.createCookiesTableQuery;
|
|
502
|
-
if (profile.storageInfo.isNewProfile) {
|
|
503
|
-
this.isFirstSession = true;
|
|
504
|
-
await this.createZeroProfile(profile.createCookiesTableQuery);
|
|
505
|
-
} else {
|
|
506
|
-
this.isFirstSession = false;
|
|
507
|
-
await this.downloadProfileAndExtract(profile, local);
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
await _promises.rm(join(profilePath, 'Default', 'Sync Data'), { recursive: true }).catch(() => null);
|
|
511
|
-
const pref_file_name = join(profilePath, 'Default', 'Preferences');
|
|
512
|
-
debug('reading', pref_file_name);
|
|
513
|
-
|
|
514
|
-
const prefFileExists = await access(pref_file_name).then(() => true).catch(() => false);
|
|
515
|
-
if (!prefFileExists) {
|
|
516
|
-
debug('Preferences file not exists waiting', pref_file_name, '. Using empty profile');
|
|
517
|
-
await mkdir(join(profilePath, 'Default'), { recursive: true });
|
|
518
|
-
await writeFile(pref_file_name, '{}');
|
|
519
|
-
}
|
|
520
489
|
|
|
521
|
-
const preferences_raw = await readFile(pref_file_name);
|
|
522
|
-
const preferences = JSON.parse(preferences_raw.toString());
|
|
523
490
|
let proxy = get(profile, 'proxy');
|
|
524
|
-
const chromeExtensions = get(profile, 'chromeExtensions') || [];
|
|
525
|
-
const userChromeExtensions = get(profile, 'userChromeExtensions') || [];
|
|
526
|
-
const allExtensions = [...chromeExtensions, ...userChromeExtensions];
|
|
527
|
-
|
|
528
|
-
if (allExtensions.length) {
|
|
529
|
-
const ExtensionsManagerInst = new ExtensionsManager();
|
|
530
|
-
ExtensionsManagerInst.apiUrl = API_URL;
|
|
531
|
-
await ExtensionsManagerInst.init()
|
|
532
|
-
.then(() => ExtensionsManagerInst.updateExtensions())
|
|
533
|
-
.catch(() => {});
|
|
534
|
-
ExtensionsManagerInst.accessToken = this.access_token;
|
|
535
|
-
|
|
536
|
-
await ExtensionsManagerInst.getExtensionsPolicies();
|
|
537
|
-
let profileExtensionsCheckRes = [];
|
|
538
|
-
|
|
539
|
-
if (ExtensionsManagerInst.useLocalExtStorage) {
|
|
540
|
-
const promises = [
|
|
541
|
-
ExtensionsManagerInst.checkChromeExtensions(allExtensions)
|
|
542
|
-
.then(res => ({ profileExtensionsCheckRes: res }))
|
|
543
|
-
.catch((e) => {
|
|
544
|
-
console.log('checkChromeExtensions error: ', e);
|
|
545
|
-
|
|
546
|
-
return { profileExtensionsCheckRes: [] };
|
|
547
|
-
}),
|
|
548
|
-
ExtensionsManagerInst.checkLocalUserChromeExtensions(userChromeExtensions, this.profile_id)
|
|
549
|
-
.then(res => ({ profileUserExtensionsCheckRes: res }))
|
|
550
|
-
.catch((error) => {
|
|
551
|
-
console.log('checkUserChromeExtensions error: ', error);
|
|
552
|
-
|
|
553
|
-
return null;
|
|
554
|
-
}),
|
|
555
|
-
];
|
|
556
|
-
|
|
557
|
-
const extensionsResult = await Promise.all(promises);
|
|
558
|
-
|
|
559
|
-
const profileExtensionPathRes = extensionsResult.find(el => 'profileExtensionsCheckRes' in el) || {};
|
|
560
|
-
const profileUserExtensionPathRes = extensionsResult.find(el => 'profileUserExtensionsCheckRes' in el);
|
|
561
|
-
profileExtensionsCheckRes =
|
|
562
|
-
(profileExtensionPathRes?.profileExtensionsCheckRes || []).concat(profileUserExtensionPathRes?.profileUserExtensionsCheckRes || []);
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
let extSettings;
|
|
566
|
-
if (ExtensionsManagerInst.useLocalExtStorage) {
|
|
567
|
-
extSettings = await setExtPathsAndRemoveDeleted(preferences, profileExtensionsCheckRes, this.profile_id);
|
|
568
|
-
} else {
|
|
569
|
-
const originalExtensionsFolder = join(profilePath, 'Default', 'Extensions');
|
|
570
|
-
extSettings = await setOriginalExtPaths(preferences, originalExtensionsFolder);
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
this.extensionPathsToInstall =
|
|
574
|
-
ExtensionsManagerInst.getExtensionsToInstall(extSettings, profileExtensionsCheckRes);
|
|
575
|
-
|
|
576
|
-
if (extSettings) {
|
|
577
|
-
const currentExtSettings = preferences.extensions || {};
|
|
578
|
-
currentExtSettings.settings = extSettings;
|
|
579
|
-
preferences.extensions = currentExtSettings;
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
|
|
583
491
|
if (proxy.mode === 'gologin' || proxy.mode === 'tor') {
|
|
584
492
|
const autoProxyServer = get(profile, 'autoProxyServer');
|
|
585
493
|
const splittedAutoProxyServer = autoProxyServer.split('://');
|
|
@@ -608,23 +516,38 @@ export class GoLogin {
|
|
|
608
516
|
|
|
609
517
|
this.proxy = proxy;
|
|
610
518
|
|
|
611
|
-
await
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
519
|
+
await Promise.all([
|
|
520
|
+
this.resolveProfileBrowserVersion(profile),
|
|
521
|
+
this.initProfileStorage({ profile, local }),
|
|
522
|
+
this.getTimeZone(proxy).catch((e) => {
|
|
523
|
+
console.error('Proxy Error. Check it and try again.');
|
|
524
|
+
throw new Error(`Proxy Error. ${e.message}`);
|
|
525
|
+
}),
|
|
526
|
+
this.initCookiesFile(profile),
|
|
527
|
+
]);
|
|
617
528
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
debug('writeCookiesFromServer', this.writeCookiesFromServer);
|
|
622
|
-
this.cookiesFilePath = await getCookiesFilePath(this.profile_id, this.tmpdir);
|
|
529
|
+
await _promises.rm(join(profilePath, 'Default', 'Sync Data'), { recursive: true }).catch(() => null);
|
|
530
|
+
const pref_file_name = join(profilePath, 'Default', 'Preferences');
|
|
531
|
+
debug('reading', pref_file_name);
|
|
623
532
|
|
|
624
|
-
|
|
625
|
-
|
|
533
|
+
const prefFileExists = await access(pref_file_name).then(() => true).catch(() => false);
|
|
534
|
+
if (!prefFileExists) {
|
|
535
|
+
debug('Preferences file not exists waiting', pref_file_name, '. Using empty profile');
|
|
536
|
+
await mkdir(join(profilePath, 'Default'), { recursive: true });
|
|
537
|
+
await writeFile(pref_file_name, '{}');
|
|
626
538
|
}
|
|
627
539
|
|
|
540
|
+
const preferences_raw = await readFile(pref_file_name);
|
|
541
|
+
const preferences = JSON.parse(preferences_raw.toString());
|
|
542
|
+
const chromeExtensions = get(profile, 'chromeExtensions') || [];
|
|
543
|
+
const userChromeExtensions = get(profile, 'userChromeExtensions') || [];
|
|
544
|
+
const allExtensions = [...chromeExtensions, ...userChromeExtensions];
|
|
545
|
+
|
|
546
|
+
const [, orbitaParamsToken] = await Promise.all([
|
|
547
|
+
this.setupProfileExtensions({ preferences, allExtensions, userChromeExtensions, profilePath }),
|
|
548
|
+
this.fetchOrbitaParamsToken(profile),
|
|
549
|
+
]);
|
|
550
|
+
|
|
628
551
|
if (this.fontsMasking) {
|
|
629
552
|
const families = fonts?.families || [];
|
|
630
553
|
if (!families.length) {
|
|
@@ -632,7 +555,8 @@ export class GoLogin {
|
|
|
632
555
|
}
|
|
633
556
|
|
|
634
557
|
try {
|
|
635
|
-
|
|
558
|
+
// TODO: uncomment this when fonts will be fixed
|
|
559
|
+
// await composeFonts(families, profilePath, this.differentOs);
|
|
636
560
|
} catch (e) {
|
|
637
561
|
console.trace(e);
|
|
638
562
|
}
|
|
@@ -642,20 +566,20 @@ export class GoLogin {
|
|
|
642
566
|
preferences.gologin = {};
|
|
643
567
|
}
|
|
644
568
|
|
|
569
|
+
const gologin = this.getGologinPreferences(profile);
|
|
570
|
+
|
|
571
|
+
debug(`Writing profile for screenWidth ${profilePath}`, JSON.stringify(gologin));
|
|
572
|
+
gologin.screenWidth = this.resolution.width;
|
|
573
|
+
gologin.screenHeight = this.resolution.height;
|
|
574
|
+
debug('writeCookiesFromServer', this.writeCookiesFromServer);
|
|
575
|
+
|
|
645
576
|
const isMAC = OS_PLATFORM === 'darwin';
|
|
646
577
|
const checkAutoLangResult = checkAutoLang(gologin, this._tz, profile.autoLang);
|
|
647
578
|
const intlConfig = getIntlProfileConfig(profile, this._tz, profile.autoLang);
|
|
648
579
|
|
|
649
|
-
let orbitaParamsToken = '';
|
|
650
|
-
if (profile.securedOrbitaVersion && (this.browserMajorVersion >= profile.securedOrbitaVersion)) {
|
|
651
|
-
const tokenRes = await this.requestOrbitaProfileParamsToken(this.profile_id);
|
|
652
|
-
|
|
653
|
-
orbitaParamsToken = tokenRes.token;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
580
|
this.browserLang = isMAC ? 'en-US' : checkAutoLangResult;
|
|
657
581
|
const prefsToWrite = Object.assign(preferences, { gologin });
|
|
658
|
-
if (this.browserMajorVersion >= this.
|
|
582
|
+
if (this.browserMajorVersion >= this.newProxyOrbitaMajorVersion && this.proxy?.mode !== 'none') {
|
|
659
583
|
prefsToWrite.proxy = {
|
|
660
584
|
mode: 'fixed_servers',
|
|
661
585
|
server: gologin.proxy.server,
|
|
@@ -666,6 +590,7 @@ export class GoLogin {
|
|
|
666
590
|
const orbitaConfig = {
|
|
667
591
|
intl: intlConfig,
|
|
668
592
|
gologin: {
|
|
593
|
+
api_domain: API_URL,
|
|
669
594
|
profile_token: orbitaParamsToken,
|
|
670
595
|
...clientGologinOpts,
|
|
671
596
|
},
|
|
@@ -678,12 +603,141 @@ export class GoLogin {
|
|
|
678
603
|
const bookmarksFromDb = profile.bookmarks?.bookmark_bar;
|
|
679
604
|
bookmarksParsedData.roots = bookmarksFromDb ? profile.bookmarks : bookmarksParsedData.roots;
|
|
680
605
|
await writeFile(this.bookmarksFilePath, JSON.stringify(bookmarksParsedData));
|
|
681
|
-
|
|
682
606
|
debug('Profile ready. Path: ', profilePath, 'PROXY', JSON.stringify(get(preferences, 'gologin.proxy')));
|
|
683
607
|
|
|
684
608
|
return profilePath;
|
|
685
609
|
}
|
|
686
610
|
|
|
611
|
+
async resolveProfileBrowserVersion(profile) {
|
|
612
|
+
if (!this.executablePath) {
|
|
613
|
+
const { userAgent } = profile.navigator;
|
|
614
|
+
try {
|
|
615
|
+
const [browserMajorVersion] = userAgent.split('Chrome/')[1].split('.');
|
|
616
|
+
this.browserMajorVersion = Number(browserMajorVersion);
|
|
617
|
+
await this.checkBrowser(browserMajorVersion);
|
|
618
|
+
} catch (e) {
|
|
619
|
+
const latestVersionNumber = await this.getLatestBrowserVersion();
|
|
620
|
+
this.browserMajorVersion = latestVersionNumber;
|
|
621
|
+
await this.checkBrowser(latestVersionNumber);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
if (!this.browserMajorVersion) {
|
|
628
|
+
const { userAgent } = profile.navigator;
|
|
629
|
+
const [browserMajorVersion] = userAgent.split('Chrome/')[1].split('.');
|
|
630
|
+
this.browserMajorVersion = Number(browserMajorVersion);
|
|
631
|
+
|
|
632
|
+
let executableDir = join(this.executablePath, '..');
|
|
633
|
+
if (OS_PLATFORM === 'darwin') {
|
|
634
|
+
executableDir = join(this.executablePath, '..', '..', '..');
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
const versionFilePath = join(executableDir, 'version');
|
|
638
|
+
try {
|
|
639
|
+
await access(versionFilePath);
|
|
640
|
+
const versionContent = await readFile(versionFilePath, 'utf8');
|
|
641
|
+
const versionFromFile = versionContent.trim();
|
|
642
|
+
const isValidVersion = /^\d+\.\d+\.\d+/.test(versionFromFile);
|
|
643
|
+
if (isValidVersion) {
|
|
644
|
+
const [browserMajorVersion] = isValidVersion.split('.');
|
|
645
|
+
this.browserMajorVersion = Number(browserMajorVersion);
|
|
646
|
+
}
|
|
647
|
+
} catch (error) {
|
|
648
|
+
console.warn('Error reading version file:', error);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
async initProfileStorage({ profile, local }) {
|
|
654
|
+
if (profile.storageInfo.isNewProfile) {
|
|
655
|
+
this.isFirstSession = true;
|
|
656
|
+
await this.createZeroProfile(profile.createCookiesTableQuery);
|
|
657
|
+
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
this.isFirstSession = false;
|
|
662
|
+
await this.downloadProfileAndExtract(profile, local);
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
async initCookiesFile(profile) {
|
|
666
|
+
this.cookiesFilePath = await getCookiesFilePath(this.profile_id, this.tmpdir);
|
|
667
|
+
if (this.writeCookiesFromServer) {
|
|
668
|
+
await this.writeCookiesToFile(profile.cookies?.cookies);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
async setupProfileExtensions({ preferences, allExtensions, userChromeExtensions, profilePath }) {
|
|
673
|
+
if (!allExtensions.length) {
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
const ExtensionsManagerInst = new ExtensionsManager();
|
|
678
|
+
ExtensionsManagerInst.apiUrl = API_URL;
|
|
679
|
+
await ExtensionsManagerInst.init()
|
|
680
|
+
.then(() => ExtensionsManagerInst.updateExtensions())
|
|
681
|
+
.catch(() => {});
|
|
682
|
+
ExtensionsManagerInst.accessToken = this.access_token;
|
|
683
|
+
|
|
684
|
+
await ExtensionsManagerInst.getExtensionsPolicies();
|
|
685
|
+
let profileExtensionsCheckRes = [];
|
|
686
|
+
|
|
687
|
+
if (ExtensionsManagerInst.useLocalExtStorage) {
|
|
688
|
+
const promises = [
|
|
689
|
+
ExtensionsManagerInst.checkChromeExtensions(allExtensions)
|
|
690
|
+
.then(res => ({ profileExtensionsCheckRes: res }))
|
|
691
|
+
.catch((e) => {
|
|
692
|
+
console.log('checkChromeExtensions error: ', e);
|
|
693
|
+
|
|
694
|
+
return { profileExtensionsCheckRes: [] };
|
|
695
|
+
}),
|
|
696
|
+
ExtensionsManagerInst.checkLocalUserChromeExtensions(userChromeExtensions, this.profile_id)
|
|
697
|
+
.then(res => ({ profileUserExtensionsCheckRes: res }))
|
|
698
|
+
.catch((error) => {
|
|
699
|
+
console.log('checkUserChromeExtensions error: ', error);
|
|
700
|
+
|
|
701
|
+
return null;
|
|
702
|
+
}),
|
|
703
|
+
];
|
|
704
|
+
|
|
705
|
+
const extensionsResult = await Promise.all(promises);
|
|
706
|
+
|
|
707
|
+
const profileExtensionPathRes = extensionsResult.find(el => 'profileExtensionsCheckRes' in el) || {};
|
|
708
|
+
const profileUserExtensionPathRes = extensionsResult.find(el => 'profileUserExtensionsCheckRes' in el);
|
|
709
|
+
profileExtensionsCheckRes =
|
|
710
|
+
(profileExtensionPathRes?.profileExtensionsCheckRes || []).concat(profileUserExtensionPathRes?.profileUserExtensionsCheckRes || []);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
let extSettings;
|
|
714
|
+
if (ExtensionsManagerInst.useLocalExtStorage) {
|
|
715
|
+
extSettings = await setExtPathsAndRemoveDeleted(preferences, profileExtensionsCheckRes, this.profile_id);
|
|
716
|
+
} else {
|
|
717
|
+
const originalExtensionsFolder = join(profilePath, 'Default', 'Extensions');
|
|
718
|
+
extSettings = await setOriginalExtPaths(preferences, originalExtensionsFolder);
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
this.extensionPathsToInstall =
|
|
722
|
+
ExtensionsManagerInst.getExtensionsToInstall(extSettings, profileExtensionsCheckRes);
|
|
723
|
+
|
|
724
|
+
if (extSettings) {
|
|
725
|
+
const currentExtSettings = preferences.extensions || {};
|
|
726
|
+
currentExtSettings.settings = extSettings;
|
|
727
|
+
preferences.extensions = currentExtSettings;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
async fetchOrbitaParamsToken(profile) {
|
|
732
|
+
if (!profile.securedOrbitaVersion || this.browserMajorVersion < profile.securedOrbitaVersion) {
|
|
733
|
+
return '';
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
const tokenRes = await this.requestOrbitaProfileParamsToken(this.profile_id);
|
|
737
|
+
|
|
738
|
+
return tokenRes.token;
|
|
739
|
+
}
|
|
740
|
+
|
|
687
741
|
async commitProfile() {
|
|
688
742
|
// wait for orbita to finish working with files
|
|
689
743
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
@@ -760,6 +814,14 @@ export class GoLogin {
|
|
|
760
814
|
return this._tz.timezone;
|
|
761
815
|
}
|
|
762
816
|
|
|
817
|
+
if (this._tz) {
|
|
818
|
+
debug('getTimeZone from cache', this._tz.timezone);
|
|
819
|
+
|
|
820
|
+
return this._tz.timezone;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
const isGologinProxy = proxy?.host?.includes('floppydata.com');
|
|
824
|
+
|
|
763
825
|
let data = null;
|
|
764
826
|
if (proxy && proxy.mode !== PROXY_NONE) {
|
|
765
827
|
if (proxy.mode.includes('socks')) {
|
|
@@ -772,7 +834,7 @@ export class GoLogin {
|
|
|
772
834
|
console.log(e.message);
|
|
773
835
|
}
|
|
774
836
|
}
|
|
775
|
-
throw new Error(
|
|
837
|
+
throw new Error(`Proxy Error${isGologinProxy ? ' (Gologin)' : ''}`);
|
|
776
838
|
}
|
|
777
839
|
|
|
778
840
|
const proxyUrl = `${proxy.mode}://${proxy.username}:${proxy.password}@${proxy.host}:${proxy.port}`;
|
|
@@ -783,6 +845,8 @@ export class GoLogin {
|
|
|
783
845
|
timeout: this.proxyCheckTimeout,
|
|
784
846
|
maxAttempts: this.proxyCheckAttempts,
|
|
785
847
|
method: 'GET',
|
|
848
|
+
}).catch((e) => {
|
|
849
|
+
throw new Error(`${e.message}${isGologinProxy ? ' (Gologin)' : ''}`);
|
|
786
850
|
});
|
|
787
851
|
} else {
|
|
788
852
|
data = await makeRequest(TIMEZONE_URL, { timeout: this.proxyCheckTimeout, maxAttempts: this.proxyCheckAttempts, method: 'GET' });
|
|
@@ -828,7 +892,9 @@ export class GoLogin {
|
|
|
828
892
|
proxy += host + ':' + port;
|
|
829
893
|
const agent = new SocksProxyAgent(proxy);
|
|
830
894
|
|
|
831
|
-
const checkData = await checkSocksProxy(agent)
|
|
895
|
+
const checkData = await checkSocksProxy(agent).catch((e) => {
|
|
896
|
+
throw new Error(`Proxy Error. ${e.message}`);
|
|
897
|
+
});
|
|
832
898
|
|
|
833
899
|
const body = checkData.body || {};
|
|
834
900
|
if (!body.ip && checkData.statusCode.toString().startsWith('4')) {
|
|
@@ -912,6 +978,7 @@ export class GoLogin {
|
|
|
912
978
|
|
|
913
979
|
const ORBITA_BROWSER = this.executablePath || this.browserChecker.getOrbitaPath;
|
|
914
980
|
debug(`ORBITA_BROWSER=${ORBITA_BROWSER}`);
|
|
981
|
+
|
|
915
982
|
const env = {};
|
|
916
983
|
Object.keys(process.env).forEach((key) => {
|
|
917
984
|
env[key] = process.env[key];
|
|
@@ -977,7 +1044,7 @@ export class GoLogin {
|
|
|
977
1044
|
params.push(`--host-resolver-rules=${hr_rules}`);
|
|
978
1045
|
}
|
|
979
1046
|
|
|
980
|
-
if (proxy && Number(this.browserMajorVersion) < this.
|
|
1047
|
+
if (proxy && Number(this.browserMajorVersion) < this.newProxyOrbitaMajorVersion) {
|
|
981
1048
|
params.push(`--proxy-server=${proxy}`);
|
|
982
1049
|
}
|
|
983
1050
|
|
|
@@ -1002,7 +1069,7 @@ export class GoLogin {
|
|
|
1002
1069
|
debug('GETTING WS URL FROM BROWSER');
|
|
1003
1070
|
const data = await makeRequest(
|
|
1004
1071
|
`http://127.0.0.1:${remote_debugging_port}/json/version`,
|
|
1005
|
-
{ json: true, maxAttempts: 30, retryDelay:
|
|
1072
|
+
{ json: true, maxAttempts: 30, retryDelay: 400, method: 'GET' },
|
|
1006
1073
|
);
|
|
1007
1074
|
|
|
1008
1075
|
debug('WS IS', get(data, 'webSocketDebuggerUrl', ''));
|
|
@@ -1428,6 +1495,7 @@ export class GoLogin {
|
|
|
1428
1495
|
|
|
1429
1496
|
async startLocal() {
|
|
1430
1497
|
await this.createStartup(true);
|
|
1498
|
+
|
|
1431
1499
|
// await this.createBrowserExtension();
|
|
1432
1500
|
const startResponse = await this.spawnBrowser();
|
|
1433
1501
|
this.setActive(true);
|
package/src/utils/http.js
CHANGED
|
@@ -33,7 +33,7 @@ const attemptRequest = async (requestUrl, options) => {
|
|
|
33
33
|
return req.body;
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
-
export const makeRequest = async (url, options, internalOptions) => {
|
|
36
|
+
export const makeRequest = async (url, options = {}, internalOptions) => {
|
|
37
37
|
options.headers = {
|
|
38
38
|
...options.headers,
|
|
39
39
|
'User-Agent': `gologin-nodejs-sdk/${version}`,
|