gologin 2.2.8 → 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/cookies/cookies-manager.js +0 -2
- package/src/gologin.js +192 -147
- package/Orbita-Browser.app/Contents/MacOS/Orbita +0 -0
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
|
@@ -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
|
@@ -397,6 +397,7 @@ export class GoLogin {
|
|
|
397
397
|
async downloadProfileAndExtract(profile, local) {
|
|
398
398
|
let profile_folder;
|
|
399
399
|
const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
|
|
400
|
+
|
|
400
401
|
const profileZipExists = await access(this.profile_zip_path).then(() => true).catch(() => false);
|
|
401
402
|
|
|
402
403
|
if (!(local && profileZipExists)) {
|
|
@@ -457,47 +458,14 @@ export class GoLogin {
|
|
|
457
458
|
|
|
458
459
|
async createStartup(local = false) {
|
|
459
460
|
const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
|
|
460
|
-
await rimraf(profilePath, () => null);
|
|
461
|
-
debug('-', profilePath, 'dropped');
|
|
462
|
-
const profile = await this.getProfile();
|
|
463
|
-
if (!profile) {
|
|
464
|
-
throw new Error('Error fetching profile data');
|
|
465
|
-
}
|
|
466
461
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
this.browserMajorVersion = Number(browserMajorVersion);
|
|
472
|
-
await this.checkBrowser(browserMajorVersion);
|
|
473
|
-
} catch (e) {
|
|
474
|
-
const latestVersionNumber = await this.getLatestBrowserVersion();
|
|
475
|
-
this.browserMajorVersion = latestVersionNumber;
|
|
476
|
-
await this.checkBrowser(latestVersionNumber);
|
|
477
|
-
}
|
|
478
|
-
} else if (!this.browserMajorVersion) {
|
|
479
|
-
const { userAgent } = profile.navigator;
|
|
480
|
-
const [browserMajorVersion] = userAgent.split('Chrome/')[1].split('.');
|
|
481
|
-
this.browserMajorVersion = Number(browserMajorVersion);
|
|
482
|
-
|
|
483
|
-
let executableDir = join(this.executablePath, '..');
|
|
484
|
-
if (OS_PLATFORM === 'darwin') {
|
|
485
|
-
executableDir = join(this.executablePath, '..', '..', '..');
|
|
486
|
-
}
|
|
462
|
+
const [profile] = await Promise.all([
|
|
463
|
+
this.getProfile(),
|
|
464
|
+
new Promise((resolve) => rimraf(profilePath, resolve)).then(() => debug('-', profilePath, 'dropped')),
|
|
465
|
+
]);
|
|
487
466
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
await access(versionFilePath);
|
|
491
|
-
const versionContent = await readFile(versionFilePath, 'utf8');
|
|
492
|
-
const versionFromFile = versionContent.trim();
|
|
493
|
-
const isValidVersion = /^\d+\.\d+\.\d+/.test(versionFromFile);
|
|
494
|
-
if (isValidVersion) {
|
|
495
|
-
const [browserMajorVersion] = isValidVersion.split('.');
|
|
496
|
-
this.browserMajorVersion = Number(browserMajorVersion);
|
|
497
|
-
}
|
|
498
|
-
} catch (error) {
|
|
499
|
-
console.warn('Error reading version file:', error);
|
|
500
|
-
}
|
|
467
|
+
if (!profile) {
|
|
468
|
+
throw new Error('Error fetching profile data');
|
|
501
469
|
}
|
|
502
470
|
|
|
503
471
|
const { navigator = {}, fonts, os: profileOs } = profile;
|
|
@@ -510,10 +478,7 @@ export class GoLogin {
|
|
|
510
478
|
OS_PLATFORM === 'linux' && profileOs !== 'lin'
|
|
511
479
|
);
|
|
512
480
|
|
|
513
|
-
const {
|
|
514
|
-
resolution = '1920x1080',
|
|
515
|
-
} = navigator;
|
|
516
|
-
|
|
481
|
+
const { resolution = '1920x1080' } = navigator;
|
|
517
482
|
const [screenWidth, screenHeight] = resolution.split('x');
|
|
518
483
|
this.resolution = {
|
|
519
484
|
width: parseInt(screenWidth, 10),
|
|
@@ -521,87 +486,8 @@ export class GoLogin {
|
|
|
521
486
|
};
|
|
522
487
|
|
|
523
488
|
this.createCookiesTableQuery = profile.createCookiesTableQuery;
|
|
524
|
-
if (profile.storageInfo.isNewProfile) {
|
|
525
|
-
this.isFirstSession = true;
|
|
526
|
-
await this.createZeroProfile(profile.createCookiesTableQuery);
|
|
527
|
-
} else {
|
|
528
|
-
this.isFirstSession = false;
|
|
529
|
-
await this.downloadProfileAndExtract(profile, local);
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
await _promises.rm(join(profilePath, 'Default', 'Sync Data'), { recursive: true }).catch(() => null);
|
|
533
|
-
const pref_file_name = join(profilePath, 'Default', 'Preferences');
|
|
534
|
-
debug('reading', pref_file_name);
|
|
535
489
|
|
|
536
|
-
const prefFileExists = await access(pref_file_name).then(() => true).catch(() => false);
|
|
537
|
-
if (!prefFileExists) {
|
|
538
|
-
debug('Preferences file not exists waiting', pref_file_name, '. Using empty profile');
|
|
539
|
-
await mkdir(join(profilePath, 'Default'), { recursive: true });
|
|
540
|
-
await writeFile(pref_file_name, '{}');
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
const preferences_raw = await readFile(pref_file_name);
|
|
544
|
-
const preferences = JSON.parse(preferences_raw.toString());
|
|
545
490
|
let proxy = get(profile, 'proxy');
|
|
546
|
-
const chromeExtensions = get(profile, 'chromeExtensions') || [];
|
|
547
|
-
const userChromeExtensions = get(profile, 'userChromeExtensions') || [];
|
|
548
|
-
const allExtensions = [...chromeExtensions, ...userChromeExtensions];
|
|
549
|
-
|
|
550
|
-
if (allExtensions.length) {
|
|
551
|
-
const ExtensionsManagerInst = new ExtensionsManager();
|
|
552
|
-
ExtensionsManagerInst.apiUrl = API_URL;
|
|
553
|
-
await ExtensionsManagerInst.init()
|
|
554
|
-
.then(() => ExtensionsManagerInst.updateExtensions())
|
|
555
|
-
.catch(() => {});
|
|
556
|
-
ExtensionsManagerInst.accessToken = this.access_token;
|
|
557
|
-
|
|
558
|
-
await ExtensionsManagerInst.getExtensionsPolicies();
|
|
559
|
-
let profileExtensionsCheckRes = [];
|
|
560
|
-
|
|
561
|
-
if (ExtensionsManagerInst.useLocalExtStorage) {
|
|
562
|
-
const promises = [
|
|
563
|
-
ExtensionsManagerInst.checkChromeExtensions(allExtensions)
|
|
564
|
-
.then(res => ({ profileExtensionsCheckRes: res }))
|
|
565
|
-
.catch((e) => {
|
|
566
|
-
console.log('checkChromeExtensions error: ', e);
|
|
567
|
-
|
|
568
|
-
return { profileExtensionsCheckRes: [] };
|
|
569
|
-
}),
|
|
570
|
-
ExtensionsManagerInst.checkLocalUserChromeExtensions(userChromeExtensions, this.profile_id)
|
|
571
|
-
.then(res => ({ profileUserExtensionsCheckRes: res }))
|
|
572
|
-
.catch((error) => {
|
|
573
|
-
console.log('checkUserChromeExtensions error: ', error);
|
|
574
|
-
|
|
575
|
-
return null;
|
|
576
|
-
}),
|
|
577
|
-
];
|
|
578
|
-
|
|
579
|
-
const extensionsResult = await Promise.all(promises);
|
|
580
|
-
|
|
581
|
-
const profileExtensionPathRes = extensionsResult.find(el => 'profileExtensionsCheckRes' in el) || {};
|
|
582
|
-
const profileUserExtensionPathRes = extensionsResult.find(el => 'profileUserExtensionsCheckRes' in el);
|
|
583
|
-
profileExtensionsCheckRes =
|
|
584
|
-
(profileExtensionPathRes?.profileExtensionsCheckRes || []).concat(profileUserExtensionPathRes?.profileUserExtensionsCheckRes || []);
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
let extSettings;
|
|
588
|
-
if (ExtensionsManagerInst.useLocalExtStorage) {
|
|
589
|
-
extSettings = await setExtPathsAndRemoveDeleted(preferences, profileExtensionsCheckRes, this.profile_id);
|
|
590
|
-
} else {
|
|
591
|
-
const originalExtensionsFolder = join(profilePath, 'Default', 'Extensions');
|
|
592
|
-
extSettings = await setOriginalExtPaths(preferences, originalExtensionsFolder);
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
this.extensionPathsToInstall =
|
|
596
|
-
ExtensionsManagerInst.getExtensionsToInstall(extSettings, profileExtensionsCheckRes);
|
|
597
|
-
|
|
598
|
-
if (extSettings) {
|
|
599
|
-
const currentExtSettings = preferences.extensions || {};
|
|
600
|
-
currentExtSettings.settings = extSettings;
|
|
601
|
-
preferences.extensions = currentExtSettings;
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
|
|
605
491
|
if (proxy.mode === 'gologin' || proxy.mode === 'tor') {
|
|
606
492
|
const autoProxyServer = get(profile, 'autoProxyServer');
|
|
607
493
|
const splittedAutoProxyServer = autoProxyServer.split('://');
|
|
@@ -630,23 +516,38 @@ export class GoLogin {
|
|
|
630
516
|
|
|
631
517
|
this.proxy = proxy;
|
|
632
518
|
|
|
633
|
-
await
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
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
|
+
]);
|
|
639
528
|
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
debug('writeCookiesFromServer', this.writeCookiesFromServer);
|
|
644
|
-
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);
|
|
645
532
|
|
|
646
|
-
|
|
647
|
-
|
|
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, '{}');
|
|
648
538
|
}
|
|
649
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
|
+
|
|
650
551
|
if (this.fontsMasking) {
|
|
651
552
|
const families = fonts?.families || [];
|
|
652
553
|
if (!families.length) {
|
|
@@ -654,7 +555,8 @@ export class GoLogin {
|
|
|
654
555
|
}
|
|
655
556
|
|
|
656
557
|
try {
|
|
657
|
-
|
|
558
|
+
// TODO: uncomment this when fonts will be fixed
|
|
559
|
+
// await composeFonts(families, profilePath, this.differentOs);
|
|
658
560
|
} catch (e) {
|
|
659
561
|
console.trace(e);
|
|
660
562
|
}
|
|
@@ -664,17 +566,17 @@ export class GoLogin {
|
|
|
664
566
|
preferences.gologin = {};
|
|
665
567
|
}
|
|
666
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
|
+
|
|
667
576
|
const isMAC = OS_PLATFORM === 'darwin';
|
|
668
577
|
const checkAutoLangResult = checkAutoLang(gologin, this._tz, profile.autoLang);
|
|
669
578
|
const intlConfig = getIntlProfileConfig(profile, this._tz, profile.autoLang);
|
|
670
579
|
|
|
671
|
-
let orbitaParamsToken = '';
|
|
672
|
-
if (profile.securedOrbitaVersion && (this.browserMajorVersion >= profile.securedOrbitaVersion)) {
|
|
673
|
-
const tokenRes = await this.requestOrbitaProfileParamsToken(this.profile_id);
|
|
674
|
-
|
|
675
|
-
orbitaParamsToken = tokenRes.token;
|
|
676
|
-
}
|
|
677
|
-
|
|
678
580
|
this.browserLang = isMAC ? 'en-US' : checkAutoLangResult;
|
|
679
581
|
const prefsToWrite = Object.assign(preferences, { gologin });
|
|
680
582
|
if (this.browserMajorVersion >= this.newProxyOrbitaMajorVersion && this.proxy?.mode !== 'none') {
|
|
@@ -701,12 +603,141 @@ export class GoLogin {
|
|
|
701
603
|
const bookmarksFromDb = profile.bookmarks?.bookmark_bar;
|
|
702
604
|
bookmarksParsedData.roots = bookmarksFromDb ? profile.bookmarks : bookmarksParsedData.roots;
|
|
703
605
|
await writeFile(this.bookmarksFilePath, JSON.stringify(bookmarksParsedData));
|
|
704
|
-
|
|
705
606
|
debug('Profile ready. Path: ', profilePath, 'PROXY', JSON.stringify(get(preferences, 'gologin.proxy')));
|
|
706
607
|
|
|
707
608
|
return profilePath;
|
|
708
609
|
}
|
|
709
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
|
+
|
|
710
741
|
async commitProfile() {
|
|
711
742
|
// wait for orbita to finish working with files
|
|
712
743
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
@@ -783,6 +814,14 @@ export class GoLogin {
|
|
|
783
814
|
return this._tz.timezone;
|
|
784
815
|
}
|
|
785
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
|
+
|
|
786
825
|
let data = null;
|
|
787
826
|
if (proxy && proxy.mode !== PROXY_NONE) {
|
|
788
827
|
if (proxy.mode.includes('socks')) {
|
|
@@ -795,7 +834,7 @@ export class GoLogin {
|
|
|
795
834
|
console.log(e.message);
|
|
796
835
|
}
|
|
797
836
|
}
|
|
798
|
-
throw new Error(
|
|
837
|
+
throw new Error(`Proxy Error${isGologinProxy ? ' (Gologin)' : ''}`);
|
|
799
838
|
}
|
|
800
839
|
|
|
801
840
|
const proxyUrl = `${proxy.mode}://${proxy.username}:${proxy.password}@${proxy.host}:${proxy.port}`;
|
|
@@ -806,6 +845,8 @@ export class GoLogin {
|
|
|
806
845
|
timeout: this.proxyCheckTimeout,
|
|
807
846
|
maxAttempts: this.proxyCheckAttempts,
|
|
808
847
|
method: 'GET',
|
|
848
|
+
}).catch((e) => {
|
|
849
|
+
throw new Error(`${e.message}${isGologinProxy ? ' (Gologin)' : ''}`);
|
|
809
850
|
});
|
|
810
851
|
} else {
|
|
811
852
|
data = await makeRequest(TIMEZONE_URL, { timeout: this.proxyCheckTimeout, maxAttempts: this.proxyCheckAttempts, method: 'GET' });
|
|
@@ -851,7 +892,9 @@ export class GoLogin {
|
|
|
851
892
|
proxy += host + ':' + port;
|
|
852
893
|
const agent = new SocksProxyAgent(proxy);
|
|
853
894
|
|
|
854
|
-
const checkData = await checkSocksProxy(agent)
|
|
895
|
+
const checkData = await checkSocksProxy(agent).catch((e) => {
|
|
896
|
+
throw new Error(`Proxy Error. ${e.message}`);
|
|
897
|
+
});
|
|
855
898
|
|
|
856
899
|
const body = checkData.body || {};
|
|
857
900
|
if (!body.ip && checkData.statusCode.toString().startsWith('4')) {
|
|
@@ -935,6 +978,7 @@ export class GoLogin {
|
|
|
935
978
|
|
|
936
979
|
const ORBITA_BROWSER = this.executablePath || this.browserChecker.getOrbitaPath;
|
|
937
980
|
debug(`ORBITA_BROWSER=${ORBITA_BROWSER}`);
|
|
981
|
+
|
|
938
982
|
const env = {};
|
|
939
983
|
Object.keys(process.env).forEach((key) => {
|
|
940
984
|
env[key] = process.env[key];
|
|
@@ -1025,7 +1069,7 @@ export class GoLogin {
|
|
|
1025
1069
|
debug('GETTING WS URL FROM BROWSER');
|
|
1026
1070
|
const data = await makeRequest(
|
|
1027
1071
|
`http://127.0.0.1:${remote_debugging_port}/json/version`,
|
|
1028
|
-
{ json: true, maxAttempts: 30, retryDelay:
|
|
1072
|
+
{ json: true, maxAttempts: 30, retryDelay: 400, method: 'GET' },
|
|
1029
1073
|
);
|
|
1030
1074
|
|
|
1031
1075
|
debug('WS IS', get(data, 'webSocketDebuggerUrl', ''));
|
|
@@ -1451,6 +1495,7 @@ export class GoLogin {
|
|
|
1451
1495
|
|
|
1452
1496
|
async startLocal() {
|
|
1453
1497
|
await this.createStartup(true);
|
|
1498
|
+
|
|
1454
1499
|
// await this.createBrowserExtension();
|
|
1455
1500
|
const startResponse = await this.spawnBrowser();
|
|
1456
1501
|
this.setActive(true);
|
|
File without changes
|