gologin 1.0.44 → 1.0.47

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.
@@ -53,7 +53,7 @@ class BrowserChecker {
53
53
  executableFilePath = path.join(this.#browserPath, 'orbita-browser', 'chrome.exe');
54
54
  }
55
55
  this.#executableFilePath = executableFilePath;
56
- console.log('executableFilePath:', executableFilePath);
56
+ // console.log('executableFilePath:', executableFilePath);
57
57
  }
58
58
 
59
59
  async checkBrowser(autoUpdateBrowser = false) {
@@ -3,6 +3,7 @@ const os = require('os');
3
3
  const request = require('requestretry');
4
4
  const { rmdirSync, createWriteStream } = require('fs');
5
5
  const { access, readFile, writeFile, mkdir, readdir, copyFile } = require('fs').promises;
6
+ const crypto = require('crypto');
6
7
 
7
8
  const fontsCollection = require('./fonts');
8
9
 
@@ -12,6 +13,7 @@ const FONTS_DIR_NAME = 'fonts';
12
13
  const HOMEDIR = os.homedir();
13
14
  const BROWSER_PATH = path.join(HOMEDIR, '.gologin', 'browser');
14
15
  const OS_PLATFORM = process.platform;
16
+ const DEFAULT_ORBITA_EXTENSIONS_NAMES = ['Google Hangouts', 'Chromium PDF Viewer', 'CryptoTokenExtension', 'Web Store'];
15
17
 
16
18
  class BrowserUserDataManager {
17
19
  static downloadCookies({ profileId, ACCESS_TOKEN, API_BASE_URL }) {
@@ -114,7 +116,7 @@ class BrowserUserDataManager {
114
116
  await writeFile(path.join(profilePath, 'Default', 'fonts_config'), result);
115
117
  }
116
118
 
117
- static setExtPaths(settings = {}, profileExtensionsCheckRes = []) {
119
+ static setExtPathsAndRemoveDeleted(settings = {}, profileExtensionsCheckRes = []) {
118
120
  const formattedLocalExtArray = profileExtensionsCheckRes.map((el) => {
119
121
  const [extFolderName = ''] = el.split(path.sep).reverse();
120
122
  const [originalId] = extFolderName.split('@');
@@ -128,21 +130,60 @@ class BrowserUserDataManager {
128
130
  }
129
131
  }).filter(Boolean);
130
132
 
131
- if (!formattedLocalExtArray.length) {
132
- return;
133
- }
134
-
135
133
  const extensionsSettings = settings.extensions?.settings || {};
136
134
  const extensionsEntries = Object.entries(extensionsSettings);
137
135
 
138
136
  extensionsEntries.forEach((extensionObj) => {
139
- const [extensionsId] = extensionObj;
140
- const localExtObj = formattedLocalExtArray.find(el => el.originalId === extensionsId);
137
+ let [extensionId, currentExtSettings = {}] = extensionObj;
138
+ const extName = currentExtSettings.manifest?.name || '';
139
+ let extPath = currentExtSettings.path || '';
140
+ let originalId = '';
141
+
142
+ const isExtensionToBeDeleted = ['resources', 'passwords-ext', 'cookies-ext'].some(substring => extPath.includes(substring))
143
+ || DEFAULT_ORBITA_EXTENSIONS_NAMES.includes(extName);
144
+ if (isExtensionToBeDeleted) {
145
+ delete extensionsSettings[extensionId];
146
+ return;
147
+ }
148
+
149
+ if (os.platform() === 'win32') {
150
+ extPath = extPath.replace(/\//g, '\\');
151
+ } else {
152
+ extPath = extPath.replace(/\\/g, '/');
153
+ }
154
+ extensionsSettings[extensionId].path = extPath;
155
+
156
+ const isExtensionManageable = ['chrome-extensions', 'user-extensions'].some(substring => extPath.includes(substring));
157
+ if (isExtensionManageable) {
158
+ const [extFolderName] = extPath.split(path.sep).reverse();
159
+ [originalId] = extFolderName.split('@');
160
+ const isExtensionInProfileSettings = formattedLocalExtArray.find(el => el.path.includes(originalId));
161
+ if (!isExtensionInProfileSettings) {
162
+ delete extensionsSettings[extensionId];
163
+ return;
164
+ }
165
+
166
+ if (!currentExtSettings.manifest?.key) {
167
+ const hexEncodedPath = crypto.createHash('sha256').update(extPath).digest('hex');
168
+ const newId = hexEncodedPath.split('').slice(0, 32).map(symbol => extIdEncoding[symbol]).join('');
169
+ delete extensionsSettings[extensionId];
170
+
171
+ extensionsSettings[newId] = currentExtSettings;
172
+ extensionId = newId;
173
+ }
174
+ } else {
175
+ const splittedPath = extPath.split(path.sep);
176
+ if (splittedPath.length === 2) {
177
+ [originalId] = splittedPath
178
+ }
179
+ }
180
+
181
+ const localExtObj = originalId && formattedLocalExtArray.find(el => el.path.includes(originalId));
141
182
  if (!localExtObj) {
142
183
  return;
143
184
  }
144
185
 
145
- extensionsSettings[extensionsId].path = localExtObj?.path || '';
186
+ extensionsSettings[extensionId].path = localExtObj?.path || '';
146
187
  });
147
188
 
148
189
  return extensionsSettings;
@@ -202,6 +243,25 @@ class BrowserUserDataManager {
202
243
  }
203
244
  }
204
245
 
246
+ const extIdEncoding = {
247
+ 0: 'a',
248
+ 1: 'b',
249
+ 2: 'c',
250
+ 3: 'd',
251
+ 4: 'e',
252
+ 5: 'f',
253
+ 6: 'g',
254
+ 7: 'h',
255
+ 8: 'i',
256
+ 9: 'j',
257
+ a: 'k',
258
+ b: 'l',
259
+ c: 'm',
260
+ d: 'n',
261
+ e: 'o',
262
+ f: 'p',
263
+ };
264
+
205
265
  module.exports = {
206
266
  BrowserUserDataManager,
207
267
  }
@@ -0,0 +1,25 @@
1
+ // Usage example: in the terminal enter
2
+ // node example-startremote.js yU0token yU0Pr0f1leiD
3
+
4
+ // your token api (located in the settings, api)
5
+ // https://github.com/gologinapp/gologin#usage
6
+ const GOLOGIN_API_TOKEN = process.argv[2];
7
+ // your profile id
8
+ const GOLOGIN_PROFILE_ID = process.argv[3];
9
+
10
+ const GoLogin = require('../gologin');
11
+
12
+ (async () =>{
13
+ const GL = new GoLogin({
14
+ token: GOLOGIN_API_TOKEN,
15
+ profile_id: GOLOGIN_PROFILE_ID,
16
+ });
17
+ // connection of the remote work method
18
+ const {status, wsUrl} = await GL.startRemote();
19
+
20
+
21
+ GOLOGIN_PROFILE_CLOUD_URL = wsUrl.split('/')[2]
22
+ console.log('Done! Launch web browser and navigate to URL:', GOLOGIN_PROFILE_CLOUD_URL);
23
+ })();
24
+
25
+ // after running the script, the url will appear on the terminal
@@ -0,0 +1,20 @@
1
+ // Usage example: in the terminal enter
2
+ // node example-stopremote.js yU0token yU0Pr0f1leiD
3
+
4
+ // your token api (located in the settings, api)
5
+ // https://github.com/gologinapp/gologin#usage
6
+ const GOLOGIN_API_TOKEN = process.argv[2];
7
+ // your profile id
8
+ const GOLOGIN_PROFILE_ID = process.argv[3];
9
+
10
+ const GoLogin = require('../gologin');
11
+
12
+ (async () =>{
13
+ const GL = new GoLogin({
14
+ token: GOLOGIN_API_TOKEN,
15
+ profile_id: GOLOGIN_PROFILE_ID,
16
+ });
17
+
18
+ // stop profile
19
+ await GL.stopRemote();
20
+ })();
@@ -249,6 +249,28 @@ class ExtensionsManager {
249
249
 
250
250
  return Promise.all(removeFoldersPromises);
251
251
  }
252
+
253
+ getExtensionsToInstall(extensionsFromPref, extensionsFromDB) {
254
+ if (!extensionsFromPref) {
255
+ return [];
256
+ }
257
+
258
+ const objectEntries = Object.entries(extensionsFromPref);
259
+ const extensionsInPref = objectEntries?.map(([_, settings]) => {
260
+ const [extFolderName] = settings.path.split(path.sep).reverse();
261
+ const [originalId] = extFolderName.split('@');
262
+ return originalId;
263
+ }) || [];
264
+
265
+ return extensionsFromDB.reduce((acc, extension) => {
266
+ const [extFolderName] = extension.split(path.sep).reverse();
267
+ const [originalId] = extFolderName.split('@');
268
+ if (!extensionsInPref.includes(originalId)) {
269
+ acc.push(extension);
270
+ }
271
+ return acc;
272
+ }, []);
273
+ }
252
274
  }
253
275
 
254
276
  const crxToZip = (buf) => {
package/gologin.js CHANGED
@@ -47,9 +47,10 @@ class GoLogin {
47
47
  this.autoUpdateBrowser = !!options.autoUpdateBrowser;
48
48
  this.browserChecker = new BrowserChecker(options.skipOrbitaHashChecking);
49
49
  this.uploadCookiesToServer = options.uploadCookiesToServer || false;
50
- this.writeCookesFromServer = options.writeCookesFromServer || true;
50
+ this.writeCookesFromServer = options.writeCookesFromServer;
51
51
  this.remote_debugging_port = options.remote_debugging_port || 0;
52
52
  this.timezone = options.timezone;
53
+ this.extensionPathsToInstall = [];
53
54
 
54
55
  if (options.tmpdir) {
55
56
  this.tmpdir = options.tmpdir;
@@ -247,7 +248,21 @@ class GoLogin {
247
248
  if (_.get(preferences, 'navigator.language')) {
248
249
  preferences.language = _.get(preferences, 'navigator.language');
249
250
  }
251
+ if (_.get(preferences, 'navigator.maxTouchPoints')) {
252
+ preferences.navigator.max_touch_points = _.get(preferences, 'navigator.maxTouchPoints');
253
+ }
250
254
 
255
+ if (_.get(preferences, 'isM1')) {
256
+ preferences.is_m1 = _.get(preferences, 'isM1');
257
+ }
258
+
259
+ preferences.mediaDevices = {
260
+ enable: preferences.mediaDevices.enableMasking,
261
+ videoInputs: preferences.mediaDevices.videoInputs,
262
+ audioInputs: preferences.mediaDevices.audioInputs,
263
+ audioOutputs: preferences.mediaDevices.audioOutputs,
264
+ }
265
+
251
266
  return preferences;
252
267
  }
253
268
 
@@ -392,13 +407,16 @@ class GoLogin {
392
407
  }
393
408
 
394
409
  let extSettings;
395
- if (ExtensionsManagerInst.useLocalExtStorage && profileExtensionsCheckRes.length) {
396
- extSettings = BrowserUserDataManager.setExtPaths(preferences, profileExtensionsCheckRes);
397
- } else if (!ExtensionsManagerInst.useLocalExtStorage) {
410
+ if (ExtensionsManagerInst.useLocalExtStorage) {
411
+ extSettings = BrowserUserDataManager.setExtPathsAndRemoveDeleted(preferences, profileExtensionsCheckRes);
412
+ } else {
398
413
  const originalExtensionsFolder = path.join(profilePath, 'Default', 'Extensions');
399
414
  extSettings = await BrowserUserDataManager.setOriginalExtPaths(preferences, originalExtensionsFolder);
400
415
  }
401
416
 
417
+ this.extensionPathsToInstall =
418
+ ExtensionsManagerInst.getExtensionsToInstall(extSettings, profileExtensionsCheckRes);
419
+
402
420
  if (extSettings) {
403
421
  const currentExtSettings = preferences.extensions || {};
404
422
  currentExtSettings.settings = extSettings
@@ -458,10 +476,16 @@ class GoLogin {
458
476
  };
459
477
 
460
478
  debug('profile.webRtc=', profile.webRtc);
479
+ debug('profile.timezone=', profile.timezone);
480
+ debug('profile.mediaDevices=', profile.mediaDevices);
461
481
 
462
482
  const audioContext = profile.audioContext || {};
463
483
  const { mode: audioCtxMode = 'off', noise: audioCtxNoise } = audioContext;
464
- profile.timezone = { id: this._tz.timezone };
484
+ if(profile.timezone.fillBasedOnIp==false){
485
+ profile.timezone = { id: profile.timezone.timezone };
486
+ } else {
487
+ profile.timezone = { id: this._tz.timezone };
488
+ }
465
489
  profile.webgl_noise_value = profile.webGL.noise;
466
490
  profile.get_client_rects_noise = profile.webGL.getClientRectsNoise;
467
491
  profile.canvasMode = profile.canvas.mode;
@@ -484,10 +508,10 @@ class GoLogin {
484
508
 
485
509
  const gologin = this.convertPreferences(profile);
486
510
 
487
- debug(`Writing profile for screenWidth ${profilePath}`, JSON.stringify(profile));
511
+ debug(`Writing profile for screenWidth ${profilePath}`, JSON.stringify(gologin));
488
512
  gologin.screenWidth = this.resolution.width;
489
513
  gologin.screenHeight = this.resolution.height;
490
-
514
+ debug("writeCookesFromServer", this.writeCookesFromServer)
491
515
  if (this.writeCookesFromServer) {
492
516
  await this.writeCookiesToFile();
493
517
  }
@@ -513,7 +537,7 @@ class GoLogin {
513
537
 
514
538
  preferences.gologin.langHeader = gologin.language;
515
539
  preferences.gologin.languages = languages;
516
-
540
+ // debug("convertedPreferences=", preferences.gologin)
517
541
  await writeFile(path.join(profilePath, 'Default', 'Preferences'), JSON.stringify(_.merge(preferences, {
518
542
  gologin
519
543
  })));
@@ -709,7 +733,7 @@ class GoLogin {
709
733
  this.port = remote_debugging_port;
710
734
 
711
735
  const ORBITA_BROWSER = this.executablePath || this.browserChecker.getOrbitaPath;
712
-
736
+ console.log("ORBITA_BROWSER=", ORBITA_BROWSER)
713
737
  const env = {};
714
738
  Object.keys(process.env).forEach((key) => {
715
739
  env[key] = process.env[key];
@@ -743,6 +767,22 @@ class GoLogin {
743
767
  `--lang=${browserLang}`,
744
768
  ];
745
769
 
770
+ if (this.extensionPathsToInstall.length) {
771
+ if (Array.isArray(this.extra_params) && this.extra_params.length) {
772
+ this.extra_params.forEach((param, index) => {
773
+ if (!param.includes('--load-extension=')) {
774
+ return;
775
+ }
776
+
777
+ const [_, extPathsString] = param.split('=');
778
+ const extPathsArray = extPathsString.split(',');
779
+ this.extensionPathsToInstall = [...this.extensionPathsToInstall, ...extPathsArray];
780
+ this.extra_params.splice(index, 1);
781
+ });
782
+ }
783
+ params.push(`--load-extension=${this.extensionPathsToInstall.join(',')}`);
784
+ }
785
+
746
786
  if (this.fontsMasking) {
747
787
  let arg = '--font-masking-mode=2';
748
788
  if (this.differentOs) {
@@ -925,7 +965,7 @@ class GoLogin {
925
965
  os = options.os;
926
966
  }
927
967
 
928
- let fingerprint = await requests.get(`https://api.gologin.com/browser/fingerprint?os=${os}`,{
968
+ let fingerprint = await requests.get(`${API_URL}/browser/fingerprint?os=${os}`,{
929
969
  headers: {
930
970
  'Authorization': `Bearer ${this.access_token}`,
931
971
  'User-Agent': 'gologin-api',
@@ -954,7 +994,7 @@ class GoLogin {
954
994
  if (deviceMemory < 1) {
955
995
  deviceMemory = 1;
956
996
  }
957
- navigator.deviceMemory = deviceMemory;
997
+ navigator.deviceMemory = deviceMemory*1024;
958
998
  webGLMetadata.mode = webGLMetadata.mode === 'noise' ? 'mask' : 'off';
959
999
 
960
1000
  const json = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gologin",
3
- "version": "1.0.44",
3
+ "version": "1.0.47",
4
4
  "description": "A high-level API to control Orbita browser over GoLogin API",
5
5
  "main": "./gologin.js",
6
6
  "repository": {