gologin 1.0.44 → 1.0.47
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/browser-checker.js +1 -1
- package/browser-user-data-manager.js +68 -8
- package/examples/example-startremote.js +25 -0
- package/examples/example-stopremote.js +20 -0
- package/extensions-manager.js +22 -0
- package/gologin.js +51 -11
- package/package.json +1 -1
package/browser-checker.js
CHANGED
|
@@ -53,7 +53,7 @@ class BrowserChecker {
|
|
|
53
53
|
executableFilePath = path.join(this.#browserPath, 'orbita-browser', 'chrome.exe');
|
|
54
54
|
}
|
|
55
55
|
this.#executableFilePath = executableFilePath;
|
|
56
|
-
console.log('executableFilePath:', executableFilePath);
|
|
56
|
+
// console.log('executableFilePath:', executableFilePath);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
async checkBrowser(autoUpdateBrowser = false) {
|
|
@@ -3,6 +3,7 @@ const os = require('os');
|
|
|
3
3
|
const request = require('requestretry');
|
|
4
4
|
const { rmdirSync, createWriteStream } = require('fs');
|
|
5
5
|
const { access, readFile, writeFile, mkdir, readdir, copyFile } = require('fs').promises;
|
|
6
|
+
const crypto = require('crypto');
|
|
6
7
|
|
|
7
8
|
const fontsCollection = require('./fonts');
|
|
8
9
|
|
|
@@ -12,6 +13,7 @@ const FONTS_DIR_NAME = 'fonts';
|
|
|
12
13
|
const HOMEDIR = os.homedir();
|
|
13
14
|
const BROWSER_PATH = path.join(HOMEDIR, '.gologin', 'browser');
|
|
14
15
|
const OS_PLATFORM = process.platform;
|
|
16
|
+
const DEFAULT_ORBITA_EXTENSIONS_NAMES = ['Google Hangouts', 'Chromium PDF Viewer', 'CryptoTokenExtension', 'Web Store'];
|
|
15
17
|
|
|
16
18
|
class BrowserUserDataManager {
|
|
17
19
|
static downloadCookies({ profileId, ACCESS_TOKEN, API_BASE_URL }) {
|
|
@@ -114,7 +116,7 @@ class BrowserUserDataManager {
|
|
|
114
116
|
await writeFile(path.join(profilePath, 'Default', 'fonts_config'), result);
|
|
115
117
|
}
|
|
116
118
|
|
|
117
|
-
static
|
|
119
|
+
static setExtPathsAndRemoveDeleted(settings = {}, profileExtensionsCheckRes = []) {
|
|
118
120
|
const formattedLocalExtArray = profileExtensionsCheckRes.map((el) => {
|
|
119
121
|
const [extFolderName = ''] = el.split(path.sep).reverse();
|
|
120
122
|
const [originalId] = extFolderName.split('@');
|
|
@@ -128,21 +130,60 @@ class BrowserUserDataManager {
|
|
|
128
130
|
}
|
|
129
131
|
}).filter(Boolean);
|
|
130
132
|
|
|
131
|
-
if (!formattedLocalExtArray.length) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
133
|
const extensionsSettings = settings.extensions?.settings || {};
|
|
136
134
|
const extensionsEntries = Object.entries(extensionsSettings);
|
|
137
135
|
|
|
138
136
|
extensionsEntries.forEach((extensionObj) => {
|
|
139
|
-
|
|
140
|
-
const
|
|
137
|
+
let [extensionId, currentExtSettings = {}] = extensionObj;
|
|
138
|
+
const extName = currentExtSettings.manifest?.name || '';
|
|
139
|
+
let extPath = currentExtSettings.path || '';
|
|
140
|
+
let originalId = '';
|
|
141
|
+
|
|
142
|
+
const isExtensionToBeDeleted = ['resources', 'passwords-ext', 'cookies-ext'].some(substring => extPath.includes(substring))
|
|
143
|
+
|| DEFAULT_ORBITA_EXTENSIONS_NAMES.includes(extName);
|
|
144
|
+
if (isExtensionToBeDeleted) {
|
|
145
|
+
delete extensionsSettings[extensionId];
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (os.platform() === 'win32') {
|
|
150
|
+
extPath = extPath.replace(/\//g, '\\');
|
|
151
|
+
} else {
|
|
152
|
+
extPath = extPath.replace(/\\/g, '/');
|
|
153
|
+
}
|
|
154
|
+
extensionsSettings[extensionId].path = extPath;
|
|
155
|
+
|
|
156
|
+
const isExtensionManageable = ['chrome-extensions', 'user-extensions'].some(substring => extPath.includes(substring));
|
|
157
|
+
if (isExtensionManageable) {
|
|
158
|
+
const [extFolderName] = extPath.split(path.sep).reverse();
|
|
159
|
+
[originalId] = extFolderName.split('@');
|
|
160
|
+
const isExtensionInProfileSettings = formattedLocalExtArray.find(el => el.path.includes(originalId));
|
|
161
|
+
if (!isExtensionInProfileSettings) {
|
|
162
|
+
delete extensionsSettings[extensionId];
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (!currentExtSettings.manifest?.key) {
|
|
167
|
+
const hexEncodedPath = crypto.createHash('sha256').update(extPath).digest('hex');
|
|
168
|
+
const newId = hexEncodedPath.split('').slice(0, 32).map(symbol => extIdEncoding[symbol]).join('');
|
|
169
|
+
delete extensionsSettings[extensionId];
|
|
170
|
+
|
|
171
|
+
extensionsSettings[newId] = currentExtSettings;
|
|
172
|
+
extensionId = newId;
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
const splittedPath = extPath.split(path.sep);
|
|
176
|
+
if (splittedPath.length === 2) {
|
|
177
|
+
[originalId] = splittedPath
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const localExtObj = originalId && formattedLocalExtArray.find(el => el.path.includes(originalId));
|
|
141
182
|
if (!localExtObj) {
|
|
142
183
|
return;
|
|
143
184
|
}
|
|
144
185
|
|
|
145
|
-
extensionsSettings[
|
|
186
|
+
extensionsSettings[extensionId].path = localExtObj?.path || '';
|
|
146
187
|
});
|
|
147
188
|
|
|
148
189
|
return extensionsSettings;
|
|
@@ -202,6 +243,25 @@ class BrowserUserDataManager {
|
|
|
202
243
|
}
|
|
203
244
|
}
|
|
204
245
|
|
|
246
|
+
const extIdEncoding = {
|
|
247
|
+
0: 'a',
|
|
248
|
+
1: 'b',
|
|
249
|
+
2: 'c',
|
|
250
|
+
3: 'd',
|
|
251
|
+
4: 'e',
|
|
252
|
+
5: 'f',
|
|
253
|
+
6: 'g',
|
|
254
|
+
7: 'h',
|
|
255
|
+
8: 'i',
|
|
256
|
+
9: 'j',
|
|
257
|
+
a: 'k',
|
|
258
|
+
b: 'l',
|
|
259
|
+
c: 'm',
|
|
260
|
+
d: 'n',
|
|
261
|
+
e: 'o',
|
|
262
|
+
f: 'p',
|
|
263
|
+
};
|
|
264
|
+
|
|
205
265
|
module.exports = {
|
|
206
266
|
BrowserUserDataManager,
|
|
207
267
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Usage example: in the terminal enter
|
|
2
|
+
// node example-startremote.js yU0token yU0Pr0f1leiD
|
|
3
|
+
|
|
4
|
+
// your token api (located in the settings, api)
|
|
5
|
+
// https://github.com/gologinapp/gologin#usage
|
|
6
|
+
const GOLOGIN_API_TOKEN = process.argv[2];
|
|
7
|
+
// your profile id
|
|
8
|
+
const GOLOGIN_PROFILE_ID = process.argv[3];
|
|
9
|
+
|
|
10
|
+
const GoLogin = require('../gologin');
|
|
11
|
+
|
|
12
|
+
(async () =>{
|
|
13
|
+
const GL = new GoLogin({
|
|
14
|
+
token: GOLOGIN_API_TOKEN,
|
|
15
|
+
profile_id: GOLOGIN_PROFILE_ID,
|
|
16
|
+
});
|
|
17
|
+
// connection of the remote work method
|
|
18
|
+
const {status, wsUrl} = await GL.startRemote();
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
GOLOGIN_PROFILE_CLOUD_URL = wsUrl.split('/')[2]
|
|
22
|
+
console.log('Done! Launch web browser and navigate to URL:', GOLOGIN_PROFILE_CLOUD_URL);
|
|
23
|
+
})();
|
|
24
|
+
|
|
25
|
+
// after running the script, the url will appear on the terminal
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Usage example: in the terminal enter
|
|
2
|
+
// node example-stopremote.js yU0token yU0Pr0f1leiD
|
|
3
|
+
|
|
4
|
+
// your token api (located in the settings, api)
|
|
5
|
+
// https://github.com/gologinapp/gologin#usage
|
|
6
|
+
const GOLOGIN_API_TOKEN = process.argv[2];
|
|
7
|
+
// your profile id
|
|
8
|
+
const GOLOGIN_PROFILE_ID = process.argv[3];
|
|
9
|
+
|
|
10
|
+
const GoLogin = require('../gologin');
|
|
11
|
+
|
|
12
|
+
(async () =>{
|
|
13
|
+
const GL = new GoLogin({
|
|
14
|
+
token: GOLOGIN_API_TOKEN,
|
|
15
|
+
profile_id: GOLOGIN_PROFILE_ID,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// stop profile
|
|
19
|
+
await GL.stopRemote();
|
|
20
|
+
})();
|
package/extensions-manager.js
CHANGED
|
@@ -249,6 +249,28 @@ class ExtensionsManager {
|
|
|
249
249
|
|
|
250
250
|
return Promise.all(removeFoldersPromises);
|
|
251
251
|
}
|
|
252
|
+
|
|
253
|
+
getExtensionsToInstall(extensionsFromPref, extensionsFromDB) {
|
|
254
|
+
if (!extensionsFromPref) {
|
|
255
|
+
return [];
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const objectEntries = Object.entries(extensionsFromPref);
|
|
259
|
+
const extensionsInPref = objectEntries?.map(([_, settings]) => {
|
|
260
|
+
const [extFolderName] = settings.path.split(path.sep).reverse();
|
|
261
|
+
const [originalId] = extFolderName.split('@');
|
|
262
|
+
return originalId;
|
|
263
|
+
}) || [];
|
|
264
|
+
|
|
265
|
+
return extensionsFromDB.reduce((acc, extension) => {
|
|
266
|
+
const [extFolderName] = extension.split(path.sep).reverse();
|
|
267
|
+
const [originalId] = extFolderName.split('@');
|
|
268
|
+
if (!extensionsInPref.includes(originalId)) {
|
|
269
|
+
acc.push(extension);
|
|
270
|
+
}
|
|
271
|
+
return acc;
|
|
272
|
+
}, []);
|
|
273
|
+
}
|
|
252
274
|
}
|
|
253
275
|
|
|
254
276
|
const crxToZip = (buf) => {
|
package/gologin.js
CHANGED
|
@@ -47,9 +47,10 @@ class GoLogin {
|
|
|
47
47
|
this.autoUpdateBrowser = !!options.autoUpdateBrowser;
|
|
48
48
|
this.browserChecker = new BrowserChecker(options.skipOrbitaHashChecking);
|
|
49
49
|
this.uploadCookiesToServer = options.uploadCookiesToServer || false;
|
|
50
|
-
this.writeCookesFromServer = options.writeCookesFromServer
|
|
50
|
+
this.writeCookesFromServer = options.writeCookesFromServer;
|
|
51
51
|
this.remote_debugging_port = options.remote_debugging_port || 0;
|
|
52
52
|
this.timezone = options.timezone;
|
|
53
|
+
this.extensionPathsToInstall = [];
|
|
53
54
|
|
|
54
55
|
if (options.tmpdir) {
|
|
55
56
|
this.tmpdir = options.tmpdir;
|
|
@@ -247,7 +248,21 @@ class GoLogin {
|
|
|
247
248
|
if (_.get(preferences, 'navigator.language')) {
|
|
248
249
|
preferences.language = _.get(preferences, 'navigator.language');
|
|
249
250
|
}
|
|
251
|
+
if (_.get(preferences, 'navigator.maxTouchPoints')) {
|
|
252
|
+
preferences.navigator.max_touch_points = _.get(preferences, 'navigator.maxTouchPoints');
|
|
253
|
+
}
|
|
250
254
|
|
|
255
|
+
if (_.get(preferences, 'isM1')) {
|
|
256
|
+
preferences.is_m1 = _.get(preferences, 'isM1');
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
preferences.mediaDevices = {
|
|
260
|
+
enable: preferences.mediaDevices.enableMasking,
|
|
261
|
+
videoInputs: preferences.mediaDevices.videoInputs,
|
|
262
|
+
audioInputs: preferences.mediaDevices.audioInputs,
|
|
263
|
+
audioOutputs: preferences.mediaDevices.audioOutputs,
|
|
264
|
+
}
|
|
265
|
+
|
|
251
266
|
return preferences;
|
|
252
267
|
}
|
|
253
268
|
|
|
@@ -392,13 +407,16 @@ class GoLogin {
|
|
|
392
407
|
}
|
|
393
408
|
|
|
394
409
|
let extSettings;
|
|
395
|
-
if (ExtensionsManagerInst.useLocalExtStorage
|
|
396
|
-
extSettings = BrowserUserDataManager.
|
|
397
|
-
} else
|
|
410
|
+
if (ExtensionsManagerInst.useLocalExtStorage) {
|
|
411
|
+
extSettings = BrowserUserDataManager.setExtPathsAndRemoveDeleted(preferences, profileExtensionsCheckRes);
|
|
412
|
+
} else {
|
|
398
413
|
const originalExtensionsFolder = path.join(profilePath, 'Default', 'Extensions');
|
|
399
414
|
extSettings = await BrowserUserDataManager.setOriginalExtPaths(preferences, originalExtensionsFolder);
|
|
400
415
|
}
|
|
401
416
|
|
|
417
|
+
this.extensionPathsToInstall =
|
|
418
|
+
ExtensionsManagerInst.getExtensionsToInstall(extSettings, profileExtensionsCheckRes);
|
|
419
|
+
|
|
402
420
|
if (extSettings) {
|
|
403
421
|
const currentExtSettings = preferences.extensions || {};
|
|
404
422
|
currentExtSettings.settings = extSettings
|
|
@@ -458,10 +476,16 @@ class GoLogin {
|
|
|
458
476
|
};
|
|
459
477
|
|
|
460
478
|
debug('profile.webRtc=', profile.webRtc);
|
|
479
|
+
debug('profile.timezone=', profile.timezone);
|
|
480
|
+
debug('profile.mediaDevices=', profile.mediaDevices);
|
|
461
481
|
|
|
462
482
|
const audioContext = profile.audioContext || {};
|
|
463
483
|
const { mode: audioCtxMode = 'off', noise: audioCtxNoise } = audioContext;
|
|
464
|
-
profile.timezone
|
|
484
|
+
if(profile.timezone.fillBasedOnIp==false){
|
|
485
|
+
profile.timezone = { id: profile.timezone.timezone };
|
|
486
|
+
} else {
|
|
487
|
+
profile.timezone = { id: this._tz.timezone };
|
|
488
|
+
}
|
|
465
489
|
profile.webgl_noise_value = profile.webGL.noise;
|
|
466
490
|
profile.get_client_rects_noise = profile.webGL.getClientRectsNoise;
|
|
467
491
|
profile.canvasMode = profile.canvas.mode;
|
|
@@ -484,10 +508,10 @@ class GoLogin {
|
|
|
484
508
|
|
|
485
509
|
const gologin = this.convertPreferences(profile);
|
|
486
510
|
|
|
487
|
-
debug(`Writing profile for screenWidth ${profilePath}`, JSON.stringify(
|
|
511
|
+
debug(`Writing profile for screenWidth ${profilePath}`, JSON.stringify(gologin));
|
|
488
512
|
gologin.screenWidth = this.resolution.width;
|
|
489
513
|
gologin.screenHeight = this.resolution.height;
|
|
490
|
-
|
|
514
|
+
debug("writeCookesFromServer", this.writeCookesFromServer)
|
|
491
515
|
if (this.writeCookesFromServer) {
|
|
492
516
|
await this.writeCookiesToFile();
|
|
493
517
|
}
|
|
@@ -513,7 +537,7 @@ class GoLogin {
|
|
|
513
537
|
|
|
514
538
|
preferences.gologin.langHeader = gologin.language;
|
|
515
539
|
preferences.gologin.languages = languages;
|
|
516
|
-
|
|
540
|
+
// debug("convertedPreferences=", preferences.gologin)
|
|
517
541
|
await writeFile(path.join(profilePath, 'Default', 'Preferences'), JSON.stringify(_.merge(preferences, {
|
|
518
542
|
gologin
|
|
519
543
|
})));
|
|
@@ -709,7 +733,7 @@ class GoLogin {
|
|
|
709
733
|
this.port = remote_debugging_port;
|
|
710
734
|
|
|
711
735
|
const ORBITA_BROWSER = this.executablePath || this.browserChecker.getOrbitaPath;
|
|
712
|
-
|
|
736
|
+
console.log("ORBITA_BROWSER=", ORBITA_BROWSER)
|
|
713
737
|
const env = {};
|
|
714
738
|
Object.keys(process.env).forEach((key) => {
|
|
715
739
|
env[key] = process.env[key];
|
|
@@ -743,6 +767,22 @@ class GoLogin {
|
|
|
743
767
|
`--lang=${browserLang}`,
|
|
744
768
|
];
|
|
745
769
|
|
|
770
|
+
if (this.extensionPathsToInstall.length) {
|
|
771
|
+
if (Array.isArray(this.extra_params) && this.extra_params.length) {
|
|
772
|
+
this.extra_params.forEach((param, index) => {
|
|
773
|
+
if (!param.includes('--load-extension=')) {
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
const [_, extPathsString] = param.split('=');
|
|
778
|
+
const extPathsArray = extPathsString.split(',');
|
|
779
|
+
this.extensionPathsToInstall = [...this.extensionPathsToInstall, ...extPathsArray];
|
|
780
|
+
this.extra_params.splice(index, 1);
|
|
781
|
+
});
|
|
782
|
+
}
|
|
783
|
+
params.push(`--load-extension=${this.extensionPathsToInstall.join(',')}`);
|
|
784
|
+
}
|
|
785
|
+
|
|
746
786
|
if (this.fontsMasking) {
|
|
747
787
|
let arg = '--font-masking-mode=2';
|
|
748
788
|
if (this.differentOs) {
|
|
@@ -925,7 +965,7 @@ class GoLogin {
|
|
|
925
965
|
os = options.os;
|
|
926
966
|
}
|
|
927
967
|
|
|
928
|
-
let fingerprint = await requests.get(
|
|
968
|
+
let fingerprint = await requests.get(`${API_URL}/browser/fingerprint?os=${os}`,{
|
|
929
969
|
headers: {
|
|
930
970
|
'Authorization': `Bearer ${this.access_token}`,
|
|
931
971
|
'User-Agent': 'gologin-api',
|
|
@@ -954,7 +994,7 @@ class GoLogin {
|
|
|
954
994
|
if (deviceMemory < 1) {
|
|
955
995
|
deviceMemory = 1;
|
|
956
996
|
}
|
|
957
|
-
navigator.deviceMemory = deviceMemory;
|
|
997
|
+
navigator.deviceMemory = deviceMemory*1024;
|
|
958
998
|
webGLMetadata.mode = webGLMetadata.mode === 'noise' ? 'mask' : 'off';
|
|
959
999
|
|
|
960
1000
|
const json = {
|