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