@@ -91,21 +91,44 @@ async function fetchWithTimeout(url, options = {}, timeout = 5000) {
9191 }
9292}
9393
94+ function isPrivateIp ( ip ) {
95+ if ( ip === '127.0.0.1' || ip === '::1' || ip === '0.0.0.0' || ip === '::ffff:127.0.0.1' ) return true ;
96+ if ( ip . startsWith ( '192.168.' ) || ip . startsWith ( '10.' ) || ip . startsWith ( '172.16.' ) ) return true ;
97+ if ( ip . startsWith ( 'fc00:' ) || ip . startsWith ( 'fd00:' ) || ip . startsWith ( 'fe80:' ) ) return true ;
98+ if ( ip . startsWith ( '::ffff:192.168.' ) || ip . startsWith ( '::ffff:10.' ) || ip . startsWith ( '::ffff:172.16.' ) ) return true ;
99+ return false ;
100+ }
101+
94102async function isVpnOrProxy ( ip ) {
95- if ( ip === '127.0.0.1' || ip === '::1' || ip === '0.0.0.0' ||
96- ip . startsWith ( '192.168.' ) || ip . startsWith ( '10.' ) || ip . startsWith ( '172.16.' ) ) {
103+ if ( isPrivateIp ( ip ) ) {
97104 console . log ( '[VPN] Skipping private IP:' , ip ) ;
98105 return false ;
99106 }
107+
108+ const cleanIp = ip . replace ( / ^ : : f f f f : / , '' ) ;
109+
100110 try {
101- const res = await fetchWithTimeout ( `https ://ip-api.com/json/${ ip } ?fields=proxy,hosting,isp,org,query` ) ;
111+ const res = await fetchWithTimeout ( `http ://ip-api.com/json/${ cleanIp } ?fields=proxy,hosting,isp,org,query` ) ;
102112 const data = await res . json ( ) ;
103- console . log ( '[VPN] ip-api response for' , ip , ':' , JSON . stringify ( data ) ) ;
104- return data . proxy === true || data . hosting === true ;
113+ console . log ( '[VPN] ip-api response for' , cleanIp , ':' , JSON . stringify ( data ) ) ;
114+ if ( data . proxy === true || data . hosting === true ) return true ;
105115 } catch ( err ) {
106- console . log ( '[VPN] ip-api failed for' , ip , ':' , err . message ) ;
107- return false ;
116+ console . log ( '[VPN] ip-api failed for' , cleanIp , ':' , err . message ) ;
117+ }
118+
119+ try {
120+ const res = await fetchWithTimeout ( `https://ipinfo.io/${ cleanIp } /json` ) ;
121+ const data = await res . json ( ) ;
122+ console . log ( '[VPN] ipinfo response for' , cleanIp , ':' , JSON . stringify ( { org : data . org , hosting : data . hosting } ) ) ;
123+ if ( data . org && ( data . org . startsWith ( 'AS' ) || data . org . toLowerCase ( ) . includes ( 'vpn' ) ||
124+ data . org . toLowerCase ( ) . includes ( 'proxy' ) || data . org . toLowerCase ( ) . includes ( 'hosting' ) ) ) {
125+ return true ;
126+ }
127+ } catch ( err ) {
128+ console . log ( '[VPN] ipinfo failed for' , cleanIp , ':' , err . message ) ;
108129 }
130+
131+ return false ;
109132}
110133
111134const MAX_EMAIL_LENGTH = 254 ;
0 commit comments