gologin-commonjs 2.1.13 → 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.
Files changed (36) hide show
  1. package/dist/src/gologin.js +299 -248
  2. package/dist/src/utils/timezone.js +21 -0
  3. package/gologin/.eslintrc.json +290 -0
  4. package/gologin/package.json +1 -1
  5. package/gologin/src/gologin.js +671 -395
  6. package/gologin/src/utils/timezone.js +470 -0
  7. package/package.json +3 -1
  8. package/tes.js +2 -1
  9. package/tsconfig.json +23 -0
  10. package/types/fonts.d.ts +21 -0
  11. package/types/{bookmarks → src/bookmarks}/utils.d.ts +0 -1
  12. package/types/src/browser/browser-api.d.ts +10 -0
  13. package/types/{browser → src/browser}/browser-checker.d.ts +1 -2
  14. package/types/{browser → src/browser}/browser-user-data-manager.d.ts +0 -1
  15. package/types/{cookies → src/cookies}/cookies-manager.d.ts +7 -3
  16. package/types/{extensions → src/extensions}/extensions-extractor.d.ts +0 -1
  17. package/types/{extensions → src/extensions}/extensions-manager.d.ts +4 -7
  18. package/types/{extensions → src/extensions}/user-extensions-manager.d.ts +1 -2
  19. package/types/src/gologin-api.d.ts +17 -0
  20. package/types/{gologin.d.ts → src/gologin.d.ts} +18 -35
  21. package/types/{profile → src/profile}/profile-archiver.d.ts +1 -2
  22. package/types/{profile → src/profile}/profile-directories-to-remove.d.ts +0 -1
  23. package/types/{utils → src/utils}/browser.d.ts +0 -1
  24. package/types/src/utils/common.d.ts +10 -0
  25. package/types/{utils → src/utils}/constants.d.ts +0 -1
  26. package/types/src/utils/timezone.d.ts +1 -0
  27. package/types/{utils → src/utils}/utils.d.ts +0 -1
  28. package/types/src/utils/zero-profile-bookmarks.d.ts +41 -0
  29. package/types/src/utils/zero-profile-preferences.d.ts +219 -0
  30. package/dist/fonts_config +0 -104
  31. package/dist/gologin-browser-ext.zip +0 -0
  32. package/dist/gologin_zeroprofile.b64 +0 -1
  33. package/dist/index.d.ts +0 -61
  34. package/dist/zero_profile.zip +0 -0
  35. package/types/browser/browser-api.d.ts +0 -10
  36. package/types/utils/common.d.ts +0 -10
@@ -1,22 +1,32 @@
1
- import { execFile, spawn } from 'child_process';
2
- import debugDefault from 'debug';
3
- import decompress from 'decompress';
4
- import decompressUnzip from 'decompress-unzip';
5
- import { existsSync, mkdirSync,promises as _promises } from 'fs';
6
- import { get as _get } from 'https';
7
- import { tmpdir } from 'os';
8
- import { dirname, join, resolve as _resolve, sep } from 'path';
9
- import requests from 'requestretry';
10
- import rimraf from 'rimraf';
11
- import { SocksProxyAgent } from 'socks-proxy-agent';
12
-
13
- import { fontsCollection } from '../fonts.js';
14
- import { getCurrentProfileBookmarks } from './bookmarks/utils.js';
15
- import { updateProfileBookmarks, updateProfileProxy, updateProfileResolution, updateProfileUserAgent } from './browser/browser-api.js';
16
- import BrowserChecker from './browser/browser-checker.js';
1
+ import { execFile, spawn } from "child_process";
2
+ import debugDefault from "debug";
3
+ import decompress from "decompress";
4
+ import decompressUnzip from "decompress-unzip";
5
+ import { existsSync, mkdirSync, promises as _promises } from "fs";
6
+ import { get as _get } from "https";
7
+ import { tmpdir } from "os";
8
+ import { dirname, join, resolve as _resolve, sep } from "path";
9
+ import requests from "requestretry";
10
+ import rimraf from "rimraf";
11
+ import { SocksProxyAgent } from "socks-proxy-agent";
12
+ import { fileURLToPath } from "url";
13
+
14
+ import { fontsCollection } from "../fonts.js";
15
+ import { getCurrentProfileBookmarks } from "./bookmarks/utils.js";
17
16
  import {
18
- composeFonts, downloadCookies, setExtPathsAndRemoveDeleted, setOriginalExtPaths, uploadCookies,
19
- } from './browser/browser-user-data-manager.js';
17
+ updateProfileBookmarks,
18
+ updateProfileProxy,
19
+ updateProfileResolution,
20
+ updateProfileUserAgent,
21
+ } from "./browser/browser-api.js";
22
+ import BrowserChecker from "./browser/browser-checker.js";
23
+ import {
24
+ composeFonts,
25
+ downloadCookies,
26
+ setExtPathsAndRemoveDeleted,
27
+ setOriginalExtPaths,
28
+ uploadCookies,
29
+ } from "./browser/browser-user-data-manager.js";
20
30
  import {
21
31
  createDBFile,
22
32
  getChunckedInsertValues,
@@ -24,29 +34,31 @@ import {
24
34
  getDB,
25
35
  getUniqueCookies,
26
36
  loadCookiesFromFile,
27
- } from './cookies/cookies-manager.js';
28
- import ExtensionsManager from './extensions/extensions-manager.js';
29
- import { archiveProfile } from './profile/profile-archiver.js';
30
- import { checkAutoLang } from './utils/browser.js';
31
- import { API_URL, getOsAdvanced } from './utils/common.js';
32
- import { STORAGE_GATEWAY_BASE_URL } from './utils/constants.js';
33
- import { get, isPortReachable } from './utils/utils.js';
34
- export { exitAll, GologinApi } from './gologin-api.js';
35
- import { zeroProfileBookmarks } from './utils/zero-profile-bookmarks.js';
36
- import { zeroProfilePreferences } from './utils/zero-profile-preferences.js';
37
+ } from "./cookies/cookies-manager.js";
38
+ import ExtensionsManager from "./extensions/extensions-manager.js";
39
+ import { archiveProfile } from "./profile/profile-archiver.js";
40
+ import { checkAutoLang } from "./utils/browser.js";
41
+ import { API_URL, getOsAdvanced } from "./utils/common.js";
42
+ import { STORAGE_GATEWAY_BASE_URL } from "./utils/constants.js";
43
+ import { get, isPortReachable } from "./utils/utils.js";
44
+ export { exitAll, GologinApi } from "./gologin-api.js";
45
+ import { zeroProfileBookmarks } from "./utils/zero-profile-bookmarks.js";
46
+ import { zeroProfilePreferences } from "./utils/zero-profile-preferences.js";
47
+ import { tzlookup } from "./utils/timezone.js";
37
48
  const { access, unlink, writeFile, readFile, mkdir, copyFile } = _promises;
38
49
 
39
50
  const SEPARATOR = sep;
40
51
  const OS_PLATFORM = process.platform;
41
- const TIMEZONE_URL = 'https://geo.myip.link';
42
- const PROXY_NONE = 'none';
52
+ const TIMEZONE_URL = "https://geolocation-db.com/json/";
53
+ // const TIMEZONE_URL = 'https://geo.myip.link';
54
+ const PROXY_NONE = "none";
43
55
 
44
- const debug = debugDefault('gologin');
56
+ const debug = debugDefault("gologin");
45
57
  const delay = (time) => new Promise((resolve) => setTimeout(resolve, time));
46
58
 
