| const { SocksProxyAgent } = require('socks-proxy-agent') |
| const { HttpsProxyAgent } = require('https-proxy-agent') |
| const logger = require('./logger') |
| const config = require('../../config/config') |
|
|
| |
| |
| |
| |
| class ProxyHelper { |
| |
| |
| |
| |
| |
| |
| |
| static createProxyAgent(proxyConfig, options = {}) { |
| if (!proxyConfig) { |
| return null |
| } |
|
|
| try { |
| |
| const proxy = typeof proxyConfig === 'string' ? JSON.parse(proxyConfig) : proxyConfig |
|
|
| |
| if (!proxy.type || !proxy.host || !proxy.port) { |
| logger.warn('⚠️ Invalid proxy configuration: missing required fields (type, host, port)') |
| return null |
| } |
|
|
| |
| const useIPv4 = ProxyHelper._getIPFamilyPreference(options.useIPv4) |
|
|
| |
| const auth = proxy.username && proxy.password ? `${proxy.username}:${proxy.password}@` : '' |
|
|
| |
| if (proxy.type === 'socks5') { |
| const socksUrl = `socks5h://${auth}${proxy.host}:${proxy.port}` |
| const socksOptions = {} |
|
|
| |
| if (useIPv4 !== null) { |
| socksOptions.family = useIPv4 ? 4 : 6 |
| } |
|
|
| return new SocksProxyAgent(socksUrl, socksOptions) |
| } else if (proxy.type === 'http' || proxy.type === 'https') { |
| const proxyUrl = `${proxy.type}://${auth}${proxy.host}:${proxy.port}` |
| const httpOptions = {} |
|
|
| |
| if (useIPv4 !== null) { |
| httpOptions.family = useIPv4 ? 4 : 6 |
| } |
|
|
| return new HttpsProxyAgent(proxyUrl, httpOptions) |
| } else { |
| logger.warn(`⚠️ Unsupported proxy type: ${proxy.type}`) |
| return null |
| } |
| } catch (error) { |
| logger.warn('⚠️ Failed to create proxy agent:', error.message) |
| return null |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| static _getIPFamilyPreference(preference) { |
| |
| if (preference === undefined) { |
| |
| const defaultUseIPv4 = config.proxy?.useIPv4 |
| if (defaultUseIPv4 !== undefined) { |
| return defaultUseIPv4 |
| } |
| |
| return true |
| } |
|
|
| |
| if (typeof preference === 'boolean') { |
| return preference |
| } |
| if (typeof preference === 'number') { |
| return preference === 4 ? true : preference === 6 ? false : null |
| } |
| if (typeof preference === 'string') { |
| const lower = preference.toLowerCase() |
| if (lower === 'ipv4' || lower === '4') { |
| return true |
| } |
| if (lower === 'ipv6' || lower === '6') { |
| return false |
| } |
| if (lower === 'auto' || lower === 'both') { |
| return null |
| } |
| } |
|
|
| |
| return true |
| } |
|
|
| |
| |
| |
| |
| |
| static validateProxyConfig(proxyConfig) { |
| if (!proxyConfig) { |
| return false |
| } |
|
|
| try { |
| const proxy = typeof proxyConfig === 'string' ? JSON.parse(proxyConfig) : proxyConfig |
|
|
| |
| if (!proxy.type || !proxy.host || !proxy.port) { |
| return false |
| } |
|
|
| |
| if (!['socks5', 'http', 'https'].includes(proxy.type)) { |
| return false |
| } |
|
|
| |
| const port = parseInt(proxy.port) |
| if (isNaN(port) || port < 1 || port > 65535) { |
| return false |
| } |
|
|
| return true |
| } catch (error) { |
| return false |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| static getProxyDescription(proxyConfig) { |
| if (!proxyConfig) { |
| return 'No proxy' |
| } |
|
|
| try { |
| const proxy = typeof proxyConfig === 'string' ? JSON.parse(proxyConfig) : proxyConfig |
| const hasAuth = proxy.username && proxy.password |
| return `${proxy.type}://${proxy.host}:${proxy.port}${hasAuth ? ' (with auth)' : ''}` |
| } catch (error) { |
| return 'Invalid proxy config' |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| static maskProxyInfo(proxyConfig) { |
| if (!proxyConfig) { |
| return 'No proxy' |
| } |
|
|
| try { |
| const proxy = typeof proxyConfig === 'string' ? JSON.parse(proxyConfig) : proxyConfig |
|
|
| let proxyDesc = `${proxy.type}://${proxy.host}:${proxy.port}` |
|
|
| |
| if (proxy.username && proxy.password) { |
| const maskedUsername = |
| proxy.username.length <= 2 |
| ? proxy.username |
| : proxy.username[0] + |
| '*'.repeat(Math.max(1, proxy.username.length - 2)) + |
| proxy.username.slice(-1) |
| const maskedPassword = '*'.repeat(Math.min(8, proxy.password.length)) |
| proxyDesc += ` (auth: ${maskedUsername}:${maskedPassword})` |
| } |
|
|
| return proxyDesc |
| } catch (error) { |
| return 'Invalid proxy config' |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| static createProxy(proxyConfig, useIPv4 = true) { |
| logger.warn('⚠️ ProxyHelper.createProxy is deprecated, use createProxyAgent instead') |
| return ProxyHelper.createProxyAgent(proxyConfig, { useIPv4 }) |
| } |
| } |
|
|
| module.exports = ProxyHelper |
|
|