gologin 2.0.10 → 2.0.12
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/examples/example-create-custom-profile.js +33 -0
- package/examples/example-create-profile.js +1 -1
- package/examples/example-startremote.js +1 -1
- package/examples/example-stopremote.js +1 -1
- package/package.json +1 -1
- package/src/bookmarks/utils.js +16 -0
- package/src/browser/browser-api.js +24 -0
- package/src/gologin.js +65 -11
- package/src/utils/browser.js +62 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import GoLogin from '../src/gologin.js';
|
|
2
|
+
|
|
3
|
+
(async () => {
|
|
4
|
+
const GL = new GoLogin({
|
|
5
|
+
token: 'yU0token',
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
const profileId = await GL.createCustom({
|
|
9
|
+
os: 'win', // required param ('lin', 'mac', 'win', 'android'), for macM1 write (os: 'mac') and add property 'isM1'
|
|
10
|
+
// isM1: true,
|
|
11
|
+
name: 'testName',
|
|
12
|
+
fingerprint: {
|
|
13
|
+
autoLang: true,
|
|
14
|
+
resolution: '800x400',
|
|
15
|
+
language: 'de',
|
|
16
|
+
dns: 'testDNS',
|
|
17
|
+
hardwareConcurrency: 8,
|
|
18
|
+
deviceMemory: 4, // 0.5, 1, 2, 4, 6, 8
|
|
19
|
+
startUrl: 'https://testurl.com',
|
|
20
|
+
googleServicesEnabled: true,
|
|
21
|
+
lockEnabled: true,
|
|
22
|
+
proxy: {
|
|
23
|
+
mode: 'http',
|
|
24
|
+
host: '123.12.123.12',
|
|
25
|
+
port: 1234,
|
|
26
|
+
username: 'user',
|
|
27
|
+
password: 'password',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
console.log('profile id=', profileId);
|
|
33
|
+
})();
|
package/package.json
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { promises as _promises } from 'fs';
|
|
2
|
+
|
|
3
|
+
const { readFile } = _promises;
|
|
4
|
+
|
|
5
|
+
export const getCurrentProfileBookmarks = async (pathToBookmarks) => {
|
|
6
|
+
const currentBookmarksFileData = await readFile(pathToBookmarks, { encoding: 'utf-8' });
|
|
7
|
+
|
|
8
|
+
let bookmarks = {};
|
|
9
|
+
try {
|
|
10
|
+
bookmarks = JSON.parse(currentBookmarksFileData);
|
|
11
|
+
} catch (error) {
|
|
12
|
+
console.log(error);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return bookmarks;
|
|
16
|
+
};
|
|
@@ -69,3 +69,27 @@ export const updateProfileProxy = (profileId, ACCESS_TOKEN, browserProxyData) =>
|
|
|
69
69
|
|
|
70
70
|
return { body: [] };
|
|
71
71
|
});
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @param {string} profileId
|
|
75
|
+
* @param {string} ACCESS_TOKEN
|
|
76
|
+
* @param {Object} bookmarks
|
|
77
|
+
*/
|
|
78
|
+
export const updateProfileBookmarks = async (profileIds, ACCESS_TOKEN, bookmarks) => {
|
|
79
|
+
const params = {
|
|
80
|
+
profileIds,
|
|
81
|
+
bookmarks,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
return requestretry.patch(`${API_URL}/browser/bookmarks/many`, {
|
|
85
|
+
headers: {
|
|
86
|
+
Authorization: `Bearer ${ACCESS_TOKEN}`,
|
|
87
|
+
'user-agent': 'gologin-api',
|
|
88
|
+
},
|
|
89
|
+
json: params,
|
|
90
|
+
maxAttempts: 3,
|
|
91
|
+
retryDelay: 2000,
|
|
92
|
+
timeout: 10 * 1000,
|
|
93
|
+
}).catch((error) => console.log(error));
|
|
94
|
+
};
|
|
95
|
+
|
package/src/gologin.js
CHANGED
|
@@ -11,15 +11,17 @@ import rimraf from 'rimraf';
|
|
|
11
11
|
import ProxyAgent from 'simple-proxy-agent';
|
|
12
12
|
|
|
13
13
|
import { fontsCollection } from '../fonts.js';
|
|
14
|
-
import {
|
|
14
|
+
import { getCurrentProfileBookmarks } from './bookmarks/utils.js';
|
|
15
|
+
import { updateProfileBookmarks, updateProfileProxy, updateProfileResolution, updateProfileUserAgent } from './browser/browser-api.js';
|
|
15
16
|
import BrowserChecker from './browser/browser-checker.js';
|
|
16
17
|
import { composeFonts, downloadCookies, setExtPathsAndRemoveDeleted,
|
|
17
18
|
setOriginalExtPaths, uploadCookies } from './browser/browser-user-data-manager.js';
|
|
18
19
|
import { getChunckedInsertValues, getDB, loadCookiesFromFile } from './cookies/cookies-manager.js';
|
|
19
20
|
import ExtensionsManager from './extensions/extensions-manager.js';
|
|
20
21
|
import { archiveProfile } from './profile/profile-archiver.js';
|
|
21
|
-
import {
|
|
22
|
+
import { checkAutoLang } from './utils/browser.js';
|
|
22
23
|
import { API_URL } from './utils/common.js';
|
|
24
|
+
import { get, isPortReachable } from './utils/utils.js';
|
|
23
25
|
|
|
24
26
|
const { access, unlink, writeFile, readFile } = _promises;
|
|
25
27
|
|
|
@@ -32,6 +34,7 @@ const delay = (time) => new Promise((resolve) => setTimeout(resolve, time));
|
|
|
32
34
|
|
|
33
35
|
export class GoLogin {
|
|
34
36
|
constructor(options = {}) {
|
|
37
|
+
this.browserLang = 'en-US';
|
|
35
38
|
this.is_remote = options.remote || false;
|
|
36
39
|
this.access_token = options.token;
|
|
37
40
|
this.profile_id = options.profile_id;
|
|
@@ -69,6 +72,7 @@ export class GoLogin {
|
|
|
69
72
|
|
|
70
73
|
this.cookiesFilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`, 'Default', 'Network', 'Cookies');
|
|
71
74
|
this.profile_zip_path = join(this.tmpdir, `gologin_${this.profile_id}.zip`);
|
|
75
|
+
this.bookmarksFilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`, 'Default', 'Bookmarks');
|
|
72
76
|
debug('INIT GOLOGIN', this.profile_id);
|
|
73
77
|
}
|
|
74
78
|
|
|
@@ -255,8 +259,13 @@ export class GoLogin {
|
|
|
255
259
|
preferences.hardwareConcurrency = get(preferences, 'navigator.hardwareConcurrency');
|
|
256
260
|
}
|
|
257
261
|
|
|
262
|
+
if (get(preferences, 'navigator.deviceMemory')) {
|
|
263
|
+
preferences.deviceMemory = get(preferences, 'navigator.deviceMemory')*1024;
|
|
264
|
+
}
|
|
265
|
+
|
|
258
266
|
if (get(preferences, 'navigator.language')) {
|
|
259
|
-
preferences.
|
|
267
|
+
preferences.langHeader = get(preferences, 'navigator.language');
|
|
268
|
+
preferences.languages = get(preferences, 'navigator.language').replace(/;|q=[\d\.]+/img, '');
|
|
260
269
|
}
|
|
261
270
|
|
|
262
271
|
if (get(preferences, 'navigator.maxTouchPoints')) {
|
|
@@ -290,6 +299,12 @@ export class GoLogin {
|
|
|
290
299
|
audioOutputs: preferences.mediaDevices.audioOutputs,
|
|
291
300
|
};
|
|
292
301
|
|
|
302
|
+
preferences.webRtc = {
|
|
303
|
+
...preferences.webRtc,
|
|
304
|
+
fill_based_on_ip: !!get(preferences, 'webRTC.fillBasedOnIp'),
|
|
305
|
+
local_ip_masking: !!get(preferences, 'webRTC.local_ip_masking'),
|
|
306
|
+
};
|
|
307
|
+
|
|
293
308
|
return preferences;
|
|
294
309
|
}
|
|
295
310
|
|
|
@@ -584,19 +599,32 @@ export class GoLogin {
|
|
|
584
599
|
}
|
|
585
600
|
}
|
|
586
601
|
|
|
587
|
-
const languages = this.language.replace(/;|q=[\d\.]+/img, '')
|
|
602
|
+
const languages = this.language.replace(/;|q=[\d\.]+/img, '');
|
|
588
603
|
|
|
589
604
|
if (preferences.gologin==null) {
|
|
590
605
|
preferences.gologin = {};
|
|
591
606
|
}
|
|
592
607
|
|
|
593
|
-
preferences.gologin.langHeader = gologin.language;
|
|
608
|
+
preferences.gologin.langHeader = gologin.navigator.language;
|
|
594
609
|
preferences.gologin.language = languages;
|
|
595
610
|
|
|
611
|
+
const [splittedLangs] = gologin.navigator.language.split(';');
|
|
612
|
+
const [browserLang] = splittedLangs.split(',');
|
|
613
|
+
gologin.browserLang = browserLang;
|
|
614
|
+
|
|
615
|
+
const isMAC = OS_PLATFORM === 'darwin';
|
|
616
|
+
const checkAutoLangResult = checkAutoLang(gologin, this._tz);
|
|
617
|
+
this.browserLang = isMAC ? 'en-US' : checkAutoLangResult;
|
|
618
|
+
|
|
596
619
|
await writeFile(join(profilePath, 'Default', 'Preferences'), JSON.stringify(Object.assign(preferences, {
|
|
597
620
|
gologin,
|
|
598
621
|
})));
|
|
599
622
|
|
|
623
|
+
const bookmarksParsedData = await getCurrentProfileBookmarks(this.bookmarksFilePath);
|
|
624
|
+
const bookmarksFromDb = profile.bookmarks?.bookmark_bar;
|
|
625
|
+
bookmarksParsedData.roots = bookmarksFromDb ? profile.bookmarks : bookmarksParsedData.roots;
|
|
626
|
+
await writeFile(this.bookmarksFilePath, JSON.stringify(bookmarksParsedData));
|
|
627
|
+
|
|
600
628
|
debug('Profile ready. Path: ', profilePath, 'PROXY', JSON.stringify(get(preferences, 'gologin.proxy')));
|
|
601
629
|
|
|
602
630
|
return profilePath;
|
|
@@ -820,18 +848,13 @@ export class GoLogin {
|
|
|
820
848
|
{ env },
|
|
821
849
|
);
|
|
822
850
|
} else {
|
|
823
|
-
const [splittedLangs] = this.language.split(';');
|
|
824
|
-
let [browserLang] = splittedLangs.split(',');
|
|
825
|
-
if (process.platform === 'darwin') {
|
|
826
|
-
browserLang = 'en-US';
|
|
827
|
-
}
|
|
828
851
|
|
|
829
852
|
let params = [
|
|
830
853
|
`--remote-debugging-port=${remote_debugging_port}`,
|
|
831
854
|
`--user-data-dir=${profile_path}`,
|
|
832
855
|
'--password-store=basic',
|
|
833
856
|
`--tz=${tz}`,
|
|
834
|
-
`--lang=${browserLang}`,
|
|
857
|
+
`--lang=${this.browserLang}`,
|
|
835
858
|
];
|
|
836
859
|
|
|
837
860
|
if (this.extensionPathsToInstall.length) {
|
|
@@ -922,6 +945,8 @@ export class GoLogin {
|
|
|
922
945
|
await this.uploadProfileCookiesToServer();
|
|
923
946
|
}
|
|
924
947
|
|
|
948
|
+
await this.saveBookmarksToDb();
|
|
949
|
+
|
|
925
950
|
this.is_stopping = true;
|
|
926
951
|
await this.sanitizeProfile();
|
|
927
952
|
|
|
@@ -1120,6 +1145,29 @@ export class GoLogin {
|
|
|
1120
1145
|
return response.body.id;
|
|
1121
1146
|
}
|
|
1122
1147
|
|
|
1148
|
+
async createCustom(options) {
|
|
1149
|
+
debug('createCustomProfile', options);
|
|
1150
|
+
const response = await requests.post(`${API_URL}/browser/custom`, {
|
|
1151
|
+
headers: {
|
|
1152
|
+
'Authorization': `Bearer ${this.access_token}`,
|
|
1153
|
+
'User-Agent': 'gologin-api',
|
|
1154
|
+
},
|
|
1155
|
+
json: options,
|
|
1156
|
+
});
|
|
1157
|
+
|
|
1158
|
+
if (response.statusCode === 400) {
|
|
1159
|
+
throw new Error(`gologin failed account creation with status code, ${response.statusCode} DATA ${JSON.stringify(response.body.message)}`);
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
if (response.statusCode === 500) {
|
|
1163
|
+
throw new Error(`gologin failed account creation with status code, ${response.statusCode}`);
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
debug(JSON.stringify(response));
|
|
1167
|
+
|
|
1168
|
+
return response.body.id;
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1123
1171
|
async delete(pid) {
|
|
1124
1172
|
const profile_id = pid || this.profile_id;
|
|
1125
1173
|
await requests.delete(`${API_URL}/browser/${profile_id}`, {
|
|
@@ -1250,6 +1298,12 @@ export class GoLogin {
|
|
|
1250
1298
|
return this.postCookies(this.profile_id, cookies);
|
|
1251
1299
|
}
|
|
1252
1300
|
|
|
1301
|
+
async saveBookmarksToDb() {
|
|
1302
|
+
const bookmarksData = await getCurrentProfileBookmarks(this.bookmarksFilePath);
|
|
1303
|
+
const bookmarks = bookmarksData.roots || {};
|
|
1304
|
+
await updateProfileBookmarks([this.profile_id], this.access_token, bookmarks);
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1253
1307
|
async start() {
|
|
1254
1308
|
if (this.is_remote) {
|
|
1255
1309
|
return this.startRemote();
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export const checkAutoLang = (profileData, timezoneCheckResult) => {
|
|
2
|
+
if (!profileData.autoLang) {
|
|
3
|
+
return checkBrowserLang(profileData);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
let timezoneLang = '';
|
|
7
|
+
const { country: timezoneCountry = '', languages } = timezoneCheckResult || {};
|
|
8
|
+
if (languages) {
|
|
9
|
+
const [firstDetectedLangLocale] = languages.split(',');
|
|
10
|
+
timezoneLang = `${firstDetectedLangLocale}-${timezoneCountry}` || '';
|
|
11
|
+
|
|
12
|
+
let resultLangsArr = [];
|
|
13
|
+
const [lang = '', country = ''] = timezoneLang.split('-');
|
|
14
|
+
if (country) {
|
|
15
|
+
resultLangsArr.push([lang, country].join('-'));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
resultLangsArr.push(lang, 'en-US', 'en');
|
|
19
|
+
resultLangsArr = [...new Set(resultLangsArr)];
|
|
20
|
+
|
|
21
|
+
const gologinLangsArr = [];
|
|
22
|
+
const result = resultLangsArr.reduce((acc, cur, index) => {
|
|
23
|
+
if (!index) {
|
|
24
|
+
acc += `${cur},`;
|
|
25
|
+
gologinLangsArr.push(cur);
|
|
26
|
+
|
|
27
|
+
return acc;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const qualityParam = 10-index;
|
|
31
|
+
if (qualityParam > 0) {
|
|
32
|
+
const separator = (resultLangsArr.length - index) < 2 ? '' : ',';
|
|
33
|
+
gologinLangsArr.push(cur);
|
|
34
|
+
acc += `${cur};q=${Number(qualityParam * 0.1).toFixed(1)}${separator}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return acc;
|
|
38
|
+
}, '');
|
|
39
|
+
|
|
40
|
+
[profileData.browserLang] = resultLangsArr;
|
|
41
|
+
profileData.languages = gologinLangsArr.join(',');
|
|
42
|
+
profileData.langHeader = result;
|
|
43
|
+
profileData.navigator.language = result;
|
|
44
|
+
|
|
45
|
+
return profileData.browserLang;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return checkBrowserLang(profileData);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const checkBrowserLang = (profileData, defaultLocale = 'en-US') => {
|
|
52
|
+
if (profileData.langHeader) {
|
|
53
|
+
return profileData.browserLang;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
profileData.browserLang = defaultLocale;
|
|
57
|
+
profileData.languages = defaultLocale;
|
|
58
|
+
profileData.langHeader = defaultLocale;
|
|
59
|
+
profileData.navigator.language = defaultLocale;
|
|
60
|
+
|
|
61
|
+
return defaultLocale;
|
|
62
|
+
};
|