figranium 0.12.0 → 0.12.2
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/LICENSE +674 -674
- package/README.md +336 -336
- package/agent.js +1 -1
- package/bin/cli.js +149 -149
- package/common-utils.js +211 -211
- package/dist/assets/{favicon-DmUMR1rm.svg → favicon-DXDXzv5K.svg} +290 -290
- package/dist/assets/index-BaVlGc48.js +18 -0
- package/dist/assets/index-T2xxnq_A.css +1 -0
- package/dist/favicon.svg +290 -290
- package/dist/figranium_icon.svg +290 -290
- package/dist/figranium_logo.svg +60 -60
- package/dist/index.html +26 -26
- package/dist/novnc.html +108 -108
- package/dist/styles.css +86 -86
- package/extraction-worker.js +211 -204
- package/headful.js +584 -569
- package/html-utils.js +24 -24
- package/package.json +82 -82
- package/proxy-rotation.js +261 -261
- package/proxy-utils.js +84 -84
- package/public/favicon.svg +290 -290
- package/public/figranium_icon.svg +290 -290
- package/public/figranium_logo.svg +60 -60
- package/public/novnc.html +108 -108
- package/public/styles.css +86 -86
- package/scrape.js +389 -389
- package/scripts/postinstall.js +21 -21
- package/server.js +626 -625
- package/src/server/cron-parser.js +325 -316
- package/src/server/routes/schedules.js +171 -171
- package/src/server/scheduler.js +379 -381
- package/url-utils.js +339 -295
- package/user-agent-settings.js +76 -76
- package/dist/assets/index-B1CypY6C.css +0 -1
- package/dist/assets/index-B295GWry.js +0 -18
package/proxy-utils.js
CHANGED
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
const crypto = require('crypto');
|
|
2
|
-
|
|
3
|
-
const ROTATION_MODES = new Set(['round-robin', 'random']);
|
|
4
|
-
|
|
5
|
-
const normalizeServer = (raw) => {
|
|
6
|
-
if (!raw) return '';
|
|
7
|
-
let server = String(raw).trim();
|
|
8
|
-
if (!server) return '';
|
|
9
|
-
if (!server.includes('://')) {
|
|
10
|
-
server = `http://${server}`;
|
|
11
|
-
}
|
|
12
|
-
return server;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const createProxyId = (seed) => {
|
|
16
|
-
// SHA-256 is stronger than SHA-1 and avoids CodeQL warnings about weak cryptography.
|
|
17
|
-
// The slice length remains 12 to keep IDs concise.
|
|
18
|
-
const hash = crypto.createHash('sha256').update(String(seed)).digest('hex').slice(0, 12);
|
|
19
|
-
return `proxy_${hash}`;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const normalizeProxy = (entry) => {
|
|
23
|
-
if (!entry) return null;
|
|
24
|
-
if (typeof entry === 'string') {
|
|
25
|
-
let raw = entry.trim();
|
|
26
|
-
if (!raw) return null;
|
|
27
|
-
if (!raw.includes('://')) {
|
|
28
|
-
raw = `http://${raw}`;
|
|
29
|
-
}
|
|
30
|
-
try {
|
|
31
|
-
const parsed = new URL(raw);
|
|
32
|
-
const server = `${parsed.protocol}//${parsed.host}`;
|
|
33
|
-
const username = parsed.username ? decodeURIComponent(parsed.username) : undefined;
|
|
34
|
-
const password = parsed.password ? decodeURIComponent(parsed.password) : undefined;
|
|
35
|
-
return {
|
|
36
|
-
id: createProxyId(`${server}|${username || ''}`),
|
|
37
|
-
server,
|
|
38
|
-
username,
|
|
39
|
-
password
|
|
40
|
-
};
|
|
41
|
-
} catch {
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (typeof entry === 'object') {
|
|
46
|
-
const serverRaw = entry.server || entry.url || entry.proxy;
|
|
47
|
-
const server = normalizeServer(serverRaw);
|
|
48
|
-
if (!server) return null;
|
|
49
|
-
const username = entry.username || entry.user;
|
|
50
|
-
const password = entry.password || entry.pass;
|
|
51
|
-
const id = entry.id || createProxyId(`${server}|${username || ''}`);
|
|
52
|
-
const isRotatingPool = !!entry.isRotatingPool;
|
|
53
|
-
let estimatedPoolSize = undefined;
|
|
54
|
-
if (entry.estimatedPoolSize !== undefined && entry.estimatedPoolSize !== null && entry.estimatedPoolSize !== '') {
|
|
55
|
-
const parsedSize = parseInt(entry.estimatedPoolSize, 10);
|
|
56
|
-
if (!Number.isNaN(parsedSize) && parsedSize > 0) {
|
|
57
|
-
estimatedPoolSize = parsedSize;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
id,
|
|
62
|
-
server,
|
|
63
|
-
username,
|
|
64
|
-
password,
|
|
65
|
-
label: entry.label,
|
|
66
|
-
isRotatingPool,
|
|
67
|
-
estimatedPoolSize
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
return null;
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
const normalizeRotationMode = (mode) => {
|
|
74
|
-
if (ROTATION_MODES.has(mode)) return mode;
|
|
75
|
-
return 'round-robin';
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
module.exports = {
|
|
79
|
-
ROTATION_MODES,
|
|
80
|
-
normalizeServer,
|
|
81
|
-
createProxyId,
|
|
82
|
-
normalizeProxy,
|
|
83
|
-
normalizeRotationMode
|
|
84
|
-
};
|
|
1
|
+
const crypto = require('crypto');
|
|
2
|
+
|
|
3
|
+
const ROTATION_MODES = new Set(['round-robin', 'random']);
|
|
4
|
+
|
|
5
|
+
const normalizeServer = (raw) => {
|
|
6
|
+
if (!raw) return '';
|
|
7
|
+
let server = String(raw).trim();
|
|
8
|
+
if (!server) return '';
|
|
9
|
+
if (!server.includes('://')) {
|
|
10
|
+
server = `http://${server}`;
|
|
11
|
+
}
|
|
12
|
+
return server;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const createProxyId = (seed) => {
|
|
16
|
+
// SHA-256 is stronger than SHA-1 and avoids CodeQL warnings about weak cryptography.
|
|
17
|
+
// The slice length remains 12 to keep IDs concise.
|
|
18
|
+
const hash = crypto.createHash('sha256').update(String(seed)).digest('hex').slice(0, 12);
|
|
19
|
+
return `proxy_${hash}`;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const normalizeProxy = (entry) => {
|
|
23
|
+
if (!entry) return null;
|
|
24
|
+
if (typeof entry === 'string') {
|
|
25
|
+
let raw = entry.trim();
|
|
26
|
+
if (!raw) return null;
|
|
27
|
+
if (!raw.includes('://')) {
|
|
28
|
+
raw = `http://${raw}`;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const parsed = new URL(raw);
|
|
32
|
+
const server = `${parsed.protocol}//${parsed.host}`;
|
|
33
|
+
const username = parsed.username ? decodeURIComponent(parsed.username) : undefined;
|
|
34
|
+
const password = parsed.password ? decodeURIComponent(parsed.password) : undefined;
|
|
35
|
+
return {
|
|
36
|
+
id: createProxyId(`${server}|${username || ''}`),
|
|
37
|
+
server,
|
|
38
|
+
username,
|
|
39
|
+
password
|
|
40
|
+
};
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (typeof entry === 'object') {
|
|
46
|
+
const serverRaw = entry.server || entry.url || entry.proxy;
|
|
47
|
+
const server = normalizeServer(serverRaw);
|
|
48
|
+
if (!server) return null;
|
|
49
|
+
const username = entry.username || entry.user;
|
|
50
|
+
const password = entry.password || entry.pass;
|
|
51
|
+
const id = entry.id || createProxyId(`${server}|${username || ''}`);
|
|
52
|
+
const isRotatingPool = !!entry.isRotatingPool;
|
|
53
|
+
let estimatedPoolSize = undefined;
|
|
54
|
+
if (entry.estimatedPoolSize !== undefined && entry.estimatedPoolSize !== null && entry.estimatedPoolSize !== '') {
|
|
55
|
+
const parsedSize = parseInt(entry.estimatedPoolSize, 10);
|
|
56
|
+
if (!Number.isNaN(parsedSize) && parsedSize > 0) {
|
|
57
|
+
estimatedPoolSize = parsedSize;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
id,
|
|
62
|
+
server,
|
|
63
|
+
username,
|
|
64
|
+
password,
|
|
65
|
+
label: entry.label,
|
|
66
|
+
isRotatingPool,
|
|
67
|
+
estimatedPoolSize
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const normalizeRotationMode = (mode) => {
|
|
74
|
+
if (ROTATION_MODES.has(mode)) return mode;
|
|
75
|
+
return 'round-robin';
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
module.exports = {
|
|
79
|
+
ROTATION_MODES,
|
|
80
|
+
normalizeServer,
|
|
81
|
+
createProxyId,
|
|
82
|
+
normalizeProxy,
|
|
83
|
+
normalizeRotationMode
|
|
84
|
+
};
|