gologin 2.2.9 → 3.0.0

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.
@@ -1,5 +1,3 @@
1
- import puppeteer from 'puppeteer-core';
2
-
3
1
  import GoLogin from './gologin.js';
4
2
  import { API_URL, FALLBACK_API_URL, getOsAdvanced } from './utils/common.js';
5
3
  import { makeRequest } from './utils/http.js';
@@ -7,6 +5,20 @@ import { makeRequest } from './utils/http.js';
7
5
  const trafficLimitMessage =
8
6
  'You dont have free traffic to use the proxy. Please go to app https://app.gologin.com/ and buy some traffic if you want to use the proxy';
9
7
 
8
+ let puppeteerModulePromise = null;
9
+
10
+ const loadPuppeteer = () => {
11
+ puppeteerModulePromise ||= import('puppeteer-core').then((module) => module.default ?? module);
12
+
13
+ return puppeteerModulePromise;
14
+ };
15
+
16
+ const connectToBrowser = async (options) => {
17
+ const puppeteer = await loadPuppeteer();
18
+
19
+ return puppeteer.connect(options);
20
+ };
21
+
10
22
  export const getDefaultParams = () => ({
11
23
  token: process.env.GOLOGIN_API_TOKEN,
12
24
  profile_id: process.env.GOLOGIN_PROFILE_ID,
@@ -48,7 +60,7 @@ export const GologinApi = ({ token }) => {
48
60
 
49
61
  const startedProfile = await legacyGologin.start();
50
62
 
51
- const browser = await puppeteer.connect({
63
+ const browser = await connectToBrowser({
52
64
  browserWSEndpoint: startedProfile.wsUrl,
53
65
  ignoreHTTPSErrors: true,
54
66
  defaultViewport: null,
@@ -75,7 +87,7 @@ export const GologinApi = ({ token }) => {
75
87
  legacyGls.push(legacyGologin);
76
88
 
77
89
  const browserWSEndpoint = `https://cloudbrowser.gologin.com/connect?token=${token}&profile=${params.profileId}`;
78
- const browser = await puppeteer.connect({
90
+ const browser = await connectToBrowser({
79
91
  browserWSEndpoint,
80
92
  ignoreHTTPSErrors: true,
81
93
  });
package/src/gologin.js CHANGED
@@ -1,39 +1,32 @@
1
- import * as Sentry from '@sentry/node';
2
1
  import { execFile, spawn } from 'child_process';
3
2
  import debugDefault from 'debug';
4
- import decompress from 'decompress';
5
- import decompressUnzip from 'decompress-unzip';
6
3
  import { existsSync, mkdirSync, promises as _promises } from 'fs';
7
4
  import { tmpdir } from 'os';
8
5
  import { join, resolve as _resolve, sep } from 'path';
9
- import rimraf from 'rimraf';
10
- import { SocksProxyAgent } from 'socks-proxy-agent';
11
6
 
12
- import { fontsCollection } from '../fonts.js';
13
7
  import { getCurrentProfileBookmarks } from './bookmarks/utils.js';
14
8
  import { updateProfileBookmarks, updateProfileProxy, updateProfileResolution, updateProfileUserAgent } from './browser/browser-api.js';
15
- import BrowserChecker from './browser/browser-checker.js';
16
9
  import {
17
- composeFonts, downloadCookies, setExtPathsAndRemoveDeleted, setOriginalExtPaths, uploadCookies,
10
+ downloadCookies, setExtPathsAndRemoveDeleted, setOriginalExtPaths, uploadCookies,
18
11
  } from './browser/browser-user-data-manager.js';
19
- import {
20
- createDBFile,
21
- getChunckedInsertValues,
22
- getCookiesFilePath,
23
- getDB,
24
- getUniqueCookies,
25
- loadCookiesFromFile,
26
- } from './cookies/cookies-manager.js';
27
- import ExtensionsManager from './extensions/extensions-manager.js';
28
- import { archiveProfile } from './profile/profile-archiver.js';
12
+ import { getProfileChromeExtensions } from './extensions/get-extensions.js';
29
13
  import { checkAutoLang, getIntlProfileConfig, securedOrbitaOpts } from './utils/browser.js';
30
14
  import { API_URL, ensureDirectoryExists, FALLBACK_API_URL, getOsAdvanced } from './utils/common.js';
31
15
  import { STORAGE_GATEWAY_BASE_URL } from './utils/constants.js';
32
- import { get, isPortReachable } from './utils/utils.js';
33
- export { exitAll, GologinApi } from './gologin-api.js';
34
- import { getProfileChromeExtensions } from './extensions/get-extensions.js';
35
16
  import { checkSocksProxy, makeRequest } from './utils/http.js';
36
- import { captureGroupedSentryError } from './utils/sentry.js';
17
+ import {
18
+ // ensureSentryInitialized,
19
+ loadBrowserChecker,
20
+ loadCookiesManager,
21
+ loadDecompress,
22
+ loadExtensionsManager,
23
+ loadProfileArchiver,
24
+ loadSocksProxyAgent,
25
+ preloadStartupDeps,
26
+ removePath,
27
+ } from './utils/lazy-deps.js';
28
+ import { get, isPortReachable } from './utils/utils.js';
29
+ // import { captureGroupedSentryError } from './utils/sentry.js';
37
30
  import { zeroProfileBookmarks } from './utils/zero-profile-bookmarks.js';
38
31
  import { zeroProfilePreferences } from './utils/zero-profile-preferences.js';
39
32
 
@@ -70,7 +63,8 @@ export class GoLogin {
70
63
  this.tmpdir = tmpdir();
71
64
  this.autoUpdateBrowser = !!options.autoUpdateBrowser;
72
65
  this.checkBrowserUpdate = options.checkBrowserUpdate ?? true;
73
- this.browserChecker = new BrowserChecker(options.skipOrbitaHashChecking);
66
+ this._skipOrbitaHashChecking = options.skipOrbitaHashChecking;
67
+ this._browserChecker = null;
74
68
  this.uploadCookiesToServer = options.uploadCookiesToServer || false;
75
69
  this.writeCookiesFromServer = options.writeCookiesFromServer ?? true;
76
70
  this.remote_debugging_port = options.remote_debugging_port || 0;
@@ -85,15 +79,6 @@ export class GoLogin {
85
79
  this.proxyCheckTimeout = options.proxyCheckTimeout || 13 * 1000;
86
80
  this.proxyCheckAttempts = options.proxyCheckAttempts || 3;
87
81
 
88
- if (process.env.DISABLE_TELEMETRY !== 'true') {
89
- Sentry.init({
90
- dsn: 'https://a13d5939a60ae4f6583e228597f1f2a0@sentry-new.amzn.pro/24',
91
- tracesSampleRate: 1.0,
92
- defaultIntegrations: false,
93
- release: process.env.npm_package_version || '2.1.34',
94
- });
95
- }
96
-
97
82
  if (options.tmpdir) {
98
83
  this.tmpdir = options.tmpdir;
99
84
  if (!existsSync(this.tmpdir)) {
@@ -107,8 +92,18 @@ export class GoLogin {
107
92
  debug('INIT GOLOGIN', this.profile_id);
108
93
  }
109
94
 
95
+ async getBrowserChecker() {
96
+ if (!this._browserChecker) {
97
+ const BrowserChecker = await loadBrowserChecker();
98
+ this._browserChecker = new BrowserChecker(this._skipOrbitaHashChecking);
99
+ }
100
+
101
+ return this._browserChecker;
102
+ }
103
+
110
104
  async checkBrowser(majorVersion) {
111
- this.executablePath = await this.browserChecker.checkBrowser({
105
+ const browserChecker = await this.getBrowserChecker();
106
+ this.executablePath = await browserChecker.checkBrowser({
112
107
  autoUpdateBrowser: this.autoUpdateBrowser,
113
108
  checkBrowserUpdate: this.checkBrowserUpdate,
114
109
  majorVersion,
@@ -130,7 +125,8 @@ export class GoLogin {
130
125
  }
131
126
 
132
127
  for (const majorVersion of versionsToDownload) {
133
- await this.browserChecker.checkBrowser({
128
+ const browserChecker = await this.getBrowserChecker();
129
+ await browserChecker.checkBrowser({
134
130
  autoUpdateBrowser: true,
135
131
  checkBrowserUpdate: true,
136
132
  majorVersion,
@@ -141,7 +137,8 @@ export class GoLogin {
141
137
  }
142
138
 
143
139
  async getLatestBrowserVersion() {
144
- const { latestVersion: browserLatestVersion } = await this.browserChecker.getLatestBrowserVersion();
140
+ const browserChecker = await this.getBrowserChecker();
141
+ const { latestVersion: browserLatestVersion } = await browserChecker.getLatestBrowserVersion();
145
142
  const [latestBrowserMajorVersion] = browserLatestVersion.split('.');
146
143
 
147
144
  return Number(latestBrowserMajorVersion);
@@ -149,6 +146,7 @@ export class GoLogin {
149
146
 
150
147
  async setProfileId(profile_id) {
151
148
  this.profile_id = profile_id;
149
+ const { getCookiesFilePath } = await loadCookiesManager();
152
150
  this.cookiesFilePath = await getCookiesFilePath(profile_id, this.tmpdir);
153
151
  this.profile_zip_path = join(this.tmpdir, `gologin_${this.profile_id}.zip`);
154
152
  this.bookmarksFilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`, 'Default', 'Bookmarks');
@@ -359,10 +357,11 @@ export class GoLogin {
359
357
  async createBrowserExtension() {
360
358
  const that = this;
361
359
  debug('start createBrowserExtension');
362
- await rimraf(this.orbitaExtensionPath(), () => null);
360
+ await removePath(this.orbitaExtensionPath());
363
361
  const extPath = this.orbitaExtensionPath();
364
362
  debug('extension folder sanitized');
365
363
  const extension_source = _resolve(__dirname, 'gologin-browser-ext.zip');
364
+ const { decompress, decompressUnzip } = await loadDecompress();
366
365
  await decompress(extension_source, extPath,
367
366
  {
368
367
  plugins: [decompressUnzip()],
@@ -383,8 +382,9 @@ export class GoLogin {
383
382
  debug('createBrowserExtension done');
384
383
  }
385
384
 
386
- extractProfile(path, zipfile) {
385
+ async extractProfile(path, zipfile) {
387
386
  debug(`extactProfile ${zipfile}, ${path}`);
387
+ const { decompress, decompressUnzip } = await loadDecompress();
388
388
 
389
389
  return decompress(zipfile, path,
390
390
  {
@@ -402,15 +402,19 @@ export class GoLogin {
402
402
 
403
403
  if (!(local && profileZipExists)) {
404
404
  try {
405
- profile_folder = await this.getProfileS3();
405
+ const [, profileData] = await Promise.all([
406
+ loadDecompress(),
407
+ this.getProfileS3(),
408
+ ]);
409
+
410
+ profile_folder = profileData;
406
411
  } catch (e) {
407
412
  debug('Cannot get profile - using empty', e);
413
+ await loadDecompress();
408
414
  }
409
415
 
410
416
  debug('FILE READY', this.profile_zip_path);
411
-
412
417
  await writeFile(this.profile_zip_path, profile_folder);
413
-
414
418
  debug('PROFILE LENGTH', profile_folder.length);
415
419
  } else {
416
420
  debug('PROFILE LOCAL HAVING', this.profile_zip_path);
@@ -436,6 +440,7 @@ export class GoLogin {
436
440
  }
437
441
 
438
442
  async createZeroProfile(createCookiesTableQuery) {
443
+ const { createDBFile } = await loadCookiesManager();
439
444
  const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
440
445
  const defaultFilePath = _resolve(profilePath, 'Default');
441
446
  const preferencesFilePath = _resolve(defaultFilePath, 'Preferences');
@@ -458,10 +463,12 @@ export class GoLogin {
458
463
 
459
464
  async createStartup(local = false) {
460
465
  const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
466
+ const startupDepsPromise = preloadStartupDeps();
461
467
 
462
468
  const [profile] = await Promise.all([
463
469
  this.getProfile(),
464
- new Promise((resolve) => rimraf(profilePath, resolve)).then(() => debug('-', profilePath, 'dropped')),
470
+ startupDepsPromise.then(() => removePath(profilePath)
471
+ .then(() => debug('-', profilePath, 'dropped'))),
465
472
  ]);
466
473
 
467
474
  if (!profile) {
@@ -544,7 +551,9 @@ export class GoLogin {
544
551
  const allExtensions = [...chromeExtensions, ...userChromeExtensions];
545
552
 
546
553
  const [, orbitaParamsToken] = await Promise.all([
547
- this.setupProfileExtensions({ preferences, allExtensions, userChromeExtensions, profilePath }),
554
+ this.setupProfileExtensions({
555
+ preferences, allExtensions, userChromeExtensions, profilePath,
556
+ }),
548
557
  this.fetchOrbitaParamsToken(profile),
549
558
  ]);
550
559
 
@@ -553,13 +562,6 @@ export class GoLogin {
553
562
  if (!families.length) {
554
563
  this.isEmptyFonts = true;
555
564
  }
556
-
557
- try {
558
- // TODO: uncomment this when fonts will be fixed
559
- // await composeFonts(families, profilePath, this.differentOs);
560
- } catch (e) {
561
- console.trace(e);
562
- }
563
565
  }
564
566
 
565
567
  if (preferences.gologin === null) {
@@ -663,6 +665,7 @@ export class GoLogin {
663
665
  }
664
666
 
665
667
  async initCookiesFile(profile) {
668
+ const { getCookiesFilePath } = await loadCookiesManager();
666
669
  this.cookiesFilePath = await getCookiesFilePath(this.profile_id, this.tmpdir);
667
670
  if (this.writeCookiesFromServer) {
668
671
  await this.writeCookiesToFile(profile.cookies?.cookies);
@@ -674,6 +677,7 @@ export class GoLogin {
674
677
  return;
675
678
  }
676
679
 
680
+ const ExtensionsManager = await loadExtensionsManager();
677
681
  const ExtensionsManagerInst = new ExtensionsManager();
678
682
  ExtensionsManagerInst.apiUrl = API_URL;
679
683
  await ExtensionsManagerInst.init()
@@ -890,6 +894,7 @@ export class GoLogin {
890
894
  }
891
895
 
892
896
  proxy += host + ':' + port;
897
+ const SocksProxyAgent = await loadSocksProxyAgent();
893
898
  const agent = new SocksProxyAgent(proxy);
894
899
 
895
900
  const checkData = await checkSocksProxy(agent).catch((e) => {
@@ -976,7 +981,12 @@ export class GoLogin {
976
981
 
977
982
  this.port = remote_debugging_port;
978
983
 
979
- const ORBITA_BROWSER = this.executablePath || this.browserChecker.getOrbitaPath;
984
+ let ORBITA_BROWSER = this.executablePath;
985
+ if (!ORBITA_BROWSER) {
986
+ const browserChecker = await this.getBrowserChecker();
987
+ ORBITA_BROWSER = browserChecker.getOrbitaPath;
988
+ }
989
+
980
990
  debug(`ORBITA_BROWSER=${ORBITA_BROWSER}`);
981
991
 
982
992
  const env = {};
@@ -1069,7 +1079,7 @@ export class GoLogin {
1069
1079
  debug('GETTING WS URL FROM BROWSER');
1070
1080
  const data = await makeRequest(
1071
1081
  `http://127.0.0.1:${remote_debugging_port}/json/version`,
1072
- { json: true, maxAttempts: 30, retryDelay: 400, method: 'GET' },
1082
+ { json: true, maxAttempts: 60, retryDelay: 100, method: 'GET' },
1073
1083
  );
1074
1084
 
1075
1085
  debug('WS IS', get(data, 'webSocketDebuggerUrl', ''));
@@ -1082,8 +1092,8 @@ export class GoLogin {
1082
1092
  }
1083
1093
 
1084
1094
  async clearProfileFiles() {
1085
- await rimraf(join(this.tmpdir, `gologin_profile_${this.profile_id}`), () => null);
1086
- await rimraf(join(this.tmpdir, `gologin_${this.profile_id}_upload.zip`), () => null);
1095
+ await removePath(join(this.tmpdir, `gologin_profile_${this.profile_id}`));
1096
+ await removePath(join(this.tmpdir, `gologin_${this.profile_id}_upload.zip`));
1087
1097
  }
1088
1098
 
1089
1099
  async stopAndCommit(options, local = false) {
@@ -1113,7 +1123,7 @@ export class GoLogin {
1113
1123
  await this.clearProfileFiles();
1114
1124
 
1115
1125
  if (!local) {
1116
- await rimraf(join(this.tmpdir, `gologin_${this.profile_id}.zip`), () => null);
1126
+ await removePath(join(this.tmpdir, `gologin_${this.profile_id}.zip`));
1117
1127
  }
1118
1128
 
1119
1129
  debug(`PROFILE ${this.profile_id} STOPPED AND CLEAR`);
@@ -1122,6 +1132,7 @@ export class GoLogin {
1122
1132
  }
1123
1133
 
1124
1134
  async uploadProfileDataToServer() {
1135
+ const { loadCookiesFromFile } = await loadCookiesManager();
1125
1136
  const cookies = await loadCookiesFromFile(this.cookiesFilePath, false, this.profile_id, this.tmpdir);
1126
1137
  const bookmarks = await getCurrentProfileBookmarks(this.bookmarksFilePath);
1127
1138
  const profilePreferencesPath = join(this.profilePath(), 'Default', 'Preferences');
@@ -1180,7 +1191,7 @@ export class GoLogin {
1180
1191
  debug('browser killed');
1181
1192
  } catch (error) {
1182
1193
  console.error(error);
1183
- captureGroupedSentryError(error, { method: 'killBrowser', profileId: this.profile_id });
1194
+ // captureGroupedSentryError(error, { method: 'killBrowser', profileId: this.profile_id });
1184
1195
  }
1185
1196
  }
1186
1197
 
@@ -1221,13 +1232,7 @@ export class GoLogin {
1221
1232
  await Promise.all(remove_dirs.map(d => {
1222
1233
  const path_to_remove = `${that.profilePath()}${d}`;
1223
1234
 
1224
- return new Promise(resolve => {
1225
- debug('DROPPING', path_to_remove);
1226
- rimraf(path_to_remove, { maxBusyTries: 100 }, (e) => {
1227
- // debug('DROPPING RESULT', e);
1228
- resolve();
1229
- });
1230
- });
1235
+ return removePath(path_to_remove, { maxBusyTries: 100 });
1231
1236
  }));
1232
1237
  }
1233
1238
 
@@ -1242,6 +1247,7 @@ export class GoLogin {
1242
1247
  debug('profile sanitized');
1243
1248
 
1244
1249
  const profilePath = this.profilePath();
1250
+ const { archiveProfile } = await loadProfileArchiver();
1245
1251
  const fileBuff = await archiveProfile(profilePath);
1246
1252
 
1247
1253
  debug('PROFILE ZIP CREATED', profilePath, zipPath);
@@ -1431,6 +1437,13 @@ export class GoLogin {
1431
1437
  return;
1432
1438
  }
1433
1439
 
1440
+ const {
1441
+ createDBFile,
1442
+ getChunckedInsertValues,
1443
+ getDB,
1444
+ getUniqueCookies,
1445
+ } = await loadCookiesManager();
1446
+
1434
1447
  const resultCookies = cookies.map((el) => ({ ...el, value: Buffer.from(el.value) }));
1435
1448
  let db;
1436
1449
  const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
@@ -1463,7 +1476,7 @@ export class GoLogin {
1463
1476
  }
1464
1477
 
1465
1478
  console.error(error.message);
1466
- captureGroupedSentryError(error, { method: 'writeCookiesToFile', profileId: this.profile_id });
1479
+ // captureGroupedSentryError(error, { method: 'writeCookiesToFile', profileId: this.profile_id });
1467
1480
  } finally {
1468
1481
  db && await db.close();
1469
1482
  await ensureDirectoryExists(cookiesPaths.primary);
@@ -1481,16 +1494,17 @@ export class GoLogin {
1481
1494
  }
1482
1495
 
1483
1496
  async start() {
1484
- try {
1485
- await this.createStartup();
1486
- const startResponse = await this.spawnBrowser();
1487
- this.setActive(true);
1497
+ // ensureSentryInitialized({ release: process.env.npm_package_version || '2.1.34' });
1488
1498
 
1489
- return { status: 'success', wsUrl: startResponse.wsUrl, resolution: startResponse.resolution };
1490
- } catch (error) {
1491
- captureGroupedSentryError(error, { method: 'start', profileId: this.profile_id });
1492
- throw error;
1493
- }
1499
+ await this.createStartup();
1500
+ const startResponse = await this.spawnBrowser();
1501
+ this.setActive(true);
1502
+
1503
+ return {
1504
+ status: 'success',
1505
+ wsUrl: startResponse.wsUrl,
1506
+ resolution: startResponse.resolution,
1507
+ };
1494
1508
  }
1495
1509
 
1496
1510
  async startLocal() {
@@ -1570,12 +1584,6 @@ export class GoLogin {
1570
1584
  return updateProfileResolution(this.profile_id, this.access_token, resolution);
1571
1585
  }
1572
1586
 
1573
- getAvailableFonts() {
1574
- return fontsCollection
1575
- .filter(elem => elem.fileNames)
1576
- .map(elem => elem.name);
1577
- }
1578
-
1579
1587
  async quickCreateProfile(name = '') {
1580
1588
  const osInfo = await getOsAdvanced();
1581
1589
  const { os, osSpec } = osInfo;
package/src/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { GoLogin, default } from './gologin.js';
2
+ export { GologinApi, getDefaultParams, exitAll } from './gologin-api.js';
@@ -1,4 +1,3 @@
1
- import AdmZip from 'adm-zip';
2
1
  import { promises as _promises } from 'fs';
3
2
  import path from 'path';
4
3
 
@@ -6,7 +5,16 @@ import { getDirectoriesForArchiver } from './profile-directories-to-remove.js';
6
5
 
7
6
  const { access } = _promises;
8
7
 
8
+ let admZipPromise = null;
9
+
10
+ const loadAdmZip = () => {
11
+ admZipPromise ||= import('adm-zip').then((module) => module.default ?? module);
12
+
13
+ return admZipPromise;
14
+ };
15
+
9
16
  export const archiveProfile = async (profileFolder = '') => {
17
+ const AdmZip = await loadAdmZip();
10
18
  const folderExists = await access(profileFolder).then(() => true, () => false);
11
19
  if (!folderExists) {
12
20
  throw new Error('Invalid profile folder path: ' + profileFolder);
@@ -32,6 +40,7 @@ export const archiveProfile = async (profileFolder = '') => {
32
40
  };
33
41
 
34
42
  export const decompressProfile = async (zipPath = '', profileFolder = '') => {
43
+ const AdmZip = await loadAdmZip();
35
44
  const zipExists = await access(zipPath).then(() => true, () => false);
36
45
  if (!zipExists) {
37
46
  throw new Error('Invalid zip path: ' + zipPath);
@@ -44,6 +44,11 @@ const DEFAULT_FOLDER_USELESS_FILE = [
44
44
  subs: [],
45
45
  isDirectory: true,
46
46
  },
47
+ {
48
+ name: 'Shared Dictionary',
49
+ subs: ['cache'],
50
+ isDirectory: true,
51
+ },
47
52
  ];
48
53
 
49
54
  export const getDirectoriesToDeleteForNode = (routerSlash = '/') =>