gologin 2.0.31 → 2.1.2

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/.eslintrc.json CHANGED
@@ -1,257 +1,290 @@
1
1
  {
2
- "env": {
3
- "browser": true,
4
- "es2021": true,
5
- "node": true
6
- },
7
- "extends": "eslint:recommended",
8
- "overrides": [
9
- ],
10
- "parserOptions": {
11
- "ecmaVersion": "latest",
12
- "sourceType": "module"
13
- },
14
- "plugins": [
15
- "simple-import-sort"
16
- ],
17
- "rules": {
18
- "padding-line-between-statements": [
19
- "warn",
20
- { "blankLine": "always", "prev": ["if", "switch", "while", "function", "multiline-const", "try"], "next": "*" },
21
- { "blankLine": "always", "prev": "*", "next": ["return"] }
22
- ],
23
- "indent": [
24
- "warn",
2
+ "env": {
3
+ "browser": true,
4
+ "es2021": true,
5
+ "node": true
6
+ },
7
+ "extends": "eslint:recommended",
8
+ "overrides": [
9
+ ],
10
+ "parserOptions": {
11
+ "ecmaVersion": "latest",
12
+ "sourceType": "module"
13
+ },
14
+ "plugins": [
15
+ "simple-import-sort"
16
+ ],
17
+ "rules": {
18
+ "padding-line-between-statements": [
19
+ "warn",
20
+ {
21
+ "blankLine": "always",
22
+ "prev": [
23
+ "if",
24
+ "switch",
25
+ "while",
26
+ "function",
27
+ "multiline-const",
28
+ "try"
29
+ ],
30
+ "next": "*"
31
+ },
32
+ {
33
+ "blankLine": "always",
34
+ "prev": "*",
35
+ "next": [
36
+ "return"
37
+ ]
38
+ }
39
+ ],
40
+ "indent": [
41
+ "warn",
42
+ 2,
43
+ {
44
+ "SwitchCase": 1,
45
+ "ignoredNodes": [
46
+ "ClassBody.body > PropertyDefinition[decorators.length > 0] > .key"
47
+ ]
48
+ }
49
+ ],
50
+ "linebreak-style": 0,
51
+ "quotes": [
52
+ "warn",
53
+ "single"
54
+ ],
55
+ "semi": [
56
+ "warn",
57
+ "always"
58
+ ],
59
+ "array-callback-return": [
60
+ "warn"
61
+ ],
62
+ "no-await-in-loop": [
63
+ "off"
64
+ ],
65
+ "no-duplicate-imports": [
66
+ "warn"
67
+ ],
68
+ "arrow-body-style": [
69
+ "warn",
70
+ "as-needed"
71
+ ],
72
+ "curly": [
73
+ "warn",
74
+ "all"
75
+ ],
76
+ "default-case": [
77
+ "warn"
78
+ ],
79
+ "default-case-last": [
80
+ "warn"
81
+ ],
82
+ "dot-notation": [
83
+ "warn"
84
+ ],
85
+ "eqeqeq": [
86
+ "warn",
87
+ "always"
88
+ ],
89
+ "id-length": [
90
+ "warn",
91
+ {
92
+ "min": 1,
93
+ "max": 40,
94
+ "properties": "never"
95
+ }
96
+ ],
97
+ "max-depth": [
98
+ "warn",
99
+ {
100
+ "max": 4
101
+ }
102
+ ],
103
+ "max-lines": [
104
+ "warn",
105
+ 1500
106
+ ],
107
+ "no-else-return": [
108
+ "warn",
109
+ {
110
+ "allowElseIf": true
111
+ }
112
+ ],
113
+ "no-unused-vars": [
114
+ "warn",
115
+ {
116
+ "vars": "all",
117
+ "args": "after-used",
118
+ "ignoreRestSiblings": false,
119
+ "varsIgnorePattern": "^_"
120
+ }
121
+ ],
122
+ "keyword-spacing": [
123
+ "error",
124
+ {
125
+ "before": true,
126
+ "after": true
127
+ }
128
+ ],
129
+ "no-empty-function": [
130
+ "warn",
131
+ {
132
+ "allow": [
133
+ "constructors"
134
+ ]
135
+ }
136
+ ],
137
+ "no-inline-comments": [
138
+ "warn"
139
+ ],
140
+ "no-labels": [
141
+ "warn"
142
+ ],
143
+ "no-lone-blocks": [
144
+ "warn"
145
+ ],
146
+ "no-lonely-if": [
147
+ "warn"
148
+ ],
149
+ "no-magic-numbers": [
150
+ "off",
151
+ {
152
+ "ignoreArrayIndexes": true,
153
+ "ignoreDefaultValues": true,
154
+ "ignore": [
155
+ 1,
25
156
  2,
26
- {
27
- "SwitchCase": 1,
28
- "ignoredNodes": [
29
- "ClassBody.body > PropertyDefinition[decorators.length > 0] > .key"
30
- ]
31
- }
32
- ],
33
- "linebreak-style": 0,
34
- "quotes": [
35
- "warn",
36
- "single"
37
- ],
38
- "semi": [
39
- "warn",
40
- "always"
41
- ],
42
- "array-callback-return": [
43
- "warn"
44
- ],
45
- "no-await-in-loop": [
46
- "off"
47
- ],
48
- "no-duplicate-imports": [
49
- "warn"
50
- ],
51
- "arrow-body-style": [
52
- "warn",
53
- "as-needed"
54
- ],
55
- "curly": [
56
- "warn",
57
- "all"
58
- ],
59
- "default-case": [
60
- "warn"
61
- ],
62
- "default-case-last": [
63
- "warn"
64
- ],
65
- "dot-notation": [
66
- "warn"
67
- ],
68
- "eqeqeq": [
69
- "warn",
70
- "always"
71
- ],
72
- "id-length": [
73
- "warn",
74
- {
75
- "min": 1,
76
- "max": 40,
77
- "properties": "never"
78
- }
79
- ],
80
- "max-depth": [
81
- "warn",
82
- {
83
- "max": 4
84
- }
85
- ],
86
- "max-lines": [
87
- "warn",
88
- 1500
89
- ],
90
- "no-else-return": [
91
- "warn",
92
- {
93
- "allowElseIf": true
94
- }
95
- ],
96
- "no-unused-vars": [
97
- "warn", {
98
- "vars": "all",
99
- "args": "after-used",
100
- "ignoreRestSiblings": false,
101
- "varsIgnorePattern": "^_"
102
- }
103
- ],
104
- "keyword-spacing": [
105
- "error", {
106
- "before": true,
107
- "after": true
108
- }
109
- ],
110
- "no-empty-function": [
111
- "warn",
112
- {
113
- "allow": ["constructors"]
114
- }
115
- ],
116
- "no-inline-comments": [
117
- "warn"
118
- ],
119
- "no-labels": [
120
- "warn"
121
- ],
122
- "no-lone-blocks": [
123
- "warn"
124
- ],
125
- "no-lonely-if": [
126
- "warn"
127
- ],
128
- "no-magic-numbers": [
129
- "off",
130
- {
131
- "ignoreArrayIndexes": true,
132
- "ignoreDefaultValues": true,
133
- "ignore": [1, 2, 3, 10, 1000, -1, 0]
134
- }
135
- ],
136
- "no-multi-assign": [
137
- "warn"
138
- ],
139
- "no-multi-str": [
140
- "warn"
141
- ],
142
- "no-nested-ternary": [
143
- "warn"
144
- ],
145
- "no-return-assign": [
146
- "warn"
147
- ],
148
- "no-return-await": [
149
- "warn"
150
- ],
151
- "no-sequences": [
152
- "warn"
153
- ],
154
- "no-shadow": [
155
- "warn"
156
- ],
157
- "no-undefined": [
158
- "warn"
159
- ],
160
- "no-underscore-dangle": [
161
- "warn",
162
- {
163
- "allow": ["_id"]
164
- }
165
- ],
166
- "no-unneeded-ternary": [
167
- "warn"
168
- ],
169
- "no-unused-expressions": [
170
- "warn",
171
- {
172
- "allowShortCircuit": true,
173
- "allowTernary": true
174
- }
175
- ],
176
- "no-useless-return": [
177
- "warn"
178
- ],
179
- "object-shorthand": [
180
- "warn",
181
- "always"
182
- ],
183
- "prefer-arrow-callback": [
184
- "warn"
185
- ],
186
- "prefer-const": [
187
- "warn"
188
- ],
189
- "prefer-destructuring": [
190
- "warn"
191
- ],
192
- "prefer-object-spread": [
193
- "warn"
194
- ],
195
- "prefer-spread": [
196
- "warn"
197
- ],
198
- "prefer-template": [
199
- "off"
200
- ],
201
- "spaced-comment": [
202
- "warn"
203
- ],
204
- "yoda": [
205
- "warn"
206
- ],
207
- "arrow-spacing": [
208
- "warn"
209
- ],
210
- "brace-style": [
211
- "warn",
212
- "1tbs",
213
- { "allowSingleLine": false }
214
- ],
215
- "comma-dangle": [
216
- "warn",
217
- "always-multiline"
218
- ],
219
- "dot-location": [
220
- "warn",
221
- "property"
222
- ],
223
- "eol-last": [
224
- "warn"
225
- ],
226
- "no-extra-parens": [
227
- "off"
228
- ],
229
- "no-multiple-empty-lines": [
230
- "warn",
231
- {
232
- "max": 1
233
- }
234
- ],
235
- "no-trailing-spaces": [
236
- "warn"
237
- ],
238
- "no-whitespace-before-property": [
239
- "warn"
240
- ],
241
- "object-curly-spacing": [
242
- "warn",
243
- "always"
244
- ],
245
- "space-in-parens": [
246
- "warn"
247
- ],
248
- "template-curly-spacing": [
249
- "warn"
250
- ],
251
- "max-len": [
252
- "warn",
253
- 150
254
- ],
255
- "simple-import-sort/imports": "warn"
256
- }
157
+ 3,
158
+ 10,
159
+ 1000,
160
+ -1,
161
+ 0
162
+ ]
163
+ }
164
+ ],
165
+ "no-multi-assign": [
166
+ "warn"
167
+ ],
168
+ "no-multi-str": [
169
+ "warn"
170
+ ],
171
+ "no-nested-ternary": [
172
+ "warn"
173
+ ],
174
+ "no-return-assign": [
175
+ "warn"
176
+ ],
177
+ "no-return-await": [
178
+ "warn"
179
+ ],
180
+ "no-sequences": [
181
+ "warn"
182
+ ],
183
+ "no-shadow": [
184
+ "warn"
185
+ ],
186
+ "no-undefined": [
187
+ "warn"
188
+ ],
189
+ "no-underscore-dangle": [
190
+ "warn",
191
+ {
192
+ "allow": [
193
+ "_id"
194
+ ]
195
+ }
196
+ ],
197
+ "no-unneeded-ternary": [
198
+ "warn"
199
+ ],
200
+ "no-unused-expressions": [
201
+ "warn",
202
+ {
203
+ "allowShortCircuit": true,
204
+ "allowTernary": true
205
+ }
206
+ ],
207
+ "no-useless-return": [
208
+ "warn"
209
+ ],
210
+ "object-shorthand": [
211
+ "warn",
212
+ "always"
213
+ ],
214
+ "prefer-arrow-callback": [
215
+ "warn"
216
+ ],
217
+ "prefer-const": [
218
+ "warn"
219
+ ],
220
+ "prefer-destructuring": [
221
+ "warn"
222
+ ],
223
+ "prefer-object-spread": [
224
+ "warn"
225
+ ],
226
+ "prefer-spread": [
227
+ "warn"
228
+ ],
229
+ "prefer-template": [
230
+ "off"
231
+ ],
232
+ "spaced-comment": [
233
+ "warn"
234
+ ],
235
+ "yoda": [
236
+ "warn"
237
+ ],
238
+ "arrow-spacing": [
239
+ "warn"
240
+ ],
241
+ "brace-style": [
242
+ "warn",
243
+ "1tbs",
244
+ {
245
+ "allowSingleLine": false
246
+ }
247
+ ],
248
+ "comma-dangle": [
249
+ "warn",
250
+ "always-multiline"
251
+ ],
252
+ "dot-location": [
253
+ "warn",
254
+ "property"
255
+ ],
256
+ "eol-last": [
257
+ "warn"
258
+ ],
259
+ "no-extra-parens": [
260
+ "off"
261
+ ],
262
+ "no-multiple-empty-lines": [
263
+ "warn",
264
+ {
265
+ "max": 1
266
+ }
267
+ ],
268
+ "no-trailing-spaces": [
269
+ "warn"
270
+ ],
271
+ "no-whitespace-before-property": [
272
+ "warn"
273
+ ],
274
+ "object-curly-spacing": [
275
+ "warn",
276
+ "always"
277
+ ],
278
+ "space-in-parens": [
279
+ "warn"
280
+ ],
281
+ "template-curly-spacing": [
282
+ "warn"
283
+ ],
284
+ "max-len": [
285
+ "warn",
286
+ 150
287
+ ],
288
+ "simple-import-sort/imports": "warn"
289
+ }
257
290
  }
