arn-browser 0.0.2 → 0.0.4
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/README.md +3 -2
- package/package.json +28 -48
- package/rowser_automation_env.js +32 -0
- package/src/all_routes/routeWithSuperagent.d.ts +67 -0
- package/src/all_routes/routeWithSuperagent.js +322 -0
- package/src/index.d.ts +19 -0
- package/src/index.js +15 -0
- package/src/others/totp-generator.d.ts +15 -0
- package/src/others/totp-generator.js +86 -0
- package/src/utility/deleteDirectory.js +105 -0
- package/src/utility/launchBrowser.d.ts +221 -0
- package/src/utility/launchBrowser.js +868 -0
- package/src/utility/multilogin_token_manager.js +186 -0
- package/src/utility/playwright-helper.d.ts +61 -0
- package/src/utility/playwright-helper.js +129 -0
- package/src/utility/proxy-utility/custom-proxy.d.ts +93 -0
- package/src/utility/proxy-utility/custom-proxy.js +669 -0
- package/src/utility/proxy-utility/proxy-chain.d.ts +123 -0
- package/src/utility/proxy-utility/proxy-chain.js +337 -0
- package/src/utility/proxy-utility/proxy-helper.d.ts +91 -0
- package/src/utility/proxy-utility/proxy-helper.js +245 -0
- /package/{LICENSE.md → LICENSE} +0 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { setTimeout as sleep } from "timers/promises";
|
|
2
|
+
import randomstring from "randomstring";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { pathToFileURL } from "url";
|
|
6
|
+
import { getMultiloginToken } from "../multilogin_token_manager.js";
|
|
7
|
+
// Assuming fetchAwsProxy is in the same directory or adjust path accordingly
|
|
8
|
+
import { getActiveProxyWithStartStop as fetchAwsProxy } from "./custom-proxy.js";
|
|
9
|
+
|
|
10
|
+
// Global configuration cache
|
|
11
|
+
let config = null;
|
|
12
|
+
|
|
13
|
+
// ==========================================
|
|
14
|
+
// SECTION 1: CONFIGURATION & UTILITIES
|
|
15
|
+
// ==========================================
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Dynamically loads 'browser_automation_env.js' from the user's project root.
|
|
19
|
+
*/
|
|
20
|
+
async function loadUserConfig() {
|
|
21
|
+
if (config) return config;
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const projectRoot = process.cwd();
|
|
25
|
+
const envPath = path.join(projectRoot, "utility", "browser_automation_env.js");
|
|
26
|
+
|
|
27
|
+
if (!fs.existsSync(envPath)) {
|
|
28
|
+
throw new Error(`Could not find configuration file at: ${envPath}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const envUrl = pathToFileURL(envPath).href;
|
|
32
|
+
const userEnv = await import(envUrl);
|
|
33
|
+
|
|
34
|
+
// Validate required exports
|
|
35
|
+
const requiredKeys = [
|
|
36
|
+
"arn",
|
|
37
|
+
"query",
|
|
38
|
+
"PACKETSTREAM_USER",
|
|
39
|
+
"PACKETSTREAM_PASS_KEY",
|
|
40
|
+
"PACKETSTREAM_HOST",
|
|
41
|
+
"PACKETSTREAM_PORT",
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
const missing = requiredKeys.filter((key) => !userEnv[key]);
|
|
45
|
+
|
|
46
|
+
if (missing.length > 0) {
|
|
47
|
+
throw new Error(`[Proxy Manager] 'browser_automation_env.js' is missing exports: ${missing.join(", ")}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
config = userEnv;
|
|
51
|
+
return config;
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error("❌ Config Error:", error.message);
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ==========================================
|
|
59
|
+
// SECTION 2: MULTILOGIN PROXY
|
|
60
|
+
// ==========================================
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Fetches and parses a Multilogin proxy using Native Fetch.
|
|
64
|
+
*/
|
|
65
|
+
export async function get_multilogin_proxy({
|
|
66
|
+
country = "us",
|
|
67
|
+
sessionType = "sticky",
|
|
68
|
+
protocol = "http",
|
|
69
|
+
region = "",
|
|
70
|
+
city = "",
|
|
71
|
+
IPTTL = 1800,
|
|
72
|
+
strictMode = false,
|
|
73
|
+
} = {}) {
|
|
74
|
+
try {
|
|
75
|
+
// 1. Get Token
|
|
76
|
+
const token = await getMultiloginToken();
|
|
77
|
+
|
|
78
|
+
// 2. Prepare Data
|
|
79
|
+
const data = { country, sessionType, protocol, region, city, IPTTL, count: 1 };
|
|
80
|
+
Object.keys(data).forEach((k) => (data[k] === "" || data[k] === 0 || data[k] == null) && delete data[k]);
|
|
81
|
+
|
|
82
|
+
// 3. Setup Timeout
|
|
83
|
+
const controller = new AbortController();
|
|
84
|
+
const timeoutId = setTimeout(() => controller.abort(), 20000);
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
const response = await fetch("https://profile-proxy.multilogin.com/v1/proxy/connection_url", {
|
|
88
|
+
method: "POST",
|
|
89
|
+
headers: {
|
|
90
|
+
Authorization: `Bearer ${token}`,
|
|
91
|
+
"X-Strict-Mode": strictMode ? "true" : "false",
|
|
92
|
+
"Content-Type": "application/json",
|
|
93
|
+
},
|
|
94
|
+
body: JSON.stringify(data),
|
|
95
|
+
signal: controller.signal,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
if (!response.ok) {
|
|
99
|
+
const errText = await response.text();
|
|
100
|
+
throw new Error(`HTTP ${response.status}: ${errText}`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const json = await response.json();
|
|
104
|
+
|
|
105
|
+
let proxyStr = json?.data;
|
|
106
|
+
if (Array.isArray(proxyStr)) proxyStr = proxyStr[0];
|
|
107
|
+
|
|
108
|
+
if (!proxyStr || typeof proxyStr !== "string") {
|
|
109
|
+
console.error("Multilogin proxy API: Unexpected format", json);
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Format: host:port:user:pass
|
|
114
|
+
const parts = proxyStr.split(":");
|
|
115
|
+
if (parts.length < 4) {
|
|
116
|
+
console.error("Unexpected Multilogin proxy string:", proxyStr);
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const [host, port, user, ...passParts] = parts;
|
|
121
|
+
const pass = passParts.join(":");
|
|
122
|
+
|
|
123
|
+
const temp_proxy = {
|
|
124
|
+
type: protocol,
|
|
125
|
+
host,
|
|
126
|
+
port: parseInt(port, 10),
|
|
127
|
+
user,
|
|
128
|
+
pass,
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
console.log("Multilogin Proxy:", temp_proxy);
|
|
132
|
+
return temp_proxy;
|
|
133
|
+
} finally {
|
|
134
|
+
clearTimeout(timeoutId);
|
|
135
|
+
}
|
|
136
|
+
} catch (error) {
|
|
137
|
+
console.error("Failed to get Multilogin proxy:", error.message);
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ==========================================
|
|
143
|
+
// SECTION 3: PACKETSTREAM PROXY
|
|
144
|
+
// ==========================================
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Generates a PacketStream proxy object with a random session ID using credentials from config.
|
|
148
|
+
*/
|
|
149
|
+
export async function get_packetstream_proxy() {
|
|
150
|
+
// 1. Load config dynamically
|
|
151
|
+
const { PACKETSTREAM_USER, PACKETSTREAM_PASS_KEY, PACKETSTREAM_HOST, PACKETSTREAM_PORT } = await loadUserConfig();
|
|
152
|
+
|
|
153
|
+
// 2. Generate Random Session ID
|
|
154
|
+
const proxy_session_id = randomstring.generate({
|
|
155
|
+
length: 8,
|
|
156
|
+
charset: "alphanumeric",
|
|
157
|
+
capitalization: "both",
|
|
158
|
+
readable: false,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// 3. Construct the proxy object
|
|
162
|
+
const temp_proxy = {
|
|
163
|
+
type: "http",
|
|
164
|
+
host: PACKETSTREAM_HOST,
|
|
165
|
+
port: Number(PACKETSTREAM_PORT),
|
|
166
|
+
user: PACKETSTREAM_USER,
|
|
167
|
+
pass: `${PACKETSTREAM_PASS_KEY}-${proxy_session_id}`,
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
console.log("PacketStream Proxy:", temp_proxy);
|
|
171
|
+
return temp_proxy;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ==========================================
|
|
175
|
+
// SECTION 4: DATABASE PROXY (X_ACCOUNTS)
|
|
176
|
+
// ==========================================
|
|
177
|
+
|
|
178
|
+
export async function get_x_proxy({ provider }) {
|
|
179
|
+
const { arn, query } = await loadUserConfig();
|
|
180
|
+
|
|
181
|
+
const { data: [proxyInstance] = [], error: getProxy_error } = await arn.single(
|
|
182
|
+
query("x_accounts_proxy")
|
|
183
|
+
.update({
|
|
184
|
+
total_used: query.raw("total_used + 1"),
|
|
185
|
+
last_used_time: new Date().toISOString(),
|
|
186
|
+
})
|
|
187
|
+
.where("id", function () {
|
|
188
|
+
let subquery = this.select("id").from("x_accounts_proxy").where("status", 1);
|
|
189
|
+
|
|
190
|
+
if (provider) {
|
|
191
|
+
subquery = subquery.where("provider", provider);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
subquery = subquery
|
|
195
|
+
.andWhere(
|
|
196
|
+
query.raw("COALESCE(last_used_time, '1970-01-01T00:00:00.000Z') < ?", [
|
|
197
|
+
new Date(Date.now() - 60 * 60 * 1000).toISOString(),
|
|
198
|
+
])
|
|
199
|
+
)
|
|
200
|
+
.orderBy("total_used", "asc")
|
|
201
|
+
.limit(1);
|
|
202
|
+
return subquery;
|
|
203
|
+
})
|
|
204
|
+
.returning("*")
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
if (getProxy_error || !proxyInstance) {
|
|
208
|
+
console.error(getProxy_error || "No proxy instances found");
|
|
209
|
+
await sleep(30000);
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return proxyInstance;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ==========================================
|
|
217
|
+
// SECTION 5: AWS PROXY ROTATION
|
|
218
|
+
// ==========================================
|
|
219
|
+
|
|
220
|
+
export function fetchNextProxy(proxies) {
|
|
221
|
+
if (proxies.isFetching) return;
|
|
222
|
+
|
|
223
|
+
proxies.isFetching = true;
|
|
224
|
+
|
|
225
|
+
fetchAwsProxy({
|
|
226
|
+
instance_name: proxies.proxyInstance,
|
|
227
|
+
})
|
|
228
|
+
.then((newProxyIp) => {
|
|
229
|
+
if (newProxyIp) {
|
|
230
|
+
proxies.proxy = {
|
|
231
|
+
host: newProxyIp,
|
|
232
|
+
port: 9002,
|
|
233
|
+
};
|
|
234
|
+
proxies.proxyUsed = 0;
|
|
235
|
+
console.log(`Successfully prepared next proxy: ${newProxyIp}`);
|
|
236
|
+
} else {
|
|
237
|
+
console.log("Next proxy fetch returned null");
|
|
238
|
+
}
|
|
239
|
+
proxies.isFetching = false;
|
|
240
|
+
})
|
|
241
|
+
.catch((error) => {
|
|
242
|
+
console.error(`Error fetching next proxy ${proxies.proxyInstance}:`, error.message);
|
|
243
|
+
proxies.isFetching = false;
|
|
244
|
+
});
|
|
245
|
+
}
|
/package/{LICENSE.md → LICENSE}
RENAMED
|
File without changes
|