gologin 1.0.21 → 1.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -32,7 +32,15 @@ const GoLogin = require('gologin');
32
32
  profile_id: 'yU0Pr0f1leiD',
33
33
  });
34
34
 
35
- const { status, wsUrl } = await GL.start();
35
+ const { status, wsUrl } = await GL.start().catch((e) => {
36
+ console.trace(e);
37
+ return { status: 'failure' };
38
+ });
39
+
40
+ if (status !== 'success') {
41
+ console.log('Invalid status');
42
+ return;
43
+ }
36
44
 
37
45
  const browser = await puppeteer.connect({
38
46
  browserWSEndpoint: wsUrl.toString(),
@@ -29,18 +29,18 @@ class CookiesManager {
29
29
  const chunckedCookiesArr = this.chunk(cookiesArr, MAX_SQLITE_VARIABLES);
30
30
 
31
31
  return chunckedCookiesArr.map((cookies) => {
32
- const queryPlaceholders = cookies.map(() => '(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)').join(', ');
33
- const query = `insert or replace into cookies (creation_utc, host_key, name, value, path, expires_utc, is_secure, is_httponly, last_access_utc, is_persistent, encrypted_value, samesite, has_expires) values ${queryPlaceholders}`;
32
+ const queryPlaceholders = cookies.map(() => '(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)').join(', ');
33
+ const query = `insert or replace into cookies (creation_utc, top_frame_site_key, host_key, name, value, path, expires_utc, is_secure, is_httponly, last_access_utc, is_persistent, encrypted_value, samesite, has_expires) values ${queryPlaceholders}`;
34
34
  const queryParams = cookies.flatMap((cookie) => {
35
35
  const creationDate = cookie.creationDate ? cookie.creationDate : this.unixToLDAP(todayUnix);
36
- const encryptedValue = cookie.value;
36
+ let expirationDate = cookie.session ? 0 : this.unixToLDAP(cookie.expirationDate);
37
+ const encryptedValue = Buffer.concat([Buffer.from('v11'), Buffer.from(encrypt(cookie.value), 'binary')]);
37
38
  const samesite = Object.keys(SAME_SITE).find((key) => SAME_SITE[key] === (cookie.sameSite || '-1'));
38
39
  const isSecure =
39
40
  cookie.name.startsWith('__Host-') || cookie.name.startsWith('__Secure-') ? 1 : Number(cookie.secure);
40
41
  let isPersistent = [undefined, null].includes(cookie.session)
41
42
  ? Number(expirationDate !== 0)
42
43
  : Number(!cookie.session);
43
- let expirationDate = cookie.session ? 0 : this.unixToLDAP(cookie.expirationDate);
44
44
 
45
45
  if (/^(\.)?mail.google.com$/.test(cookie.domain) && cookie.name === 'COMPASS') {
46
46
  expirationDate = 0;
@@ -49,6 +49,7 @@ class CookiesManager {
49
49
 
50
50
  return [
51
51
  creationDate,
52
+ '', // top_frame_site_key
52
53
  cookie.domain,
53
54
  cookie.name,
54
55
  '', // value
package/example.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const puppeteer = require('puppeteer-core');
2
- const GoLogin = require('gologin');
2
+ const GoLogin = require('./gologin');
3
3
 
4
4
  (async () => {
5
5
  const GL = new GoLogin({
@@ -7,7 +7,16 @@ const GoLogin = require('gologin');
7
7
  profile_id: 'yU0Pr0f1leiD',
8
8
  });
9
9
 
10
- const { status, wsUrl } = await GL.start();
10
+ const { status, wsUrl } = await GL.start().catch((e) => {
11
+ console.trace(e);
12
+ return { status: 'failure' };
13
+ });
14
+
15
+ if (status !== 'success') {
16
+ console.log('Invalid status');
17
+ return;
18
+ }
19
+
11
20
  const browser = await puppeteer.connect({
12
21
  browserWSEndpoint: wsUrl.toString(),
13
22
  ignoreHTTPSErrors: true,
@@ -13,6 +13,13 @@ const GoLogin = require('../gologin');
13
13
  });
14
14
 
15
15
  const page = await browser.newPage();
16
+ const viewPort = GL.getViewPort();
17
+ await page.setViewport({ width: Math.round(viewPort.width * 0.994), height: Math.round(viewPort.height * 0.92) });
18
+ const session = await page.target().createCDPSession();
19
+ const { windowId } = await session.send('Browser.getWindowForTarget');
20
+ await session.send('Browser.setWindowBounds', { windowId, bounds: viewPort });
21
+ await session.detach();
22
+
16
23
  await page.goto('https://www.amazon.com/-/dp/B0771V1JZX');
17
24
  const content = await page.content();
18
25
  const matchData = content.match(/'initial': (.*)}/);
@@ -15,7 +15,7 @@ const delay = ms => new Promise(res => setTimeout(res, ms));
15
15
  os: 'mac',
16
16
  navigator: {
17
17
  language: 'enUS',
18
- userAgent: 'MyUserAgent',
18
+ userAgent: 'random', // get random user agent for selected os
19
19
  resolution: '1024x768',
20
20
  platform: 'mac',
21
21
  }
@@ -31,6 +31,6 @@ const delay = ms => new Promise(res => setTimeout(res, ms));
31
31
  const profile = await GL.getProfile(profile_id);
32
32
 
33
33
  console.log('new profile name=', profile.name);
34
-
34
+
35
35
  //await GL.delete(profile_id);
36
36
  })();
@@ -0,0 +1,64 @@
1
+ const puppeteer = require('puppeteer-core');
2
+ const GoLogin = require('../gologin');
3
+
4
+ const delay = ms => new Promise(res => setTimeout(res, ms));
5
+
6
+ (async () =>{
7
+ const GL = new GoLogin({
8
+ token: 'yU0token',
9
+ });
10
+
11
+ const profile_id = await GL.create({
12
+ name: 'profile_gmail',
13
+ os: 'lin',
14
+ navigator: {
15
+ userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36',
16
+ resolution: '1280x720',
17
+ language: 'en-GB,en-US;q=0.9,en;q=0.8',
18
+ platform: 'Linux x86_64',
19
+ hardwareConcurrency: 8,
20
+ deviceMemory: 8,
21
+ maxTouchPoints: 5,
22
+ },
23
+ proxy: {
24
+ mode: 'http',
25
+ host: 'proxy_host',
26
+ port: 'proxy_port',
27
+ username: 'proxy_username',
28
+ password: 'proxy_password',
29
+ }
30
+ });
31
+
32
+ console.log('profile id=', profile_id);
33
+ GL.setProfileId(profile_id);
34
+
35
+ const {status, wsUrl} = await GL.start();
36
+ const browser = await puppeteer.connect({
37
+ browserWSEndpoint: wsUrl.toString(),
38
+ ignoreHTTPSErrors: true,
39
+ });
40
+
41
+ const page = await browser.newPage();
42
+
43
+ const viewPort = GL.getViewPort();
44
+ await page.setViewport({ width: Math.round(viewPort.width * 0.994), height: Math.round(viewPort.height * 0.92) });
45
+ const session = await page.target().createCDPSession();
46
+ const { windowId } = await session.send('Browser.getWindowForTarget');
47
+ await session.send('Browser.setWindowBounds', { windowId, bounds: viewPort });
48
+ await session.detach();
49
+
50
+ await page.goto('https://gmail.com');
51
+ await delay(1000);
52
+ await page.goto('https://accounts.google.com/signup/v2?service=mail&continue=https%3A%2F%2Fmail.google.com%2Fmail%2F&flowName=GlifWebSignIn&flowEntry=SignUp');
53
+ await delay(3000);
54
+ await page.type('#firstName', 'first_name', { delay: 100 });
55
+ await page.type('#lastName', 'last_name', { delay: 100 });
56
+ await page.type('#username', 'username', { delay: 100 });
57
+ await page.type('[name=Passwd]', 'pa$$w0rd', { delay: 100 });
58
+ await page.type('[name=ConfirmPasswd]', 'pa$$w0rd', { delay: 100 });
59
+ await page.click('#accountDetailsNext > div > button');
60
+
61
+ await delay(60000)
62
+ await browser.close();
63
+ await GL.stop();
64
+ })();
@@ -15,7 +15,7 @@ const GoLogin = require('../gologin');
15
15
  });
16
16
 
17
17
  const page = await browser.newPage();
18
- await page.goto('https://myip.gologin.app/mini');
18
+ await page.goto('https://myip.link');
19
19
  console.log(await page.content());
20
20
  await browser.close();
21
21
  await GL.stopLocal({posting: false});
@@ -0,0 +1,41 @@
1
+ const puppeteer = require('puppeteer-core');
2
+ const GoLogin = require('../gologin');
3
+
4
+ const delay = ms => new Promise(res => setTimeout(res, ms));
5
+
6
+ (async () =>{
7
+ const GL = new GoLogin({
8
+ token: 'yU0token',
9
+ profile_id: 'yU0Pr0f1leiD',
10
+ timezone: {
11
+ ip:'1.1.1.1',
12
+ timezone:'Europe/Amsterdam',
13
+ accuracy:100,
14
+ ll: ['52.3759','4.8975'],
15
+ country: 'NL',
16
+ city: 'Amsterdam',
17
+ stateProv:'',
18
+ }
19
+ });
20
+
21
+ const {status, wsUrl} = await GL.start();
22
+ const browser = await puppeteer.connect({
23
+ browserWSEndpoint: wsUrl.toString(),
24
+ ignoreHTTPSErrors: true,
25
+ });
26
+
27
+ const page = await browser.newPage();
28
+
29
+ const viewPort = GL.getViewPort();
30
+ await page.setViewport({ width: Math.round(viewPort.width * 0.994), height: Math.round(viewPort.height * 0.92) });
31
+ const session = await page.target().createCDPSession();
32
+ const { windowId } = await session.send('Browser.getWindowForTarget');
33
+ await session.send('Browser.setWindowBounds', { windowId, bounds: viewPort });
34
+ await session.detach();
35
+
36
+ await page.goto('https://myip.link');
37
+
38
+ await delay(60000)
39
+ await browser.close();
40
+ await GL.stop();
41
+ })();
package/gologin.js CHANGED
@@ -48,7 +48,8 @@ class GoLogin {
48
48
  this.writeCookesFromServer = options.writeCookesFromServer || true;
49
49
  this.cookiesFilePath = path.join(os.tmpdir(), `gologin_profile_${this.profile_id}`, 'Default', 'Cookies');
50
50
  this.remote_debugging_port = options.remote_debugging_port || 0;
51
-
51
+ this.timezone = options.timezone;
52
+
52
53
  if (options.tmpdir) {
53
54
  this.tmpdir = options.tmpdir;
54
55
  if (!fs.existsSync(this.tmpdir)) {
@@ -81,10 +82,10 @@ class GoLogin {
81
82
  }
82
83
  }
83
84
 
84
- async getNewFingerPrint() {
85
+ async getNewFingerPrint(os) {
85
86
  debug('GETTING FINGERPRINT');
86
87
 
87
- const fpResponse = await requests.get(`${API_URL}/browser/fingerprint?os=lin`, {
88
+ const fpResponse = await requests.get(`${API_URL}/browser/fingerprint?os=${os}`, {
88
89
  json: true,
89
90
  headers: {
90
91
  'Authorization': `Bearer ${this.access_token}`,
@@ -123,6 +124,11 @@ class GoLogin {
123
124
  if (profileResponse.statusCode !== 200) {
124
125
  throw new Error(`Gologin /browser/${id} response error ${profileResponse.statusCode}`);
125
126
  }
127
+
128
+ if(profileResponse.statusCode == 401){
129
+ throw new Error("invalid token");
130
+ }
131
+
126
132
  return JSON.parse(profileResponse.body);
127
133
  }
128
134
 
@@ -356,7 +362,10 @@ class GoLogin {
356
362
  }
357
363
  this.proxy = proxy;
358
364
 
359
- await this.getTimeZone(proxy);
365
+ await this.getTimeZone(proxy).catch((e) => {
366
+ console.error('Proxy Error. Check it and try again.');
367
+ throw e;
368
+ });
360
369
 
361
370
  const [latitude, longitude] = this._tz.ll;
362
371
  const accuracy = this._tz.accuracy;
@@ -488,6 +497,12 @@ class GoLogin {
488
497
  }
489
498
 
490
499
  async getTimeZone(proxy) {
500
+ if(this.timezone){
501
+ debug('getTimeZone from options', this.timezone);
502
+ this._tz = this.timezone;
503
+ return this._tz.timezone;
504
+ }
505
+
491
506
  let data = null;
492
507
  if (proxy) {
493
508
  if (proxy.mode.includes('socks')) {
@@ -496,9 +511,9 @@ class GoLogin {
496
511
 
497
512
  const proxyUrl = `${proxy.mode}://${proxy.username}:${proxy.password}@${proxy.host}:${proxy.port}`;
498
513
  debug('getTimeZone start https://time.gologin.com', proxyUrl);
499
- data = await requests.get('https://time.gologin.com', { proxy: proxyUrl });
514
+ data = await requests.get('https://time.gologin.com', { proxy: proxyUrl, timeout: 10 * 1000, maxAttempts: 2 });
500
515
  } else {
501
- data = await requests.get('https://time.gologin.com');
516
+ data = await requests.get('https://time.gologin.com', { timeout: 10 * 1000, maxAttempts: 2 });
502
517
  }
503
518
  debug('getTimeZone finish', data.body);
504
519
  this._tz = JSON.parse(data.body);
@@ -543,6 +558,7 @@ class GoLogin {
543
558
  }).on('error', (err) => reject(err));
544
559
  });
545
560
 
561
+ console.log('checkData:', checkData);
546
562
  body = checkData.body || {};
547
563
  if (!body.ip && checkData.statusCode.toString().startsWith('4')) {
548
564
  throw checkData;
@@ -563,7 +579,10 @@ class GoLogin {
563
579
  Object.keys(process.env).forEach((key) => {
564
580
  env[key] = process.env[key];
565
581
  });
566
- const tz = await this.getTimeZone(this.proxy);
582
+ const tz = await this.getTimeZone(this.proxy).catch((e) => {
583
+ console.error('Proxy Error. Check it and try again.');
584
+ throw e;
585
+ });
567
586
  env['TZ'] = tz;
568
587
 
569
588
  let params = [`--proxy-server=${proxy}`, `--user-data-dir=${profile_path}`, `--password-store=basic`, `--tz=${tz}`, `--lang=en`]
@@ -579,7 +598,6 @@ class GoLogin {
579
598
  }
580
599
 
581
600
  async spawnBrowser() {
582
-
583
601
  let remote_debugging_port = this.remote_debugging_port;
584
602
  if(!remote_debugging_port){
585
603
  remote_debugging_port = await this.getRandomPort();
@@ -602,7 +620,10 @@ class GoLogin {
602
620
  Object.keys(process.env).forEach((key) => {
603
621
  env[key] = process.env[key];
604
622
  });
605
- const tz = await this.getTimeZone(this.proxy);
623
+ const tz = await this.getTimeZone(this.proxy).catch((e) => {
624
+ console.error('Proxy Error. Check it and try again.');
625
+ throw e;
626
+ });
606
627
  env['TZ'] = tz;
607
628
 
608
629
  if (this.vnc_port) {
@@ -825,6 +846,15 @@ class GoLogin {
825
846
  debug('createProfile', options);
826
847
 
827
848
  const fingerprint = await this.getRandomFingerprint(options);
849
+ debug("fingerprint=", fingerprint)
850
+
851
+ if(fingerprint.statusCode == 500){
852
+ throw new Error("no valid random fingerprint check os param");
853
+ }
854
+
855
+ if(fingerprint.statusCode == 401){
856
+ throw new Error("invalid token");
857
+ }
828
858
 
829
859
  const { navigator, fonts, webGLMetadata, webRTC } = fingerprint;
830
860
  let deviceMemory = navigator.deviceMemory || 2;
@@ -849,9 +879,12 @@ class GoLogin {
849
879
  mode: 'alerted',
850
880
  },
851
881
  };
852
-
882
+ let user_agent = options.navigator?.userAgent;
883
+ let orig_user_agent = json.navigator.userAgent;
853
884
  Object.keys(options).map((e)=>{ json[e] = options[e] });
854
-
885
+ if(user_agent=='random'){
886
+ json.navigator.userAgent = orig_user_agent;
887
+ }
855
888
  // console.log('profileOptions', json);
856
889
 
857
890
  const response = await requests.post(`${API_URL}/browser`, {
@@ -861,7 +894,15 @@ class GoLogin {
861
894
  },
862
895
  json,
863
896
  });
864
- // console.log(JSON.stringify(response.body));
897
+
898
+ if(response.body.statusCode==400){
899
+ throw new Error(`gologin failed account creation with status code, ${data.statusCode} DATA ${JSON.stringify(response.body.message)}`);
900
+ }
901
+
902
+ if(response.body.statusCode==500){
903
+ throw new Error(`gologin failed account creation with status code, ${data.statusCode}`);
904
+ }
905
+ debug(JSON.stringify(response.body));
865
906
  return response.body.id;
866
907
  }
867
908
 
@@ -1060,6 +1101,11 @@ class GoLogin {
1060
1101
  'Authorization': `Bearer ${this.access_token}`
1061
1102
  }
1062
1103
  });
1104
+
1105
+ if(profileResponse.statusCode == 401){
1106
+ throw new Error("invalid token");
1107
+ }
1108
+
1063
1109
  debug('profileResponse', profileResponse.statusCode, profileResponse.body);
1064
1110
  if (profileResponse.statusCode !== 202) {
1065
1111
  return {'status': 'failure', 'code': profileResponse.statusCode};
@@ -1067,8 +1113,6 @@ class GoLogin {
1067
1113
 
1068
1114
  if (profileResponse.body === 'ok') {
1069
1115
  let wsUrl = await this.waitDebuggingUrl(delay_ms);
1070
- // const wsUrl = `wss://${this.profile_id}.orbita.gologin.app`
1071
- // const wsUrl = `wss://${this.profile_id}.orbita.gologin.com`
1072
1116
  return { 'status': 'success', wsUrl }
1073
1117
  }
1074
1118
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gologin",
3
- "version": "1.0.21",
3
+ "version": "1.0.25",
4
4
  "description": "A high-level API to control Orbita browser over GoLogin API",
5
5
  "main": "./gologin.js",
6
6
  "repository": {
@@ -28,5 +28,5 @@ chrome.setDefaultService(new chrome.ServiceBuilder('./chromedriver').build());
28
28
  .setChromeOptions(chromeOptions)
29
29
  .build();
30
30
 
31
- await driver.get('https://myip.gologin.app/mini')
31
+ await driver.get('https://myip.link')
32
32
  })();
@@ -0,0 +1,30 @@
1
+ from gologin import GoLogin
2
+
3
+
4
+ gl = GoLogin({
5
+ "token": "yU0token",
6
+ })
7
+
8
+ profile_id = gl.create({
9
+ "name": 'profile_mac',
10
+ "os": 'mac',
11
+ "navigator": {
12
+ "language": 'enUS',
13
+ "userAgent": 'MyUserAgent',
14
+ "resolution": '1024x768',
15
+ "platform": 'mac',
16
+ }
17
+ });
18
+
19
+ print('profile id=', profile_id);
20
+
21
+ gl.update({
22
+ "id": profile_id,
23
+ "name": 'profile_mac2',
24
+ });
25
+
26
+ profile = gl.getProfile(profile_id);
27
+
28
+ print('new profile name=', profile.get("name"));
29
+
30
+ gl.delete(profile_id)
@@ -100,7 +100,10 @@ class GoLogin(object):
100
100
  continue
101
101
  if stat.S_ISSOCK(os.stat(path).st_mode):
102
102
  continue
103
- ziph.write(path, path.replace(self.profile_path, ''))
103
+ try:
104
+ ziph.write(path, path.replace(self.profile_path, ''))
105
+ except:
106
+ continue
104
107
 
105
108
  def stop(self):
106
109
  self.sanitizeProfile()
@@ -167,9 +170,9 @@ class GoLogin(object):
167
170
  proxy = self.proxy
168
171
  if proxy:
169
172
  proxies = {proxy.get('mode'): self.formatProxyUrlPassword(proxy)}
170
- data = requests.get('https://time.gologin.app', proxies=proxies)
173
+ data = requests.get('https://time.gologin.com', proxies=proxies)
171
174
  else:
172
- data = requests.get('https://time.gologin.app')
175
+ data = requests.get('https://time.gologin.com')
173
176
  return json.loads(data.content.decode('utf-8'))
174
177
 
175
178
 
@@ -302,9 +305,8 @@ class GoLogin(object):
302
305
 
303
306
  def updatePreferences(self):
304
307
  pref_file = os.path.join(self.profile_path, 'Default/Preferences')
305
- pfile = open(pref_file, 'r')
306
- preferences = json.load(pfile)
307
- pfile.close()
308
+ with open(pref_file, 'r', encoding="utf-8") as pfile:
309
+ preferences = json.load(pfile)
308
310
  profile = self.profile
309
311
  proxy = self.profile.get('proxy')
310
312
  # print('proxy=', proxy)
@@ -420,9 +422,12 @@ class GoLogin(object):
420
422
  def update(self, options):
421
423
  self.profile_id = options.get('id')
422
424
  profile = self.getProfile()
425
+ #print("profile", profile)
423
426
  for k,v in options.items():
424
427
  profile[k] = v
425
- return json.loads(requests.put(API_URL + '/browser/' + profile_id, headers=self.headers(), json=profile).content.decode('utf-8'))
428
+ resp = requests.put(API_URL + '/browser/' + self.profile_id, headers=self.headers(), json=profile).content.decode('utf-8')
429
+ #print("update", resp)
430
+ #return json.loads(resp)
426
431
 
427
432
  def waitDebuggingUrl(self, delay_s, try_count=3):
428
433
  url = 'https://' + self.profile_id + '.orbita.gologin.com/json/version'