gologin 2.1.15 → 2.1.17

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": "gologin",
3
- "version": "2.1.15",
3
+ "version": "2.1.17",
4
4
  "description": "A high-level API to control Orbita browser over GoLogin API",
5
5
  "types": "./index.d.ts",
6
6
  "main": "./src/gologin.js",
@@ -6,10 +6,8 @@ import { get } from 'https';
6
6
  import { homedir } from 'os';
7
7
  import { join } from 'path';
8
8
  import ProgressBar from 'progress';
9
- import { createInterface } from 'readline';
10
9
  import util from 'util';
11
10
 
12
- import { findLatestBrowserVersionDirectory } from '../utils/utils.js';
13
11
  import { API_URL, getOS } from '../utils/common.js';
14
12
 
15
13
  const exec = util.promisify(execNonPromise);
@@ -37,87 +35,65 @@ const FAIL_SUM_MATCH_MESSAGE = 'hash_sum_not_matched';
37
35
  const EXTRACTED_FOLDER = 'extracted-browser';
38
36
 
39
37
  export class BrowserChecker {
40
- #homedir;
41
- #browserPath;
38
+ #homedir = homedir();
39
+ #browserPath = join(this.#homedir, '.gologin', 'browser');
42
40
  #executableFilePath;
43
41
  #skipOrbitaHashChecking = false;
44
42
 
45
- constructor(skipOrbitaHashChecking) {
46
- this.#skipOrbitaHashChecking = skipOrbitaHashChecking;
47
- this.#homedir = homedir();
48
- this.#browserPath = join(this.#homedir, '.gologin', 'browser');
43
+ constructor() {
49
44
 
50
- let executableFilePath = join(this.#browserPath, 'orbita-browser', 'chrome');
51
- if (PLATFORM === 'darwin') {
52
- const orbitaFolderName = findLatestBrowserVersionDirectory(this.#browserPath);
53
- if (orbitaFolderName === 'error') {
54
- throw Error('Orbita folder not found in this directory: ' + this.#browserPath);
55
- }
56
-
57
- executableFilePath = join(this.#browserPath, orbitaFolderName, 'Orbita-Browser.app', 'Contents', 'MacOS', 'Orbita');
58
- } else if (PLATFORM === 'win32') {
59
- executableFilePath = join(this.#browserPath, 'orbita-browser', 'chrome.exe');
60
- }
61
-
62
- this.#executableFilePath = executableFilePath;
63
- // console.log('executableFilePath:', executableFilePath);
64
45
  }
65
46
 
66
- async checkBrowser(autoUpdateBrowser = false, checkBrowserUpdate = true) {
67
- const browserFolderExists = await access(this.#executableFilePath).then(() => true).catch(() => false);
68
-
69
- const { latestVersion: browserLatestVersion, browserDownloadUrl } = await this.getLatestBrowserVersion();
70
-
71
- if (!browserFolderExists) {
72
- return this.downloadBrowser(browserLatestVersion, browserDownloadUrl);
73
- }
74
-
75
- const currentVersionReq = await this.getCurrentVersion();
76
- const currentVersion = (currentVersionReq?.stdout || '').replace(/(\r\n|\n|\r)/gm, '');
77
-
78
- if (browserLatestVersion === currentVersion || !checkBrowserUpdate) {
79
- return;
47
+ async checkBrowser(majorVersion) {
48
+ const isBrowserFolderExists = await access(join(this.#browserPath, `orbita-browser-${majorVersion}`)).then(() => true).catch(() => false);
49
+ if (isBrowserFolderExists) {
50
+ return this.getBrowserExecutablePath(majorVersion);
80
51
  }
81
52
 
82
- if (autoUpdateBrowser) {
83
- return this.downloadBrowser(browserLatestVersion, browserDownloadUrl);
84
- }
53
+ await this.downloadBrowser(majorVersion);
85
54
 
86
- return new Promise(resolve => {
87
- const rl = createInterface(process.stdin, process.stdout);
88
- const timeout = setTimeout(() => {
89
- console.log(`\nContinue with current ${currentVersion} version.`);
90
- resolve();
91
- }, 10000);
92
-
93
- rl.question(`New Orbita ${browserLatestVersion} is available. Update? [y/n] `, (answer) => {
94
- clearTimeout(timeout);
95
- rl.close();
96
- if (answer && answer[0].toString().toLowerCase() === 'y') {
97
- return this.downloadBrowser(browserLatestVersion, browserDownloadUrl).then(() => resolve());
98
- }
99
-
100
- console.log(`Continue with current ${currentVersion} version.`);
101
- resolve();
102
- });
103
- });
55
+ return this.getBrowserExecutablePath(majorVersion);
104
56
  }
105
57
 
106
- async downloadBrowser(latestVersion, browserDownloadUrl) {
107
- await this.deleteOldArchives(true);
58
+ async downloadBrowser(majorVersion) {
108
59
  await mkdir(this.#browserPath, { recursive: true });
109
60
 
110
- const pathStr = join(this.#browserPath, BROWSER_ARCHIVE_NAME);
61
+ const browserPath = join(this.#browserPath, BROWSER_ARCHIVE_NAME);
111
62
 
112
- await this.downloadBrowserArchive(browserDownloadUrl, pathStr);
113
- await this.checkBrowserArchive(pathStr);
63
+ const browserDownloadUrl = this.getBrowserDownloadUrl(majorVersion);
64
+
65
+ await this.downloadBrowserArchive(browserDownloadUrl, browserPath);
114
66
  await this.extractBrowser();
115
- await this.checkBrowserSum(latestVersion);
116
- console.log('Orbita hash checked successfully');
117
- await this.replaceBrowser();
118
- await this.addLatestVersion(latestVersion).catch(() => null);
67
+ await this.replaceBrowser(majorVersion);
119
68
  await this.deleteOldArchives();
120
- console.log('Orbita updated successfully');
69
+ }
70
+
71
+ getBrowserExecutablePath(majorVersion) {
72
+ const os = getOS();
73
+ switch (os) {
74
+ case 'mac':
75
+ return join(this.#browserPath, `orbita-browser-${majorVersion}`, 'Orbita-Browser.app', 'Contents', 'MacOS', 'Orbita');
76
+ case 'win':
77
+ return join(this.#browserPath, `orbita-browser-${majorVersion}`, 'chrome.exe');
78
+ case 'macM1':
79
+ return join(this.#browserPath, `orbita-browser-${majorVersion}`, 'Orbita-Browser.app', 'Contents', 'MacOS', 'Orbita');
80
+ default:
81
+ return join(this.#browserPath, `orbita-browser-${majorVersion}`, 'chrome');
82
+ }
83
+ }
84
+
85
+ getBrowserDownloadUrl(majorVersion) {
86
+ const os = getOS();
87
+ switch (os) {
88
+ case 'mac':
89
+ return `https://orbita-browser-mac.gologin.com/orbita-browser-latest-${majorVersion}.tar.gz`;
90
+ case 'win':
91
+ return `https://orbita-browser-windows.gologin.com/orbita-browser-latest-${majorVersion}.zip`;
92
+ case 'macM1':
93
+ return `https://orbita-browser-mac-arm.gologin.com/orbita-browser-latest-${majorVersion}.tar.gz`;
94
+ default:
95
+ return `https://orbita-browser-linux.gologin.com/orbita-browser-latest-${majorVersion}.tar.gz`;
96
+ }
121
97
  }
122
98
 
123
99
  addLatestVersion(latestVersion) {
@@ -208,6 +184,7 @@ export class BrowserChecker {
208
184
  if (ARCH === 'arm64') {
209
185
  hashLink = MAC_ARM_HASHFILE_LINK;
210
186
  }
187
+
211
188
  resultPath = join(this.#browserPath, MAC_HASH_FILE);
212
189
  }
213
190
 
@@ -282,13 +259,13 @@ export class BrowserChecker {
282
259
  }
283
260
  }
284
261
 
285
- async replaceBrowser() {
262
+ async replaceBrowser(majorVersion) {
286
263
  console.log('Copy Orbita to target path');
287
264
  if (PLATFORM === 'darwin') {
288
- return rename(join(this.#browserPath, EXTRACTED_FOLDER), join(this.#browserPath, 'orbita-browser'))
265
+ return rename(join(this.#browserPath, EXTRACTED_FOLDER), join(this.#browserPath, `orbita-browser-${majorVersion}`));
289
266
  }
290
267
 
291
- const targetBrowserPath = join(this.#browserPath, 'orbita-browser');
268
+ const targetBrowserPath = join(this.#browserPath, `orbita-browser-${majorVersion}`);
292
269
  await this.deleteDir(targetBrowserPath);
293
270
 
294
271
  await this.copyDir(
package/src/gologin.js CHANGED
@@ -92,8 +92,8 @@ export class GoLogin {
92
92
  debug('INIT GOLOGIN', this.profile_id);
93
93
  }
94
94
 
95
- async checkBrowser() {
96
- return this.browserChecker.checkBrowser(this.autoUpdateBrowser, this.checkBrowserUpdate);
95
+ async checkBrowser(majorVersion) {
96
+ this.executablePath = await this.browserChecker.checkBrowser(majorVersion);
97
97
  }
98
98
 
99
99
  async setProfileId(profile_id) {
@@ -252,63 +252,105 @@ export class GoLogin {
252
252
  return profile;
253
253
  }
254
254
 
255
- convertPreferences(preferences) {
256
- if (get(preferences, 'navigator.userAgent')) {
257
- preferences.userAgent = get(preferences, 'navigator.userAgent');
258
- }
259
-
260
- if (get(preferences, 'navigator.doNotTrack')) {
261
- preferences.doNotTrack = get(preferences, 'navigator.doNotTrack');
262
- }
263
-
264
- if (get(preferences, 'navigator.hardwareConcurrency')) {
265
- preferences.hardwareConcurrency = get(preferences, 'navigator.hardwareConcurrency');
266
- }
267
-
268
- if (get(preferences, 'navigator.deviceMemory')) {
269
- preferences.deviceMemory = get(preferences, 'navigator.deviceMemory') * 1024;
270
- }
271
-
272
- if (get(preferences, 'navigator.language')) {
273
- preferences.langHeader = get(preferences, 'navigator.language');
274
- preferences.languages = get(preferences, 'navigator.language').replace(/;|q=[\d\.]+/img, '');
275
- }
276
-
277
- if (get(preferences, 'navigator.maxTouchPoints')) {
278
- preferences.navigator.max_touch_points = get(preferences, 'navigator.maxTouchPoints');
279
- }
280
-
281
- if (get(preferences, 'isM1')) {
282
- preferences.is_m1 = get(preferences, 'isM1');
283
- }
284
-
285
- if (get(preferences, 'os') == 'android') {
286
- const devicePixelRatio = get(preferences, 'devicePixelRatio');
287
- const deviceScaleFactorCeil = Math.ceil(devicePixelRatio || 3.5);
288
- let deviceScaleFactor = devicePixelRatio;
289
- if (deviceScaleFactorCeil === devicePixelRatio) {
290
- deviceScaleFactor += 0.00000001;
291
- }
292
-
293
- preferences.mobile = {
294
- enable: true,
295
- width: parseInt(this.resolution.width, 10),
296
- height: parseInt(this.resolution.height, 10),
297
- device_scale_factor: deviceScaleFactor,
298
- };
299
- }
300
-
301
- preferences.mediaDevices = {
302
- enable: preferences.mediaDevices.enableMasking,
303
- videoInputs: preferences.mediaDevices.videoInputs,
304
- audioInputs: preferences.mediaDevices.audioInputs,
305
- audioOutputs: preferences.mediaDevices.audioOutputs,
306
- };
307
-
308
- preferences.webRtc = {
309
- ...preferences.webRtc,
310
- fill_based_on_ip: !!get(preferences, 'webRTC.fillBasedOnIp'),
311
- local_ip_masking: !!get(preferences, 'webRTC.local_ip_masking'),
255
+ getGologinPreferences(profileData) {
256
+ const os = profileData.os || '';
257
+ const osSpec = profileData.osSpec || '';
258
+ const isM1 = profileData.isM1 || false;
259
+ const isArm = (os === 'mac' && osSpec && osSpec.includes('M')) || isM1;
260
+ const resolution = (profileData.navigator && profileData.navigator.resolution) || '1920x1080';
261
+ const [screenWidth, screenHeight] = resolution.split('x').map(Number);
262
+ const langHeader = (profileData.navigator && profileData.navigator.language) || '';
263
+ console.log('langHeader', langHeader);
264
+ const splittedLangs = langHeader ? langHeader.split(',')[0] : 'en-US';
265
+
266
+ const startupUrl = (profileData.startUrl || '').trim().split(',')[0];
267
+ const startupUrls = (profileData.startUrl || '').split(',')
268
+ .map(url => url.trim())
269
+ .filter(url => url);
270
+
271
+ const preferences = {
272
+ profile_id: profileData.id,
273
+ name: profileData.name,
274
+ is_m1: isArm,
275
+ navigator: {
276
+ platform: (profileData.navigator?.platform) || '',
277
+ max_touch_points: (profileData.navigator?.maxTouchPoints) || 0,
278
+ },
279
+ dns: profileData.dns || {},
280
+ proxy: {
281
+ username: (profileData.proxy?.username) || '',
282
+ password: (profileData.proxy?.password) || '',
283
+ },
284
+ webRTC: profileData.webRTC || {},
285
+ screenHeight,
286
+ screenWidth,
287
+ userAgent: (profileData.navigator?.userAgent) || '',
288
+ webGl: {
289
+ vendor: (profileData.webGLMetadata?.vendor) || '',
290
+ renderer: (profileData.webGLMetadata?.renderer) || '',
291
+ mode: (profileData.webGLMetadata?.mode) === 'mask',
292
+ },
293
+ webgl: {
294
+ metadata: {
295
+ vendor: (profileData.webGLMetadata?.vendor) || '',
296
+ renderer: (profileData.webGLMetadata?.renderer) || '',
297
+ mode: (profileData.webGLMetadata?.mode) === 'mask',
298
+ },
299
+ },
300
+ mobile: {
301
+ enable: profileData.os === 'android',
302
+ width: profileData.screenWidth || 1920,
303
+ height: profileData.screenHeight || 1080,
304
+ device_scale_factor: profileData.devicePixelRatio || 1,
305
+ },
306
+ webglParams: profileData.webglParams || {},
307
+ webGpu: profileData.webGpu || {},
308
+ webgl_noice_enable: (profileData.webGL?.mode) === 'noise',
309
+ webglNoiceEnable: (profileData.webGL?.mode) === 'noise',
310
+ webgl_noise_enable: (profileData.webGL?.mode) === 'noise',
311
+ webgl_noise_value: profileData.webGL?.noise,
312
+ webglNoiseValue: profileData.webGL?.noise,
313
+ getClientRectsNoice: (profileData.clientRects?.noise) || (profileData.webGL?.getClientRectsNoise),
314
+ client_rects_noise_enable: (profileData.clientRects?.mode) === 'noise',
315
+ media_devices: {
316
+ enable: profileData.mediaDevices?.enableMasking,
317
+ uid: (profileData.mediaDevices?.uid) || '',
318
+ audioInputs: (profileData.mediaDevices?.audioInputs) || 1,
319
+ audioOutputs: (profileData.mediaDevices?.audioOutputs) || 1,
320
+ videoInputs: (profileData.mediaDevices?.videoInputs) || 1,
321
+ },
322
+ doNotTrack: (profileData.navigator?.doNotTrack) || false,
323
+ plugins: {
324
+ all_enable: profileData.plugins?.enableVulnerable,
325
+ flash_enable: profileData.plugins?.enableFlash,
326
+ },
327
+ storage: {
328
+ enable: profileData.storage?.local,
329
+ },
330
+ audioContext: {
331
+ enable: (profileData.audioContext?.mode) !== 'off',
332
+ noiseValue: (profileData.audioContext?.noise) || '',
333
+ },
334
+ canvas: {
335
+ mode: (profileData.canvas?.mode) || '',
336
+ },
337
+ languages: splittedLangs,
338
+ langHeader,
339
+ canvasMode: (profileData.canvas?.mode) || '',
340
+ canvasNoise: (profileData.canvas?.noise) || '',
341
+ deviceMemory: ((profileData.navigator?.deviceMemory) || 2) * 1024,
342
+ hardwareConcurrency: (profileData.navigator?.hardwareConcurrency) || 2,
343
+ startupUrl,
344
+ startup_urls: startupUrls,
345
+ geolocation: {
346
+ mode: (profileData.geolocation?.mode) || 'prompt',
347
+ latitude: parseFloat((this._tz && this._tz.ll && this._tz.ll[0]) || 0),
348
+ longitude: parseFloat((this._tz && this._tz.ll && this._tz.ll[1]) || 0),
349
+ accuracy: parseFloat((this._tz && this._tz.accuracy) || 0),
350
+ },
351
+ timezone: {
352
+ id: (this._tz && this._tz.timezone) || '',
353
+ },
312
354
  };
313
355
 
314
356
  return preferences;
@@ -420,6 +462,16 @@ export class GoLogin {
420
462
  await rimraf(profilePath, () => null);
421
463
  debug('-', profilePath, 'dropped');
422
464
  const profile = await this.getProfile();
465
+ if (!profile) {
466
+ throw new Error('Error fetching profile data');
467
+ }
468
+
469
+ if (!this.executablePath) {
470
+ const { userAgent } = profile.navigator;
471
+ const [browserMajorVersion] = userAgent.split('Chrome/')[1].split('.');
472
+ await this.checkBrowser(browserMajorVersion);
473
+ }
474
+
423
475
  const { navigator = {}, fonts, os: profileOs } = profile;
424
476
  this.fontsMasking = fonts?.enableMasking;
425
477
  this.profileOs = profileOs;
@@ -461,7 +513,6 @@ export class GoLogin {
461
513
  const preferences_raw = await readFile(pref_file_name);
462
514
  const preferences = JSON.parse(preferences_raw.toString());
463
515
  let proxy = get(profile, 'proxy');
464
- const name = get(profile, 'name');
465
516
  const chromeExtensions = get(profile, 'chromeExtensions') || [];
466
517
  const userChromeExtensions = get(profile, 'userChromeExtensions') || [];
467
518
  const allExtensions = [...chromeExtensions, ...userChromeExtensions];
@@ -554,60 +605,7 @@ export class GoLogin {
554
605
  throw new Error(`Proxy Error. ${e.message}`);
555
606
  });
556
607
 
557
- const [latitude, longitude] = this._tz.ll;
558
- const { accuracy } = this._tz;
559
-
560
- const profileGeolocation = profile.geolocation;
561
- const tzGeoLocation = {
562
- latitude,
563
- longitude,
564
- accuracy,
565
- };
566
-
567
- profile.geoLocation = this.getGeolocationParams(profileGeolocation, tzGeoLocation);
568
- profile.name = name;
569
- profile.name_base64 = Buffer.from(name).toString('base64');
570
- profile.profile_id = this.profile_id;
571
-
572
- profile.webRtc = {
573
- mode: get(profile, 'webRTC.mode') === 'alerted' ? 'public' : get(profile, 'webRTC.mode'),
574
- publicIP: get(profile, 'webRTC.fillBasedOnIp') ? this._tz.ip : get(profile, 'webRTC.publicIp'),
575
- localIps: get(profile, 'webRTC.localIps', []),
576
- };
577
-
578
- debug('profile.webRtc=', profile.webRtc);
579
- debug('profile.timezone=', profile.timezone);
580
- debug('profile.mediaDevices=', profile.mediaDevices);
581
-
582
- const audioContext = profile.audioContext || {};
583
- const { mode: audioCtxMode = 'off', noise: audioCtxNoise } = audioContext;
584
- if (profile.timezone.fillBasedOnIp === false) {
585
- profile.timezone = { id: profile.timezone.timezone };
586
- } else {
587
- profile.timezone = { id: this._tz.timezone };
588
- }
589
-
590
- profile.webgl_noise_value = profile.webGL.noise;
591
- profile.get_client_rects_noise = profile.webGL.getClientRectsNoise;
592
- profile.canvasMode = profile.canvas.mode;
593
- profile.canvasNoise = profile.canvas.noise;
594
- profile.audioContext = {
595
- enable: audioCtxMode !== 'off',
596
- noiseValue: audioCtxNoise,
597
- };
598
- profile.webgl = {
599
- metadata: {
600
- vendor: get(profile, 'webGLMetadata.vendor'),
601
- renderer: get(profile, 'webGLMetadata.renderer'),
602
- mode: get(profile, 'webGLMetadata.mode') === 'mask',
603
- },
604
- };
605
-
606
- profile.custom_fonts = {
607
- enable: !!fonts?.enableMasking,
608
- };
609
-
610
- const gologin = this.convertPreferences(profile);
608
+ const gologin = this.getGologinPreferences(profile);
611
609
 
612
610
  debug(`Writing profile for screenWidth ${profilePath}`, JSON.stringify(gologin));
613
611
  gologin.screenWidth = this.resolution.width;
@@ -632,19 +630,10 @@ export class GoLogin {
632
630
  }
633
631
  }
634
632
 
635
- const languages = this.language.replace(/;|q=[\d\.]+/img, '');
636
-
637
633
  if (preferences.gologin == null) {
638
634
  preferences.gologin = {};
639
635
  }
640
636
 
641
- preferences.gologin.langHeader = gologin.navigator.language;
642
- preferences.gologin.language = languages;
643
-
644
- const [splittedLangs] = gologin.navigator.language.split(';');
645
- const [browserLang] = splittedLangs.split(',');
646
- gologin.browserLang = browserLang;
647
-
648
637
  const isMAC = OS_PLATFORM === 'darwin';
649
638
  const checkAutoLangResult = checkAutoLang(gologin, this._tz);
650
639
  this.browserLang = isMAC ? 'en-US' : checkAutoLangResult;
@@ -755,9 +744,9 @@ export class GoLogin {
755
744
 
756
745
  const proxyUrl = `${proxy.mode}://${proxy.username}:${proxy.password}@${proxy.host}:${proxy.port}`;
757
746
  debug(`getTimeZone start ${TIMEZONE_URL}`, proxyUrl);
758
- data = await requests.get(TIMEZONE_URL, { proxy: proxyUrl, timeout: 20 * 1000, maxAttempts: 5 });
747
+ data = await requests.get(TIMEZONE_URL, { proxy: proxyUrl, timeout: 13 * 1000, maxAttempts: 3 });
759
748
  } else {
760
- data = await requests.get(TIMEZONE_URL, { timeout: 20 * 1000, maxAttempts: 5 });
749
+ data = await requests.get(TIMEZONE_URL, { timeout: 13 * 1000, maxAttempts: 3 });
761
750
  }
762
751
 
763
752
  debug('getTimeZone finish', data.body);
@@ -944,7 +933,7 @@ export class GoLogin {
944
933
 
945
934
  if (this.waitWebsocket) {
946
935
  debug('GETTING WS URL FROM BROWSER');
947
- const data = await requests.get(`http://127.0.0.1:${remote_debugging_port}/json/version`, { json: true });
936
+ const data = await requests.get(`http://127.0.0.1:${remote_debugging_port}/json/version`, { json: true, maxAttempts: 10, retryDelay: 1000 });
948
937
 
949
938
  debug('WS IS', get(data, 'body.webSocketDebuggerUrl', ''));
950
939
  this.is_active = true;
@@ -1444,16 +1433,6 @@ export class GoLogin {
1444
1433
  }
1445
1434
 
1446
1435
  async start() {
1447
- if (!this.executablePath) {
1448
- await this.checkBrowser();
1449
- }
1450
-
1451
- const ORBITA_BROWSER = this.executablePath || this.browserChecker.getOrbitaPath;
1452
-
1453
- const orbitaBrowserExists = await access(ORBITA_BROWSER).then(() => true).catch(() => false);
1454
- if (!orbitaBrowserExists) {
1455
- throw new Error(`Orbita browser is not exists on path ${ORBITA_BROWSER}, check executablePath param`);
1456
- }
1457
1436
 
1458
1437
  await this.createStartup();
1459
1438
  // await this.createBrowserExtension();
@@ -1 +1 @@
1
- export const STORAGE_GATEWAY_BASE_URL = 'https://files-gateway.gologin.com';
1
+ export const STORAGE_GATEWAY_BASE_URL = 'https://storage-worker-test.gologin.com';