@@ -5,12 +5,12 @@ import {
55 BadMethodCallError ,
66 Reader ,
77} from '@maxmind/geoip2-node' ;
8+ import { logger } from '../lib/logger' ;
89
910interface GeoIPReader extends Reader {
1011 city ( ip : string ) : City ;
1112}
1213
13- // Database configuration
1414const CDN_URL = 'https://cdn.databuddy.cc/GeoLite2-City.mmdb' ;
1515
1616let reader : GeoIPReader | null = null ;
@@ -30,22 +30,20 @@ async function loadDatabaseFromCdn(): Promise<Buffer> {
3030 const arrayBuffer = await response . arrayBuffer ( ) ;
3131 const dbBuffer = Buffer . from ( arrayBuffer ) ;
3232
33- // Validate that we got a reasonable file size (should be ~50-100MB)
3433 if ( dbBuffer . length < 1_000_000 ) {
35- // Less than 1MB
3634 throw new Error (
3735 `Database file seems too small: ${ dbBuffer . length } bytes`
3836 ) ;
3937 }
4038
4139 return dbBuffer ;
4240 } catch ( error ) {
43- console . error ( 'Failed to load database from CDN:' , error ) ;
41+ logger . error ( 'Failed to load database from CDN:' , { error } ) ;
4442 throw error ;
4543 }
4644}
4745
48- async function loadDatabase ( ) {
46+ function loadDatabase ( ) {
4947 if ( loadError ) {
5048 throw loadError ;
5149 }
@@ -63,12 +61,11 @@ async function loadDatabase() {
6361 try {
6462 const dbBuffer = await loadDatabaseFromCdn ( ) ;
6563
66- // Add a small delay to prevent overwhelming the system
6764 await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
6865
6966 reader = Reader . openBuffer ( dbBuffer ) as GeoIPReader ;
7067 } catch ( error ) {
71- console . error ( 'Failed to load GeoIP database:' , error ) ;
68+ logger . error ( 'Failed to load GeoIP database:' , { error } ) ;
7269 loadError = error as Error ;
7370 reader = null ;
7471 } finally {
@@ -79,21 +76,25 @@ async function loadDatabase() {
7976 return loadPromise ;
8077}
8178
82- // Don't initialize on module load - wait for first use
8379const ignore = [ '127.0.0.1' , '::1' ] ;
8480
85- // Helper function to validate IP address format
81+ const ipv4Regex =
82+ / ^ (?: (?: 2 5 [ 0 - 5 ] | 2 [ 0 - 4 ] [ 0 - 9 ] | [ 0 1 ] ? [ 0 - 9 ] [ 0 - 9 ] ? ) \. ) { 3 } (?: 2 5 [ 0 - 5 ] | 2 [ 0 - 4 ] [ 0 - 9 ] | [ 0 1 ] ? [ 0 - 9 ] [ 0 - 9 ] ? ) $ / ;
83+
84+ const ipv6Regex = / ^ (?: [ 0 - 9 a - f A - F ] { 1 , 4 } : ) { 7 } [ 0 - 9 a - f A - F ] { 1 , 4 } $ / ;
85+
8686function isValidIp ( ip : string ) : boolean {
87- if ( ! ip ) return false ;
87+ if ( ! ip ) {
88+ return false ;
89+ }
8890
89- // Check for IPv4 format
90- const ipv4Regex =
91- / ^ (?: (?: 2 5 [ 0 - 5 ] | 2 [ 0 - 4 ] [ 0 - 9 ] | [ 0 1 ] ? [ 0 - 9 ] [ 0 - 9 ] ? ) \. ) { 3 } (?: 2 5 [ 0 - 5 ] | 2 [ 0 - 4 ] [ 0 - 9 ] | [ 0 1 ] ? [ 0 - 9 ] [ 0 - 9 ] ? ) $ / ;
92- if ( ipv4Regex . test ( ip ) ) return true ;
91+ if ( ipv4Regex . test ( ip ) ) {
92+ return true ;
93+ }
9394
94- // Check for IPv6 format (basic check)
95- const ipv6Regex = / ^ (?: [ 0 - 9 a - f A - F ] { 1 , 4 } : ) { 7 } [ 0 - 9 a - f A - F ] { 1 , 4 } $ / ;
96- if ( ipv6Regex . test ( ip ) ) return true ;
95+ if ( ipv6Regex . test ( ip ) ) {
96+ return true ;
97+ }
9798
9899 return false ;
99100}
@@ -103,12 +104,11 @@ export async function getGeoLocation(ip: string) {
103104 return { country : undefined , region : undefined , city : undefined } ;
104105 }
105106
106- // Lazy load database on first use
107107 if ( ! ( reader || isLoading || loadError ) ) {
108108 try {
109109 await loadDatabase ( ) ;
110110 } catch ( error ) {
111- console . error ( 'Failed to load database for IP lookup:' , error ) ;
111+ logger . error ( 'Failed to load database for IP lookup:' , { error } ) ;
112112 return { country : undefined , region : undefined , city : undefined } ;
113113 }
114114 }
@@ -137,41 +137,48 @@ export async function getGeoLocation(ip: string) {
137137
138138 // Handle BadMethodCallError (wrong database type)
139139 if ( error instanceof BadMethodCallError ) {
140- console . error (
140+ logger . error (
141141 'Database type mismatch - using city() method with ipinfo database'
142142 ) ;
143143 return { country : undefined , region : undefined , city : undefined } ;
144144 }
145145
146- // Handle other errors
147- console . error ( 'Error looking up IP:' , ip , error ) ;
146+ logger . error ( 'Error looking up IP:' , { ip, error } ) ;
148147 return { country : undefined , region : undefined , city : undefined } ;
149148 }
150149}
151150
152151export function getClientIp ( req : Request ) : string | undefined {
153152 const cfIp = req . headers . get ( 'cf-connecting-ip' ) ;
154- if ( cfIp ) return cfIp ;
153+ if ( cfIp ) {
154+ return cfIp ;
155+ }
155156
156157 const forwardedFor = req . headers . get ( 'x-forwarded-for' ) ;
157158 if ( forwardedFor ) {
158159 const firstIp = forwardedFor . split ( ',' ) [ 0 ] ?. trim ( ) ;
159- if ( firstIp ) return firstIp ;
160+ if ( firstIp ) {
161+ return firstIp ;
162+ }
160163 }
161164
162165 const realIp = req . headers . get ( 'x-real-ip' ) ;
163- if ( realIp ) return realIp ;
166+ if ( realIp ) {
167+ return realIp ;
168+ }
164169
165170 return ;
166171}
167172
168- export async function parseIp ( req : Request ) {
173+ export function parseIp ( req : Request ) {
169174 const ip = getClientIp ( req ) ;
170175 return getGeoLocation ( ip || '' ) ;
171176}
172177
173178export function anonymizeIp ( ip : string ) : string {
174- if ( ! ip ) return '' ;
179+ if ( ! ip ) {
180+ return '' ;
181+ }
175182
176183 const salt = process . env . IP_HASH_SALT || 'databuddy-ip-salt' ;
177184 const hash = createHash ( 'sha256' ) ;
@@ -191,14 +198,20 @@ export async function getGeo(ip: string) {
191198
192199export function extractIpFromRequest ( request : Request ) : string {
193200 const cfIp = request . headers . get ( 'cf-connecting-ip' ) ;
194- if ( cfIp ) return cfIp . trim ( ) ;
201+ if ( cfIp ) {
202+ return cfIp . trim ( ) ;
203+ }
195204
196205 const forwardedFor = request . headers . get ( 'x-forwarded-for' ) ;
197206 const firstIp = forwardedFor ?. split ( ',' ) [ 0 ] ?. trim ( ) ;
198- if ( firstIp ) return firstIp ;
207+ if ( firstIp ) {
208+ return firstIp ;
209+ }
199210
200211 const realIp = request . headers . get ( 'x-real-ip' ) ;
201- if ( realIp ) return realIp . trim ( ) ;
212+ if ( realIp ) {
213+ return realIp . trim ( ) ;
214+ }
202215
203216 return '' ;
204217}
0 commit comments