gologin 2.1.12 → 2.1.13
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/package.json +1 -1
- package/src/gologin.js +2 -1
- package/.sentry-native/15e25388-76f1-4a90-cea4-9a33e95e5be5.run/af276dd3-14b9-4b32-df19-69cb16a9a85e.envelope +0 -5
- package/.sentry-native/15e25388-76f1-4a90-cea4-9a33e95e5be5.run.lock +0 -0
- package/.sentry-native/last_crash +0 -1
- package/gologin/.eslintrc.json +0 -290
- package/gologin/README.md +0 -163
- package/gologin/example.js +0 -36
- package/gologin/examples/example-amazon-cloud-browser.js +0 -37
- package/gologin/examples/example-amazon-headless.js +0 -50
- package/gologin/examples/example-amazon.js +0 -47
- package/gologin/examples/example-create-custom-profile.js +0 -39
- package/gologin/examples/example-create-profile.js +0 -40
- package/gologin/examples/example-custom-args.js +0 -34
- package/gologin/examples/example-fast-profile-settings.js +0 -69
- package/gologin/examples/example-gmail.js +0 -67
- package/gologin/examples/example-iphey.js +0 -17
- package/gologin/examples/example-local-profile.js +0 -26
- package/gologin/examples/example-login-walmart.js +0 -35
- package/gologin/examples/example-stopremote.js +0 -20
- package/gologin/examples/example-timezone.js +0 -44
- package/gologin/fonts.js +0 -4293
- package/gologin/fonts_config +0 -104
- package/gologin/gologin-browser-ext.zip +0 -0
- package/gologin/gologin_zeroprofile.b64 +0 -1
- package/gologin/index.d.ts +0 -61
- package/gologin/package.json +0 -49
- package/gologin/profile_export_example.csv +0 -2
- package/gologin/run.sh +0 -1
- package/gologin/src/bookmarks/utils.js +0 -15
- package/gologin/src/browser/browser-api.js +0 -95
- package/gologin/src/browser/browser-checker.js +0 -392
- package/gologin/src/browser/browser-user-data-manager.js +0 -335
- package/gologin/src/cookies/cookies-manager.js +0 -189
- package/gologin/src/extensions/extensions-extractor.js +0 -56
- package/gologin/src/extensions/extensions-manager.js +0 -384
- package/gologin/src/extensions/user-extensions-manager.js +0 -295
- package/gologin/src/gologin-api.js +0 -110
- package/gologin/src/gologin.js +0 -1472
- package/gologin/src/profile/profile-archiver.js +0 -86
- package/gologin/src/profile/profile-directories-to-remove.js +0 -75
- package/gologin/src/utils/browser.js +0 -62
- package/gologin/src/utils/common.js +0 -76
- package/gologin/src/utils/constants.js +0 -1
- package/gologin/src/utils/utils.js +0 -49
- package/gologin/zero_profile.zip +0 -0
- package/gologin-canvas.zip +0 -0
- package/gologin.zip +0 -0
- package/test.html +0 -1
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
import { createHash } from 'crypto';
|
|
2
|
-
import { createWriteStream, promises as _promises, rmdirSync } from 'fs';
|
|
3
|
-
import { homedir, tmpdir } from 'os';
|
|
4
|
-
import { dirname, join, resolve, sep } from 'path';
|
|
5
|
-
import requestretry from 'requestretry';
|
|
6
|
-
import { fileURLToPath } from 'url';
|
|
7
|
-
|
|
8
|
-
import { fontsCollection } from '../../fonts.js';
|
|
9
|
-
|
|
10
|
-
const { access, readFile, writeFile, mkdir, readdir, copyFile, rename } = _promises;
|
|
11
|
-
|
|
12
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
-
const __dirname = dirname(__filename);
|
|
14
|
-
|
|
15
|
-
const FONTS_URL = 'https://fonts.gologin.com/';
|
|
16
|
-
const FONTS_DIR_NAME = 'fonts';
|
|
17
|
-
|
|
18
|
-
const HOMEDIR = homedir();
|
|
19
|
-
const BROWSER_PATH = join(HOMEDIR, '.gologin', 'browser');
|
|
20
|
-
const OS_PLATFORM = process.platform;
|
|
21
|
-
const DEFAULT_ORBITA_EXTENSIONS_NAMES = ['Google Hangouts', 'Chromium PDF Viewer', 'CryptoTokenExtension', 'Web Store'];
|
|
22
|
-
const GOLOGIN_BASE_FOLDER_NAME = '.gologin';
|
|
23
|
-
const GOLOGIN_TEST_FOLDER_NAME = '.gologin_test';
|
|
24
|
-
const osPlatform = process.platform;
|
|
25
|
-
|
|
26
|
-
export const downloadCookies = ({ profileId, ACCESS_TOKEN, API_BASE_URL }) =>
|
|
27
|
-
requestretry.get(`${API_BASE_URL}/browser/${profileId}/cookies`, {
|
|
28
|
-
headers: {
|
|
29
|
-
Authorization: `Bearer ${ACCESS_TOKEN}`,
|
|
30
|
-
'user-agent': 'gologin-api',
|
|
31
|
-
},
|
|
32
|
-
json: true,
|
|
33
|
-
maxAttempts: 3,
|
|
34
|
-
retryDelay: 2000,
|
|
35
|
-
timeout: 10 * 1000,
|
|
36
|
-
}).catch((e) => {
|
|
37
|
-
console.log(e);
|
|
38
|
-
|
|
39
|
-
return { body: [] };
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
export const uploadCookies = ({ cookies = [], profileId, ACCESS_TOKEN, API_BASE_URL }) =>
|
|
43
|
-
requestretry.post(`${API_BASE_URL}/browser/${profileId}/cookies?encrypted=true`, {
|
|
44
|
-
headers: {
|
|
45
|
-
Authorization: `Bearer ${ACCESS_TOKEN}`,
|
|
46
|
-
'User-Agent': 'gologin-api',
|
|
47
|
-
},
|
|
48
|
-
json: cookies,
|
|
49
|
-
maxAttempts: 3,
|
|
50
|
-
retryDelay: 2000,
|
|
51
|
-
timeout: 20 * 1000,
|
|
52
|
-
}).catch((e) => {
|
|
53
|
-
console.log(e);
|
|
54
|
-
|
|
55
|
-
return e;
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
export const downloadFonts = async (fontsList = [], profilePath) => {
|
|
59
|
-
if (!fontsList.length) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const browserFontsPath = join(BROWSER_PATH, FONTS_DIR_NAME);
|
|
64
|
-
await mkdir(browserFontsPath, { recursive: true });
|
|
65
|
-
|
|
66
|
-
const files = await readdir(browserFontsPath);
|
|
67
|
-
const fontsToDownload = fontsList.filter(font => !files.includes(font));
|
|
68
|
-
|
|
69
|
-
let promises = fontsToDownload.map(font => requestretry.get(FONTS_URL + font, {
|
|
70
|
-
maxAttempts: 5,
|
|
71
|
-
retryDelay: 2000,
|
|
72
|
-
timeout: 30 * 1000,
|
|
73
|
-
})
|
|
74
|
-
.pipe(createWriteStream(join(browserFontsPath, font))),
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
if (promises.length) {
|
|
78
|
-
await Promise.all(promises);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
promises = fontsList.map((font) =>
|
|
82
|
-
copyFile(join(browserFontsPath, font), join(profilePath, FONTS_DIR_NAME, font)));
|
|
83
|
-
|
|
84
|
-
await Promise.all(promises);
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
export const composeFonts = async (fontsList = [], profilePath, differentOs = false) => {
|
|
88
|
-
if (!(fontsList.length && profilePath)) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const fontsToDownload = fontsCollection
|
|
93
|
-
.filter(elem => fontsList.includes(elem.value))
|
|
94
|
-
.reduce((res, elem) => res.concat(elem.fileNames || []), []);
|
|
95
|
-
|
|
96
|
-
if (differentOs && !fontsToDownload.length) {
|
|
97
|
-
throw new Error('No fonts to download found. Use getAvailableFonts() method and set some fonts from this list');
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
fontsToDownload.push('LICENSE.txt');
|
|
101
|
-
fontsToDownload.push('OFL.txt');
|
|
102
|
-
|
|
103
|
-
const pathToFontsDir = join(profilePath, FONTS_DIR_NAME);
|
|
104
|
-
const fontsDirExists = await access(pathToFontsDir).then(() => true, () => false);
|
|
105
|
-
if (fontsDirExists) {
|
|
106
|
-
rmdirSync(pathToFontsDir, { recursive: true });
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
await mkdir(pathToFontsDir, { recursive: true });
|
|
110
|
-
await downloadFonts(fontsToDownload, profilePath);
|
|
111
|
-
|
|
112
|
-
if (OS_PLATFORM === 'linux') {
|
|
113
|
-
await copyFontsConfigFile(profilePath);
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
export const copyFontsConfigFile = async (profilePath) => {
|
|
118
|
-
if (!profilePath) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const fileContent = await readFile(resolve(__dirname, '..', '..', 'fonts_config'), 'utf-8');
|
|
123
|
-
const result = fileContent.replace(/\$\$GOLOGIN_FONTS\$\$/g, join(profilePath, FONTS_DIR_NAME));
|
|
124
|
-
|
|
125
|
-
const defaultFolderPath = join(profilePath, 'Default');
|
|
126
|
-
await mkdir(defaultFolderPath, { recursive: true });
|
|
127
|
-
await writeFile(join(defaultFolderPath, 'fonts_config'), result);
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
export const setExtPathsAndRemoveDeleted = (settings = {}, profileExtensionsCheckRes = [], profileId = '') => {
|
|
131
|
-
const formattedLocalExtArray = profileExtensionsCheckRes.map((el) => {
|
|
132
|
-
const [extFolderName = ''] = el.split(sep).reverse();
|
|
133
|
-
const [originalId] = extFolderName.split('@');
|
|
134
|
-
if (!originalId) {
|
|
135
|
-
return null;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
path: el,
|
|
140
|
-
originalId,
|
|
141
|
-
};
|
|
142
|
-
}).filter(Boolean);
|
|
143
|
-
|
|
144
|
-
const extensionsSettings = settings.extensions?.settings || {};
|
|
145
|
-
const extensionsEntries = Object.entries(extensionsSettings);
|
|
146
|
-
|
|
147
|
-
const promises = extensionsEntries.map(async (extensionObj) => {
|
|
148
|
-
let [extensionId, currentExtSettings = {}] = extensionObj;
|
|
149
|
-
const extName = currentExtSettings.manifest?.name || '';
|
|
150
|
-
let extPath = currentExtSettings.path || '';
|
|
151
|
-
let originalId = '';
|
|
152
|
-
|
|
153
|
-
const isExtensionToBeDeleted = ['resources', 'passwords-ext', 'cookies-ext'].some(substring => extPath.includes(substring))
|
|
154
|
-
&& [GOLOGIN_BASE_FOLDER_NAME, GOLOGIN_TEST_FOLDER_NAME].some(substring => extPath.includes(substring))
|
|
155
|
-
|| DEFAULT_ORBITA_EXTENSIONS_NAMES.includes(extName)
|
|
156
|
-
&& [GOLOGIN_BASE_FOLDER_NAME, GOLOGIN_TEST_FOLDER_NAME].some(substring => extPath.includes(substring));
|
|
157
|
-
|
|
158
|
-
if (isExtensionToBeDeleted) {
|
|
159
|
-
delete extensionsSettings[extensionId];
|
|
160
|
-
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (osPlatform === 'win32') {
|
|
165
|
-
extPath = extPath.replace(/\//g, '\\');
|
|
166
|
-
} else {
|
|
167
|
-
extPath = extPath.replace(/\\/g, '/');
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
extensionsSettings[extensionId].path = extPath;
|
|
171
|
-
|
|
172
|
-
const splittedPath = extPath.split(sep);
|
|
173
|
-
const isExtensionManageable = ['chrome-extensions', 'user-extensions'].some(substring => extPath.includes(substring))
|
|
174
|
-
&& [GOLOGIN_BASE_FOLDER_NAME, GOLOGIN_TEST_FOLDER_NAME].some(substring => extPath.includes(substring));
|
|
175
|
-
|
|
176
|
-
if (isExtensionManageable) {
|
|
177
|
-
const [extFolderName] = extPath.split(sep).reverse();
|
|
178
|
-
[originalId] = extFolderName.split('@');
|
|
179
|
-
} else if (splittedPath.length === 2) {
|
|
180
|
-
[originalId] = splittedPath;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
if (isExtensionManageable || splittedPath.length === 2) {
|
|
184
|
-
const isExtensionInProfileSettings = formattedLocalExtArray.find(el => el.path.includes(originalId));
|
|
185
|
-
if (!isExtensionInProfileSettings) {
|
|
186
|
-
delete extensionsSettings[extensionId];
|
|
187
|
-
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
const localExtObj = originalId && formattedLocalExtArray.find(el => el.path.includes(originalId));
|
|
193
|
-
if (!localExtObj) {
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const initialExtName = extensionId;
|
|
198
|
-
|
|
199
|
-
extensionId = await recalculateId({
|
|
200
|
-
localExtObj, extensionId, extensionsSettings, currentExtSettings,
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
if (initialExtName !== extensionId) {
|
|
204
|
-
const profilePath = join(tmpdir(), `gologin_profile_${profileId}`);
|
|
205
|
-
const extSyncFolder = join(profilePath, 'Default', 'Sync Extension Settings', initialExtName);
|
|
206
|
-
const newSyncFolder = join(profilePath, 'Default', 'Sync Extension Settings', extensionId);
|
|
207
|
-
|
|
208
|
-
await rename(extSyncFolder, newSyncFolder).catch(() => null);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
if (localExtObj.path.endsWith('.zip')) {
|
|
212
|
-
localExtObj.path = localExtObj.path.replace('.zip', '');
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
extensionsSettings[extensionId].path = localExtObj.path || '';
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
return Promise.all(promises).then(() => extensionsSettings);
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
export const setOriginalExtPaths = async (settings = {}, originalExtensionsFolder = '') => {
|
|
222
|
-
if (!originalExtensionsFolder) {
|
|
223
|
-
return null;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const extensionsSettings = settings.extensions?.settings || {};
|
|
227
|
-
const extensionsEntries = Object.entries(extensionsSettings);
|
|
228
|
-
|
|
229
|
-
const originalExtensionsList = await readdir(originalExtensionsFolder).catch(() => []);
|
|
230
|
-
if (!originalExtensionsList.length) {
|
|
231
|
-
return null;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
const promises = originalExtensionsList.map(async (originalId) => {
|
|
235
|
-
const extFolderPath = join(originalExtensionsFolder, originalId);
|
|
236
|
-
const extFolderContent = await readdir(extFolderPath);
|
|
237
|
-
if (!extFolderPath.length) {
|
|
238
|
-
return {};
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (extFolderContent.includes('manifest.json')) {
|
|
242
|
-
return {
|
|
243
|
-
originalId,
|
|
244
|
-
path: join(originalExtensionsFolder, originalId),
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const [version] = extFolderContent;
|
|
249
|
-
|
|
250
|
-
return {
|
|
251
|
-
originalId,
|
|
252
|
-
path: join(originalExtensionsFolder, originalId, version),
|
|
253
|
-
};
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
const originalExtPaths = await Promise.all(promises);
|
|
257
|
-
|
|
258
|
-
extensionsEntries.forEach((extensionObj) => {
|
|
259
|
-
const [extensionsId] = extensionObj;
|
|
260
|
-
const extPath = extensionsSettings[extensionsId].path;
|
|
261
|
-
if (!/chrome-extensions/.test(extPath)) {
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
const originalExtPath = originalExtPaths.find(el => el.originalId === extensionsId);
|
|
266
|
-
if (!originalExtPath) {
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
extensionsSettings[extensionsId].path = originalExtPath.path || '';
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
return extensionsSettings;
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
export const recalculateId = async ({ localExtObj, extensionId, extensionsSettings, currentExtSettings }) => {
|
|
277
|
-
if (currentExtSettings.manifest?.key) {
|
|
278
|
-
return extensionId;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
const manifestFilePath = join(localExtObj.path, 'manifest.json');
|
|
282
|
-
const manifestString = await readFile(manifestFilePath, { encoding: 'utf8' }).catch(() => ({}));
|
|
283
|
-
|
|
284
|
-
if (!manifestString) {
|
|
285
|
-
return extensionId;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
let manifestObject;
|
|
289
|
-
try {
|
|
290
|
-
manifestObject = JSON.parse(manifestString);
|
|
291
|
-
} catch {
|
|
292
|
-
return extensionId;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
if (manifestObject.key) {
|
|
296
|
-
return extensionId;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
let encoding = 'utf8';
|
|
300
|
-
if (osPlatform === 'win32') {
|
|
301
|
-
encoding = 'utf16le';
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
const extPathToEncode = Buffer.from(localExtObj.path, encoding);
|
|
305
|
-
|
|
306
|
-
const hexEncodedPath = createHash('sha256').update(extPathToEncode).digest('hex');
|
|
307
|
-
const newId = hexEncodedPath.split('').slice(0, 32).map(symbol => extIdEncoding[symbol]).join('');
|
|
308
|
-
if (extensionId !== newId) {
|
|
309
|
-
delete extensionsSettings[extensionId];
|
|
310
|
-
|
|
311
|
-
extensionsSettings[newId] = currentExtSettings;
|
|
312
|
-
extensionId = newId;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return extensionId;
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
const extIdEncoding = {
|
|
319
|
-
0: 'a',
|
|
320
|
-
1: 'b',
|
|
321
|
-
2: 'c',
|
|
322
|
-
3: 'd',
|
|
323
|
-
4: 'e',
|
|
324
|
-
5: 'f',
|
|
325
|
-
6: 'g',
|
|
326
|
-
7: 'h',
|
|
327
|
-
8: 'i',
|
|
328
|
-
9: 'j',
|
|
329
|
-
a: 'k',
|
|
330
|
-
b: 'l',
|
|
331
|
-
c: 'm',
|
|
332
|
-
d: 'n',
|
|
333
|
-
e: 'o',
|
|
334
|
-
f: 'p',
|
|
335
|
-
};
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
import { open } from 'sqlite';
|
|
2
|
-
import sqlite3 from 'sqlite3';
|
|
3
|
-
import { promises as fsPromises } from 'fs';
|
|
4
|
-
import { join } from 'path';
|
|
5
|
-
|
|
6
|
-
const { access } = fsPromises;
|
|
7
|
-
const { Database, OPEN_READONLY } = sqlite3;
|
|
8
|
-
|
|
9
|
-
const MAX_SQLITE_VARIABLES = 76;
|
|
10
|
-
|
|
11
|
-
const SAME_SITE = {
|
|
12
|
-
'-1': 'unspecified',
|
|
13
|
-
0: 'no_restriction',
|
|
14
|
-
1: 'lax',
|
|
15
|
-
2: 'strict',
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export const getDB = (filePath, readOnly = true) => {
|
|
19
|
-
const connectionOpts = {
|
|
20
|
-
filename: filePath,
|
|
21
|
-
driver: Database,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
if (readOnly) {
|
|
25
|
-
connectionOpts.mode = OPEN_READONLY;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return open(connectionOpts);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export const getChunckedInsertValues = (cookiesArr) => {
|
|
32
|
-
const todayUnix = Math.floor(new Date().getTime() / 1000.0);
|
|
33
|
-
const chunckedCookiesArr = chunk(cookiesArr, MAX_SQLITE_VARIABLES);
|
|
34
|
-
|
|
35
|
-
return chunckedCookiesArr.map((cookies) => {
|
|
36
|
-
const queryPlaceholders = cookies.map(() => '(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)').join(', ');
|
|
37
|
-
const query = `insert or replace into cookies (creation_utc, host_key, top_frame_site_key, name, value, encrypted_value, path, expires_utc, is_secure, is_httponly, last_access_utc, has_expires, is_persistent, priority, samesite, source_scheme, source_port, is_same_party, last_update_utc) values ${queryPlaceholders}`;
|
|
38
|
-
const queryParams = cookies.flatMap((cookie) => {
|
|
39
|
-
const creationDate = cookie.creationDate ? cookie.creationDate : unixToLDAP(todayUnix);
|
|
40
|
-
let expirationDate = cookie.session ? 0 : unixToLDAP(cookie.expirationDate);
|
|
41
|
-
const encryptedValue = cookie.value;
|
|
42
|
-
const samesite = Object.keys(SAME_SITE).find((key) => SAME_SITE[key] === (cookie.sameSite || '-1'));
|
|
43
|
-
const isSecure =
|
|
44
|
-
cookie.name.startsWith('__Host-') || cookie.name.startsWith('__Secure-') ? 1 : Number(cookie.secure);
|
|
45
|
-
|
|
46
|
-
const sourceScheme = isSecure === 1 ? 2 : 1;
|
|
47
|
-
const sourcePort = isSecure === 1 ? 443 : 80;
|
|
48
|
-
// eslint-disable-next-line no-undefined
|
|
49
|
-
let isPersistent = [undefined, null].includes(cookie.session)
|
|
50
|
-
? Number(expirationDate !== 0)
|
|
51
|
-
: Number(!cookie.session);
|
|
52
|
-
|
|
53
|
-
if (/^(\.)?mail.google.com$/.test(cookie.domain) && cookie.name === 'COMPASS') {
|
|
54
|
-
expirationDate = 0;
|
|
55
|
-
isPersistent = 0;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return [
|
|
59
|
-
creationDate,
|
|
60
|
-
cookie.domain,
|
|
61
|
-
'', // top_frame_site_key
|
|
62
|
-
cookie.name,
|
|
63
|
-
'', // value
|
|
64
|
-
encryptedValue,
|
|
65
|
-
cookie.path,
|
|
66
|
-
expirationDate,
|
|
67
|
-
isSecure,
|
|
68
|
-
Number(cookie.httpOnly),
|
|
69
|
-
0, // last_access_utc
|
|
70
|
-
expirationDate === 0 ? 0 : 1, // has_expires
|
|
71
|
-
isPersistent,
|
|
72
|
-
1, // default priority value (https://github.com/chromium/chromium/blob/main/net/cookies/cookie_constants.h)
|
|
73
|
-
samesite,
|
|
74
|
-
sourceScheme,
|
|
75
|
-
sourcePort,
|
|
76
|
-
0, // is_same_party
|
|
77
|
-
0, // last_update_utc
|
|
78
|
-
];
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
return [query, queryParams];
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export const loadCookiesFromFile = async (filePath) => {
|
|
86
|
-
let db;
|
|
87
|
-
const cookies = [];
|
|
88
|
-
|
|
89
|
-
try {
|
|
90
|
-
db = await getDB(filePath);
|
|
91
|
-
const cookiesRows = await db.all('select * from cookies');
|
|
92
|
-
for (const row of cookiesRows) {
|
|
93
|
-
const {
|
|
94
|
-
host_key,
|
|
95
|
-
name,
|
|
96
|
-
encrypted_value,
|
|
97
|
-
path,
|
|
98
|
-
is_secure,
|
|
99
|
-
is_httponly,
|
|
100
|
-
expires_utc,
|
|
101
|
-
is_persistent,
|
|
102
|
-
samesite,
|
|
103
|
-
creation_utc,
|
|
104
|
-
} = row;
|
|
105
|
-
|
|
106
|
-
cookies.push({
|
|
107
|
-
url: buildCookieURL(host_key, is_secure, path),
|
|
108
|
-
domain: host_key,
|
|
109
|
-
name,
|
|
110
|
-
value: encrypted_value,
|
|
111
|
-
path,
|
|
112
|
-
sameSite: SAME_SITE[samesite],
|
|
113
|
-
secure: Boolean(is_secure),
|
|
114
|
-
httpOnly: Boolean(is_httponly),
|
|
115
|
-
hostOnly: !host_key.startsWith('.'),
|
|
116
|
-
session: !is_persistent,
|
|
117
|
-
expirationDate: ldapToUnix(expires_utc),
|
|
118
|
-
creationDate: ldapToUnix(creation_utc),
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
} catch (error) {
|
|
122
|
-
console.log(error);
|
|
123
|
-
} finally {
|
|
124
|
-
db && await db.close();
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return cookies;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export const unixToLDAP = (unixtime) => {
|
|
131
|
-
if (unixtime === 0) {
|
|
132
|
-
return unixtime;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const win32filetime = new Date(Date.UTC(1601, 0, 1)).getTime() / 1000;
|
|
136
|
-
const sum = unixtime - win32filetime;
|
|
137
|
-
|
|
138
|
-
return sum * 1000000;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export const ldapToUnix = (ldap) => {
|
|
142
|
-
const ldapLength = ldap.toString().length;
|
|
143
|
-
if (ldap === 0 || ldapLength > 18) {
|
|
144
|
-
return ldap;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
let _ldap = ldap;
|
|
148
|
-
if (ldapLength < 18) {
|
|
149
|
-
_ldap = Number(_ldap + '0'.repeat(18 - ldapLength));
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const win32filetime = new Date(Date.UTC(1601, 0, 1)).getTime();
|
|
153
|
-
|
|
154
|
-
return (_ldap / 10000 + win32filetime) / 1000;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export const buildCookieURL = (domain, secure, path) => {
|
|
158
|
-
let domainWithoutDot = domain;
|
|
159
|
-
if (domain.startsWith('.')) {
|
|
160
|
-
domainWithoutDot = domain.substr(1);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return 'http' + (secure ? 's' : '') + '://' + domainWithoutDot + path;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
export const chunk = (arr, chunkSize = 1, cache = []) => {
|
|
167
|
-
const tmp = [...arr];
|
|
168
|
-
if (chunkSize <= 0) {
|
|
169
|
-
return cache;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
while (tmp.length) {
|
|
173
|
-
cache.push(tmp.splice(0, chunkSize));
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return cache;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export const getCookiesFilePath = async (profileId, tmpdir) => {
|
|
180
|
-
const baseCookiesFilePath = join(tmpdir, `gologin_profile_${profileId}`, 'Default', 'Cookies');
|
|
181
|
-
const bypassCookiesFilePath = join(tmpdir, `gologin_profile_${profileId}`, 'Default', 'Network', 'Cookies');
|
|
182
|
-
|
|
183
|
-
return access(baseCookiesFilePath)
|
|
184
|
-
.then(() => baseCookiesFilePath)
|
|
185
|
-
.catch(() => access(bypassCookiesFilePath)
|
|
186
|
-
.then(() => bypassCookiesFilePath)
|
|
187
|
-
.catch(() => baseCookiesFilePath)
|
|
188
|
-
);
|
|
189
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import decompress from 'decompress';
|
|
2
|
-
import decompressUnzip from 'decompress-unzip';
|
|
3
|
-
import { promises } from 'fs';
|
|
4
|
-
|
|
5
|
-
const { access, unlink } = promises;
|
|
6
|
-
|
|
7
|
-
export const extractExtension = (source, dest) => {
|
|
8
|
-
if (!(source && dest)) {
|
|
9
|
-
throw new Error('Missing parameter');
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
return access(source)
|
|
13
|
-
.then(() =>
|
|
14
|
-
withRetry({
|
|
15
|
-
fn() {
|
|
16
|
-
return decompress(source, dest, {
|
|
17
|
-
plugins: [decompressUnzip()],
|
|
18
|
-
filter: file => !file.path.endsWith('/'),
|
|
19
|
-
});
|
|
20
|
-
},
|
|
21
|
-
}),
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const deleteExtensionArchive = (dest) => {
|
|
26
|
-
if (!dest) {
|
|
27
|
-
throw new Error('Missing parameter');
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return access(dest)
|
|
31
|
-
.then(
|
|
32
|
-
() => unlink(dest),
|
|
33
|
-
() => Promise.resolve(),
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const withRetry = optionsOrUndefined => {
|
|
38
|
-
const opts = optionsOrUndefined || {};
|
|
39
|
-
const callCounter = opts.callCounter || 1;
|
|
40
|
-
const fnToProducePromise = opts.fn;
|
|
41
|
-
const callLimit = opts.limit || 5;
|
|
42
|
-
delete opts.callCounter;
|
|
43
|
-
|
|
44
|
-
return fnToProducePromise(opts).catch(err => {
|
|
45
|
-
console.error(err);
|
|
46
|
-
if (callCounter >= callLimit) {
|
|
47
|
-
return Promise.reject(err);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
opts.callCounter = callCounter + 1;
|
|
51
|
-
|
|
52
|
-
return new Promise(resolve => process.nextTick(resolve)).then(() =>
|
|
53
|
-
withRetry(opts),
|
|
54
|
-
);
|
|
55
|
-
});
|
|
56
|
-
};
|