@@ -0,0 +1,17 @@
1
+ import { exitAll, GologinApi } from '../src/gologin-api.js';
2
+
3
+ const token = process.env.GOLOGIN_API_TOKEN; // get token https://app.gologin.com/personalArea/TokenApi
4
+ const gologin = GologinApi({ token });
5
+
6
+ async function main() {
7
+ const { browser } = await gologin.launch();
8
+ const page = await browser.newPage();
9
+ await page.goto('https://iphey.com/', { waitUntil: 'networkidle2' });
10
+ const status = await page.$eval('.trustworthy-status:not(.hide)', (elt) =>
11
+ elt?.innerText?.trim(),
12
+ );
13
+
14
+ return status; // Expecting 'Trustworthy'
15
+ }
16
+
17
+ main().catch(console.error).then(console.info).finally(exitAll);
package/index.d.ts ADDED
@@ -0,0 +1,61 @@
1
+ import { type Browser } from 'puppeteer-core/lib/Browser';
2
+
3
+ export const OPERATING_SYSTEMS = {
4
+ win: 'win',
5
+ lin: 'lin',
6
+ mac: 'mac',
7
+ android: 'android',
8
+ } as const;
9
+ export type OsType = (typeof OPERATING_SYSTEMS)[keyof typeof OPERATING_SYSTEMS];
10
+
11
+ type CloudLaunchParams = {
12
+ cloud: true;
13
+
14
+ /**
15
+ * Format: 'dataCenter:DE'
16
+ */
17
+ geolocation?: string;
18
+ };
19
+ type LocalLaunchParams = {
20
+ cloud: false;
21
+ headless: boolean;
22
+ };
23
+
24
+ type ExistingProfileLaunchParams = {
25
+ profileId: string;
26
+ };
27
+ type NewProfileLaunchParams = {
28
+ proxyGeolocation: string;
29
+ };
30
+
31
+ type LaunchParams =
32
+ | CloudLaunchParams
33
+ | LocalLaunchParams
34
+ | ExistingProfileLaunchParams
35
+ | NewProfileLaunchParams
36
+ | {
37
+ /**
38
+ * default delay, 250
39
+ */
40
+ defaultDelay: number;
41
+
42
+ /**
43
+ * Operating system
44
+ */
45
+ os: OsType;
46
+ };
47
+
48
+ type LaunchFn = (params?: LaunchParams) => Promise<{ browser: Browser }>;
49
+
50
+ type GologinApiType = {
51
+ launch: LaunchFn;
52
+ exit: (status = 0) => Promise<void>;
53
+ delay: (ms: number) => Promise<void>;
54
+ };
55
+
56
+ type GologinApiParams = {
57
+ token: string;
58
+ };
59
+
60
+ export declare function GologinApi(params: GologinApiParams): GologinApiType;
61
+ export declare function exitAll(): Promise<void>;
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "gologin",
3
- "version": "2.0.31",
3
+ "version": "2.1.2",
4
4
  "description": "A high-level API to control Orbita browser over GoLogin API",
