mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-04 14:22:09 +03:00
- Add TlsClient module (Chrome 124 fingerprint via wreq-js) - Integrate TLS client as opt-in layer in proxyFetch.js (ENABLE_TLS_FINGERPRINT) - Add per-request TLS tracking via AsyncLocalStorage - Add TLS fingerprint column and badge to Proxy Logger dashboard - Add TLS Fingerprint section to ProxyLogDetail modal - Add wreq-js dependency - Document ENABLE_TLS_FINGERPRINT in .env.example Adapted from upstream PR decolua/9router#137, preserving all OmniRoute-specific proxy features (AsyncLocalStorage context, proxyDispatcher, SOCKS5, Symbol-based patch state).
124 lines
3.5 KiB
JavaScript
124 lines
3.5 KiB
JavaScript
/**
|
|
* Proxy Logger — In-memory ring buffer for proxy events
|
|
* Mirrors the call-log pattern used by RequestLoggerV2
|
|
*/
|
|
import { v4 as uuidv4 } from "uuid";
|
|
|
|
const MAX_ENTRIES = 500;
|
|
const proxyLogs = [];
|
|
|
|
/**
|
|
* Log a proxy event
|
|
* @param {Object} entry
|
|
* @param {"success"|"error"|"timeout"} entry.status
|
|
* @param {Object} entry.proxy - { type, host, port }
|
|
* @param {"key"|"combo"|"provider"|"global"|"direct"} entry.level
|
|
* @param {string} [entry.levelId]
|
|
* @param {string} [entry.provider]
|
|
* @param {string} [entry.targetUrl]
|
|
* @param {string} [entry.publicIp]
|
|
* @param {number} [entry.latencyMs]
|
|
* @param {string} [entry.error]
|
|
* @param {string} [entry.connectionId]
|
|
* @param {string} [entry.comboId]
|
|
*/
|
|
export function logProxyEvent(entry) {
|
|
const log = {
|
|
id: uuidv4(),
|
|
timestamp: new Date().toISOString(),
|
|
status: entry.status || "success",
|
|
proxy: entry.proxy || null,
|
|
level: entry.level || "direct",
|
|
levelId: entry.levelId || null,
|
|
provider: entry.provider || null,
|
|
targetUrl: entry.targetUrl || null,
|
|
publicIp: entry.publicIp || null,
|
|
latencyMs: entry.latencyMs || 0,
|
|
error: entry.error || null,
|
|
connectionId: entry.connectionId || null,
|
|
comboId: entry.comboId || null,
|
|
account: entry.account || null,
|
|
tlsFingerprint: entry.tlsFingerprint || false,
|
|
};
|
|
|
|
proxyLogs.unshift(log); // newest first
|
|
|
|
// Trim to max
|
|
if (proxyLogs.length > MAX_ENTRIES) {
|
|
proxyLogs.length = MAX_ENTRIES;
|
|
}
|
|
|
|
return log;
|
|
}
|
|
|
|
/**
|
|
* Get proxy logs with optional filters
|
|
* @param {Object} filters
|
|
* @param {string} [filters.status] - "success"|"error"|"timeout"
|
|
* @param {string} [filters.type] - "http"|"https"|"socks5"
|
|
* @param {string} [filters.provider]
|
|
* @param {string} [filters.level] - "key"|"combo"|"provider"|"global"|"direct"
|
|
* @param {string} [filters.search] - free text search
|
|
* @param {number} [filters.limit] - max results (default 300)
|
|
* @returns {Array}
|
|
*/
|
|
export function getProxyLogs(filters = {}) {
|
|
let logs = [...proxyLogs];
|
|
|
|
if (filters.status) {
|
|
if (filters.status === "ok") {
|
|
logs = logs.filter((l) => l.status === "success");
|
|
} else {
|
|
logs = logs.filter((l) => l.status === filters.status);
|
|
}
|
|
}
|
|
|
|
if (filters.type) {
|
|
logs = logs.filter((l) => l.proxy?.type === filters.type);
|
|
}
|
|
|
|
if (filters.provider) {
|
|
logs = logs.filter((l) => l.provider === filters.provider);
|
|
}
|
|
|
|
if (filters.level) {
|
|
logs = logs.filter((l) => l.level === filters.level);
|
|
}
|
|
|
|
if (filters.search) {
|
|
const q = filters.search.toLowerCase();
|
|
logs = logs.filter(
|
|
(l) =>
|
|
(l.proxy?.host || "").toLowerCase().includes(q) ||
|
|
(l.provider || "").toLowerCase().includes(q) ||
|
|
(l.targetUrl || "").toLowerCase().includes(q) ||
|
|
(l.publicIp || "").toLowerCase().includes(q) ||
|
|
(l.level || "").toLowerCase().includes(q) ||
|
|
(l.error || "").toLowerCase().includes(q) ||
|
|
(l.account || "").toLowerCase().includes(q)
|
|
);
|
|
}
|
|
|
|
const limit = filters.limit || 300;
|
|
return logs.slice(0, limit);
|
|
}
|
|
|
|
/**
|
|
* Clear all proxy logs
|
|
*/
|
|
export function clearProxyLogs() {
|
|
proxyLogs.length = 0;
|
|
}
|
|
|
|
/**
|
|
* Get proxy log stats
|
|
*/
|
|
export function getProxyLogStats() {
|
|
const total = proxyLogs.length;
|
|
const success = proxyLogs.filter((l) => l.status === "success").length;
|
|
const error = proxyLogs.filter((l) => l.status === "error").length;
|
|
const timeout = proxyLogs.filter((l) => l.status === "timeout").length;
|
|
const direct = proxyLogs.filter((l) => l.level === "direct").length;
|
|
return { total, success, error, timeout, direct };
|
|
}
|