profile-manager-secure 1.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/dist/cli.d.ts +2 -0
- package/dist/cli.js +107 -0
- package/dist/cli.js.map +1 -0
- package/dist/frontend/assets/index-D0IIAYWB.css +1 -0
- package/dist/frontend/assets/index-D9Y0_s3b.js +273 -0
- package/dist/frontend/index.html +26 -0
- package/dist/middleware/auth.middleware.d.ts +8 -0
- package/dist/middleware/auth.middleware.js +51 -0
- package/dist/middleware/auth.middleware.js.map +1 -0
- package/dist/middleware/error.middleware.d.ts +2 -0
- package/dist/middleware/error.middleware.js +11 -0
- package/dist/middleware/error.middleware.js.map +1 -0
- package/dist/modules/auth/auth.controller.d.ts +1 -0
- package/dist/modules/auth/auth.controller.js +175 -0
- package/dist/modules/auth/auth.controller.js.map +1 -0
- package/dist/modules/credential/credential.controller.d.ts +1 -0
- package/dist/modules/credential/credential.controller.js +263 -0
- package/dist/modules/credential/credential.controller.js.map +1 -0
- package/dist/modules/proxy/proxy.controller.d.ts +1 -0
- package/dist/modules/proxy/proxy.controller.js +270 -0
- package/dist/modules/proxy/proxy.controller.js.map +1 -0
- package/dist/modules/proxy/proxy.service.d.ts +28 -0
- package/dist/modules/proxy/proxy.service.js +185 -0
- package/dist/modules/proxy/proxy.service.js.map +1 -0
- package/dist/modules/tailscale/tailscale.controller.d.ts +1 -0
- package/dist/modules/tailscale/tailscale.controller.js +149 -0
- package/dist/modules/tailscale/tailscale.controller.js.map +1 -0
- package/dist/modules/tailscale/tailscale.service.d.ts +96 -0
- package/dist/modules/tailscale/tailscale.service.js +561 -0
- package/dist/modules/tailscale/tailscale.service.js.map +1 -0
- package/dist/modules/totp/totp.controller.d.ts +1 -0
- package/dist/modules/totp/totp.controller.js +41 -0
- package/dist/modules/totp/totp.controller.js.map +1 -0
- package/dist/modules/totp/totp.service.d.ts +26 -0
- package/dist/modules/totp/totp.service.js +96 -0
- package/dist/modules/totp/totp.service.js.map +1 -0
- package/dist/modules/totp/totp.service.test.d.ts +1 -0
- package/dist/modules/totp/totp.service.test.js +41 -0
- package/dist/modules/totp/totp.service.test.js.map +1 -0
- package/dist/modules/vault/apikey.service.d.ts +27 -0
- package/dist/modules/vault/apikey.service.js +87 -0
- package/dist/modules/vault/apikey.service.js.map +1 -0
- package/dist/modules/vault/constants.d.ts +2 -0
- package/dist/modules/vault/constants.js +24 -0
- package/dist/modules/vault/constants.js.map +1 -0
- package/dist/modules/vault/types.d.ts +73 -0
- package/dist/modules/vault/types.js +2 -0
- package/dist/modules/vault/types.js.map +1 -0
- package/dist/modules/vault/vault-migration.service.d.ts +21 -0
- package/dist/modules/vault/vault-migration.service.js +99 -0
- package/dist/modules/vault/vault-migration.service.js.map +1 -0
- package/dist/modules/vault/vault-storage.service.d.ts +22 -0
- package/dist/modules/vault/vault-storage.service.js +76 -0
- package/dist/modules/vault/vault-storage.service.js.map +1 -0
- package/dist/modules/vault/vault.service.d.ts +66 -0
- package/dist/modules/vault/vault.service.js +229 -0
- package/dist/modules/vault/vault.service.js.map +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +67 -0
- package/dist/server.js.map +1 -0
- package/dist/utils/crypto.d.ts +20 -0
- package/dist/utils/crypto.js +54 -0
- package/dist/utils/crypto.js.map +1 -0
- package/dist/utils/crypto.test.d.ts +1 -0
- package/dist/utils/crypto.test.js +66 -0
- package/dist/utils/crypto.test.js.map +1 -0
- package/dist/utils/logger.d.ts +5 -0
- package/dist/utils/logger.js +12 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import http from 'http';
|
|
3
|
+
import { logger } from '../../utils/logger.js';
|
|
4
|
+
import { proxyService } from './proxy.service.js';
|
|
5
|
+
const router = Router();
|
|
6
|
+
// Parse proxy string formats: host:port, host:port:user:pass, user:pass@host:port, etc.
|
|
7
|
+
function parseProxy(proxyStr) {
|
|
8
|
+
let cleaned = proxyStr.trim();
|
|
9
|
+
// Strip protocol
|
|
10
|
+
if (cleaned.startsWith('http://')) {
|
|
11
|
+
cleaned = cleaned.substring(7);
|
|
12
|
+
}
|
|
13
|
+
else if (cleaned.startsWith('https://')) {
|
|
14
|
+
cleaned = cleaned.substring(8);
|
|
15
|
+
}
|
|
16
|
+
let host = '';
|
|
17
|
+
let port = 0;
|
|
18
|
+
let username = '';
|
|
19
|
+
let password = '';
|
|
20
|
+
if (cleaned.includes('@')) {
|
|
21
|
+
// format: user:pass@host:port
|
|
22
|
+
const parts = cleaned.split('@');
|
|
23
|
+
const authParts = parts[0].split(':');
|
|
24
|
+
username = authParts[0];
|
|
25
|
+
password = authParts[1] || '';
|
|
26
|
+
const hostParts = parts[1].split(':');
|
|
27
|
+
host = hostParts[0];
|
|
28
|
+
port = parseInt(hostParts[1] || '80', 10);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// formats: host:port:user:pass or host:port
|
|
32
|
+
const parts = cleaned.split(':');
|
|
33
|
+
if (parts.length >= 4) {
|
|
34
|
+
host = parts[0];
|
|
35
|
+
port = parseInt(parts[1], 10);
|
|
36
|
+
username = parts[2];
|
|
37
|
+
password = parts[3];
|
|
38
|
+
}
|
|
39
|
+
else if (parts.length === 3) {
|
|
40
|
+
host = parts[0];
|
|
41
|
+
port = parseInt(parts[1], 10);
|
|
42
|
+
username = parts[2];
|
|
43
|
+
}
|
|
44
|
+
else if (parts.length === 2) {
|
|
45
|
+
host = parts[0];
|
|
46
|
+
port = parseInt(parts[1], 10);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
throw new Error('Định dạng proxy không hợp lệ');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (!host || !port || isNaN(port)) {
|
|
53
|
+
throw new Error('Host hoặc Port không hợp lệ');
|
|
54
|
+
}
|
|
55
|
+
return { host, port, username, password };
|
|
56
|
+
}
|
|
57
|
+
// Perform proxy check
|
|
58
|
+
function checkSingleProxy(proxyStr, timeout) {
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
let parsedProxy;
|
|
61
|
+
try {
|
|
62
|
+
parsedProxy = parseProxy(proxyStr);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
return resolve({
|
|
66
|
+
proxy: proxyStr,
|
|
67
|
+
host: '',
|
|
68
|
+
port: 0,
|
|
69
|
+
status: 'dead',
|
|
70
|
+
error: err.message || 'Lỗi định dạng proxy'
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
const { host, port, username, password } = parsedProxy;
|
|
74
|
+
const startTime = Date.now();
|
|
75
|
+
const headers = {
|
|
76
|
+
'Host': 'ip-api.com',
|
|
77
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
78
|
+
};
|
|
79
|
+
if (username) {
|
|
80
|
+
const auth = Buffer.from(`${username}:${password}`).toString('base64');
|
|
81
|
+
headers['Proxy-Authorization'] = `Basic ${auth}`;
|
|
82
|
+
}
|
|
83
|
+
const req = http.request({
|
|
84
|
+
host: host,
|
|
85
|
+
port: port,
|
|
86
|
+
method: 'GET',
|
|
87
|
+
path: 'http://ip-api.com/json',
|
|
88
|
+
headers: headers,
|
|
89
|
+
});
|
|
90
|
+
const timeoutTimer = setTimeout(() => {
|
|
91
|
+
req.destroy();
|
|
92
|
+
resolve({
|
|
93
|
+
proxy: proxyStr,
|
|
94
|
+
host,
|
|
95
|
+
port,
|
|
96
|
+
status: 'dead',
|
|
97
|
+
error: 'Timeout kết nối'
|
|
98
|
+
});
|
|
99
|
+
}, timeout);
|
|
100
|
+
req.on('response', (res) => {
|
|
101
|
+
clearTimeout(timeoutTimer);
|
|
102
|
+
if (res.statusCode === 407) {
|
|
103
|
+
resolve({
|
|
104
|
+
proxy: proxyStr,
|
|
105
|
+
host,
|
|
106
|
+
port,
|
|
107
|
+
status: 'dead',
|
|
108
|
+
error: 'Yêu cầu xác thực Proxy (407)'
|
|
109
|
+
});
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
let data = '';
|
|
113
|
+
res.setEncoding('utf8');
|
|
114
|
+
res.on('data', (chunk) => data += chunk);
|
|
115
|
+
res.on('end', () => {
|
|
116
|
+
const latency = Date.now() - startTime;
|
|
117
|
+
try {
|
|
118
|
+
const parsed = JSON.parse(data);
|
|
119
|
+
if (parsed.status === 'success') {
|
|
120
|
+
resolve({
|
|
121
|
+
proxy: proxyStr,
|
|
122
|
+
host,
|
|
123
|
+
port,
|
|
124
|
+
status: 'active',
|
|
125
|
+
latency,
|
|
126
|
+
ip: parsed.query,
|
|
127
|
+
country: parsed.country || 'Unknown',
|
|
128
|
+
countryCode: parsed.countryCode || 'UN',
|
|
129
|
+
city: parsed.city || '',
|
|
130
|
+
isp: parsed.isp || ''
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
resolve({
|
|
135
|
+
proxy: proxyStr,
|
|
136
|
+
host,
|
|
137
|
+
port,
|
|
138
|
+
status: 'dead',
|
|
139
|
+
error: parsed.message || 'Lấy thông tin IP thất bại'
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
resolve({
|
|
145
|
+
proxy: proxyStr,
|
|
146
|
+
host,
|
|
147
|
+
port,
|
|
148
|
+
status: 'dead',
|
|
149
|
+
error: 'Phản hồi từ proxy không đúng định dạng JSON'
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
req.on('error', (err) => {
|
|
155
|
+
clearTimeout(timeoutTimer);
|
|
156
|
+
resolve({
|
|
157
|
+
proxy: proxyStr,
|
|
158
|
+
host,
|
|
159
|
+
port,
|
|
160
|
+
status: 'dead',
|
|
161
|
+
error: err.message || 'Lỗi kết nối socket'
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
req.end();
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
// API endpoint to check batch of proxies
|
|
168
|
+
router.post('/check', async (req, res) => {
|
|
169
|
+
try {
|
|
170
|
+
const { proxies, timeout = 5000, concurrency = 10 } = req.body;
|
|
171
|
+
if (!proxies || !Array.isArray(proxies)) {
|
|
172
|
+
return res.status(400).json({ error: 'Danh sách proxies phải là một mảng chuỗi.' });
|
|
173
|
+
}
|
|
174
|
+
const testTimeout = Math.min(Math.max(timeout, 1000), 15000); // between 1s and 15s
|
|
175
|
+
const batchConcurrency = Math.min(Math.max(concurrency, 1), 50); // limit parallel checks
|
|
176
|
+
logger.info(`Bắt đầu check ${proxies.length} proxy (Concurrency: ${batchConcurrency}, Timeout: ${testTimeout}ms)`);
|
|
177
|
+
const results = [];
|
|
178
|
+
// Chunking to support concurrency control
|
|
179
|
+
for (let i = 0; i < proxies.length; i += batchConcurrency) {
|
|
180
|
+
const chunk = proxies.slice(i, i + batchConcurrency);
|
|
181
|
+
const chunkPromises = chunk.map(p => checkSingleProxy(p, testTimeout));
|
|
182
|
+
const chunkResults = await Promise.all(chunkPromises);
|
|
183
|
+
results.push(...chunkResults);
|
|
184
|
+
}
|
|
185
|
+
logger.info(`Đã hoàn thành check ${proxies.length} proxy.`);
|
|
186
|
+
// Auto-save check results to vault
|
|
187
|
+
try {
|
|
188
|
+
const now = new Date().toISOString();
|
|
189
|
+
const saveList = results.map(r => ({
|
|
190
|
+
proxy: r.proxy,
|
|
191
|
+
host: r.host || '',
|
|
192
|
+
port: r.port || 0,
|
|
193
|
+
status: r.status,
|
|
194
|
+
latency: r.latency,
|
|
195
|
+
ip: r.ip,
|
|
196
|
+
country: r.country,
|
|
197
|
+
countryCode: r.countryCode,
|
|
198
|
+
city: r.city,
|
|
199
|
+
isp: r.isp,
|
|
200
|
+
error: r.error,
|
|
201
|
+
last_checked: now
|
|
202
|
+
}));
|
|
203
|
+
await proxyService.saveCheckedProxiesBulk(saveList);
|
|
204
|
+
logger.info(`Đã tự động lưu ${results.length} kết quả check proxy vào vault.`);
|
|
205
|
+
}
|
|
206
|
+
catch (saveErr) {
|
|
207
|
+
logger.error('Lỗi khi tự động lưu kết quả check proxy:', saveErr.message);
|
|
208
|
+
}
|
|
209
|
+
res.json({ success: true, results });
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
logger.error('Proxy check API error:', error);
|
|
213
|
+
res.status(500).json({ error: error.message });
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
// 1. Get all saved proxies
|
|
217
|
+
router.get('/', (req, res) => {
|
|
218
|
+
try {
|
|
219
|
+
const list = proxyService.getProxies();
|
|
220
|
+
res.json(list);
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
logger.error('Lấy danh sách proxy lỗi:', error.message);
|
|
224
|
+
res.status(500).json({ error: error.message });
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
// 2. Add multiple proxies manually
|
|
228
|
+
router.post('/', async (req, res) => {
|
|
229
|
+
try {
|
|
230
|
+
const { proxies } = req.body;
|
|
231
|
+
if (!proxies || !Array.isArray(proxies)) {
|
|
232
|
+
return res.status(400).json({ error: 'Danh sách proxies phải là một mảng chuỗi.' });
|
|
233
|
+
}
|
|
234
|
+
const added = await proxyService.addProxiesBulk(proxies);
|
|
235
|
+
res.status(201).json({ success: true, addedCount: added.length, added });
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
logger.error('Thêm proxy thủ công lỗi:', error.message);
|
|
239
|
+
res.status(500).json({ error: error.message });
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
// 3. Delete a single proxy
|
|
243
|
+
router.delete('/:id', async (req, res) => {
|
|
244
|
+
try {
|
|
245
|
+
const { id } = req.params;
|
|
246
|
+
await proxyService.deleteProxy(id);
|
|
247
|
+
res.json({ success: true });
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
logger.error('Xóa proxy lỗi:', error.message);
|
|
251
|
+
res.status(500).json({ error: error.message });
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
// 4. Delete batch of proxies
|
|
255
|
+
router.post('/delete-batch', async (req, res) => {
|
|
256
|
+
try {
|
|
257
|
+
const { ids } = req.body;
|
|
258
|
+
if (!ids || !Array.isArray(ids)) {
|
|
259
|
+
return res.status(400).json({ error: 'Danh sách IDs phải là mảng.' });
|
|
260
|
+
}
|
|
261
|
+
await proxyService.deleteProxiesBulk(ids);
|
|
262
|
+
res.json({ success: true });
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
logger.error('Xóa nhiều proxy lỗi:', error.message);
|
|
266
|
+
res.status(500).json({ error: error.message });
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
export const proxyRouter = router;
|
|
270
|
+
//# sourceMappingURL=proxy.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.controller.js","sourceRoot":"","sources":["../../../src/modules/proxy/proxy.controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Proxy } from '../vault/vault.service.js';
|
|
2
|
+
export declare class ProxyService {
|
|
3
|
+
/**
|
|
4
|
+
* Get all proxies from vault
|
|
5
|
+
*/
|
|
6
|
+
getProxies(): Proxy[];
|
|
7
|
+
/**
|
|
8
|
+
* Add a new proxy or update an existing one (based on the raw proxy string)
|
|
9
|
+
*/
|
|
10
|
+
saveProxy(proxyData: Omit<Proxy, 'id' | 'created_at' | 'updated_at'>): Promise<Proxy>;
|
|
11
|
+
/**
|
|
12
|
+
* Save multiple checked proxies in a single disk write
|
|
13
|
+
*/
|
|
14
|
+
saveCheckedProxiesBulk(results: Omit<Proxy, 'id' | 'created_at' | 'updated_at'>[]): Promise<Proxy[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Add multiple proxies to database manually
|
|
17
|
+
*/
|
|
18
|
+
addProxiesBulk(proxiesList: string[]): Promise<Proxy[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Delete a single proxy
|
|
21
|
+
*/
|
|
22
|
+
deleteProxy(id: string): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Delete multiple proxies
|
|
25
|
+
*/
|
|
26
|
+
deleteProxiesBulk(ids: string[]): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
export declare const proxyService: ProxyService;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
import { vaultService } from '../vault/vault.service.js';
|
|
3
|
+
export class ProxyService {
|
|
4
|
+
/**
|
|
5
|
+
* Get all proxies from vault
|
|
6
|
+
*/
|
|
7
|
+
getProxies() {
|
|
8
|
+
const data = vaultService.getData();
|
|
9
|
+
return data.proxies || [];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Add a new proxy or update an existing one (based on the raw proxy string)
|
|
13
|
+
*/
|
|
14
|
+
async saveProxy(proxyData) {
|
|
15
|
+
const data = vaultService.getData();
|
|
16
|
+
if (!data.proxies) {
|
|
17
|
+
data.proxies = [];
|
|
18
|
+
}
|
|
19
|
+
const now = new Date().toISOString();
|
|
20
|
+
const existingIndex = data.proxies.findIndex(p => p.proxy === proxyData.proxy);
|
|
21
|
+
let savedProxy;
|
|
22
|
+
if (existingIndex !== -1) {
|
|
23
|
+
// Update existing proxy
|
|
24
|
+
savedProxy = {
|
|
25
|
+
...data.proxies[existingIndex],
|
|
26
|
+
...proxyData,
|
|
27
|
+
updated_at: now
|
|
28
|
+
};
|
|
29
|
+
data.proxies[existingIndex] = savedProxy;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
// Create a new proxy
|
|
33
|
+
savedProxy = {
|
|
34
|
+
...proxyData,
|
|
35
|
+
id: crypto.randomUUID(),
|
|
36
|
+
created_at: now,
|
|
37
|
+
updated_at: now
|
|
38
|
+
};
|
|
39
|
+
data.proxies.push(savedProxy);
|
|
40
|
+
}
|
|
41
|
+
await vaultService.save();
|
|
42
|
+
return savedProxy;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Save multiple checked proxies in a single disk write
|
|
46
|
+
*/
|
|
47
|
+
async saveCheckedProxiesBulk(results) {
|
|
48
|
+
const data = vaultService.getData();
|
|
49
|
+
if (!data.proxies) {
|
|
50
|
+
data.proxies = [];
|
|
51
|
+
}
|
|
52
|
+
const now = new Date().toISOString();
|
|
53
|
+
const savedList = [];
|
|
54
|
+
for (const pData of results) {
|
|
55
|
+
const existingIndex = data.proxies.findIndex(p => p.proxy === pData.proxy);
|
|
56
|
+
let savedProxy;
|
|
57
|
+
if (existingIndex !== -1) {
|
|
58
|
+
savedProxy = {
|
|
59
|
+
...data.proxies[existingIndex],
|
|
60
|
+
...pData,
|
|
61
|
+
updated_at: now
|
|
62
|
+
};
|
|
63
|
+
data.proxies[existingIndex] = savedProxy;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
savedProxy = {
|
|
67
|
+
...pData,
|
|
68
|
+
id: crypto.randomUUID(),
|
|
69
|
+
created_at: now,
|
|
70
|
+
updated_at: now
|
|
71
|
+
};
|
|
72
|
+
data.proxies.push(savedProxy);
|
|
73
|
+
}
|
|
74
|
+
savedList.push(savedProxy);
|
|
75
|
+
}
|
|
76
|
+
await vaultService.save();
|
|
77
|
+
return savedList;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Add multiple proxies to database manually
|
|
81
|
+
*/
|
|
82
|
+
async addProxiesBulk(proxiesList) {
|
|
83
|
+
const data = vaultService.getData();
|
|
84
|
+
if (!data.proxies) {
|
|
85
|
+
data.proxies = [];
|
|
86
|
+
}
|
|
87
|
+
const now = new Date().toISOString();
|
|
88
|
+
const addedProxies = [];
|
|
89
|
+
for (const rawProxy of proxiesList) {
|
|
90
|
+
const trimmed = rawProxy.trim();
|
|
91
|
+
if (!trimmed)
|
|
92
|
+
continue;
|
|
93
|
+
const existingIndex = data.proxies.findIndex(p => p.proxy === trimmed);
|
|
94
|
+
if (existingIndex !== -1) {
|
|
95
|
+
continue; // Skip if already exists to prevent duplication
|
|
96
|
+
}
|
|
97
|
+
// Simple parsing just to get host/port
|
|
98
|
+
let host = '';
|
|
99
|
+
let port = 80;
|
|
100
|
+
let username = '';
|
|
101
|
+
let password = '';
|
|
102
|
+
try {
|
|
103
|
+
let cleaned = trimmed;
|
|
104
|
+
if (cleaned.startsWith('http://'))
|
|
105
|
+
cleaned = cleaned.substring(7);
|
|
106
|
+
else if (cleaned.startsWith('https://'))
|
|
107
|
+
cleaned = cleaned.substring(8);
|
|
108
|
+
if (cleaned.includes('@')) {
|
|
109
|
+
const parts = cleaned.split('@');
|
|
110
|
+
const authParts = parts[0].split(':');
|
|
111
|
+
username = authParts[0];
|
|
112
|
+
password = authParts[1] || '';
|
|
113
|
+
const hostParts = parts[1].split(':');
|
|
114
|
+
host = hostParts[0];
|
|
115
|
+
port = parseInt(hostParts[1] || '80', 10);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
const parts = cleaned.split(':');
|
|
119
|
+
if (parts.length >= 4) {
|
|
120
|
+
host = parts[0];
|
|
121
|
+
port = parseInt(parts[1], 10);
|
|
122
|
+
username = parts[2];
|
|
123
|
+
password = parts[3];
|
|
124
|
+
}
|
|
125
|
+
else if (parts.length === 3) {
|
|
126
|
+
host = parts[0];
|
|
127
|
+
port = parseInt(parts[1], 10);
|
|
128
|
+
username = parts[2];
|
|
129
|
+
}
|
|
130
|
+
else if (parts.length === 2) {
|
|
131
|
+
host = parts[0];
|
|
132
|
+
port = parseInt(parts[1], 10);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
host = trimmed;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
host = trimmed;
|
|
141
|
+
}
|
|
142
|
+
const newProxy = {
|
|
143
|
+
id: crypto.randomUUID(),
|
|
144
|
+
proxy: trimmed,
|
|
145
|
+
host,
|
|
146
|
+
port: isNaN(port) ? 80 : port,
|
|
147
|
+
username,
|
|
148
|
+
password,
|
|
149
|
+
status: 'dead',
|
|
150
|
+
last_checked: now,
|
|
151
|
+
created_at: now,
|
|
152
|
+
updated_at: now
|
|
153
|
+
};
|
|
154
|
+
data.proxies.push(newProxy);
|
|
155
|
+
addedProxies.push(newProxy);
|
|
156
|
+
}
|
|
157
|
+
if (addedProxies.length > 0) {
|
|
158
|
+
await vaultService.save();
|
|
159
|
+
}
|
|
160
|
+
return addedProxies;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Delete a single proxy
|
|
164
|
+
*/
|
|
165
|
+
async deleteProxy(id) {
|
|
166
|
+
const data = vaultService.getData();
|
|
167
|
+
if (data.proxies) {
|
|
168
|
+
data.proxies = data.proxies.filter(p => p.id !== id);
|
|
169
|
+
await vaultService.save();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Delete multiple proxies
|
|
174
|
+
*/
|
|
175
|
+
async deleteProxiesBulk(ids) {
|
|
176
|
+
const data = vaultService.getData();
|
|
177
|
+
if (data.proxies) {
|
|
178
|
+
const idSet = new Set(ids);
|
|
179
|
+
data.proxies = data.proxies.filter(p => !idSet.has(p.id));
|
|
180
|
+
await vaultService.save();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
export const proxyService = new ProxyService();
|
|
185
|
+
//# sourceMappingURL=proxy.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.service.js","sourceRoot":"","sources":["../../../src/modules/proxy/proxy.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const tailscaleRouter: import("express-serve-static-core").Router;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { tailscaleService } from './tailscale.service.js';
|
|
3
|
+
import { logger } from '../../utils/logger.js';
|
|
4
|
+
const router = Router();
|
|
5
|
+
// 1. Get Tailscale status
|
|
6
|
+
router.get('/status', async (req, res) => {
|
|
7
|
+
try {
|
|
8
|
+
const status = await tailscaleService.getStatus();
|
|
9
|
+
res.json(status);
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
logger.error('Error in tailscale status endpoint:', error);
|
|
13
|
+
res.status(500).json({ error: error.message || 'Internal Server Error' });
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
// 2. Connect Tailscale (up)
|
|
17
|
+
router.post('/connect', async (req, res) => {
|
|
18
|
+
try {
|
|
19
|
+
const { authKey, acceptDns, exitNode } = req.body;
|
|
20
|
+
const result = await tailscaleService.up({ authKey, acceptDns, exitNode });
|
|
21
|
+
if (result.success) {
|
|
22
|
+
res.json(result);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
res.status(400).json({ error: result.message });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
logger.error('Error in tailscale connect endpoint:', error);
|
|
30
|
+
res.status(500).json({ error: error.message || 'Internal Server Error' });
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
// 3. Disconnect Tailscale (down)
|
|
34
|
+
router.post('/disconnect', async (req, res) => {
|
|
35
|
+
try {
|
|
36
|
+
const result = await tailscaleService.down();
|
|
37
|
+
if (result.success) {
|
|
38
|
+
res.json(result);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
res.status(400).json({ error: result.message });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
logger.error('Error in tailscale disconnect endpoint:', error);
|
|
46
|
+
res.status(500).json({ error: error.message || 'Internal Server Error' });
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
// 4. Logout Tailscale
|
|
50
|
+
router.post('/logout', async (req, res) => {
|
|
51
|
+
try {
|
|
52
|
+
const result = await tailscaleService.logout();
|
|
53
|
+
if (result.success) {
|
|
54
|
+
res.json(result);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
res.status(400).json({ error: result.message });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
logger.error('Error in tailscale logout endpoint:', error);
|
|
62
|
+
res.status(500).json({ error: error.message || 'Internal Server Error' });
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
// 5. Get Funnel/Serve status
|
|
66
|
+
router.get('/funnel-status', async (req, res) => {
|
|
67
|
+
try {
|
|
68
|
+
const status = await tailscaleService.getFunnelStatus();
|
|
69
|
+
res.json(status);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
logger.error('Error in tailscale funnel-status endpoint:', error);
|
|
73
|
+
res.status(500).json({ error: error.message || 'Internal Server Error' });
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
// 6. Toggle Funnel (Public Tunnel)
|
|
77
|
+
router.post('/funnel/toggle', async (req, res) => {
|
|
78
|
+
try {
|
|
79
|
+
const { active } = req.body;
|
|
80
|
+
if (active === undefined || typeof active !== 'boolean') {
|
|
81
|
+
return res.status(400).json({ error: 'Active state is required' });
|
|
82
|
+
}
|
|
83
|
+
const result = await tailscaleService.toggleFunnel(active);
|
|
84
|
+
if (result.success) {
|
|
85
|
+
res.json(result);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
res.status(400).json({ error: result.message });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
logger.error('Error in tailscale funnel toggle endpoint:', error);
|
|
93
|
+
res.status(500).json({ error: error.message || 'Internal Server Error' });
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
// 7. Toggle Serve (Tailnet HTTPS Serve)
|
|
97
|
+
router.post('/serve/toggle', async (req, res) => {
|
|
98
|
+
try {
|
|
99
|
+
const { active } = req.body;
|
|
100
|
+
if (active === undefined || typeof active !== 'boolean') {
|
|
101
|
+
return res.status(400).json({ error: 'Active state is required' });
|
|
102
|
+
}
|
|
103
|
+
const result = await tailscaleService.toggleServe(active);
|
|
104
|
+
if (result.success) {
|
|
105
|
+
res.json(result);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
res.status(400).json({ error: result.message });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
logger.error('Error in tailscale serve toggle endpoint:', error);
|
|
113
|
+
res.status(500).json({ error: error.message || 'Internal Server Error' });
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
// 8. Silent install Tailscale CLI (Windows only)
|
|
117
|
+
router.post('/install', async (req, res) => {
|
|
118
|
+
try {
|
|
119
|
+
const result = await tailscaleService.installTailscale();
|
|
120
|
+
if (result.success) {
|
|
121
|
+
res.json(result);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
res.status(400).json({ error: result.message });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
logger.error('Error in tailscale install endpoint:', error);
|
|
129
|
+
res.status(500).json({ error: error.message || 'Internal Server Error' });
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
// 9. Provision TLS Certificate from Tailscale
|
|
133
|
+
router.post('/provision-cert', async (req, res) => {
|
|
134
|
+
try {
|
|
135
|
+
const result = await tailscaleService.provisionCert();
|
|
136
|
+
if (result.success) {
|
|
137
|
+
res.json(result);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
res.status(400).json({ error: result.message });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
logger.error('Error in tailscale provision-cert endpoint:', error);
|
|
145
|
+
res.status(500).json({ error: error.message || 'Internal Server Error' });
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
export const tailscaleRouter = router;
|
|
149
|
+
//# sourceMappingURL=tailscale.controller.js.map
|