gologin 2.2.9 → 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 +8 -0
- package/api.d.ts +105 -0
- package/index.d.ts +4 -120
- 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 -13
- 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 +86 -78
- 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/fonts.js +0 -4293
- package/fonts_config +0 -104
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
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
|
+
|
|
5
13
|
## [2.2.9] 2026-06-08
|
|
6
14
|
|
|
7
15
|
### 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>;
|
package/index.d.ts
CHANGED
|
@@ -1,100 +1,3 @@
|
|
|
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<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
|
-
/** Options for the GoLogin class constructor (advanced usage, custom wrappers). */
|
|
98
1
|
export type GoLoginOptions = {
|
|
99
2
|
token?: string;
|
|
100
3
|
profile_id?: string;
|
|
@@ -109,7 +12,7 @@ export type GoLoginOptions = {
|
|
|
109
12
|
uploadCookiesToServer?: boolean;
|
|
110
13
|
writeCookiesFromServer?: boolean;
|
|
111
14
|
remote_debugging_port?: number;
|
|
112
|
-
timezone?: { timezone: string; country?: string; city?: string; ip?: string; ll?: [number, number]; accuracy?: number, stateProv?: string, languages?: string };
|
|
15
|
+
timezone?: { timezone: string; country?: string; city?: string; ip?: string; ll?: [number, number]; accuracy?: number, stateProv?: string, languages?: string };
|
|
113
16
|
args?: string[];
|
|
114
17
|
restoreLastSession?: boolean;
|
|
115
18
|
browserMajorVersion?: number;
|
|
@@ -119,25 +22,14 @@ export type GoLoginOptions = {
|
|
|
119
22
|
checkBrowserUpdate?: boolean;
|
|
120
23
|
};
|
|
121
24
|
|
|
122
|
-
/** Return type of GoLogin#start() — use wsUrl to connect with Puppeteer. */
|
|
123
25
|
export type GoLoginStartResult = {
|
|
124
26
|
status: 'success';
|
|
125
27
|
wsUrl: string;
|
|
126
28
|
resolution?: { width: number; height: number };
|
|
127
29
|
};
|
|
128
30
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
* Use when you need direct control over the browser lifecycle (e.g. custom launchLocal,
|
|
132
|
-
* multiple instances, or access to wsUrl from start() for Puppeteer).
|
|
133
|
-
*
|
|
134
|
-
* @example
|
|
135
|
-
* import { GoLogin } from 'gologin';
|
|
136
|
-
* const gologin = new GoLogin({ token: 'YOUR_TOKEN', profile_id: 'PROFILE_ID' });
|
|
137
|
-
* const { wsUrl } = await gologin.start();
|
|
138
|
-
* // connect with puppeteer.connect({ browserWSEndpoint: wsUrl })
|
|
139
|
-
* await gologin.stop();
|
|
140
|
-
*/
|
|
31
|
+
export { GologinApi, getDefaultParams, exitAll } from './api.d.ts';
|
|
32
|
+
|
|
141
33
|
export declare class GoLogin {
|
|
142
34
|
constructor(options?: GoLoginOptions);
|
|
143
35
|
start(): Promise<GoLoginStartResult>;
|
|
@@ -151,12 +43,4 @@ export declare class GoLogin {
|
|
|
151
43
|
commitProfile(): Promise<void>;
|
|
152
44
|
}
|
|
153
45
|
|
|
154
|
-
export
|
|
155
|
-
token: string | undefined;
|
|
156
|
-
profile_id: string | undefined;
|
|
157
|
-
executablePath: string | undefined;
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
export declare function GologinApi(params: GologinApiParams): GologinApiType;
|
|
161
|
-
|
|
162
|
-
export declare function exitAll(): Promise<void>;
|
|
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
|
|
|
@@ -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 || {};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { createWriteStream, promises as _promises } from 'fs';
|
|
2
2
|
import { join, sep } from 'path';
|
|
3
|
-
import request from 'requestretry';
|
|
4
3
|
|
|
5
4
|
import { CHROME_EXTENSIONS_PATH, composeExtractionPromises, USER_EXTENSIONS_PATH } from '../utils/common.js';
|
|
6
5
|
import UserExtensionsManager from './user-extensions-manager.js';
|
|
7
|
-
import { makeRequest } from '../utils/http.js';
|
|
6
|
+
import { fetchBufferWithRetry, fetchHeadWithRetry, makeRequest } from '../utils/http.js';
|
|
8
7
|
import { FALLBACK_API_URL } from '../utils/common.js';
|
|
9
8
|
|
|
10
9
|
const { mkdir, readdir, rmdir, unlink } = _promises;
|
|
@@ -134,19 +133,11 @@ export class ExtensionsManager extends UserExtensionsManager {
|
|
|
134
133
|
const reqPath = uploadedProfileMetadata.req.path;
|
|
135
134
|
const extVer = getExtVersion(reqPath);
|
|
136
135
|
|
|
137
|
-
const buffer = await
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
maxAttempts: 3,
|
|
142
|
-
retryDelay: 1000,
|
|
143
|
-
timeout: 8 * 1000,
|
|
144
|
-
fullResponse: false,
|
|
145
|
-
})
|
|
146
|
-
.on('data', (data) => chunks.push(data))
|
|
147
|
-
.on('end', () => res(Buffer.concat(chunks)));
|
|
136
|
+
const buffer = await fetchBufferWithRetry(extUrl, {
|
|
137
|
+
maxAttempts: 3,
|
|
138
|
+
retryDelay: 1000,
|
|
139
|
+
timeout: 8 * 1000,
|
|
148
140
|
});
|
|
149
|
-
console.log('buffer', buffer);
|
|
150
141
|
let zipExt;
|
|
151
142
|
try {
|
|
152
143
|
zipExt = crxToZip(buffer);
|
|
@@ -357,14 +348,11 @@ const calcLength = (a, b, c, d) => {
|
|
|
357
348
|
return length;
|
|
358
349
|
};
|
|
359
350
|
|
|
360
|
-
const getExtMetadata = (extUrl) => (
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
fullResponse: true,
|
|
366
|
-
})
|
|
367
|
-
);
|
|
351
|
+
const getExtMetadata = (extUrl) => fetchHeadWithRetry(extUrl, {
|
|
352
|
+
maxAttempts: 3,
|
|
353
|
+
retryDelay: 2000,
|
|
354
|
+
timeout: 2 * 1000,
|
|
355
|
+
});
|
|
368
356
|
|
|
369
357
|
const getExtVersion = (metadata) => {
|
|
370
358
|
const [extFullName = ''] = metadata.split('/').reverse();
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { createWriteStream, promises as _promises } from 'fs';
|
|
2
2
|
import { join, sep } from 'path';
|
|
3
|
-
import request from 'requestretry';
|
|
4
3
|
|
|
5
4
|
import { CHROME_EXTENSIONS_PATH, composeExtractionPromises, FALLBACK_API_URL, USER_EXTENSIONS_PATH } from '../utils/common.js';
|
|
6
|
-
import { makeRequest } from '../utils/http.js';
|
|
5
|
+
import { fetchToWriteStream, makeRequest } from '../utils/http.js';
|
|
7
6
|
|
|
8
7
|
const { readdir, readFile, stat, mkdir, copyFile } = _promises;
|
|
9
8
|
|
|
@@ -105,12 +104,10 @@ export class UserExtensionsManager {
|
|
|
105
104
|
const zipPath = `${join(USER_EXTENSIONS_PATH, extId)}.zip`;
|
|
106
105
|
const archiveZip = createWriteStream(zipPath);
|
|
107
106
|
|
|
108
|
-
await
|
|
107
|
+
await fetchToWriteStream(awsPath, archiveZip, {
|
|
109
108
|
retryDelay: 2 * 1000,
|
|
110
109
|
maxAttempts: 3,
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
await new Promise(r => archiveZip.on('close', () => r()));
|
|
110
|
+
});
|
|
114
111
|
|
|
115
112
|
return zipPath;
|
|
116
113
|
});
|