gologin 1.0.45 → 1.0.48

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
  }
@@ -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,9 +248,35 @@ 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
 
251
255
  if (_.get(preferences, 'isM1')) {
252
- preferences.is_m1 = _.get(preferences, 'navigator.language');
256
+ preferences.is_m1 = _.get(preferences, 'isM1');
257
+ }
258
+
259
+ if (_.get(preferences, 'os') == 'android'){
260
+ const devicePixelRatio = _.get(preferences, "devicePixelRatio");
261
+ const deviceScaleFactorCeil = Math.ceil(devicePixelRatio || 3.5);
262
+ let deviceScaleFactor = devicePixelRatio;
263
+ if (deviceScaleFactorCeil === devicePixelRatio) {
264
+ deviceScaleFactor += 0.00000001;
265
+ }
266
+
267
+ preferences.mobile = {
268
+ enable: true,
269
+ width: parseInt(this.resolution.width, 10),
270
+ height: parseInt(this.resolution.height, 10),
271
+ device_scale_factor: deviceScaleFactor,
272
+ }
273
+ }
274
+
275
+ preferences.mediaDevices = {
276
+ enable: preferences.mediaDevices.enableMasking,
277
+ videoInputs: preferences.mediaDevices.videoInputs,
278
+ audioInputs: preferences.mediaDevices.audioInputs,
279
+ audioOutputs: preferences.mediaDevices.audioOutputs,
253
280
  }
254
281
 
255
282
  return preferences;
@@ -396,13 +423,16 @@ class GoLogin {
396
423
  }
397
424
 
398
425
  let extSettings;
399
- if (ExtensionsManagerInst.useLocalExtStorage && profileExtensionsCheckRes.length) {
400
- extSettings = BrowserUserDataManager.setExtPaths(preferences, profileExtensionsCheckRes);
401
- } else if (!ExtensionsManagerInst.useLocalExtStorage) {
426
+ if (ExtensionsManagerInst.useLocalExtStorage) {
427
+ extSettings = BrowserUserDataManager.setExtPathsAndRemoveDeleted(preferences, profileExtensionsCheckRes);
428
+ } else {
402
429
  const originalExtensionsFolder = path.join(profilePath, 'Default', 'Extensions');
403
430
  extSettings = await BrowserUserDataManager.setOriginalExtPaths(preferences, originalExtensionsFolder);
404
431
  }
405
432
 
433
+ this.extensionPathsToInstall =
434
+ ExtensionsManagerInst.getExtensionsToInstall(extSettings, profileExtensionsCheckRes);
435
+
406
436
  if (extSettings) {
407
437
  const currentExtSettings = preferences.extensions || {};
408
438
  currentExtSettings.settings = extSettings
@@ -462,10 +492,16 @@ class GoLogin {
462
492
  };
463
493
 
464
494
  debug('profile.webRtc=', profile.webRtc);
495
+ debug('profile.timezone=', profile.timezone);
496
+ debug('profile.mediaDevices=', profile.mediaDevices);
465
497
 
466
498
  const audioContext = profile.audioContext || {};
467
499
  const { mode: audioCtxMode = 'off', noise: audioCtxNoise } = audioContext;
468
- profile.timezone = { id: this._tz.timezone };
500
+ if(profile.timezone.fillBasedOnIp==false){
501
+ profile.timezone = { id: profile.timezone.timezone };
502
+ } else {
503
+ profile.timezone = { id: this._tz.timezone };
504
+ }
469
505
  profile.webgl_noise_value = profile.webGL.noise;
470
506
  profile.get_client_rects_noise = profile.webGL.getClientRectsNoise;
471
507
  profile.canvasMode = profile.canvas.mode;
@@ -488,10 +524,10 @@ class GoLogin {
488
524
 
489
525
  const gologin = this.convertPreferences(profile);
490
526
 
491
- debug(`Writing profile for screenWidth ${profilePath}`, JSON.stringify(profile));
527
+ debug(`Writing profile for screenWidth ${profilePath}`, JSON.stringify(gologin));
492
528
  gologin.screenWidth = this.resolution.width;
493
529
  gologin.screenHeight = this.resolution.height;
494
-
530
+ debug("writeCookesFromServer", this.writeCookesFromServer)
495
531
  if (this.writeCookesFromServer) {
496
532
  await this.writeCookiesToFile();
497
533
  }
@@ -517,7 +553,7 @@ class GoLogin {
517
553
 
518
554
  preferences.gologin.langHeader = gologin.language;
519
555
  preferences.gologin.languages = languages;
520
-
556
+ // debug("convertedPreferences=", preferences.gologin)
521
557
  await writeFile(path.join(profilePath, 'Default', 'Preferences'), JSON.stringify(_.merge(preferences, {
522
558
  gologin
523
559
  })));
@@ -713,7 +749,7 @@ class GoLogin {
713
749
  this.port = remote_debugging_port;
714
750
 
715
751
  const ORBITA_BROWSER = this.executablePath || this.browserChecker.getOrbitaPath;
716
-
752
+ console.log("ORBITA_BROWSER=", ORBITA_BROWSER)
717
753
  const env = {};
718
754
  Object.keys(process.env).forEach((key) => {
719
755
  env[key] = process.env[key];
@@ -747,6 +783,22 @@ class GoLogin {
747
783
  `--lang=${browserLang}`,
748
784
  ];
749
785
 
786
+ if (this.extensionPathsToInstall.length) {
787
+ if (Array.isArray(this.extra_params) && this.extra_params.length) {
788
+ this.extra_params.forEach((param, index) => {
789
+ if (!param.includes('--load-extension=')) {
790
+ return;
791
+ }
792
+
793
+ const [_, extPathsString] = param.split('=');
794
+ const extPathsArray = extPathsString.split(',');
795
+ this.extensionPathsToInstall = [...this.extensionPathsToInstall, ...extPathsArray];
796
+ this.extra_params.splice(index, 1);
797
+ });
798
+ }
799
+ params.push(`--load-extension=${this.extensionPathsToInstall.join(',')}`);
800
+ }
801
+
750
802
  if (this.fontsMasking) {
751
803
  let arg = '--font-masking-mode=2';
752
804
  if (this.differentOs) {
@@ -929,7 +981,7 @@ class GoLogin {
929
981
  os = options.os;
930
982
  }
931
983
 
932
- let fingerprint = await requests.get(`https://api.gologin.com/browser/fingerprint?os=${os}`,{
984
+ let fingerprint = await requests.get(`${API_URL}/browser/fingerprint?os=${os}`,{
933
985
  headers: {
934
986
  'Authorization': `Bearer ${this.access_token}`,
935
987
  'User-Agent': 'gologin-api',
@@ -958,7 +1010,7 @@ class GoLogin {
958
1010
  if (deviceMemory < 1) {
959
1011
  deviceMemory = 1;
960
1012
  }
961
- navigator.deviceMemory = deviceMemory;
1013
+ navigator.deviceMemory = deviceMemory*1024;
962
1014
  webGLMetadata.mode = webGLMetadata.mode === 'noise' ? 'mask' : 'off';
963
1015
 
964
1016
  const json = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gologin",
3
- "version": "1.0.45",
3
+ "version": "1.0.48",
4
4
  "description": "A high-level API to control Orbita browser over GoLogin API",
5
5
  "main": "./gologin.js",
6
6
  "repository": {