import { SocksClientOptions , SocksClientChainOptions , SocksRemoteHost , } from '../client/socksclient' ; import { SocksClientError } from './util' ; import { ERRORS , SOCKS5_CUSTOM_AUTH_END , SOCKS5_CUSTOM_AUTH_START , SocksCommand , SocksProxy , } from './constants' ; import * as stream from 'stream' ; param options { SocksClientOptions } param acceptedCommands { string [ ] } function validateSocksClientOptions ( options , acceptedCommands = [ 'connect' , 'bind' , 'associate' ] ) { if ( ! SocksCommand [ options . command ] ) { throw new SocksClientError ( ERRORS . InvalidSocksCommand , options ) ; } if ( acceptedCommands . indexOf ( options . command ) === - 1 ) { throw new SocksClientError ( ERRORS . InvalidSocksCommandForOperation , options ) ; } if ( ! isValidSocksRemoteHost ( options . destination ) ) { throw new SocksClientError ( ERRORS . InvalidSocksClientOptionsDestination , options ) ; } if ( ! isValidSocksProxy ( options . proxy ) ) { throw new SocksClientError ( ERRORS . InvalidSocksClientOptionsProxy , options ) ; } validateCustomProxyAuth ( options . proxy , options ) ; if ( options . timeout && ! isValidTimeoutValue ( options . timeout ) ) { throw new SocksClientError ( ERRORS . InvalidSocksClientOptionsTimeout , options ) ; } if ( options . existing_socket && ! ( options . existing_socket instanceof stream . Duplex ) ) { throw new SocksClientError ( ERRORS . InvalidSocksClientOptionsExistingSocket , options ) ; } } param options { SocksClientChainOptions } function validateSocksClientChainOptions ( options ) { if ( options . command !== 'connect' ) { throw new SocksClientError ( ERRORS . InvalidSocksCommandChain , options ) ; } if ( ! isValidSocksRemoteHost ( options . destination ) ) { throw new SocksClientError ( ERRORS . InvalidSocksClientOptionsDestination , options ) ; } if ( ! ( options . proxies && Array . isArray ( options . proxies ) && options . proxies . length >= 2 ) ) { throw new SocksClientError ( ERRORS . InvalidSocksClientOptionsProxiesLength , options ) ; } options . proxies . forEach ( ( proxy ) => { if ( ! isValidSocksProxy ( proxy ) ) { throw new SocksClientError ( ERRORS . InvalidSocksClientOptionsProxy , options ) ; } validateCustomProxyAuth ( proxy , options ) ; } ) ; if ( options . timeout && ! isValidTimeoutValue ( options . timeout ) ) { throw new SocksClientError ( ERRORS . InvalidSocksClientOptionsTimeout , options ) ; } } function validateCustomProxyAuth ( proxy , options ) { if ( proxy . custom_auth_method !== undefined ) { if ( proxy . custom_auth_method < SOCKS5_CUSTOM_AUTH_START || proxy . custom_auth_method > SOCKS5_CUSTOM_AUTH_END ) { throw new SocksClientError ( ERRORS . InvalidSocksClientOptionsCustomAuthRange , options ) ; } if ( proxy . custom_auth_request_handler === undefined || typeof proxy . custom_auth_request_handler !== 'function' ) { throw new SocksClientError ( ERRORS . InvalidSocksClientOptionsCustomAuthOptions , options ) ; } if ( proxy . custom_auth_response_size === undefined ) { throw new SocksClientError ( ERRORS . InvalidSocksClientOptionsCustomAuthOptions , options ) ; } if ( proxy . custom_auth_response_handler === undefined || typeof proxy . custom_auth_response_handler !== 'function' ) { throw new SocksClientError ( ERRORS . InvalidSocksClientOptionsCustomAuthOptions , options ) ; } } } param remoteHost { SocksRemoteHost } function isValidSocksRemoteHost ( remoteHost ) { return ( remoteHost && typeof remoteHost . host === 'string' && typeof remoteHost . port === 'number' && remoteHost . port >= 0 && remoteHost . port <= 65535 ) ; } param proxy { SocksProxy } function isValidSocksProxy ( proxy ) { return ( proxy && ( typeof proxy . host === 'string' || typeof proxy . ipaddress === 'string' ) && typeof proxy . port === 'number' && proxy . port >= 0 && proxy . port <= 65535 && ( proxy . type === 4 || proxy . type === 5 ) ) ; } param value { Number } function isValidTimeoutValue ( value ) { return typeof value === 'number' && value > 0 ; } export { validateSocksClientOptions , validateSocksClientChainOptions } ;