47
59
  export class GoLogin {
48
60
  constructor(options = {}) {
49
- this.browserLang = 'en-US';
61
+ this.browserLang = "en-US";
50
62
  this.access_token = options.token;
51
63
  this.profile_id = options.profile_id;
52
64
  this.password = options.password;
@@ -57,11 +69,12 @@ export class GoLogin {
57
69
  this.is_active = false;
58
70
  this.is_stopping = false;
59
71
  this.differentOs = false;
60
- this.profileOs = 'lin';
72
+ this.profileOs = "lin";
61
73
  this.waitWebsocket = options.waitWebsocket ?? true;
62
74
  this.isEmptyFonts = false;
63
75
  this.isFirstSession = false;
64
76
  this.isCloudHeadless = options.isCloudHeadless ?? true;
77
+ this.storageGatewayUrl = `${STORAGE_GATEWAY_BASE_URL}/upload`;
65
78
 
66
79
  this.tmpdir = tmpdir();
67
80
  this.autoUpdateBrowser = !!options.autoUpdateBrowser;
@@ -80,25 +93,38 @@ export class GoLogin {
80
93
  if (options.tmpdir) {
81
94
  this.tmpdir = options.tmpdir;
82
95
  if (!existsSync(this.tmpdir)) {
83
- debug('making tmpdir', this.tmpdir);
96
+ debug("making tmpdir", this.tmpdir);
84
97
  mkdirSync(this.tmpdir, { recursive: true });
85
98
  }
86
99
  }
87
100
 
88
101
  this.profile_zip_path = join(this.tmpdir, `gologin_${this.profile_id}.zip`);
89
- this.bookmarksFilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`, 'Default', 'Bookmarks');
90
- debug('INIT GOLOGIN', this.profile_id);
102
+ this.bookmarksFilePath = join(
103
+ this.tmpdir,
104
+ `gologin_profile_${this.profile_id}`,
105
+ "Default",
106
+ "Bookmarks"
107
+ );
108
+ debug("INIT GOLOGIN", this.profile_id);
91
109
  }
92
110
 
93
111
  async checkBrowser() {
94
- return this.browserChecker.checkBrowser(this.autoUpdateBrowser, this.checkBrowserUpdate);
112
+ return this.browserChecker.checkBrowser(
113
+ this.autoUpdateBrowser,
114
+ this.checkBrowserUpdate
115
+ );
95
116
  }
96
117
 
97
118
  async setProfileId(profile_id) {
98
119
  this.profile_id = profile_id;
99
120
  this.cookiesFilePath = await getCookiesFilePath(profile_id, this.tmpdir);
100
121
  this.profile_zip_path = join(this.tmpdir, `gologin_${this.profile_id}.zip`);
101
- this.bookmarksFilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`, 'Default', 'Bookmarks');
122
+ this.bookmarksFilePath = join(
123
+ this.tmpdir,
124
+ `gologin_profile_${this.profile_id}`,
125
+ "Default",
126
+ "Bookmarks"
127
+ );
102
128
  }
103
129
 
104
130
  async getToken(username, password) {
@@ -109,21 +135,28 @@ export class GoLogin {
109
135
  },
110
136
  });
111
137
 
112
- if (!Reflect.has(data, 'body.access_token')) {
113
- throw new Error(`gologin auth failed with status code, ${data.statusCode} DATA ${JSON.stringify(data)}`);
138
+ if (!Reflect.has(data, "body.access_token")) {
139
+ throw new Error(
140
+ `gologin auth failed with status code, ${
141
+ data.statusCode
142
+ } DATA ${JSON.stringify(data)}`
143
+ );
114
144
  }
115
145
  }
116
146
 
117
147
  async getNewFingerPrint(os) {
118
- debug('GETTING FINGERPRINT');
148
+ debug("GETTING FINGERPRINT");
119
149
 
120
- const fpResponse = await requests.get(`${API_URL}/browser/fingerprint?os=${os}`, {
121
- json: true,
122
- headers: {
123
- 'Authorization': `Bearer ${this.access_token}`,
124
- 'User-Agent': 'gologin-api',
125
- },
126
- });
150
+ const fpResponse = await requests.get(
151
+ `${API_URL}/browser/fingerprint?os=${os}`,
152
+ {
153
+ json: true,
154
+ headers: {
155
+ Authorization: `Bearer ${this.access_token}`,
156
+ "User-Agent": "gologin-api",
157
+ },
158
+ }
159
+ );
127
160
 
128
161
  return fpResponse?.body || {};
129
162
  }
@@ -131,14 +164,13 @@ export class GoLogin {
131
164
  async profiles() {
132
165
  const profilesResponse = await requests.get(`${API_URL}/browser/v2`, {
133
166
  headers: {
134
- 'Authorization': `Bearer ${this.access_token}`,
135
- 'User-Agent': 'gologin-api',
136
-
167
+ Authorization: `Bearer ${this.access_token}`,
168
+ "User-Agent": "gologin-api",
137
169
  },
138
170
  });
139
171
 
140
172
  if (profilesResponse.statusCode !== 200) {
141
- throw new Error('Gologin /browser response error');
173
+ throw new Error("Gologin /browser response error");
142
174
  }
143
175
 
144
176
  return JSON.parse(profilesResponse.body);
@@ -146,23 +178,23 @@ export class GoLogin {
146
178
 
147
179
  async getProfile(profile_id) {
148
180
  const id = profile_id || this.profile_id;
149
- debug('getProfile', this.access_token, id);
150
- const profileResponse = await requests.get(`${API_URL}/browser/features/${id}/info-for-run`, {
151
- headers: {
152
- 'Authorization': `Bearer ${this.access_token}`,
153
- 'User-Agent': 'gologin-api',
154
- },
155
- });
181
+ debug("getProfile", this.access_token, id);
182
+ const profileResponse = await requests.get(
183
+ `${API_URL}/browser/features/${id}/info-for-run`,
184
+ {
185
+ headers: {
186
+ Authorization: `Bearer ${this.access_token}`,
187
+ "User-Agent": "gologin-api",
188
+ },
189
+ }
190
+ );
156
191
 
157
- debug('profileResponse', profileResponse.statusCode, profileResponse.body);
192
+ debug("profileResponse", profileResponse.statusCode, profileResponse.body);
158
193
 
159
- const { body: errorBody = '' } = profileResponse;
160
- const backendErrorHeader = 'backend@error::';
194
+ const { body: errorBody = "" } = profileResponse;
195
+ const backendErrorHeader = "backend@error::";
161
196
  if (errorBody.includes(backendErrorHeader)) {
162
- const errorData =
163
- errorBody
164
- .replace(backendErrorHeader, '')
165
- .slice(1, -1);
197
+ const errorData = errorBody.replace(backendErrorHeader, "").slice(1, -1);
166
198
 
167
199
  throw new Error(errorData);
168
200
  }
@@ -176,25 +208,29 @@ export class GoLogin {
176
208
  }
177
209
 
178
210
  if (profileResponse.statusCode !== 200) {
179
- throw new Error(`Gologin /browser/${id} response error ${profileResponse.statusCode} INVALID TOKEN OR PROFILE NOT FOUND`);
211
+ throw new Error(
212
+ `Gologin /browser/${id} response error ${profileResponse.statusCode} INVALID TOKEN OR PROFILE NOT FOUND`
213
+ );
180
214
  }
181
215
 
182
216
  if (profileResponse.statusCode === 401) {
183
- throw new Error('invalid token');
217
+ throw new Error("invalid token");
184
218
  }
185
219
 
186
220
  return JSON.parse(profileResponse.body);
187
221
  }
188
222
 
189
223
  async emptyProfile() {
190
- return readFile(_resolve(__dirname, 'gologin_zeroprofile.b64')).then(res => res.toString());
224
+ return readFile(_resolve(__dirname, "gologin_zeroprofile.b64")).then(
225
+ (res) => res.toString()
226
+ );
191
227
  }
192
228
 
193
229
  async getProfileS3() {
194
230
  const token = this.access_token;
195
- debug('getProfileS3 token=', token, 'profile=', this.profile_id);
231
+ debug("getProfileS3 token=", token, "profile=", this.profile_id);
196
232
  const downloadURL = `${STORAGE_GATEWAY_BASE_URL}/download`;
197
- debug('loading profile from public s3 bucket, url=', downloadURL);
233
+ debug("loading profile from public s3 bucket, url=", downloadURL);
198
234
 
199
235
  const profileResponse = await fetch(downloadURL, {
200
236
  headers: {
@@ -206,28 +242,29 @@ export class GoLogin {
206
242
  const profileResponseBody = await profileResponse.arrayBuffer();
207
243
 
208
244
  if (profileResponse.status !== 200) {
209
- debug(`Gologin S3 BUCKET ${downloadURL} response error ${profileResponse.statusCode} - use empty`);
245
+ debug(
246
+ `Gologin S3 BUCKET ${downloadURL} response error ${profileResponse.statusCode} - use empty`
247
+ );
210
248
 
211
- return '';
249
+ return "";
212
250
  }
213
251
 
214
252
  return Buffer.from(profileResponseBody);
215
253
  }
216
254
 
217
255
  async postFile(fileName, fileBuff) {
218
- debug('POSTING FILE', fileBuff.length);
219
- debug('Getting signed URL for S3');
220
- const apiUrl = `${STORAGE_GATEWAY_BASE_URL}/upload`;
256
+ debug("POSTING FILE", fileBuff.length);
257
+ debug("Getting signed URL for S3");
221
258
 
222
259
  const bodyBufferBiteLength = Buffer.byteLength(fileBuff);
223
- console.log('BUFFER SIZE', bodyBufferBiteLength);
260
+ console.log("BUFFER SIZE", bodyBufferBiteLength);
224
261
 
225
- await requests.put(apiUrl, {
262
+ await requests.put(this.storageGatewayUrl, {
226
263
  headers: {
227
264
  Authorization: `Bearer ${this.access_token}`,
228
265
  browserId: this.profile_id,
229
- 'Content-Type': 'application/zip',
230
- 'Content-Length': bodyBufferBiteLength,
266
+ "Content-Type": "application/zip",
267
+ "Content-Length": bodyBufferBiteLength,
231
268
  },
232
269
  body: fileBuff,
233
270
  maxBodyLength: Infinity,
@@ -238,51 +275,61 @@ export class GoLogin {
238
275
  fullResponse: false,
239
276
  });
240
277
 
241
- console.log('Profile has been uploaded to S3 successfully');
278
+ console.log("Profile has been uploaded to S3 successfully");
242
279
  }
243
280
 
244
281
  async emptyProfileFolder() {
245
- debug('get emptyProfileFolder');
246
- const currentDir = dirname(new URL(import.meta.url).pathname);
247
- const zeroProfilePath = join(currentDir, '..', 'zero_profile.zip');
282
+ debug("get emptyProfileFolder");
283
+ const currentDir = dirname(fileURLToPath(import.meta.url));
284
+ const zeroProfilePath = join(currentDir, "..", "zero_profile.zip");
248
285
  const profile = await readFile(_resolve(zeroProfilePath));
249
- debug('emptyProfileFolder LENGTH ::', profile.length);
286
+ debug("emptyProfileFolder LENGTH ::", profile.length);
250
287
 
251
288
  return profile;
252
289
  }
253
290
 
254
291
  convertPreferences(preferences) {
255
- if (get(preferences, 'navigator.userAgent')) {
256
- preferences.userAgent = get(preferences, 'navigator.userAgent');
292
+ if (get(preferences, "navigator.userAgent")) {
293
+ preferences.userAgent = get(preferences, "navigator.userAgent");
257
294
  }
258
295
 
259
- if (get(preferences, 'navigator.doNotTrack')) {
260
- preferences.doNotTrack = get(preferences, 'navigator.doNotTrack');
296
+ if (get(preferences, "navigator.doNotTrack")) {
297
+ preferences.doNotTrack = get(preferences, "navigator.doNotTrack");
261
298
  }
262
299
 
263
- if (get(preferences, 'navigator.hardwareConcurrency')) {
264
- preferences.hardwareConcurrency = get(preferences, 'navigator.hardwareConcurrency');
300
+ if (get(preferences, "navigator.hardwareConcurrency")) {
301
+ preferences.hardwareConcurrency = get(
302
+ preferences,
303
+ "navigator.hardwareConcurrency"
304
+ );
265
305
  }
266
306
 
267
- if (get(preferences, 'navigator.deviceMemory')) {
268
- preferences.deviceMemory = get(preferences, 'navigator.deviceMemory') * 1024;
307
+ if (get(preferences, "navigator.deviceMemory")) {
308
+ preferences.deviceMemory =
309
+ get(preferences, "navigator.deviceMemory") * 1024;
269
310
  }
270
311
 
271
- if (get(preferences, 'navigator.language')) {
272
- preferences.langHeader = get(preferences, 'navigator.language');
273
- preferences.languages = get(preferences, 'navigator.language').replace(/;|q=[\d\.]+/img, '');
312
+ if (get(preferences, "navigator.language")) {
313
+ preferences.langHeader = get(preferences, "navigator.language");
314
+ preferences.languages = get(preferences, "navigator.language").replace(
315
+ /;|q=[\d\.]+/gim,
316
+ ""
317
+ );
274
318
  }
275
319
 
276
- if (get(preferences, 'navigator.maxTouchPoints')) {
277
- preferences.navigator.max_touch_points = get(preferences, 'navigator.maxTouchPoints');
320
+ if (get(preferences, "navigator.maxTouchPoints")) {
321
+ preferences.navigator.max_touch_points = get(
322
+ preferences,
323
+ "navigator.maxTouchPoints"
324
+ );
278
325
  }
279
326
 
280
- if (get(preferences, 'isM1')) {
281
- preferences.is_m1 = get(preferences, 'isM1');
327
+ if (get(preferences, "isM1")) {
328
+ preferences.is_m1 = get(preferences, "isM1");
282
329
  }
283
330
 
284
- if (get(preferences, 'os') == 'android') {
285
- const devicePixelRatio = get(preferences, 'devicePixelRatio');
331
+ if (get(preferences, "os") == "android") {
332
+ const devicePixelRatio = get(preferences, "devicePixelRatio");
286
333
  const deviceScaleFactorCeil = Math.ceil(devicePixelRatio || 3.5);
287
334
  let deviceScaleFactor = devicePixelRatio;
288
335
  if (deviceScaleFactorCeil === devicePixelRatio) {
@@ -306,8 +353,8 @@ export class GoLogin {
306
353
 
307
354
  preferences.webRtc = {
308
355
  ...preferences.webRtc,
309
- fill_based_on_ip: !!get(preferences, 'webRTC.fillBasedOnIp'),
310
- local_ip_masking: !!get(preferences, 'webRTC.local_ip_masking'),
356
+ fill_based_on_ip: !!get(preferences, "webRTC.fillBasedOnIp"),
357
+ local_ip_masking: !!get(preferences, "webRTC.local_ip_masking"),
311
358
  };
312
359
 
313
360
  return preferences;
@@ -315,68 +362,68 @@ export class GoLogin {
315
362
 
316
363
  async createBrowserExtension() {
317
364
  const that = this;
318
- debug('start createBrowserExtension');
365
+ debug("start createBrowserExtension");
319
366
  await rimraf(this.orbitaExtensionPath(), () => null);
320
367
  const extPath = this.orbitaExtensionPath();
321
- debug('extension folder sanitized');
322
- const extension_source = _resolve(__dirname, 'gologin-browser-ext.zip');
323
- await decompress(extension_source, extPath,
324
- {
325
- plugins: [decompressUnzip()],
326
- filter: file => !file.path.endsWith('/'),
327
- },
328
- )
368
+ debug("extension folder sanitized");
369
+ const extension_source = _resolve(__dirname, "gologin-browser-ext.zip");
370
+ await decompress(extension_source, extPath, {
371
+ plugins: [decompressUnzip()],
372
+ filter: (file) => !file.path.endsWith("/"),
373
+ })
329
374
  .then(() => {
330
- debug('extraction done');
331
- debug('create uid.json');
375
+ debug("extraction done");
376
+ debug("create uid.json");
332
377
 
333
- return writeFile(join(extPath, 'uid.json'), JSON.stringify({ uid: that.profile_id }, null, 2))
334
- .then(() => extPath);
378
+ return writeFile(
379
+ join(extPath, "uid.json"),
380
+ JSON.stringify({ uid: that.profile_id }, null, 2)
381
+ ).then(() => extPath);
335
382
  })
336
383
  .catch(async (e) => {
337
- debug('orbita extension error', e);
384
+ debug("orbita extension error", e);
338
385
  });
339
386
 
340
- debug('createBrowserExtension done');
387
+ debug("createBrowserExtension done");
341
388
  }
342
389
 
343
390
  extractProfile(path, zipfile) {
344
391
  debug(`extactProfile ${zipfile}, ${path}`);
345
392
 
346
- return decompress(zipfile, path,
347
- {
348
- plugins: [decompressUnzip()],
349
- filter: file => !file.path.endsWith('/'),
350
- },
351
- );
393
+ return decompress(zipfile, path, {
394
+ plugins: [decompressUnzip()],
395
+ filter: (file) => !file.path.endsWith("/"),
396
+ });
352
397
  }
353
398
 
354
399
  async downloadProfileAndExtract(profile, local) {
355
400
  let profile_folder;
356
401
  const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
357
- const profileZipExists = await access(this.profile_zip_path).then(() => true).catch(() => false);
402
+ const profileZipExists = await access(this.profile_zip_path)
403
+ .then(() => true)
404
+ .catch(() => false);
358
405
 
359
406
  if (!(local && profileZipExists)) {
360
407
  try {
361
408
  profile_folder = await this.getProfileS3();
362
409
  } catch (e) {
363
- debug('Cannot get profile - using empty', e);
410
+ debug("Cannot get profile - using empty", e);
364
411
  }
365
412
 
366
- debug('FILE READY', this.profile_zip_path);
413
+ debug("FILE READY", this.profile_zip_path);
367
414
 
368
415
  await writeFile(this.profile_zip_path, profile_folder);
369
416
 
370
- debug('PROFILE LENGTH', profile_folder.length);
417
+ debug("PROFILE LENGTH", profile_folder.length);
371
418
  } else {
372
- debug('PROFILE LOCAL HAVING', this.profile_zip_path);
419
+ debug("PROFILE LOCAL HAVING", this.profile_zip_path);
373
420
  }
374
421
 
375
- debug('Cleaning up..', profilePath);
422
+ debug("Cleaning up..", profilePath);
376
423
 
377
424
  try {
378
425
  await this.extractProfile(profilePath, this.profile_zip_path);
379
- debug('extraction done');
426
+ debug("extraction done");
380
427
  } catch (e) {
381
428
  console.trace(e);
382
429
  profile_folder = await this.emptyProfileFolder();
@@ -384,28 +431,36 @@ export class GoLogin {
384
431
  await this.extractProfile(profilePath, this.profile_zip_path);
385
432
  }
386
433
 
387
- const singletonLockPath = join(profilePath, 'SingletonLock');
388
- const singletonLockExists = await access(singletonLockPath).then(() => true).catch(() => false);
434
+ const singletonLockPath = join(profilePath, "SingletonLock");
435
+ const singletonLockExists = await access(singletonLockPath)
436
+ .then(() => true)
437
+ .catch(() => false);
389
438
  if (singletonLockExists) {
390
- debug('removing SingletonLock');
439
+ debug("removing SingletonLock");
391
440
  await unlink(singletonLockPath);
392
- debug('SingletonLock removed');
441
+ debug("SingletonLock removed");
393
442
  }
394
443
  }
395
444
 
396
445
  async createZeroProfile(createCookiesTableQuery) {
397
446
  const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
398
- const defaultFilePath = _resolve(profilePath, 'Default');
399
- const preferencesFilePath = _resolve(defaultFilePath, 'Preferences');
400
- const bookmarksFilePath = _resolve(defaultFilePath, 'Bookmarks');
401
- const cookiesFilePath = _resolve(defaultFilePath, 'Network', 'Cookies');
402
- const cookiesFileSecondPath = _resolve(defaultFilePath, 'Cookies');
447
+ const defaultFilePath = _resolve(profilePath, "Default");
448
+ const preferencesFilePath = _resolve(defaultFilePath, "Preferences");
449
+ const bookmarksFilePath = _resolve(defaultFilePath, "Bookmarks");
450
+ const cookiesFilePath = _resolve(defaultFilePath, "Network", "Cookies");
451
+ const cookiesFileSecondPath = _resolve(defaultFilePath, "Cookies");
403
452
 
404
- await mkdir(_resolve(defaultFilePath, 'Network'), { recursive: true }).catch(console.log);
453
+ await mkdir(_resolve(defaultFilePath, "Network"), {
454
+ recursive: true,
455
+ }).catch(console.log);
405
456
 
406
457
  await Promise.all([
407
- writeFile(preferencesFilePath, JSON.stringify(zeroProfilePreferences), { mode: 0o666 }),
408
- writeFile(bookmarksFilePath, JSON.stringify(zeroProfileBookmarks), { mode: 0o666 }),
458
+ writeFile(preferencesFilePath, JSON.stringify(zeroProfilePreferences), {
459
+ mode: 0o666,
460
+ }),
461
+ writeFile(bookmarksFilePath, JSON.stringify(zeroProfileBookmarks), {
462
+ mode: 0o666,
463
+ }),
409
464
  createDBFile({
410
465
  cookiesFilePath,
411
466
  cookiesFileSecondPath,
@@ -417,25 +472,21 @@ export class GoLogin {
417
472
  async createStartup(local = false) {
418
473
  const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
419
474
  await rimraf(profilePath, () => null);
420
- debug('-', profilePath, 'dropped');
475
+ debug("-", profilePath, "dropped");
421
476
  const profile = await this.getProfile();
422
477
  const { navigator = {}, fonts, os: profileOs } = profile;
423
478
  this.fontsMasking = fonts?.enableMasking;
424
479
  this.profileOs = profileOs;
425
480
  this.differentOs =
426
- profileOs !== 'android' && (
427
- OS_PLATFORM === 'win32' && profileOs !== 'win' ||
428
- OS_PLATFORM === 'darwin' && profileOs !== 'mac' ||
429
- OS_PLATFORM === 'linux' && profileOs !== 'lin'
430
- );
481
+ profileOs !== "android" &&
482
+ ((OS_PLATFORM === "win32" && profileOs !== "win") ||
483
+ (OS_PLATFORM === "darwin" && profileOs !== "mac") ||
484
+ (OS_PLATFORM === "linux" && profileOs !== "lin"));
431
485
 
432
- const {
433
- resolution = '1920x1080',
434
- language = 'en-US,en;q=0.9',
435
- } = navigator;
486
+ const { resolution = "1920x1080", language = "en-US,en;q=0.9" } = navigator;
436
487
 
437
488
  this.language = language;
438
- const [screenWidth, screenHeight] = resolution.split('x');
489
+ const [screenWidth, screenHeight] = resolution.split("x");
439
490
  this.resolution = {
440
491
  width: parseInt(screenWidth, 10),
441
492
  height: parseInt(screenHeight, 10),
@@ -448,21 +499,27 @@ export class GoLogin {
448
499
  await this.downloadProfileAndExtract(profile, local);
449
500
  }
450
501
 
451
- const pref_file_name = join(profilePath, 'Default', 'Preferences');
452
- debug('reading', pref_file_name);
502
+ const pref_file_name = join(profilePath, "Default", "Preferences");
503
+ debug("reading", pref_file_name);
453
504
 
454
- const prefFileExists = await access(pref_file_name).then(() => true).catch(() => false);
505
+ const prefFileExists = await access(pref_file_name)
506
+ .then(() => true)
507
+ .catch(() => false);
455
508
  if (!prefFileExists) {
456
- debug('Preferences file not exists waiting', pref_file_name, '. Using empty profile');
457
- await writeFile(pref_file_name, '{}');
509
+ debug(
510
+ "Preferences file not exists waiting",
511
+ pref_file_name,
512
+ ". Using empty profile"
513
+ );
514
+ await writeFile(pref_file_name, "{}");
458
515
  }
459
516
 
460
517
  const preferences_raw = await readFile(pref_file_name);
461
518
  const preferences = JSON.parse(preferences_raw.toString());
462
- let proxy = get(profile, 'proxy');
463
- const name = get(profile, 'name');
464
- const chromeExtensions = get(profile, 'chromeExtensions') || [];
465
- const userChromeExtensions = get(profile, 'userChromeExtensions') || [];
519
+ let proxy = get(profile, "proxy");
520
+ const name = get(profile, "name");
521
+ const chromeExtensions = get(profile, "chromeExtensions") || [];
522
+ const userChromeExtensions = get(profile, "userChromeExtensions") || [];
466
523
  const allExtensions = [...chromeExtensions, ...userChromeExtensions];
467
524
 
468
525
  if (allExtensions.length) {
@@ -470,7 +527,7 @@ export class GoLogin {
470
527
  ExtensionsManagerInst.apiUrl = API_URL;
471
528
  await ExtensionsManagerInst.init()
472
529
  .then(() => ExtensionsManagerInst.updateExtensions())
473
- .catch(() => { });
530
+ .catch(() => {});
474
531
  ExtensionsManagerInst.accessToken = this.access_token;
475
532
 
476
533
  await ExtensionsManagerInst.getExtensionsPolicies();
@@ -479,16 +536,19 @@ export class GoLogin {
479
536
  if (ExtensionsManagerInst.useLocalExtStorage) {
480
537
  const promises = [
481
538
  ExtensionsManagerInst.checkChromeExtensions(allExtensions)
482
- .then(res => ({ profileExtensionsCheckRes: res }))
539
+ .then((res) => ({ profileExtensionsCheckRes: res }))
483
540
  .catch((e) => {
484
- console.log('checkChromeExtensions error: ', e);
541
+ console.log("checkChromeExtensions error: ", e);
485
542
 
486
543
  return { profileExtensionsCheckRes: [] };
487
544
  }),
488
- ExtensionsManagerInst.checkLocalUserChromeExtensions(userChromeExtensions, this.profile_id)
489
- .then(res => ({ profileUserExtensionsCheckRes: res }))
545
+ ExtensionsManagerInst.checkLocalUserChromeExtensions(
546
+ userChromeExtensions,
547
+ this.profile_id
548
+ )
549
+ .then((res) => ({ profileUserExtensionsCheckRes: res }))
490
550
  .catch((error) => {
491
- console.log('checkUserChromeExtensions error: ', error);
551
+ console.log("checkUserChromeExtensions error: ", error);
492
552
 
493
553
  return null;
494
554
  }),
@@ -496,22 +556,43 @@ export class GoLogin {
496
556
 
497
557
  const extensionsResult = await Promise.all(promises);
498
558
 
499
- const profileExtensionPathRes = extensionsResult.find(el => 'profileExtensionsCheckRes' in el) || {};
500
- const profileUserExtensionPathRes = extensionsResult.find(el => 'profileUserExtensionsCheckRes' in el);
501
- profileExtensionsCheckRes =
502
- (profileExtensionPathRes?.profileExtensionsCheckRes || []).concat(profileUserExtensionPathRes?.profileUserExtensionsCheckRes || []);
559
+ const profileExtensionPathRes =
560
+ extensionsResult.find((el) => "profileExtensionsCheckRes" in el) ||
561
+ {};
562
+ const profileUserExtensionPathRes = extensionsResult.find(
563
+ (el) => "profileUserExtensionsCheckRes" in el
564
+ );
565
+ profileExtensionsCheckRes = (
566
+ profileExtensionPathRes?.profileExtensionsCheckRes || []
567
+ ).concat(
568
+ profileUserExtensionPathRes?.profileUserExtensionsCheckRes || []
569
+ );
503
570
  }
504
571
 
505
572
  let extSettings;
506
573
  if (ExtensionsManagerInst.useLocalExtStorage) {
507
- extSettings = await setExtPathsAndRemoveDeleted(preferences, profileExtensionsCheckRes, this.profile_id);
574
+ extSettings = await setExtPathsAndRemoveDeleted(
575
+ preferences,
576
+ profileExtensionsCheckRes,
577
+ this.profile_id
578
+ );
508
579
  } else {
509
- const originalExtensionsFolder = join(profilePath, 'Default', 'Extensions');
510
- extSettings = await setOriginalExtPaths(preferences, originalExtensionsFolder);
580
+ const originalExtensionsFolder = join(
581
+ profilePath,
582
+ "Default",
583
+ "Extensions"
584
+ );
585
+ extSettings = await setOriginalExtPaths(
586
+ preferences,
587
+ originalExtensionsFolder
588
+ );
511
589
  }
512
590
 
513
591
  this.extensionPathsToInstall =
514
- ExtensionsManagerInst.getExtensionsToInstall(extSettings, profileExtensionsCheckRes);
592
+ ExtensionsManagerInst.getExtensionsToInstall(
593
+ extSettings,
594
+ profileExtensionsCheckRes
595
+ );
515
596
 
516
597
  if (extSettings) {
517
598
  const currentExtSettings = preferences.extensions || {};
@@ -520,26 +601,26 @@ export class GoLogin {
520
601
  }
521
602
  }
522
603
 
523
- if (proxy.mode === 'gologin' || proxy.mode === 'tor') {
524
- const autoProxyServer = get(profile, 'autoProxyServer');
525
- const splittedAutoProxyServer = autoProxyServer.split('://');
526
- const splittedProxyAddress = splittedAutoProxyServer[1].split(':');
604
+ if (proxy.mode === "gologin" || proxy.mode === "tor") {
605
+ const autoProxyServer = get(profile, "autoProxyServer");
606
+ const splittedAutoProxyServer = autoProxyServer.split("://");
607
+ const splittedProxyAddress = splittedAutoProxyServer[1].split(":");
527
608
  const port = splittedProxyAddress[1];
528
609
 
529
610
  proxy = {
530
- 'mode': splittedAutoProxyServer[0],
531
- 'host': splittedProxyAddress[0],
611
+ mode: splittedAutoProxyServer[0],
612
+ host: splittedProxyAddress[0],
532
613
  port,
533
- 'username': get(profile, 'autoProxyUsername'),
534
- 'password': get(profile, 'autoProxyPassword'),
614
+ username: get(profile, "autoProxyUsername"),
615
+ password: get(profile, "autoProxyPassword"),
535
616
  };
536
617
 
537
- profile.proxy.username = get(profile, 'autoProxyUsername');
538
- profile.proxy.password = get(profile, 'autoProxyPassword');
618
+ profile.proxy.username = get(profile, "autoProxyUsername");
619
+ profile.proxy.password = get(profile, "autoProxyPassword");
539
620
  }
540
621
 
541
- if (proxy.mode === 'geolocation') {
542
- proxy.mode = 'http';
622
+ if (proxy.mode === "geolocation") {
623
+ proxy.mode = "http";
543
624
  }
544
625
 
545
626
  if (proxy.mode === PROXY_NONE) {
@@ -549,7 +630,7 @@ export class GoLogin {
549
630
  this.proxy = proxy;
550
631
 
551
632
  await this.getTimeZone(proxy).catch((e) => {
552
- console.error('Proxy Error. Check it and try again.');
633
+ console.error("Proxy Error. Check it and try again.");
553
634
  throw new Error(`Proxy Error. ${e.message}`);
554
635
  });
555
636
 
@@ -563,23 +644,31 @@ export class GoLogin {
563
644
  accuracy,
564
645
  };
565
646
 
566
- profile.geoLocation = this.getGeolocationParams(profileGeolocation, tzGeoLocation);
647
+ profile.geoLocation = this.getGeolocationParams(
648
+ profileGeolocation,
649
+ tzGeoLocation
650
+ );
567
651
  profile.name = name;
568
- profile.name_base64 = Buffer.from(name).toString('base64');
652
+ profile.name_base64 = Buffer.from(name).toString("base64");
569
653
  profile.profile_id = this.profile_id;
570
654
 
571
655
  profile.webRtc = {
572
- mode: get(profile, 'webRTC.mode') === 'alerted' ? 'public' : get(profile, 'webRTC.mode'),
573
- publicIP: get(profile, 'webRTC.fillBasedOnIp') ? this._tz.ip : get(profile, 'webRTC.publicIp'),
574
- localIps: get(profile, 'webRTC.localIps', []),
656
+ mode:
657
+ get(profile, "webRTC.mode") === "alerted"
658
+ ? "public"
659
+ : get(profile, "webRTC.mode"),
660
+ publicIP: get(profile, "webRTC.fillBasedOnIp")
661
+ ? this._tz.ip
662
+ : get(profile, "webRTC.publicIp"),
663
+ localIps: get(profile, "webRTC.localIps", []),
575
664
  };
576
665
 
577
- debug('profile.webRtc=', profile.webRtc);
578
- debug('profile.timezone=', profile.timezone);
579
- debug('profile.mediaDevices=', profile.mediaDevices);
666
+ debug("profile.webRtc=", profile.webRtc);
667
+ debug("profile.timezone=", profile.timezone);
668
+ debug("profile.mediaDevices=", profile.mediaDevices);
580
669
 
581
670
  const audioContext = profile.audioContext || {};
582
- const { mode: audioCtxMode = 'off', noise: audioCtxNoise } = audioContext;
671
+ const { mode: audioCtxMode = "off", noise: audioCtxNoise } = audioContext;
583
672
  if (profile.timezone.fillBasedOnIp === false) {
584
673
  profile.timezone = { id: profile.timezone.timezone };
585
674
  } else {
@@ -591,14 +680,14 @@ export class GoLogin {
591
680
  profile.canvasMode = profile.canvas.mode;
592
681
  profile.canvasNoise = profile.canvas.noise;
593
682
  profile.audioContext = {
594
- enable: audioCtxMode !== 'off',
683
+ enable: audioCtxMode !== "off",
595
684
  noiseValue: audioCtxNoise,
596
685
  };
597
686
  profile.webgl = {
598
687
  metadata: {
599
- vendor: get(profile, 'webGLMetadata.vendor'),
600
- renderer: get(profile, 'webGLMetadata.renderer'),
601
- mode: get(profile, 'webGLMetadata.mode') === 'mask',
688
+ vendor: get(profile, "webGLMetadata.vendor"),
689
+ renderer: get(profile, "webGLMetadata.renderer"),
690
+ mode: get(profile, "webGLMetadata.mode") === "mask",
602
691
  },
603
692
  };
604
693
 
@@ -608,11 +697,17 @@ export class GoLogin {
608
697
 
609
698
  const gologin = this.convertPreferences(profile);
610
699
 
611
- debug(`Writing profile for screenWidth ${profilePath}`, JSON.stringify(gologin));
700
+ debug(
701
+ `Writing profile for screenWidth ${profilePath}`,
702
+ JSON.stringify(gologin)
703
+ );
612
704
  gologin.screenWidth = this.resolution.width;
613
705
  gologin.screenHeight = this.resolution.height;
614
- debug('writeCookiesFromServer', this.writeCookiesFromServer);
615
- this.cookiesFilePath = await getCookiesFilePath(this.profile_id, this.tmpdir);
706
+ debug("writeCookiesFromServer", this.writeCookiesFromServer);
707
+ this.cookiesFilePath = await getCookiesFilePath(
708
+ this.profile_id,
709
+ this.tmpdir
710
+ );
616
711
 
617
712
  if (this.writeCookiesFromServer) {
618
713
  await this.writeCookiesToFile(profile.cookies?.cookies);
@@ -631,7 +726,7 @@ export class GoLogin {
631
726
  }
632
727
  }
633
728
 
634
- const languages = this.language.replace(/;|q=[\d\.]+/img, '');
729
+ const languages = this.language.replace(/;|q=[\d\.]+/gim, "");
635
730
 
636
731
  if (preferences.gologin == null) {
637
732
  preferences.gologin = {};
@@ -640,24 +735,41 @@ export class GoLogin {
640
735
  preferences.gologin.langHeader = gologin.navigator.language;
641
736
  preferences.gologin.language = languages;
642
737
 
643
- const [splittedLangs] = gologin.navigator.language.split(';');
644
- const [browserLang] = splittedLangs.split(',');
738
+ const [splittedLangs] = gologin.navigator.language.split(";");
739
+ const [browserLang] = splittedLangs.split(",");
645
740
  gologin.browserLang = browserLang;
646
741
 
647
- const isMAC = OS_PLATFORM === 'darwin';
742
+ const isMAC = OS_PLATFORM === "darwin";
648
743
  const checkAutoLangResult = checkAutoLang(gologin, this._tz);
649
- this.browserLang = isMAC ? 'en-US' : checkAutoLangResult;
650
-
651
- await writeFile(join(profilePath, 'Default', 'Preferences'), JSON.stringify(Object.assign(preferences, {
652
- gologin,
653
- })));
744
+ this.browserLang = isMAC ? "en-US" : checkAutoLangResult;
745
+
746
+ await writeFile(
747
+ join(profilePath, "Default", "Preferences"),
748
+ JSON.stringify(
749
+ Object.assign(preferences, {
750
+ gologin,
751
+ })
752
+ )
753
+ );
654
754
 
655
- const bookmarksParsedData = await getCurrentProfileBookmarks(this.bookmarksFilePath);
755
+ const bookmarksParsedData = await getCurrentProfileBookmarks(
756
+ this.bookmarksFilePath
757
+ );
656
758
  const bookmarksFromDb = profile.bookmarks?.bookmark_bar;
657
- bookmarksParsedData.roots = bookmarksFromDb ? profile.bookmarks : bookmarksParsedData.roots;
658
- await writeFile(this.bookmarksFilePath, JSON.stringify(bookmarksParsedData));
759
+ bookmarksParsedData.roots = bookmarksFromDb
760
+ ? profile.bookmarks
761
+ : bookmarksParsedData.roots;
762
+ await writeFile(
763
+ this.bookmarksFilePath,
764
+ JSON.stringify(bookmarksParsedData)
765
+ );
659
766
 
660
- debug('Profile ready. Path: ', profilePath, 'PROXY', JSON.stringify(get(preferences, 'gologin.proxy')));
767
+ debug(
768
+ "Profile ready. Path: ",
769
+ profilePath,
770
+ "PROXY",
771
+ JSON.stringify(get(preferences, "gologin.proxy"))
772
+ );
661
773
 
662
774
  return profilePath;
663
775
  }
@@ -665,21 +777,21 @@ export class GoLogin {
665
777
  async commitProfile() {
666
778
  const dataBuff = await this.getProfileDataToUpdate();
667
779
 
668
- debug('begin updating', dataBuff.length);
780
+ debug("begin updating", dataBuff.length);
669
781
  if (!dataBuff.length) {
670
- debug('WARN: profile zip data empty - SKIPPING PROFILE COMMIT');
782
+ debug("WARN: profile zip data empty - SKIPPING PROFILE COMMIT");
671
783
 
672
784
  return;
673
785
  }
674
786
 
675
787
  try {
676
- debug('Patching profile');
677
- await this.postFile('profile', dataBuff);
788
+ debug("Patching profile");
789
+ await this.postFile("profile", dataBuff);
678
790
  } catch (e) {
679
- debug('CANNOT COMMIT PROFILE', e);
791
+ debug("CANNOT COMMIT PROFILE", e);
680
792
  }
681
793
 
682
- debug('COMMIT COMPLETED');
794
+ debug("COMMIT COMPLETED");
683
795
  }
684
796
 
685
797
  profilePath() {
@@ -698,10 +810,10 @@ export class GoLogin {
698
810
  }
699
811
 
700
812
  async checkPortAvailable(port) {
701
- debug('CHECKING PORT AVAILABLE', port);
813
+ debug("CHECKING PORT AVAILABLE", port);
702
814
 
703
815
  try {
704
- const portAvailable = await isPortReachable(port, { host: 'localhost' });
816
+ const portAvailable = await isPortReachable(port, { host: "localhost" });
705
817
  if (portAvailable) {
706
818
  debug(`PORT ${port} IS OPEN`);
707
819
 
@@ -728,10 +840,10 @@ export class GoLogin {
728
840
  }
729
841
 
730
842
  async getTimeZone(proxy) {
731
- debug('getting timeZone proxy=', proxy);
843
+ debug("getting timeZone proxy=", proxy);
732
844
 
733
845
  if (this.timezone) {
734
- debug('getTimeZone from options', this.timezone);
846
+ debug("getTimeZone from options", this.timezone);
735
847
  this._tz = this.timezone;
736
848
 
737
849
  return this._tz.timezone;
@@ -739,50 +851,81 @@ export class GoLogin {
739
851
 
740
852
  let data = null;
741
853
  if (proxy && proxy.mode !== PROXY_NONE) {
742
- if (proxy.mode.includes('socks')) {
854
+ if (proxy.mode.includes("socks")) {
743
855
  for (let i = 0; i < 5; i++) {
744
856
  try {
745
- debug('getting timeZone socks try', i + 1);
857
+ debug("getting timeZone socks try", i + 1);
746
858
 
747
859
  return this.getTimezoneWithSocks(proxy);
748
860
  } catch (e) {
749
861
  console.log(e.message);
750
862
  }
751
863
  }
752
- throw new Error('Socks proxy connection timed out');
864
+ throw new Error("Socks proxy connection timed out");
753
865
  }
754
866
 
755
867
  const proxyUrl = `${proxy.mode}://${proxy.username}:${proxy.password}@${proxy.host}:${proxy.port}`;
756
868
  debug(`getTimeZone start ${TIMEZONE_URL}`, proxyUrl);
757
- data = await requests.get(TIMEZONE_URL, { proxy: proxyUrl, timeout: 20 * 1000, maxAttempts: 5 });
869
+ const response = await requests.get(TIMEZONE_URL, {
870
+ proxy: proxyUrl,
871
+ timeout: 20 * 1000,
872
+ maxAttempts: 5,
873
+ });
874
+ const result = JSON.parse(response.body);
875
+ data = {
876
+ body: {
877
+ country: result.country_code,
878
+ stateProv: result.city,
879
+ city: result.city,
880
+ timezone: tzlookup(result.latitude, result.longitude),
881
+ ll: [result.latitude, result.longitude],
882
+ languages: "en",
883
+ accuracy: 100,
884
+ },
885
+ };
758
886
  } else {
759
- data = await requests.get(TIMEZONE_URL, { timeout: 20 * 1000, maxAttempts: 5 });
887
+ const response = await requests.get(TIMEZONE_URL, {
888
+ timeout: 20 * 1000,
889
+ maxAttempts: 5,
890
+ });
891
+ const result = JSON.parse(response.body);
892
+ data = {
893
+ body: {
894
+ country: result.country_code,
895
+ stateProv: result.city,
896
+ city: result.city,
897
+ timezone: tzlookup(result.latitude, result.longitude),
898
+ ll: [result.latitude, result.longitude],
899
+ languages: "en",
900
+ accuracy: 100,
901
+ },
902
+ };
760
903
  }
761
904
 
762
- debug('getTimeZone finish', data.body);
763
- this._tz = JSON.parse(data.body);
905
+ debug("getTimeZone finish", data.body);
906
+ this._tz = data.body;
764
907
 
765
908
  return this._tz.timezone;
766
909
  }
767
910
 
768
911
  async getTimezoneWithSocks(params) {
769
- const { host, port, username = '', password = '' } = params;
912
+ const { host, port, username = "", password = "" } = params;
770
913
  let body;
771
914
 
772
- let proxy = 'socks://';
915
+ let proxy = "socks://";
773
916
  if (username) {
774
- const resultPassword = password ? ':' + password + '@' : '@';
917
+ const resultPassword = password ? ":" + password + "@" : "@";
775
918
  proxy += username + resultPassword;
776
919
  }
777
920
 
778
- proxy += host + ':' + port;
921
+ proxy += host + ":" + port;
779
922
  const agent = new SocksProxyAgent(proxy);
780
923
  const checkData = await new Promise((resolve, reject) => {
781
924
  _get(TIMEZONE_URL, { agent, timeout: 10000 }, (res) => {
782
- let resultResponse = '';
783
- res.on('data', (data) => resultResponse += data);
925
+ let resultResponse = "";
926
+ res.on("data", (data) => (resultResponse += data));
784
927
 
785
- res.on('end', () => {
928
+ res.on("end", () => {
786
929
  let parsedData;
787
930
  try {
788
931
  parsedData = JSON.parse(resultResponse);
@@ -795,15 +938,15 @@ export class GoLogin {
795
938
  body: parsedData,
796
939
  });
797
940
  });
798
- }).on('error', (err) => reject(err));
941
+ }).on("error", (err) => reject(err));
799
942
  });
800
943
 
801
944
  body = checkData.body || {};
802
- if (!body.ip && checkData.statusCode.toString().startsWith('4')) {
945
+ if (!body.ip && checkData.statusCode.toString().startsWith("4")) {
803
946
  throw checkData;
804
947
  }
805
948
 
806
- debug('getTimeZone finish', body.body);
949
+ debug("getTimeZone finish", body.body);
807
950
  this._tz = body;
808
951
 
809
952
  return this._tz.timezone;
@@ -821,13 +964,19 @@ export class GoLogin {
821
964
  });
822
965
 
823
966
  const tz = await this.getTimeZone(this.proxy).catch((e) => {
824
- console.error('Proxy Error. Check it and try again.');
967
+ console.error("Proxy Error. Check it and try again.");
825
968
  throw e;
826
969
  });
827
970
 
828
971
  env.TZ = tz;
829
972
 
830
- let params = [`--proxy-server=${proxy}`, `--user-data-dir=${profile_path}`, '--password-store=basic', `--tz=${tz}`, '--lang=en'];
973
+ let params = [
974
+ `--proxy-server=${proxy}`,
975
+ `--user-data-dir=${profile_path}`,
976
+ "--password-store=basic",
977
+ `--tz=${tz}`,
978
+ "--lang=en",
979
+ ];
831
980
  if (Array.isArray(this.extra_params) && this.extra_params.length) {
832
981
  params = params.concat(this.extra_params);
833
982
  }
@@ -848,7 +997,7 @@ export class GoLogin {
848
997
  const profile_path = this.profilePath();
849
998
 
850
999
  let { proxy } = this;
851
- let proxy_host = '';
1000
+ let proxy_host = "";
852
1001
  if (proxy) {
853
1002
  proxy_host = this.proxy.host;
854
1003
  proxy = `${proxy.mode}://${proxy.host}:${proxy.port}`;
@@ -856,7 +1005,8 @@ export class GoLogin {
856
1005
 
857
1006
  this.port = remote_debugging_port;
858
1007
 
859
- const ORBITA_BROWSER = this.executablePath || this.browserChecker.getOrbitaPath;
1008
+ const ORBITA_BROWSER =
1009
+ this.executablePath || this.browserChecker.getOrbitaPath;
860
1010
  debug(`ORBITA_BROWSER=${ORBITA_BROWSER}`);
861
1011
  const env = {};
862
1012
  Object.keys(process.env).forEach((key) => {
@@ -864,25 +1014,40 @@ export class GoLogin {
864
1014
  });
865
1015
 
866
1016
  const tz = await this.getTimeZone(this.proxy).catch((e) => {
867
- console.error('Proxy Error. Check it and try again.');
1017
+ console.error("Proxy Error. Check it and try again.");
868
1018
  throw e;
869
1019
  });
870
1020
 
871
1021
  env.TZ = tz;
872
1022
 
873
1023
  if (this.vnc_port) {
874
- const script_path = _resolve(__dirname, './run.sh');
875
- debug('RUNNING', script_path, ORBITA_BROWSER, remote_debugging_port, proxy, profile_path, this.vnc_port);
1024
+ const script_path = _resolve(__dirname, "./run.sh");
1025
+ debug(
1026
+ "RUNNING",
1027
+ script_path,
1028
+ ORBITA_BROWSER,
1029
+ remote_debugging_port,
1030
+ proxy,
1031
+ profile_path,
1032
+ this.vnc_port
1033
+ );
876
1034
  execFile(
877
1035
  script_path,
878
- [ORBITA_BROWSER, remote_debugging_port, proxy, profile_path, this.vnc_port, tz],
879
- { env },
1036
+ [
1037
+ ORBITA_BROWSER,
1038
+ remote_debugging_port,
1039
+ proxy,
1040
+ profile_path,
1041
+ this.vnc_port,
1042
+ tz,
1043
+ ],
1044
+ { env }
880
1045
  );
881
1046
  } else {
882
1047
  let params = [
883
1048
  `--remote-debugging-port=${remote_debugging_port}`,
884
1049
  `--user-data-dir=${profile_path}`,
885
- '--password-store=basic',
1050
+ "--password-store=basic",
886
1051
  `--tz=${tz}`,
887
1052
  `--lang=${this.browserLang}`,
888
1053
  ];
@@ -890,28 +1055,33 @@ export class GoLogin {
890
1055
  if (this.extensionPathsToInstall.length) {
891
1056
  if (Array.isArray(this.extra_params) && this.extra_params.length) {
892
1057
  this.extra_params.forEach((param, index) => {
893
- if (!param.includes('--load-extension=')) {
1058
+ if (!param.includes("--load-extension=")) {
894
1059
  return;
895
1060
  }
896
1061
 
897
- const [_, extPathsString] = param.split('=');
898
- const extPathsArray = extPathsString.split(',');
899
- this.extensionPathsToInstall = [...this.extensionPathsToInstall, ...extPathsArray];
1062
+ const [_, extPathsString] = param.split("=");
1063
+ const extPathsArray = extPathsString.split(",");
1064
+ this.extensionPathsToInstall = [
1065
+ ...this.extensionPathsToInstall,
1066
+ ...extPathsArray,
1067
+ ];
900
1068
  this.extra_params.splice(index, 1);
901
1069
  });
902
1070
  }
903
1071
 
904
- params.push(`--load-extension=${this.extensionPathsToInstall.join(',')}`);
1072
+ params.push(
1073
+ `--load-extension=${this.extensionPathsToInstall.join(",")}`
1074
+ );
905
1075
  }
906
1076
 
907
1077
  if (this.fontsMasking) {
908
- let arg = '--font-masking-mode=2';
1078
+ let arg = "--font-masking-mode=2";
909
1079
  if (this.differentOs) {
910
- arg = '--font-masking-mode=3';
1080
+ arg = "--font-masking-mode=3";
911
1081
  }
912
1082
 
913
- if (this.profileOs === 'android' || this.isEmptyFonts) {
914
- arg = '--font-masking-mode=1';
1083
+ if (this.profileOs === "android" || this.isEmptyFonts) {
1084
+ arg = "--font-masking-mode=1";
915
1085
  }
916
1086
 
917
1087
  params.push(arg);
@@ -928,7 +1098,7 @@ export class GoLogin {
928
1098
  }
929
1099
 
930
1100
  if (!this.isFirstSession && this.restoreLastSession) {
931
- params.push('--restore-last-session');
1101
+ params.push("--restore-last-session");
932
1102
  }
933
1103
 
934
1104
  params.push(...new Set(customArgs));
@@ -937,21 +1107,24 @@ export class GoLogin {
937
1107
  const child = execFile(ORBITA_BROWSER, params, { env });
938
1108
  this.processSpawned = child;
939
1109
  // const child = spawn(ORBITA_BROWSER, params, { env, shell: true });
940
- child.stdout.on('data', (data) => debug(data.toString()));
941
- debug('SPAWN CMD', ORBITA_BROWSER, params.join(' '));
1110
+ child.stdout.on("data", (data) => debug(data.toString()));
1111
+ debug("SPAWN CMD", ORBITA_BROWSER, params.join(" "));
942
1112
  }
943
1113
 
944
1114
  if (this.waitWebsocket) {
945
- debug('GETTING WS URL FROM BROWSER');
946
- const data = await requests.get(`http://127.0.0.1:${remote_debugging_port}/json/version`, { json: true });
1115
+ debug("GETTING WS URL FROM BROWSER");
1116
+ const data = await requests.get(
1117
+ `http://127.0.0.1:${remote_debugging_port}/json/version`,
1118
+ { json: true }
1119
+ );
947
1120
 
948
- debug('WS IS', get(data, 'body.webSocketDebuggerUrl', ''));
1121
+ debug("WS IS", get(data, "body.webSocketDebuggerUrl", ""));
949
1122
  this.is_active = true;
950
1123
 
951
- return get(data, 'body.webSocketDebuggerUrl', '');
1124
+ return get(data, "body.webSocketDebuggerUrl", "");
952
1125
  }
953
1126
 
954
- return '';
1127
+ return "";
955
1128
  }
956
1129
 
957
1130
  async createStartupAndSpawnBrowser() {
@@ -961,8 +1134,14 @@ export class GoLogin {
961
1134
  }
962
1135
 
963
1136
  async clearProfileFiles() {
964
- await rimraf(join(this.tmpdir, `gologin_profile_${this.profile_id}`), () => null);
965
- await rimraf(join(this.tmpdir, `gologin_${this.profile_id}_upload.zip`), () => null);
1137
+ await rimraf(
1138
+ join(this.tmpdir, `gologin_profile_${this.profile_id}`),
1139
+ () => null
1140
+ );
1141
+ await rimraf(
1142
+ join(this.tmpdir, `gologin_${this.profile_id}_upload.zip`),
1143
+ () => null
1144
+ );
966
1145
  }
967
1146
 
968
1147
  async stopAndCommit(options, local = false) {
@@ -970,19 +1149,20 @@ export class GoLogin {
970
1149
  return true;
971
1150
  }
972
1151
 
973
- const is_posting = options.posting ||
1152
+ const is_posting =
1153
+ options.posting ||
974
1154
  options.postings || // backward compability
975
1155
  false;
976
1156
 
977
1157
  if (this.uploadCookiesToServer) {
978
- await this.uploadProfileCookiesToServer();
1158
+ const updateResult = await this.uploadProfileDataToServer();
1159
+ this.storageGatewayUrl = updateResult.storageGateway.url;
979
1160
  }
980
1161
 
981
1162
  this.is_stopping = true;
982
1163
  await this.sanitizeProfile();
983
1164
 
984
1165
  if (is_posting) {
985
- await this.saveBookmarksToDb();
986
1166
  await this.commitProfile();
987
1167
  }
988
1168
 
@@ -992,7 +1172,10 @@ export class GoLogin {
992
1172
  await this.clearProfileFiles();
993
1173
 
994
1174
  if (!local) {
995
- await rimraf(join(this.tmpdir, `gologin_${this.profile_id}.zip`), () => null);
1175
+ await rimraf(
1176
+ join(this.tmpdir, `gologin_${this.profile_id}.zip`),
1177
+ () => null
1178
+ );
996
1179
  }
997
1180
 
998
1181
  debug(`PROFILE ${this.profile_id} STOPPED AND CLEAR`);
@@ -1000,22 +1183,50 @@ export class GoLogin {
1000
1183
  return false;
1001
1184
  }
1002
1185
 
1186
+ async uploadProfileDataToServer() {
1187
+ const cookies = await loadCookiesFromFile(this.cookiesFilePath);
1188
+ const bookmarks = await getCurrentProfileBookmarks(this.bookmarksFilePath);
1189
+
1190
+ const body = {
1191
+ cookies,
1192
+ bookmarks,
1193
+ isCookiesEncrypted: true,
1194
+ isStorageGateway: true,
1195
+ };
1196
+
1197
+ const updateResult = await requests
1198
+ .post(
1199
+ `${API_URL}/browser/features/profile/${this.profile_id}/update_after_close`,
1200
+ {
1201
+ headers: {
1202
+ Authorization: `Bearer ${this.access_token}`,
1203
+ "User-Agent": "gologin-api",
1204
+ },
1205
+ json: body,
1206
+ maxAttempts: 3,
1207
+ retryDelay: 2000,
1208
+ timeout: 20 * 1000,
1209
+ }
1210
+ )
1211
+ .catch((e) => {
1212
+ console.log(e);
1213
+
1214
+ return e;
1215
+ });
1216
+
1217
+ return updateResult.body;
1218
+ }
1219
+
1003
1220
  async stopBrowser() {
1004
1221
  if (!this.port) {
1005
- throw new Error('Empty GoLogin port');
1222
+ throw new Error("Empty GoLogin port");
1006
1223
  }
1007
1224
 
1008
- const ls = await spawn('fuser',
1009
- [
1010
- '-k TERM',
1011
- `-n tcp ${this.port}`,
1012
- ],
1013
- {
1014
- shell: true,
1015
- },
1016
- );
1225
+ const ls = await spawn("fuser", ["-k TERM", `-n tcp ${this.port}`], {
1226
+ shell: true,
1227
+ });
1017
1228
 
1018
- debug('browser killed');
1229
+ debug("browser killed");
1019
1230
  }
1020
1231
 
1021
1232
  killBrowser() {
@@ -1025,7 +1236,7 @@ export class GoLogin {
1025
1236
 
1026
1237
  try {
1027
1238
  this.processSpawned.kill();
1028
- debug('browser killed');
1239
+ debug("browser killed");
1029
1240
  } catch (error) {
1030
1241
  console.error(error);
1031
1242
  }
@@ -1064,33 +1275,37 @@ export class GoLogin {
1064
1275
 
1065
1276
  const that = this;
1066
1277
 
1067
- await Promise.all(remove_dirs.map(d => {
1068
- const path_to_remove = `${that.profilePath()}${d}`;
1278
+ await Promise.all(
1279
+ remove_dirs.map((d) => {
1280
+ const path_to_remove = `${that.profilePath()}${d}`;
1069
1281
 
1070
- return new Promise(resolve => {
1071
- debug('DROPPING', path_to_remove);
1072
- rimraf(path_to_remove, { maxBusyTries: 100 }, (e) => {
1073
- // debug('DROPPING RESULT', e);
1074
- resolve();
1282
+ return new Promise((resolve) => {
1283
+ debug("DROPPING", path_to_remove);
1284
+ rimraf(path_to_remove, { maxBusyTries: 100 }, (e) => {
1285
+ // debug('DROPPING RESULT', e);
1286
+ resolve();
1287
+ });
1075
1288
  });
1076
- });
1077
- }));
1289
+ })
1290
+ );
1078
1291
  }
1079
1292
 
1080
1293
  async getProfileDataToUpdate() {
1081
1294
  const zipPath = join(this.tmpdir, `gologin_${this.profile_id}_upload.zip`);
1082
- const zipExists = await access(zipPath).then(() => true).catch(() => false);
1295
+ const zipExists = await access(zipPath)
1296
+ .then(() => true)
1297
+ .catch(() => false);
1083
1298
  if (zipExists) {
1084
1299
  await unlink(zipPath);
1085
1300
  }
1086
1301
 
1087
1302
  await this.sanitizeProfile();
1088
- debug('profile sanitized');
1303
+ debug("profile sanitized");
1089
1304
 
1090
1305
  const profilePath = this.profilePath();
1091
1306
  const fileBuff = await archiveProfile(profilePath);
1092
1307
 
1093
- debug('PROFILE ZIP CREATED', profilePath, zipPath);
1308
+ debug("PROFILE ZIP CREATED", profilePath, zipPath);
1094
1309
 
1095
1310
  return fileBuff;
1096
1311
  }
@@ -1098,25 +1313,23 @@ export class GoLogin {
1098
1313
  async profileExists() {
1099
1314
  const profileResponse = await requests.post(`${API_URL}/browser`, {
1100
1315
  headers: {
1101
- 'Authorization': `Bearer ${this.access_token}`,
1102
- 'User-Agent': 'gologin-api',
1103
- },
1104
- json: {
1105
-
1316
+ Authorization: `Bearer ${this.access_token}`,
1317
+ "User-Agent": "gologin-api",
1106
1318
  },
1319
+ json: {},
1107
1320
  });
1108
1321
 
1109
1322
  if (profileResponse.statusCode !== 200) {
1110
1323
  return false;
1111
1324
  }
1112
1325
 
1113
- debug('profile is', profileResponse.body);
1326
+ debug("profile is", profileResponse.body);
1114
1327
 
1115
1328
  return true;
1116
1329
  }
1117
1330
 
1118
1331
  async getRandomFingerprint(options) {
1119
- let os = 'lin';
1332
+ let os = "lin";
1120
1333
 
1121
1334
  if (options.os) {
1122
1335
  os = options.os;
@@ -1124,13 +1337,13 @@ export class GoLogin {
1124
1337
 
1125
1338
  let url = `${API_URL}/browser/fingerprint?os=${os}`;
1126
1339
  if (options.isM1) {
1127
- url += '&isM1=true';
1340
+ url += "&isM1=true";
1128
1341
  }
1129
1342
 
1130
1343
  const fingerprint = await requests.get(url, {
1131
1344
  headers: {
1132
- 'Authorization': `Bearer ${this.access_token}`,
1133
- 'User-Agent': 'gologin-api',
1345
+ Authorization: `Bearer ${this.access_token}`,
1346
+ "User-Agent": "gologin-api",
1134
1347
  },
1135
1348
  });
1136
1349
 
@@ -1138,17 +1351,17 @@ export class GoLogin {
1138
1351
  }
1139
1352
 
1140
1353
  async create(options) {
1141
- debug('createProfile', options);
1354
+ debug("createProfile", options);
1142
1355
 
1143
1356
  const fingerprint = await this.getRandomFingerprint(options);
1144
- debug('fingerprint=', fingerprint);
1357
+ debug("fingerprint=", fingerprint);
1145
1358
 
1146
1359
  if (fingerprint.statusCode === 500) {
1147
- throw new Error('no valid random fingerprint check os param');
1360
+ throw new Error("no valid random fingerprint check os param");
1148
1361
  }
1149
1362
 
1150
1363
  if (fingerprint.statusCode === 401) {
1151
- throw new Error('invalid token');
1364
+ throw new Error("invalid token");
1152
1365
  }
1153
1366
 
1154
1367
  const { navigator, fonts, webGLMetadata, webRTC } = fingerprint;
@@ -1158,28 +1371,28 @@ export class GoLogin {
1158
1371
  }
1159
1372
 
1160
1373
  navigator.deviceMemory = deviceMemory * 1024;
1161
- webGLMetadata.mode = webGLMetadata.mode === 'noise' ? 'mask' : 'off';
1374
+ webGLMetadata.mode = webGLMetadata.mode === "noise" ? "mask" : "off";
1162
1375
 
1163
1376
  const json = {
1164
1377
  ...fingerprint,
1165
1378
  navigator,
1166
1379
  webGLMetadata,
1167
- browserType: 'chrome',
1168
- name: 'default_name',
1169
- notes: 'auto generated',
1380
+ browserType: "chrome",
1381
+ name: "default_name",
1382
+ notes: "auto generated",
1170
1383
  fonts: {
1171
1384
  families: fonts,
1172
1385
  },
1173
1386
  webRTC: {
1174
1387
  ...webRTC,
1175
- mode: 'alerted',
1388
+ mode: "alerted",
1176
1389
  },
1177
1390
  };
1178
1391
 
1179
1392
  const user_agent = options.navigator?.userAgent;
1180
1393
  const orig_user_agent = json.navigator.userAgent;
1181
1394
  Object.keys(options).forEach((key) => {
1182
- if (typeof json[key] === 'object') {
1395
+ if (typeof json[key] === "object") {
1183
1396
  json[key] = { ...json[key], ...options[key] };
1184
1397
 
1185
1398
  return;
@@ -1188,24 +1401,30 @@ export class GoLogin {
1188
1401
  json[key] = options[key];
1189
1402
  });
1190
1403
 
1191
- if (user_agent === 'random') {
1404
+ if (user_agent === "random") {
1192
1405
  json.navigator.userAgent = orig_user_agent;
1193
1406
  }
1194
1407
 
1195
1408
  const response = await requests.post(`${API_URL}/browser`, {
1196
1409
  headers: {
1197
- 'Authorization': `Bearer ${this.access_token}`,
1198
- 'User-Agent': 'gologin-api',
1410
+ Authorization: `Bearer ${this.access_token}`,
1411
+ "User-Agent": "gologin-api",
1199
1412
  },
1200
1413
  json,
1201
1414
  });
1202
1415
 
1203
1416
  if (response.statusCode === 400) {
1204
- throw new Error(`gologin failed account creation with status code, ${response.statusCode} DATA ${JSON.stringify(response.body.message)}`);
1417
+ throw new Error(
1418
+ `gologin failed account creation with status code, ${
1419
+ response.statusCode
1420
+ } DATA ${JSON.stringify(response.body.message)}`
1421
+ );
1205
1422
  }
1206
1423
 
1207
1424
  if (response.statusCode === 500) {
1208
- throw new Error(`gologin failed account creation with status code, ${response.statusCode}`);
1425
+ throw new Error(
1426
+ `gologin failed account creation with status code, ${response.statusCode}`
1427
+ );
1209
1428
  }
1210
1429
 
1211
1430
  debug(JSON.stringify(response.body));
@@ -1214,21 +1433,27 @@ export class GoLogin {
1214
1433
  }
1215
1434
 
1216
1435
  async createCustom(options) {
1217
- debug('createCustomProfile', options);
1436
+ debug("createCustomProfile", options);
1218
1437
  const response = await requests.post(`${API_URL}/browser/custom`, {
1219
1438
  headers: {
1220
- 'Authorization': `Bearer ${this.access_token}`,
1221
- 'User-Agent': 'gologin-api',
1439
+ Authorization: `Bearer ${this.access_token}`,
1440
+ "User-Agent": "gologin-api",
1222
1441
  },
1223
1442
  json: options,
1224
1443
  });
1225
1444
 
1226
1445
  if (response.statusCode === 400) {
1227
- throw new Error(`gologin failed account creation with status code, ${response.statusCode} DATA ${JSON.stringify(response.body.message)}`);
1446
+ throw new Error(
1447
+ `gologin failed account creation with status code, ${
1448
+ response.statusCode
1449
+ } DATA ${JSON.stringify(response.body.message)}`
1450
+ );
1228
1451
  }
1229
1452
 
1230
1453
  if (response.statusCode === 500) {
1231
- throw new Error(`gologin failed account creation with status code, ${response.statusCode}`);
1454
+ throw new Error(
1455
+ `gologin failed account creation with status code, ${response.statusCode}`
1456
+ );
1232
1457
  }
1233
1458
 
1234
1459
  debug(JSON.stringify(response));
@@ -1236,31 +1461,32 @@ export class GoLogin {
1236
1461
  return response.body.id;
1237
1462
  }
1238
1463
 
1239
- async quickCreateProfile(name = '') {
1464
+ async quickCreateProfile(name = "") {
1240
1465
  const osInfo = await getOsAdvanced();
1241
1466
  const { os, osSpec } = osInfo;
1242
- const resultName = name || 'api-generated';
1243
-
1244
- return requests.post(`${API_URL}/browser/quick`, {
1245
- headers: {
1246
- 'Authorization': `Bearer ${this.access_token}`,
1247
- 'User-Agent': 'gologin-api',
1248
- },
1249
- json: {
1250
- os,
1251
- osSpec,
1252
- name: resultName,
1253
- },
1254
- })
1255
- .then(res => res.body);
1467
+ const resultName = name || "api-generated";
1468
+
1469
+ return requests
1470
+ .post(`${API_URL}/browser/quick`, {
1471
+ headers: {
1472
+ Authorization: `Bearer ${this.access_token}`,
1473
+ "User-Agent": "gologin-api",
1474
+ },
1475
+ json: {
1476
+ os,
1477
+ osSpec,
1478
+ name: resultName,
1479
+ },
1480
+ })
1481
+ .then((res) => res.body);
1256
1482
  }
1257
1483
 
1258
1484
  async delete(pid) {
1259
1485
  const profile_id = pid || this.profile_id;
1260
1486
  await requests.delete(`${API_URL}/browser/${profile_id}`, {
1261
1487
  headers: {
1262
- 'Authorization': `Bearer ${this.access_token}`,
1263
- 'User-Agent': 'gologin-api',
1488
+ Authorization: `Bearer ${this.access_token}`,
1489
+ "User-Agent": "gologin-api",
1264
1490
  },
1265
1491
  });
1266
1492
  }
@@ -1275,20 +1501,22 @@ export class GoLogin {
1275
1501
  });
1276
1502
  }
1277
1503
 
1278
- Object.keys(options).filter(el => el !== 'navigator').forEach((el) => {
1279
- profile[el] = options[el];
1280
- });
1504
+ Object.keys(options)
1505
+ .filter((el) => el !== "navigator")
1506
+ .forEach((el) => {
1507
+ profile[el] = options[el];
1508
+ });
1281
1509
 
1282
- debug('update profile', profile);
1510
+ debug("update profile", profile);
1283
1511
  const response = await requests.put(`${API_URL}/browser/${options.id}`, {
1284
1512
  json: profile,
1285
1513
  headers: {
1286
- 'Authorization': `Bearer ${this.access_token}`,
1287
- 'User-Agent': 'gologin-api',
1514
+ Authorization: `Bearer ${this.access_token}`,
1515
+ "User-Agent": "gologin-api",
1288
1516
  },
1289
1517
  });
1290
1518
 
1291
- debug('response', JSON.stringify(response.body));
1519
+ debug("response", JSON.stringify(response.body));
1292
1520
 
1293
1521
  return response.body;
1294
1522
  }
@@ -1320,9 +1548,13 @@ export class GoLogin {
1320
1548
  }
1321
1549
 
1322
1550
  async postCookies(profileId, cookies) {
1323
- const formattedCookies = cookies.map(cookie => {
1324
- if (!['no_restriction', 'lax', 'strict', 'unspecified'].includes(cookie.sameSite)) {
1325
- cookie.sameSite = 'unspecified';
1551
+ const formattedCookies = cookies.map((cookie) => {
1552
+ if (
1553
+ !["no_restriction", "lax", "strict", "unspecified"].includes(
1554
+ cookie.sameSite
1555
+ )
1556
+ ) {
1557
+ cookie.sameSite = "unspecified";
1326
1558
  }
1327
1559
 
1328
1560
  return cookie;
@@ -1339,7 +1571,11 @@ export class GoLogin {
1339
1571
  return response.body;
1340
1572
  }
1341
1573
 
1342
- return { status: 'failure', status_code: response.statusCode, body: response.body };
1574
+ return {
1575
+ status: "failure",
1576
+ status_code: response.statusCode,
1577
+ body: response.body,
1578
+ };
1343
1579
  }
1344
1580
 
1345
1581
  async getCookies(profileId) {
@@ -1353,12 +1589,12 @@ export class GoLogin {
1353
1589
  }
1354
1590
 
1355
1591
  getCookiePath(defaultFilePath) {
1356
- let primary = join(defaultFilePath, 'Cookies');
1357
- let secondary = join(defaultFilePath, 'Network', 'Cookies');
1592
+ let primary = join(defaultFilePath, "Cookies");
1593
+ let secondary = join(defaultFilePath, "Network", "Cookies");
1358
1594
 
1359
1595
  if (!existsSync(primary)) {
1360
- primary = join(defaultFilePath, 'Network', 'Cookies');
1361
- secondary = join(defaultFilePath, 'Cookies');
1596
+ primary = join(defaultFilePath, "Network", "Cookies");
1597
+ secondary = join(defaultFilePath, "Cookies");
1362
1598
  }
1363
1599
 
1364
1600
  return { primary, secondary };
@@ -1373,15 +1609,21 @@ export class GoLogin {
1373
1609
  return;
1374
1610
  }
1375
1611
 
1376
- const resultCookies = cookies.map((el) => ({ ...el, value: Buffer.from(el.value) }));
1612
+ const resultCookies = cookies.map((el) => ({
1613
+ ...el,
1614
+ value: Buffer.from(el.value),
1615
+ }));
1377
1616
  let db;
1378
1617
  const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
1379
1618
 
1380
- const defaultFilePath = _resolve(profilePath, 'Default');
1619
+ const defaultFilePath = _resolve(profilePath, "Default");
1381
1620
  const cookiesPaths = this.getCookiePath(defaultFilePath);
1382
1621
  try {
1383
1622
  db = await getDB(cookiesPaths.primary, false);
1384
- const cookiesToInsert = await getUniqueCookies(resultCookies, cookiesPaths.primary);
1623
+ const cookiesToInsert = await getUniqueCookies(
1624
+ resultCookies,
1625
+ cookiesPaths.primary
1626
+ );
1385
1627
  if (cookiesToInsert.length) {
1386
1628
  const chunckInsertValues = getChunckedInsertValues(cookiesToInsert);
1387
1629
  for (const [query, queryParams] of chunckInsertValues) {
@@ -1393,8 +1635,10 @@ export class GoLogin {
1393
1635
  } catch (error) {
1394
1636
  console.log(error.message);
1395
1637
  } finally {
1396
- db && await db.close();
1397
- await copyFile(cookiesPaths.primary, cookiesPaths.secondary).catch(console.log);
1638
+ db && (await db.close());
1639
+ await copyFile(cookiesPaths.primary, cookiesPaths.secondary).catch(
1640
+ console.log
1641
+ );
1398
1642
  }
1399
1643
  }
1400
1644
 
@@ -1408,9 +1652,15 @@ export class GoLogin {
1408
1652
  }
1409
1653
 
1410
1654
  async saveBookmarksToDb() {
1411
- const bookmarksData = await getCurrentProfileBookmarks(this.bookmarksFilePath);
1655
+ const bookmarksData = await getCurrentProfileBookmarks(
1656
+ this.bookmarksFilePath
1657
+ );
1412
1658
  const bookmarks = bookmarksData.roots || {};
1413
- await updateProfileBookmarks([this.profile_id], this.access_token, bookmarks);
1659
+ await updateProfileBookmarks(
1660
+ [this.profile_id],
1661
+ this.access_token,
1662
+ bookmarks
1663
+ );
1414
1664
  }
1415
1665
 
1416
1666
  async start() {
@@ -1418,11 +1668,16 @@ export class GoLogin {
1418
1668
  await this.checkBrowser();
1419
1669
  }
1420
1670
 
1421
- const ORBITA_BROWSER = this.executablePath || this.browserChecker.getOrbitaPath;
1671
+ const ORBITA_BROWSER =
1672
+ this.executablePath || this.browserChecker.getOrbitaPath;
1422
1673
 
1423
- const orbitaBrowserExists = await access(ORBITA_BROWSER).then(() => true).catch(() => false);
1674
+ const orbitaBrowserExists = await access(ORBITA_BROWSER)
1675
+ .then(() => true)
1676
+ .catch(() => false);
1424
1677
  if (!orbitaBrowserExists) {
1425
- throw new Error(`Orbita browser is not exists on path ${ORBITA_BROWSER}, check executablePath param`);
1678
+ throw new Error(
1679
+ `Orbita browser is not exists on path ${ORBITA_BROWSER}, check executablePath param`
1680
+ );
1426
1681
  }
1427
1682
 
1428
1683
  await this.createStartup();
@@ -1430,7 +1685,7 @@ export class GoLogin {
1430
1685
  const wsUrl = await this.spawnBrowser();
1431
1686
  this.setActive(true);
1432
1687
 
1433
- return { status: 'success', wsUrl };
1688
+ return { status: "success", wsUrl };
1434
1689
  }
1435
1690
 
1436
1691
  async startLocal() {
@@ -1439,11 +1694,11 @@ export class GoLogin {
1439
1694
  const wsUrl = await this.spawnBrowser();
1440
1695
  this.setActive(true);
1441
1696
 
1442
- return { status: 'success', wsUrl };
1697
+ return { status: "success", wsUrl };
1443
1698
  }
1444
1699
 
1445
1700
  async stop() {
1446
- await new Promise(resolve => setTimeout(resolve, 500));
1701
+ await new Promise((resolve) => setTimeout(resolve, 500));
1447
1702
 
1448
1703
  await this.stopAndCommit({ posting: true }, false);
1449
1704
  }
@@ -1456,10 +1711,10 @@ export class GoLogin {
1456
1711
  async waitDebuggingUrl(delay_ms, try_count = 0, remoteOrbitaUrl) {
1457
1712
  await delay(delay_ms);
1458
1713
  const url = `${remoteOrbitaUrl}/json/version`;
1459
- console.log('try_count=', try_count, 'url=', url);
1714
+ console.log("try_count=", try_count, "url=", url);
1460
1715
  const response = await requests.get(url);
1461
- let wsUrl = '';
1462
- console.log('response', response.body);
1716
+ let wsUrl = "";
1717
+ console.log("response", response.body);
1463
1718
 
1464
1719
  if (!response.body) {
1465
1720
  return wsUrl;
@@ -1473,23 +1728,36 @@ export class GoLogin {
1473
1728
  return this.waitDebuggingUrl(delay_ms, try_count + 1, remoteOrbitaUrl);
1474
1729
  }
1475
1730
 
1476
- return { status: 'failure', wsUrl, message: 'Check proxy settings', 'profile_id': this.profile_id };
1731
+ return {
1732
+ status: "failure",
1733
+ wsUrl,
1734
+ message: "Check proxy settings",
1735
+ profile_id: this.profile_id,
1736
+ };
1477
1737
  }
1478
1738
 
1479
- const remoteOrbitaUrlWithoutProtocol = remoteOrbitaUrl.replace('https://', '');
1480
- wsUrl = wsUrl.replace('ws://', 'wss://').replace('127.0.0.1', remoteOrbitaUrlWithoutProtocol);
1739
+ const remoteOrbitaUrlWithoutProtocol = remoteOrbitaUrl.replace(
1740
+ "https://",
1741
+ ""
1742
+ );
1743
+ wsUrl = wsUrl
1744
+ .replace("ws://", "wss://")
1745
+ .replace("127.0.0.1", remoteOrbitaUrlWithoutProtocol);
1481
1746
 
1482
1747
  return wsUrl;
1483
1748
  }
1484
1749
 
1485
1750
  async stopRemote() {
1486
1751
  debug(`stopRemote ${this.profile_id}`);
1487
- const profileResponse = await requests.delete(`${API_URL}/browser/${this.profile_id}/web`, {
1488
- headers: {
1489
- 'Authorization': `Bearer ${this.access_token}`,
1490
- 'User-Agent': 'gologin-api',
1491
- },
1492
- });
1752
+ const profileResponse = await requests.delete(
1753
+ `${API_URL}/browser/${this.profile_id}/web`,
1754
+ {
1755
+ headers: {
1756
+ Authorization: `Bearer ${this.access_token}`,
1757
+ "User-Agent": "gologin-api",
1758
+ },
1759
+ }
1760
+ );
1493
1761
 
1494
1762
  console.log(`stopRemote ${profileResponse.body}`);
1495
1763
  if (profileResponse.body) {
@@ -1499,16 +1767,24 @@ export class GoLogin {
1499
1767
 
1500
1768
  getAvailableFonts() {
1501
1769
  return fontsCollection
1502
- .filter(elem => elem.fileNames)
1503
- .map(elem => elem.name);
1770
+ .filter((elem) => elem.fileNames)
1771
+ .map((elem) => elem.name);
1504
1772
  }
1505
1773
 
1506
1774
  async changeProfileResolution(resolution) {
1507
- return updateProfileResolution(this.profile_id, this.access_token, resolution);
1775
+ return updateProfileResolution(
1776
+ this.profile_id,
1777
+ this.access_token,
1778
+ resolution
1779
+ );
1508
1780
  }
1509
1781
 
1510
1782
  async changeProfileUserAgent(userAgent) {
1511
- return updateProfileUserAgent(this.profile_id, this.access_token, userAgent);
1783
+ return updateProfileUserAgent(
1784
+ this.profile_id,
1785
+ this.access_token,
1786
+ userAgent
1787
+ );
1512
1788
  }
1513
1789
 
1514
1790
  async changeProfileProxy(proxyData) {