1"use strict"; 2Object.defineProperty(exports, "__esModule", { value: true }); 3exports.ipToBuffer = exports.int32ToIpv4 = exports.ipv4ToInt32 = exports.validateSocksClientChainOptions = exports.validateSocksClientOptions = void 0; 4const util_1 = require("./util"); 5const constants_1 = require("./constants"); 6const stream = require("stream"); 7const ip_address_1 = require("ip-address"); 8const net = require("net"); 9/** 10 * Validates the provided SocksClientOptions 11 * @param options { SocksClientOptions } 12 * @param acceptedCommands { string[] } A list of accepted SocksProxy commands. 13 */ 14function validateSocksClientOptions(options, acceptedCommands = ['connect', 'bind', 'associate']) { 15 // Check SOCKs command option. 16 if (!constants_1.SocksCommand[options.command]) { 17 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksCommand, options); 18 } 19 // Check SocksCommand for acceptable command. 20 if (acceptedCommands.indexOf(options.command) === -1) { 21 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksCommandForOperation, options); 22 } 23 // Check destination 24 if (!isValidSocksRemoteHost(options.destination)) { 25 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsDestination, options); 26 } 27 // Check SOCKS proxy to use 28 if (!isValidSocksProxy(options.proxy)) { 29 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsProxy, options); 30 } 31 // Validate custom auth (if set) 32 validateCustomProxyAuth(options.proxy, options); 33 // Check timeout 34 if (options.timeout && !isValidTimeoutValue(options.timeout)) { 35 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsTimeout, options); 36 } 37 // Check existing_socket (if provided) 38 if (options.existing_socket && 39 !(options.existing_socket instanceof stream.Duplex)) { 40 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsExistingSocket, options); 41 } 42} 43exports.validateSocksClientOptions = validateSocksClientOptions; 44/** 45 * Validates the SocksClientChainOptions 46 * @param options { SocksClientChainOptions } 47 */ 48function validateSocksClientChainOptions(options) { 49 // Only connect is supported when chaining. 50 if (options.command !== 'connect') { 51 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksCommandChain, options); 52 } 53 // Check destination 54 if (!isValidSocksRemoteHost(options.destination)) { 55 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsDestination, options); 56 } 57 // Validate proxies (length) 58 if (!(options.proxies && 59 Array.isArray(options.proxies) && 60 options.proxies.length >= 2)) { 61 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsProxiesLength, options); 62 } 63 // Validate proxies 64 options.proxies.forEach((proxy) => { 65 if (!isValidSocksProxy(proxy)) { 66 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsProxy, options); 67 } 68 // Validate custom auth (if set) 69 validateCustomProxyAuth(proxy, options); 70 }); 71 // Check timeout 72 if (options.timeout && !isValidTimeoutValue(options.timeout)) { 73 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsTimeout, options); 74 } 75} 76exports.validateSocksClientChainOptions = validateSocksClientChainOptions; 77function validateCustomProxyAuth(proxy, options) { 78 if (proxy.custom_auth_method !== undefined) { 79 // Invalid auth method range 80 if (proxy.custom_auth_method < constants_1.SOCKS5_CUSTOM_AUTH_START || 81 proxy.custom_auth_method > constants_1.SOCKS5_CUSTOM_AUTH_END) { 82 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsCustomAuthRange, options); 83 } 84 // Missing custom_auth_request_handler 85 if (proxy.custom_auth_request_handler === undefined || 86 typeof proxy.custom_auth_request_handler !== 'function') { 87 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsCustomAuthOptions, options); 88 } 89 // Missing custom_auth_response_size 90 if (proxy.custom_auth_response_size === undefined) { 91 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsCustomAuthOptions, options); 92 } 93 // Missing/invalid custom_auth_response_handler 94 if (proxy.custom_auth_response_handler === undefined || 95 typeof proxy.custom_auth_response_handler !== 'function') { 96 throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsCustomAuthOptions, options); 97 } 98 } 99} 100/** 101 * Validates a SocksRemoteHost 102 * @param remoteHost { SocksRemoteHost } 103 */ 104function isValidSocksRemoteHost(remoteHost) { 105 return (remoteHost && 106 typeof remoteHost.host === 'string' && 107 typeof remoteHost.port === 'number' && 108 remoteHost.port >= 0 && 109 remoteHost.port <= 65535); 110} 111/** 112 * Validates a SocksProxy 113 * @param proxy { SocksProxy } 114 */ 115function isValidSocksProxy(proxy) { 116 return (proxy && 117 (typeof proxy.host === 'string' || typeof proxy.ipaddress === 'string') && 118 typeof proxy.port === 'number' && 119 proxy.port >= 0 && 120 proxy.port <= 65535 && 121 (proxy.type === 4 || proxy.type === 5)); 122} 123/** 124 * Validates a timeout value. 125 * @param value { Number } 126 */ 127function isValidTimeoutValue(value) { 128 return typeof value === 'number' && value > 0; 129} 130function ipv4ToInt32(ip) { 131 const address = new ip_address_1.Address4(ip); 132 // Convert the IPv4 address parts to an integer 133 return address.toArray().reduce((acc, part) => (acc << 8) + part, 0); 134} 135exports.ipv4ToInt32 = ipv4ToInt32; 136function int32ToIpv4(int32) { 137 // Extract each byte (octet) from the 32-bit integer 138 const octet1 = (int32 >>> 24) & 0xff; 139 const octet2 = (int32 >>> 16) & 0xff; 140 const octet3 = (int32 >>> 8) & 0xff; 141 const octet4 = int32 & 0xff; 142 // Combine the octets into a string in IPv4 format 143 return [octet1, octet2, octet3, octet4].join('.'); 144} 145exports.int32ToIpv4 = int32ToIpv4; 146function ipToBuffer(ip) { 147 if (net.isIPv4(ip)) { 148 // Handle IPv4 addresses 149 const address = new ip_address_1.Address4(ip); 150 return Buffer.from(address.toArray()); 151 } 152 else if (net.isIPv6(ip)) { 153 // Handle IPv6 addresses 154 const address = new ip_address_1.Address6(ip); 155 return Buffer.from(address.toByteArray()); 156 } 157 else { 158 throw new Error('Invalid IP address format'); 159 } 160} 161exports.ipToBuffer = ipToBuffer; 162//# sourceMappingURL=helpers.js.map