5
+ "types": "./index.d.ts",
5
6
  "main": "./src/gologin.js",
6
7
  "repository": {
7
8
  "type": "git",
@@ -41,6 +42,8 @@
41
42
  "eslint-plugin-simple-import-sort": "^8.0.0"
42
43
  },
43
44
  "scripts": {
44
- "test": "echo \"Error: no test specified\" && exit 1"
45
+ "test": "echo \"Error: no test specified\" && exit 1",
46
+ "format": "npx prettier --single-quote src/* --write",
47
+ "iphey": "GOLOGIN_PROFILE_ID= GOLOGIN_API_TOKEN= node examples/example-iphey "
45
48
  }
46
49
  }
@@ -3,10 +3,9 @@ import { promises as _promises } from 'fs';
3
3
  const { readFile } = _promises;
4
4
 
5
5
  export const getCurrentProfileBookmarks = async (pathToBookmarks) => {
6
- const currentBookmarksFileData = await readFile(pathToBookmarks, { encoding: 'utf-8' });
7
-
8
6
  let bookmarks = {};
9
7
  try {
8
+ const currentBookmarksFileData = await readFile(pathToBookmarks, { encoding: 'utf-8' });
10
9
  bookmarks = JSON.parse(currentBookmarksFileData);
11
10
  } catch (error) {
12
11
  console.log(error);
@@ -357,6 +357,7 @@ export class BrowserChecker {
357
357
  timeout: 15 * 1000,
358
358
  headers: {
359
359
  'Content-Type': 'application/json',
360
+ 'User-Agent': 'gologin-api',
360
361
  },
361
362
  }, (res) => {
362
363
  res.setEncoding('utf8');
@@ -1,9 +1,9 @@
1
1
  import { createHash } from 'crypto';
2
2
  import { createWriteStream, promises as _promises, rmdirSync } from 'fs';
3
3
  import { homedir, tmpdir } from 'os';
4
- import { join, resolve, sep, dirname } from 'path';
5
- import { fileURLToPath } from 'url';
4
+ import { dirname, join, resolve, sep } from 'path';
6
5
  import requestretry from 'requestretry';
6
+ import { fileURLToPath } from 'url';
7
7
 
8
8
  import { fontsCollection } from '../../fonts.js';
9
9
 
@@ -40,7 +40,7 @@ export const downloadCookies = ({ profileId, ACCESS_TOKEN, API_BASE_URL }) =>
40
40
  });
41
41
 
42
42
  export const uploadCookies = ({ cookies = [], profileId, ACCESS_TOKEN, API_BASE_URL }) =>
43
- requestretry.post(`${API_BASE_URL}/browser/${profileId}/cookies/?encrypted=true`, {
43
+ requestretry.post(`${API_BASE_URL}/browser/${profileId}/cookies?encrypted=true`, {
44
44
  headers: {
45
45
  Authorization: `Bearer ${ACCESS_TOKEN}`,
46
46
  'User-Agent': 'gologin-api',
@@ -0,0 +1,110 @@
1
+ import puppeteer from 'puppeteer-core';
2
+
3
+ import GoLogin from './gologin.js';
4
+
5
+ export function getDefaultParams() {
6
+ return {
7
+ token: process.env.GOLOGIN_API_TOKEN,
8
+ profile_id: process.env.GOLOGIN_PROFILE_ID,
9
+ executablePath: process.env.GOLOGIN_EXECUTABLE_PATH,
10
+ autoUpdateBrowser: true,
11
+ };
12
+ }
13
+
14
+ const createLegacyGologin = ({ profileId, ...params }) => {
15
+ const defaults = getDefaultParams();
16
+ const mergedParams = {
17
+ ...defaults,
18
+ ...params,
19
+ };
20
+
21
+ mergedParams.profile_id = profileId ?? mergedParams.profile_id;
22
+
23
+ console.log({ mergedParams });
24
+
25
+ return new GoLogin(mergedParams);
26
+ };
27
+
28
+ const createdApis = [];
29
+
30
+ export const delay = (ms = 250) => new Promise((res) => setTimeout(res, ms));
31
+
32
+ export function GologinApi({ token }) {
33
+ if (!token) {
34
+ throw new Error('GoLogin API token is missing');
35
+ }
36
+
37
+ const browsers = [];
38
+ const legacyGls = [];
39
+
40
+ const launchLocal = async (params) => {
41
+ const legacyGologin = createLegacyGologin({
42
+ ...params,
43
+ token,
44
+ });
45
+
46
+ if (!params.profileId) {
47
+ const { id } = await legacyGologin.quickCreateProfile();
48
+ await legacyGologin.setProfileId(id);
49
+ }
50
+
51
+ const started = await legacyGologin.start();
52
+ const browser = await puppeteer.connect({
53
+ browserWSEndpoint: started.wsUrl,
54
+ ignoreHTTPSErrors: true,
55
+ });
56
+
57
+ browsers.push(browser);
58
+ legacyGls.push(legacyGologin);
59
+
60
+ return { browser };
61
+ };
62
+
63
+ const launchCloudProfile = async (params) => {
64
+ const profileParam = params.profileId
65
+ ? `&profile=${params.profileId}`
66
+ : '';
67
+
68
+ const geolocationParam = params.geolocation
69
+ ? `&geolocation=${params.geolocation}`
70
+ : '';
71
+
72
+ const browserWSEndpoint = `https://cloud.gologin.com/connect?token=${token}${profileParam}${geolocationParam}`;
73
+ const browser = await puppeteer.connect({
74
+ browserWSEndpoint,
75
+ ignoreHTTPSErrors: true,
76
+ });
77
+
78
+ browsers.push(browser);
79
+
80
+ return { browser };
81
+ };
82
+
83
+ const api = {
84
+ async launch(params = {}) {
85
+ if (params.cloud) {
86
+ return launchCloudProfile(params);
87
+ }
88
+
89
+ return launchLocal(params);
90
+ },
91
+
92
+ async exit(status = 0) {
93
+ Promise.allSettled(browsers.map((browser) => browser.close()));
94
+ Promise.allSettled(
95
+ legacyGls.map((gl) => gl.stopLocal({ posting: false })),
96
+ );
97
+ process.exit(status);
98
+ },
99
+
100
+ delay,
101
+ };
102
+
103
+ createdApis.push(api);
104
+
105
+ return api;
106
+ }
107
+
108
+ export function exitAll() {
109
+ Promise.allSettled(createdApis.map((api) => api.exit()));
110
+ }
package/src/gologin.js CHANGED
@@ -2,7 +2,7 @@ import { execFile, spawn } from 'child_process';
2
2
  import debugDefault from 'debug';
3
3
  import decompress from 'decompress';
4
4
  import decompressUnzip from 'decompress-unzip';
5
- import { existsSync, mkdirSync, promises as _promises } from 'fs';
5
+ import { existsSync, mkdirSync,promises as _promises } from 'fs';
6
6
  import { get as _get } from 'https';
7
7
  import { tmpdir } from 'os';
8
8
  import { dirname, join, resolve as _resolve, sep } from 'path';
@@ -26,9 +26,10 @@ import {
26
26
  import ExtensionsManager from './extensions/extensions-manager.js';
27
27
  import { archiveProfile } from './profile/profile-archiver.js';
28
28
  import { checkAutoLang } from './utils/browser.js';
29
- import { API_URL } from './utils/common.js';
29
+ import { API_URL, getOsAdvanced } from './utils/common.js';
30
30
  import { STORAGE_GATEWAY_BASE_URL } from './utils/constants.js';
31
31
  import { get, isPortReachable } from './utils/utils.js';
32
+ export { exitAll, GologinApi } from './gologin-api.js';
32
33
 
33
34
  const { access, unlink, writeFile, readFile } = _promises;
34
35
 
@@ -55,16 +56,10 @@ export class GoLogin {
55
56
  this.is_stopping = false;
56
57
  this.differentOs = false;
57
58
  this.profileOs = 'lin';
58
- this.waitWebsocket = true;
59
- if (options.waitWebsocket === false) {
60
- this.waitWebsocket = false;
61
- }
59
+ this.waitWebsocket = options.waitWebsocket ?? true;
62
60
 
63
61
  this.isCloudHeadless = options.isCloudHeadless ?? true;
64
- this.isNewCloudBrowser = true;
65
- if (options.isNewCloudBrowser === false) {
66
- this.isNewCloudBrowser = false;
67
- }
62
+ this.isNewCloudBrowser = options.isNewCloudBrowser ?? true;
68
63
 
69
64
  this.tmpdir = tmpdir();
70
65
  this.autoUpdateBrowser = !!options.autoUpdateBrowser;
@@ -153,6 +148,7 @@ export class GoLogin {
153
148
  const profileResponse = await requests.get(`${API_URL}/browser/${id}`, {
154
149
  headers: {
155
150
  'Authorization': `Bearer ${this.access_token}`,
151
+ 'User-Agent': 'gologin-api',
156
152
  },
157
153
  });
158
154
 
@@ -162,9 +158,9 @@ export class GoLogin {
162
158
  const backendErrorHeader = 'backend@error::';
163
159
  if (errorBody.includes(backendErrorHeader)) {
164
160
  const errorData =
165
- errorBody
166
- .replace(backendErrorHeader, '')
167
- .slice(1, -1);
161
+ errorBody
162
+ .replace(backendErrorHeader, '')
163
+ .slice(1, -1);
168
164
 
169
165
  throw new Error(errorData);
170
166
  }
@@ -270,7 +266,7 @@ export class GoLogin {
270
266
  }
271
267
 
272
268
  if (get(preferences, 'navigator.deviceMemory')) {
273
- preferences.deviceMemory = get(preferences, 'navigator.deviceMemory')*1024;
269
+ preferences.deviceMemory = get(preferences, 'navigator.deviceMemory') * 1024;
274
270
  }
275
271
 
276
272
  if (get(preferences, 'navigator.language')) {
@@ -356,14 +352,14 @@ export class GoLogin {
356
352
  );
357
353
  }
358
354
 
359
- async createStartup(local=false) {
355
+ async createStartup(local = false) {
360
356
  const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
361
357
  let profile;
362
358
  let profile_folder;
363
359
  await rimraf(profilePath, () => null);
364
360
  debug('-', profilePath, 'dropped');
365
361
  profile = await this.getProfile();
366
- const { navigator = {}, fonts, os: profileOs } = profile;
362
+ const { navigator = {}, fonts, os: profileOs } = profile;
367
363
  this.fontsMasking = fonts?.enableMasking;
368
364
  this.profileOs = profileOs;
369
365
  this.differentOs =
@@ -450,7 +446,7 @@ export class GoLogin {
450
446
  ExtensionsManagerInst.apiUrl = API_URL;
451
447
  await ExtensionsManagerInst.init()
452
448
  .then(() => ExtensionsManagerInst.updateExtensions())
453
- .catch(() => {});
449
+ .catch(() => { });
454
450
  ExtensionsManagerInst.accessToken = this.access_token;
455
451
 
456
452
  await ExtensionsManagerInst.getExtensionsPolicies();
@@ -517,7 +513,6 @@ export class GoLogin {
517
513
  profile.proxy.username = get(profile, 'autoProxyUsername');
518
514
  profile.proxy.password = get(profile, 'autoProxyPassword');
519
515
  }
520
- // console.log('proxy=', proxy);
521
516
 
522
517
  if (proxy.mode === 'geolocation') {
523
518
  proxy.mode = 'http';
@@ -531,7 +526,7 @@ export class GoLogin {
531
526
 
532
527
  await this.getTimeZone(proxy).catch((e) => {
533
528
  console.error('Proxy Error. Check it and try again.');
534
- throw e;
529
+ throw new Error(`Proxy Error. ${e.message}`);
535
530
  });
536
531
 
537
532
  const [latitude, longitude] = this._tz.ll;
@@ -561,7 +556,7 @@ export class GoLogin {
561
556
 
562
557
  const audioContext = profile.audioContext || {};
563
558
  const { mode: audioCtxMode = 'off', noise: audioCtxNoise } = audioContext;
564
- if (profile.timezone.fillBasedOnIp==false) {
559
+ if (profile.timezone.fillBasedOnIp === false) {
565
560
  profile.timezone = { id: profile.timezone.timezone };
566
561
  } else {
567
562
  profile.timezone = { id: this._tz.timezone };
@@ -613,7 +608,7 @@ export class GoLogin {
613
608
 
614
609
  const languages = this.language.replace(/;|q=[\d\.]+/img, '');
615
610
 
616
- if (preferences.gologin==null) {
611
+ if (preferences.gologin == null) {
617
612
  preferences.gologin = {};
618
613
  }
619
614
 
@@ -778,7 +773,6 @@ export class GoLogin {
778
773
  }).on('error', (err) => reject(err));
779
774
  });
780
775
 
781
- // console.log('checkData:', checkData);
782
776
  body = checkData.body || {};
783
777
  if (!body.ip && checkData.statusCode.toString().startsWith('4')) {
784
778
  throw checkData;
@@ -800,6 +794,7 @@ export class GoLogin {
800
794
  Object.keys(process.env).forEach((key) => {
801
795
  env[key] = process.env[key];
802
796
  });
797
+
803
798
  const tz = await this.getTimeZone(this.proxy).catch((e) => {
804
799
  console.error('Proxy Error. Check it and try again.');
805
800
  throw e;
@@ -842,6 +837,7 @@ export class GoLogin {
842
837
  Object.keys(process.env).forEach((key) => {
843
838
  env[key] = process.env[key];
844
839
  });
840
+
845
841
  const tz = await this.getTimeZone(this.proxy).catch((e) => {
846
842
  console.error('Proxy Error. Check it and try again.');
847
843
  throw e;
@@ -858,7 +854,6 @@ export class GoLogin {
858
854
  { env },
859
855
  );
860
856
  } else {
861
-
862
857
  let params = [
863
858
  `--remote-debugging-port=${remote_debugging_port}`,
864
859
  `--user-data-dir=${profile_path}`,
@@ -1080,6 +1075,7 @@ export class GoLogin {
1080
1075
  const profileResponse = await requests.post(`${API_URL}/browser`, {
1081
1076
  headers: {
1082
1077
  'Authorization': `Bearer ${this.access_token}`,
1078
+ 'User-Agent': 'gologin-api',
1083
1079
  },
1084
1080
  json: {
1085
1081
 
@@ -1107,7 +1103,7 @@ export class GoLogin {
1107
1103
  url += '&isM1=true';
1108
1104
  }
1109
1105
 
1110
- const fingerprint = await requests.get(url,{
1106
+ const fingerprint = await requests.get(url, {
1111
1107
  headers: {
1112
1108
  'Authorization': `Bearer ${this.access_token}`,
1113
1109
  'User-Agent': 'gologin-api',
@@ -1137,7 +1133,7 @@ export class GoLogin {
1137
1133
  deviceMemory = 1;
1138
1134
  }
1139
1135
 
1140
- navigator.deviceMemory = deviceMemory*1024;
1136
+ navigator.deviceMemory = deviceMemory * 1024;
1141
1137
  webGLMetadata.mode = webGLMetadata.mode === 'noise' ? 'mask' : 'off';
1142
1138
 
1143
1139
  const json = {
@@ -1172,8 +1168,6 @@ export class GoLogin {
1172
1168
  json.navigator.userAgent = orig_user_agent;
1173
1169
  }
1174
1170
 
1175
- // console.log('profileOptions', json);
1176
-
1177
1171
  const response = await requests.post(`${API_URL}/browser`, {
1178
1172
  headers: {
1179
1173
  'Authorization': `Bearer ${this.access_token}`,
@@ -1218,6 +1212,25 @@ export class GoLogin {
1218
1212
  return response.body.id;
1219
1213
  }
1220
1214
 
1215
+ async quickCreateProfile(name = '') {
1216
+ const osInfo = await getOsAdvanced();
1217
+ const { os, osSpec } = osInfo;
1218
+ const resultName = name || 'api-generated';
1219
+
1220
+ return requests.post(`${API_URL}/browser/quick`, {
1221
+ headers: {
1222
+ 'Authorization': `Bearer ${this.access_token}`,
1223
+ 'User-Agent': 'gologin-api',
1224
+ },
1225
+ json: {
1226
+ os,
1227
+ osSpec,
1228
+ name: resultName,
1229
+ },
1230
+ })
1231
+ .then(res => res.body);
1232
+ }
1233
+
1221
1234
  async delete(pid) {
1222
1235
  const profile_id = pid || this.profile_id;
1223
1236
  await requests.delete(`${API_URL}/browser/${profile_id}`, {
@@ -1234,19 +1247,20 @@ export class GoLogin {
1234
1247
 
1235
1248
  if (options.navigator) {
1236
1249
  Object.keys(options.navigator).map((e) => {
1237
- profile.navigator[e]=options.navigator[e];
1250
+ profile.navigator[e] = options.navigator[e];
1238
1251
  });
1239
1252
  }
1240
1253
 
1241
- Object.keys(options).filter(e => e !== 'navigator').map((e) => {
1242
- profile[e]=options[e];
1254
+ Object.keys(options).filter(el => el !== 'navigator').forEach((el) => {
1255
+ profile[el] = options[el];
1243
1256
  });
1244
1257
 
1245
1258
  debug('update profile', profile);
1246
- const response = await requests.put(`${API_URL}/browser/${options.id}`,{
1259
+ const response = await requests.put(`${API_URL}/browser/${options.id}`, {
1247
1260
  json: profile,
1248
1261
  headers: {
1249
1262
  'Authorization': `Bearer ${this.access_token}`,
1263
+ 'User-Agent': 'gologin-api',
1250
1264
  },
1251
1265
  });
1252
1266
 
@@ -1404,7 +1418,7 @@ export class GoLogin {
1404
1418
  await this.stopAndCommit(opts, true);
1405
1419
  }
1406
1420
 
1407
- async waitDebuggingUrl(delay_ms, try_count=0, remoteOrbitaUrl) {
1421
+ async waitDebuggingUrl(delay_ms, try_count = 0, remoteOrbitaUrl) {
1408
1422
  await delay(delay_ms);
1409
1423
  const url = `${remoteOrbitaUrl}/json/version`;
1410
1424
  console.log('try_count=', try_count, 'url=', url);
@@ -1444,7 +1458,7 @@ export class GoLogin {
1444
1458
 
1445
1459
  const profile = await this.getProfile();
1446
1460
  const profileResponse = await requests.post(`${API_URL}/browser/${this.profile_id}/web`, {
1447
- headers: { 'Authorization': `Bearer ${this.access_token}` },
1461
+ headers: { 'Authorization': `Bearer ${this.access_token}`, 'User-Agent': 'gologin-api' },
1448
1462
  json: { isNewCloudBrowser: this.isNewCloudBrowser, isHeadless: this.isCloudHeadless },
1449
1463
  }).catch(() => null);
1450
1464
 
@@ -1472,7 +1486,7 @@ export class GoLogin {
1472
1486
  remoteOrbitaUrl = profileResponse.body.remoteOrbitaUrl;
1473
1487
  }
1474
1488
 
1475
- const { navigator = {}, fonts, os: profileOs } = profile;
1489
+ const { navigator = {}, fonts, os: profileOs } = profile;
1476
1490
  this.fontsMasking = fonts?.enableMasking;
1477
1491
  this.profileOs = profileOs;
1478
1492
  this.differentOs =
@@ -1505,7 +1519,10 @@ export class GoLogin {
1505
1519
  async stopRemote() {
1506
1520
  debug(`stopRemote ${this.profile_id}`);
1507
1521
  const profileResponse = await requests.delete(`${API_URL}/browser/${this.profile_id}/web?isNewCloudBrowser=${this.isNewCloudBrowser}`, {
1508
- headers: { 'Authorization': `Bearer ${this.access_token}` },
1522
+ headers: {
1523
+ 'Authorization': `Bearer ${this.access_token}`,
1524
+ 'User-Agent': 'gologin-api',
1525
+ },
1509
1526
  });
1510
1527
 
1511
1528
  console.log(`stopRemote ${profileResponse.body}`);
@@ -1,5 +1,7 @@
1
+ import { exec } from 'child_process';
1
2
  import { homedir } from 'os';
2
3
  import { join, sep } from 'path';
4
+ import { promisify } from 'util';
3
5
 
4
6
  import { deleteExtensionArchive, extractExtension } from '../extensions/extensions-extractor.js';
5
7
 
@@ -21,6 +23,31 @@ const composeExtractionPromises = (filteredArchives, destPath = CHROME_EXTENSION
21
23
  })
22
24
  );
23
25
 
26
+ const getMacArmSpec = async () => {
27
+ const doExec = promisify(exec);
28
+
29
+ const { stdout } = await doExec('sysctl machdep.cpu');
30
+ const regExp = /Apple M\d/;
31
+ const [match] = stdout.match(regExp);
32
+ const [_, armVersion] = match.split(' ');
33
+
34
+ return armVersion;
35
+ };
36
+
37
+ const getOsAdvanced = async () => {
38
+ const os = getOS();
39
+ if (!['mac', 'macM1'].includes(os)) {
40
+ return { os, osSpec: '' };
41
+ }
42
+
43
+ const osSpec = await getMacArmSpec();
44
+
45
+ return {
46
+ os: 'mac',
47
+ osSpec,
48
+ };
49
+ };
50
+
24
51
  const getOS = () => {
25
52
  if (process.platform === 'win32') {
26
53
  return 'win';
@@ -35,9 +62,15 @@ const getOS = () => {
35
62
 
36
63
  const _composeExtractionPromises = composeExtractionPromises;
37
64
  export { _composeExtractionPromises as composeExtractionPromises };
65
+
38
66
  const _getOS = getOS;
39
67
  export { _getOS as getOS };
68
+
69
+ const _getOsAdvanced = getOsAdvanced;
70
+ export { _getOsAdvanced as getOsAdvanced };
71
+
40
72
  const _USER_EXTENSIONS_PATH = USER_EXTENSIONS_PATH;
41
73
  export { _USER_EXTENSIONS_PATH as USER_EXTENSIONS_PATH };
74
+
42
75
  const _CHROME_EXTENSIONS_PATH = CHROME_EXTENSIONS_PATH;
43
76
  export { _CHROME_EXTENSIONS_PATH as CHROME_EXTENSIONS_PATH };
@@ -3,9 +3,9 @@ import net from 'node:net';
3
3
  import { join } from 'node:path';
4
4
 
5
5
  export const get = (value, path, defaultValue) =>
6
- String(path).split('.').reduce((acc, v) => {
6
+ String(path).split('.').reduce((acc, val) => {
7
7
  try {
8
- acc = acc[v] ? acc[v] : defaultValue;
8
+ acc = acc[val] ? acc[val] : defaultValue;
9
9
  } catch (e) {
10
10
  return defaultValue;
11
11
  }