gologin 2.2.8 → 3.0.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/CHANGELOG.md +18 -0
- package/api.d.ts +105 -0
- package/examples/puppeter/cloud-browser.js +25 -14
- package/index.d.ts +46 -105
- package/package.json +16 -4
- package/src/browser/browser-checker.js +3 -2
- package/src/browser/browser-user-data-manager.js +4 -89
- package/src/cookies/cookies-manager.js +30 -15
- package/src/extensions/extensions-extractor.js +7 -5
- package/src/extensions/extensions-manager.js +10 -22
- package/src/extensions/user-extensions-manager.js +3 -6
- package/src/gologin-api.js +16 -4
- package/src/gologin.js +273 -220
- package/src/index.js +2 -0
- package/src/profile/profile-archiver.js +10 -1
- package/src/profile/profile-directories-to-remove.js +5 -0
- package/src/utils/http.js +326 -30
- package/src/utils/lazy-deps.js +206 -0
- package/src/utils/sentry.js +9 -2
- package/Orbita-Browser.app/Contents/MacOS/Orbita +0 -0
- package/fonts.js +0 -4293
- package/fonts_config +0 -104
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
Combined changelog for GoLogin node.js SDK
|
|
4
4
|
|
|
5
|
+
## [3.0.0] 2026-06-24
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* Impoved package initialization speed and profile start speed
|
|
10
|
+
* Replaced request npm package with native fetch
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## [2.2.9] 2026-06-08
|
|
14
|
+
|
|
15
|
+
### Fixes
|
|
16
|
+
|
|
17
|
+
* Disabled fonts downloading which was throwing errors
|
|
18
|
+
* Type fixes
|
|
19
|
+
* Added Proxy Error message to socks5 proxies check fails
|
|
20
|
+
* Added (Gologin) prefix where gologin proxies failed
|
|
21
|
+
* Profile start timing optimization
|
|
22
|
+
|
|
5
23
|
## [2.2.7] 2026-02-06
|
|
6
24
|
|
|
7
25
|
### Fixes
|
package/api.d.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Browser } from 'puppeteer-core/lib/Browser';
|
|
2
|
+
|
|
3
|
+
import { CreateCustomBrowserValidation, BrowserProxyCreateValidation } from './types/profile-params';
|
|
4
|
+
|
|
5
|
+
export declare const OPERATING_SYSTEMS: {
|
|
6
|
+
readonly win: 'win';
|
|
7
|
+
readonly lin: 'lin';
|
|
8
|
+
readonly mac: 'mac';
|
|
9
|
+
readonly android: 'android';
|
|
10
|
+
};
|
|
11
|
+
export type OsType = (typeof OPERATING_SYSTEMS)[keyof typeof OPERATING_SYSTEMS];
|
|
12
|
+
|
|
13
|
+
type CloudLaunchParams = {
|
|
14
|
+
cloud: true;
|
|
15
|
+
geolocation?: string;
|
|
16
|
+
};
|
|
17
|
+
type LocalLaunchParams = {
|
|
18
|
+
cloud: false;
|
|
19
|
+
headless: boolean;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type ExistingProfileLaunchParams = {
|
|
23
|
+
profileId: string;
|
|
24
|
+
};
|
|
25
|
+
type NewProfileLaunchParams = {
|
|
26
|
+
proxyGeolocation: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type LaunchParams =
|
|
30
|
+
| CloudLaunchParams
|
|
31
|
+
| LocalLaunchParams
|
|
32
|
+
| ExistingProfileLaunchParams
|
|
33
|
+
| NewProfileLaunchParams
|
|
34
|
+
| {
|
|
35
|
+
defaultDelay: number;
|
|
36
|
+
os: OsType;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
type Cookie = {
|
|
40
|
+
name: string;
|
|
41
|
+
value: string;
|
|
42
|
+
domain: string;
|
|
43
|
+
path: string;
|
|
44
|
+
expirationDate?: number;
|
|
45
|
+
creationDate?: number;
|
|
46
|
+
hostOnly?: boolean;
|
|
47
|
+
httpOnly?: boolean;
|
|
48
|
+
sameSite?: 'no_restriction' | 'lax' | 'strict';
|
|
49
|
+
secure?: boolean;
|
|
50
|
+
session?: boolean;
|
|
51
|
+
url?: string;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
type TrafficData = {
|
|
55
|
+
trafficUsedBytes: number;
|
|
56
|
+
trafficLimitBytes: number;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
type AvailableTrafficData = {
|
|
60
|
+
mobileTrafficData: TrafficData;
|
|
61
|
+
residentialTrafficData: TrafficData;
|
|
62
|
+
dataCenterTrafficData: TrafficData;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
type ProxyType = 'mobile' | 'resident' | 'dataCenter';
|
|
66
|
+
|
|
67
|
+
type ProxyResponse = {
|
|
68
|
+
trafficLimitBytes: number;
|
|
69
|
+
trafficUsedBytes: number;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type ProfileResponse = {
|
|
73
|
+
id: string;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
type GologinApiType = {
|
|
77
|
+
launch: (params?: LaunchParams) => Promise<{ browser: Browser }>;
|
|
78
|
+
createProfileWithCustomParams: (options: CreateCustomBrowserValidation) => Promise<string>;
|
|
79
|
+
refreshProfilesFingerprint: (profileIds: string[]) => Promise<Record<string, unknown>>;
|
|
80
|
+
createProfileRandomFingerprint: (name?: string) => Promise<ProfileResponse>;
|
|
81
|
+
updateUserAgentToLatestBrowser: (profileIds: string[], workspaceId?: string) => Promise<Record<string, unknown>>;
|
|
82
|
+
changeProfileProxy: (profileId: string, proxyData: BrowserProxyCreateValidation) => Promise<number>;
|
|
83
|
+
getAvailableType: (availableTrafficData: AvailableTrafficData) => ProxyType | 'none';
|
|
84
|
+
addGologinProxyToProfile: (profileId: string, countryCode: string, proxyType?: ProxyType | '') => Promise<ProxyResponse>;
|
|
85
|
+
addCookiesToProfile: (profileId: string, cookies: Cookie[]) => Promise<number>;
|
|
86
|
+
deleteProfile: (profileId: string) => Promise<number>;
|
|
87
|
+
exit: () => Promise<void>;
|
|
88
|
+
createCustom: (params: CreateCustomBrowserValidation) => Promise<string>;
|
|
89
|
+
updateProfileFingerprint: (profileId: string[]) => Promise<void>;
|
|
90
|
+
updateProfileProxy: (profileId: string, proxyData: BrowserProxyCreateValidation) => Promise<void>;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
type GologinApiParams = {
|
|
94
|
+
token: string;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export declare function getDefaultParams(): {
|
|
98
|
+
token: string | undefined;
|
|
99
|
+
profile_id: string | undefined;
|
|
100
|
+
executablePath: string | undefined;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export declare function GologinApi(params: GologinApiParams): GologinApiType;
|
|
104
|
+
|
|
105
|
+
export declare function exitAll(): Promise<void>;
|
|
@@ -1,17 +1,31 @@
|
|
|
1
|
-
// Gologin provides a cloud browser that can be used to run puppeteer
|
|
2
|
-
// It will handle the browser start and close management - you just need to control the browser with
|
|
3
|
-
import
|
|
1
|
+
// Gologin provides a cloud browser that can be used to run puppeteer automation.
|
|
2
|
+
// It will handle the browser start and close management - you just need to control the browser with puppeteer
|
|
3
|
+
import puppeteer from 'puppeteer-core';
|
|
4
4
|
|
|
5
5
|
const token = process.env.GL_API_TOKEN || 'your dev token here';
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
}
|
|
6
|
+
const profileId = 'profile ID';
|
|
7
|
+
|
|
8
|
+
const CLOUD_BROWSER_URL = `https://cloudbrowser.gologin.com/connect?token=${token}&profile=${profileId}`;
|
|
9
|
+
const STOP_PROFILE_URL = `https://api.gologin.com/browser/${profileId}/web`;
|
|
10
|
+
|
|
11
|
+
async function stopProfile() {
|
|
12
|
+
await fetch(STOP_PROFILE_URL, {
|
|
13
|
+
method: 'DELETE',
|
|
14
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
15
|
+
});
|
|
16
|
+
}
|
|
9
17
|
|
|
10
18
|
async function main() {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
const response = await fetch(CLOUD_BROWSER_URL);
|
|
20
|
+
|
|
21
|
+
if (!response.ok) {
|
|
22
|
+
const errorReason = response.headers.get('X-Error-Reason');
|
|
23
|
+
throw new Error(`Failed to start cloud browser: ${errorReason ?? response.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const browser = await puppeteer.connect({
|
|
27
|
+
browserWSEndpoint: CLOUD_BROWSER_URL,
|
|
28
|
+
ignoreHTTPSErrors: true,
|
|
15
29
|
});
|
|
16
30
|
|
|
17
31
|
const page = await browser.newPage();
|
|
@@ -21,10 +35,7 @@ async function main() {
|
|
|
21
35
|
(elt) => elt?.innerText?.trim(),
|
|
22
36
|
);
|
|
23
37
|
|
|
24
|
-
console.log('status', status);
|
|
25
|
-
|
|
26
38
|
return status;
|
|
27
39
|
}
|
|
28
40
|
|
|
29
|
-
main().catch(console.error)
|
|
30
|
-
.finally(gologin.exit);
|
|
41
|
+
main().catch(console.error).finally(stopProfile);
|
package/index.d.ts
CHANGED
|
@@ -1,105 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
type
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
httpOnly?: boolean;
|
|
48
|
-
sameSite?: 'no_restriction' | 'lax' | 'strict';
|
|
49
|
-
secure?: boolean;
|
|
50
|
-
session?: boolean;
|
|
51
|
-
url?: string;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
type TrafficData = {
|
|
55
|
-
trafficUsedBytes: number;
|
|
56
|
-
trafficLimitBytes: number;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
type AvailableTrafficData = {
|
|
60
|
-
mobileTrafficData: TrafficData;
|
|
61
|
-
residentialTrafficData: TrafficData;
|
|
62
|
-
dataCenterTrafficData: TrafficData;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
type ProxyType = 'mobile' | 'resident' | 'dataCenter';
|
|
66
|
-
|
|
67
|
-
type ProxyResponse = {
|
|
68
|
-
trafficLimitBytes: number;
|
|
69
|
-
trafficUsedBytes: number;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
type ProfileResponse = {
|
|
73
|
-
id: string;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
type GologinApiType = {
|
|
77
|
-
launch: (params?: LaunchParams) => Promise<{ browser: Browser }>;
|
|
78
|
-
createProfileWithCustomParams: (options: CreateCustomBrowserValidation) => Promise<string>;
|
|
79
|
-
refreshProfilesFingerprint: (profileIds: string[]) => Promise<any>;
|
|
80
|
-
createProfileRandomFingerprint: (name?: string) => Promise<ProfileResponse>;
|
|
81
|
-
updateUserAgentToLatestBrowser: (profileIds: string[], workspaceId?: string) => Promise<any>;
|
|
82
|
-
changeProfileProxy: (profileId: string, proxyData: BrowserProxyCreateValidation) => Promise<number>;
|
|
83
|
-
getAvailableType: (availableTrafficData: AvailableTrafficData) => ProxyType | 'none';
|
|
84
|
-
addGologinProxyToProfile: (profileId: string, countryCode: string, proxyType?: ProxyType | '') => Promise<ProxyResponse>;
|
|
85
|
-
addCookiesToProfile: (profileId: string, cookies: Cookie[]) => Promise<number>;
|
|
86
|
-
deleteProfile: (profileId: string) => Promise<number>;
|
|
87
|
-
exit: () => Promise<void>;
|
|
88
|
-
createCustom: (params: CreateCustomBrowserValidation) => Promise<string>;
|
|
89
|
-
updateProfileFingerprint: (profileId: string[]) => Promise<void>;
|
|
90
|
-
updateProfileProxy: (profileId: string, proxyData: BrowserProxyCreateValidation) => Promise<void>;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
type GologinApiParams = {
|
|
94
|
-
token: string;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
export declare function getDefaultParams(): {
|
|
98
|
-
token: string | undefined;
|
|
99
|
-
profile_id: string | undefined;
|
|
100
|
-
executablePath: string | undefined;
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export declare function GologinApi(params: GologinApiParams): GologinApiType;
|
|
104
|
-
|
|
105
|
-
export declare function exitAll(): Promise<void>;
|
|
1
|
+
export type GoLoginOptions = {
|
|
2
|
+
token?: string;
|
|
3
|
+
profile_id?: string;
|
|
4
|
+
password?: string;
|
|
5
|
+
extra_params?: string[];
|
|
6
|
+
executablePath?: string;
|
|
7
|
+
vncPort?: number;
|
|
8
|
+
tmpdir?: string;
|
|
9
|
+
waitWebsocket?: boolean;
|
|
10
|
+
isCloudHeadless?: boolean;
|
|
11
|
+
skipOrbitaHashChecking?: boolean;
|
|
12
|
+
uploadCookiesToServer?: boolean;
|
|
13
|
+
writeCookiesFromServer?: boolean;
|
|
14
|
+
remote_debugging_port?: number;
|
|
15
|
+
timezone?: { timezone: string; country?: string; city?: string; ip?: string; ll?: [number, number]; accuracy?: number, stateProv?: string, languages?: string };
|
|
16
|
+
args?: string[];
|
|
17
|
+
restoreLastSession?: boolean;
|
|
18
|
+
browserMajorVersion?: number;
|
|
19
|
+
proxyCheckTimeout?: number;
|
|
20
|
+
proxyCheckAttempts?: number;
|
|
21
|
+
autoUpdateBrowser?: boolean;
|
|
22
|
+
checkBrowserUpdate?: boolean;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type GoLoginStartResult = {
|
|
26
|
+
status: 'success';
|
|
27
|
+
wsUrl: string;
|
|
28
|
+
resolution?: { width: number; height: number };
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export { GologinApi, getDefaultParams, exitAll } from './api.d.ts';
|
|
32
|
+
|
|
33
|
+
export declare class GoLogin {
|
|
34
|
+
constructor(options?: GoLoginOptions);
|
|
35
|
+
start(): Promise<GoLoginStartResult>;
|
|
36
|
+
stop(): Promise<void>;
|
|
37
|
+
startLocal(): Promise<{ status: string, wsUrl: string }>;
|
|
38
|
+
stopLocal(options?: { posting?: boolean }): Promise<void>;
|
|
39
|
+
setProfileId(profile_id: string): Promise<void>;
|
|
40
|
+
getProfile(profile_id?: string): Promise<Record<string, unknown>>;
|
|
41
|
+
quickCreateProfile(name?: string): Promise<{ id: string }>;
|
|
42
|
+
profilePath(): string;
|
|
43
|
+
commitProfile(): Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default GoLogin;
|
package/package.json
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gologin",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "A high-level API to control Orbita browser over GoLogin API",
|
|
5
5
|
"types": "./index.d.ts",
|
|
6
|
-
"main": "./src/
|
|
6
|
+
"main": "./src/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./index.d.ts",
|
|
10
|
+
"import": "./src/index.js"
|
|
11
|
+
},
|
|
12
|
+
"./api": {
|
|
13
|
+
"types": "./api.d.ts",
|
|
14
|
+
"import": "./src/gologin-api.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
7
17
|
"repository": {
|
|
8
18
|
"type": "git",
|
|
9
19
|
"url": "git+https://github.com/gologinapp/gologin.git"
|
|
@@ -14,6 +24,9 @@
|
|
|
14
24
|
"type": "module",
|
|
15
25
|
"author": "The GoLogin Authors",
|
|
16
26
|
"license": "GPL-3.0",
|
|
27
|
+
"overrides": {
|
|
28
|
+
"https-proxy-agent": "$https-proxy-agent"
|
|
29
|
+
},
|
|
17
30
|
"dependencies": {
|
|
18
31
|
"@sentry/node": "^9.24.0",
|
|
19
32
|
"adm-zip": "^0.5.1",
|
|
@@ -22,10 +35,9 @@
|
|
|
22
35
|
"decompress": "^4.2.1",
|
|
23
36
|
"decompress-unzip": "^4.0.1",
|
|
24
37
|
"form-data": "^3.0.0",
|
|
38
|
+
"https-proxy-agent": "^7.0.6",
|
|
25
39
|
"progress": "^2.0.3",
|
|
26
40
|
"puppeteer-core": "^2.1.1",
|
|
27
|
-
"request": "^2.88.2",
|
|
28
|
-
"requestretry": "^4.1.0",
|
|
29
41
|
"rimraf": "^3.0.2",
|
|
30
42
|
"socks-proxy-agent": "^8.0.3",
|
|
31
43
|
"sqlite": "^4.0.23",
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { exec as execNonPromise } from 'child_process';
|
|
2
|
-
import decompress from 'decompress';
|
|
3
|
-
import decompressUnzip from 'decompress-unzip';
|
|
4
2
|
import { createWriteStream, promises as _promises } from 'fs';
|
|
5
3
|
import { get } from 'https';
|
|
6
4
|
import { homedir } from 'os';
|
|
@@ -10,6 +8,7 @@ import util from 'util';
|
|
|
10
8
|
|
|
11
9
|
import { API_URL, getOS } from '../utils/common.js';
|
|
12
10
|
import { makeRequest } from '../utils/http.js';
|
|
11
|
+
import { loadDecompress } from '../utils/lazy-deps.js';
|
|
13
12
|
import BrowserDownloadLockManager from './browser-download-manager.js';
|
|
14
13
|
|
|
15
14
|
const exec = util.promisify(execNonPromise);
|
|
@@ -202,6 +201,8 @@ export class BrowserChecker {
|
|
|
202
201
|
console.log('Extracting Orbita');
|
|
203
202
|
await mkdir(join(this.browserPath, EXTRACTED_FOLDER), { recursive: true });
|
|
204
203
|
if (PLATFORM === 'win32') {
|
|
204
|
+
const { decompress, decompressUnzip } = await loadDecompress();
|
|
205
|
+
|
|
205
206
|
return decompress(join(this.browserPath, BROWSER_ARCHIVE_NAME), join(this.browserPath, EXTRACTED_FOLDER),
|
|
206
207
|
{
|
|
207
208
|
plugins: [decompressUnzip()],
|
|
@@ -1,24 +1,13 @@
|
|
|
1
1
|
import { createHash } from 'crypto';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
2
|
+
import { promises as _promises } from 'fs';
|
|
3
|
+
import { tmpdir } from 'os';
|
|
4
|
+
import { join, sep } from 'path';
|
|
6
5
|
|
|
7
|
-
import { fontsCollection } from '../../fonts.js';
|
|
8
6
|
import { FALLBACK_API_URL } from '../utils/common.js';
|
|
9
7
|
import { makeRequest } from '../utils/http.js';
|
|
10
8
|
|
|
11
|
-
const {
|
|
9
|
+
const { readFile, readdir, rename } = _promises;
|
|
12
10
|
|
|
13
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
-
const __dirname = dirname(__filename);
|
|
15
|
-
|
|
16
|
-
const FONTS_URL = 'https://fonts.gologin.com/';
|
|
17
|
-
const FONTS_DIR_NAME = 'fonts';
|
|
18
|
-
|
|
19
|
-
const HOMEDIR = homedir();
|
|
20
|
-
const BROWSER_PATH = join(HOMEDIR, '.gologin', 'browser');
|
|
21
|
-
const OS_PLATFORM = process.platform;
|
|
22
11
|
const DEFAULT_ORBITA_EXTENSIONS_NAMES = ['Google Hangouts', 'Chromium PDF Viewer', 'CryptoTokenExtension', 'Web Store'];
|
|
23
12
|
const GOLOGIN_BASE_FOLDER_NAME = '.gologin';
|
|
24
13
|
const GOLOGIN_TEST_FOLDER_NAME = '.gologin_test';
|
|
@@ -56,80 +45,6 @@ export const uploadCookies = ({ cookies = [], profileId, ACCESS_TOKEN, API_BASE_
|
|
|
56
45
|
return e;
|
|
57
46
|
});
|
|
58
47
|
|
|
59
|
-
export const downloadFonts = async (fontsList = [], profilePath) => {
|
|
60
|
-
if (!fontsList.length) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const browserFontsPath = join(BROWSER_PATH, FONTS_DIR_NAME);
|
|
65
|
-
await mkdir(browserFontsPath, { recursive: true });
|
|
66
|
-
|
|
67
|
-
const files = await readdir(browserFontsPath);
|
|
68
|
-
const fontsToDownload = fontsList.filter(font => !files.includes(font));
|
|
69
|
-
|
|
70
|
-
let promises = fontsToDownload.map(async font => {
|
|
71
|
-
const body = await makeRequest(FONTS_URL + font, {
|
|
72
|
-
maxAttempts: 5,
|
|
73
|
-
retryDelay: 2000,
|
|
74
|
-
timeout: 30 * 1000,
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
await writeFile(join(browserFontsPath, font), body);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
if (promises.length) {
|
|
81
|
-
await Promise.all(promises);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
promises = fontsList.map((font) =>
|
|
85
|
-
copyFile(join(browserFontsPath, font), join(profilePath, FONTS_DIR_NAME, font)));
|
|
86
|
-
|
|
87
|
-
await Promise.all(promises);
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
export const composeFonts = async (fontsList = [], profilePath, differentOs = false) => {
|
|
91
|
-
if (!(fontsList.length && profilePath)) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const fontsToDownload = fontsCollection
|
|
96
|
-
.filter(elem => fontsList.includes(elem.value))
|
|
97
|
-
.reduce((res, elem) => res.concat(elem.fileNames || []), []);
|
|
98
|
-
|
|
99
|
-
if (differentOs && !fontsToDownload.length) {
|
|
100
|
-
throw new Error('No fonts to download found. Use getAvailableFonts() method and set some fonts from this list');
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
fontsToDownload.push('LICENSE.txt');
|
|
104
|
-
fontsToDownload.push('OFL.txt');
|
|
105
|
-
|
|
106
|
-
const pathToFontsDir = join(profilePath, FONTS_DIR_NAME);
|
|
107
|
-
const fontsDirExists = await access(pathToFontsDir).then(() => true, () => false);
|
|
108
|
-
if (fontsDirExists) {
|
|
109
|
-
rmdirSync(pathToFontsDir, { recursive: true });
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
await mkdir(pathToFontsDir, { recursive: true });
|
|
113
|
-
await downloadFonts(fontsToDownload, profilePath);
|
|
114
|
-
|
|
115
|
-
if (OS_PLATFORM === 'linux') {
|
|
116
|
-
await copyFontsConfigFile(profilePath);
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
export const copyFontsConfigFile = async (profilePath) => {
|
|
121
|
-
if (!profilePath) {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const fileContent = await readFile(resolve(__dirname, '..', '..', 'fonts_config'), 'utf-8');
|
|
126
|
-
const result = fileContent.replace(/\$\$GOLOGIN_FONTS\$\$/g, join(profilePath, FONTS_DIR_NAME));
|
|
127
|
-
|
|
128
|
-
const defaultFolderPath = join(profilePath, 'Default');
|
|
129
|
-
await mkdir(defaultFolderPath, { recursive: true });
|
|
130
|
-
await writeFile(join(defaultFolderPath, 'fonts_config'), result);
|
|
131
|
-
};
|
|
132
|
-
|
|
133
48
|
export const setExtPathsAndRemoveDeleted = (settings = {}, profileExtensionsCheckRes = [], profileId = '') => {
|
|
134
49
|
const formattedLocalExtArray = profileExtensionsCheckRes.map((el) => {
|
|
135
50
|
const [extFolderName = ''] = el.split(sep).reverse();
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { promises as fsPromises } from 'fs';
|
|
2
2
|
import { join } from 'path';
|
|
3
|
-
import { open } from 'sqlite';
|
|
4
|
-
import sqlite3 from 'sqlite3';
|
|
5
3
|
|
|
6
4
|
import { ensureDirectoryExists } from '../utils/common.js';
|
|
7
5
|
|
|
8
6
|
const { access } = fsPromises;
|
|
9
|
-
const { Database, OPEN_READONLY } = sqlite3;
|
|
10
7
|
|
|
11
8
|
const MAX_SQLITE_VARIABLES = 76;
|
|
12
9
|
|
|
@@ -17,7 +14,27 @@ const SAME_SITE = {
|
|
|
17
14
|
2: 'strict',
|
|
18
15
|
};
|
|
19
16
|
|
|
20
|
-
|
|
17
|
+
let sqliteModulePromise = null;
|
|
18
|
+
|
|
19
|
+
const loadSqlite = () => {
|
|
20
|
+
sqliteModulePromise ||= Promise.all([
|
|
21
|
+
import('sqlite'),
|
|
22
|
+
import('sqlite3'),
|
|
23
|
+
]).then(([sqliteModule, sqlite3Module]) => {
|
|
24
|
+
const sqlite3 = sqlite3Module.default ?? sqlite3Module;
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
open: sqliteModule.open,
|
|
28
|
+
Database: sqlite3.Database,
|
|
29
|
+
OPEN_READONLY: sqlite3.OPEN_READONLY,
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return sqliteModulePromise;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const getDB = async (filePath, readOnly = true) => {
|
|
37
|
+
const { open, Database, OPEN_READONLY } = await loadSqlite();
|
|
21
38
|
const connectionOpts = {
|
|
22
39
|
filename: filePath,
|
|
23
40
|
driver: Database,
|
|
@@ -35,11 +52,12 @@ export const createDBFile = async ({
|
|
|
35
52
|
cookiesFileSecondPath,
|
|
36
53
|
createCookiesTableQuery,
|
|
37
54
|
}) => {
|
|
55
|
+
const { open, Database } = await loadSqlite();
|
|
38
56
|
await fsPromises.writeFile(cookiesFilePath, '', { mode: 0o666 });
|
|
39
57
|
|
|
40
58
|
const connectionOpts = {
|
|
41
59
|
filename: cookiesFilePath,
|
|
42
|
-
driver:
|
|
60
|
+
driver: Database,
|
|
43
61
|
};
|
|
44
62
|
|
|
45
63
|
const db = await open(connectionOpts);
|
|
@@ -77,7 +95,6 @@ export const getChunckedInsertValues = (cookiesArr) => {
|
|
|
77
95
|
|
|
78
96
|
const sourceScheme = isSecure === 1 ? 2 : 1;
|
|
79
97
|
const sourcePort = isSecure === 1 ? 443 : 80;
|
|
80
|
-
// eslint-disable-next-line no-undefined
|
|
81
98
|
let isPersistent = [undefined, null].includes(cookie.session)
|
|
82
99
|
? Number(expirationDate !== 0)
|
|
83
100
|
: Number(!cookie.session);
|
|
@@ -90,23 +107,23 @@ export const getChunckedInsertValues = (cookiesArr) => {
|
|
|
90
107
|
return [
|
|
91
108
|
creationDate,
|
|
92
109
|
cookie.domain,
|
|
93
|
-
'',
|
|
110
|
+
'',
|
|
94
111
|
cookie.name,
|
|
95
|
-
'',
|
|
112
|
+
'',
|
|
96
113
|
encryptedValue,
|
|
97
114
|
cookie.path,
|
|
98
115
|
expirationDate,
|
|
99
116
|
isSecure,
|
|
100
117
|
Number(cookie.httpOnly),
|
|
101
|
-
0,
|
|
102
|
-
expirationDate === 0 ? 0 : 1,
|
|
118
|
+
0,
|
|
119
|
+
expirationDate === 0 ? 0 : 1,
|
|
103
120
|
isPersistent,
|
|
104
|
-
1,
|
|
121
|
+
1,
|
|
105
122
|
samesite,
|
|
106
123
|
sourceScheme,
|
|
107
124
|
sourcePort,
|
|
108
|
-
0,
|
|
109
|
-
0,
|
|
125
|
+
0,
|
|
126
|
+
0,
|
|
110
127
|
];
|
|
111
128
|
});
|
|
112
129
|
|
|
@@ -128,8 +145,6 @@ export const loadCookiesFromFile = async (filePath, isSecondTry = false, profile
|
|
|
128
145
|
console.log('error in loadCookiesFromFile', error.message);
|
|
129
146
|
}
|
|
130
147
|
|
|
131
|
-
console.log(1);
|
|
132
|
-
|
|
133
148
|
try {
|
|
134
149
|
db = await getDB(filePath);
|
|
135
150
|
const cookiesRows = await db.all('select * from cookies');
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import decompress from 'decompress';
|
|
2
|
-
import decompressUnzip from 'decompress-unzip';
|
|
3
1
|
import { promises } from 'fs';
|
|
4
2
|
|
|
3
|
+
import { loadDecompress } from '../utils/lazy-deps.js';
|
|
4
|
+
|
|
5
5
|
const { access, unlink } = promises;
|
|
6
6
|
|
|
7
|
-
export const extractExtension = (source, dest) => {
|
|
7
|
+
export const extractExtension = async (source, dest) => {
|
|
8
8
|
if (!(source && dest)) {
|
|
9
9
|
throw new Error('Missing parameter');
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
const { decompress, decompressUnzip } = await loadDecompress();
|
|
13
|
+
|
|
12
14
|
return access(source)
|
|
13
15
|
.then(() =>
|
|
14
16
|
withRetry({
|
|
@@ -20,7 +22,7 @@ export const extractExtension = (source, dest) => {
|
|
|
20
22
|
},
|
|
21
23
|
}),
|
|
22
24
|
);
|
|
23
|
-
}
|
|
25
|
+
};
|
|
24
26
|
|
|
25
27
|
export const deleteExtensionArchive = (dest) => {
|
|
26
28
|
if (!dest) {
|
|
@@ -32,7 +34,7 @@ export const deleteExtensionArchive = (dest) => {
|
|
|
32
34
|
() => unlink(dest),
|
|
33
35
|
() => Promise.resolve(),
|
|
34
36
|
);
|
|
35
|
-
}
|
|
37
|
+
};
|
|
36
38
|
|
|
37
39
|
const withRetry = optionsOrUndefined => {
|
|
38
40
|
const opts = optionsOrUndefined || {};
|