@@ -1094,23 +1094,50 @@ export function accomodateGuest(): {
10941094 firstVisit : firstVisit ,
10951095 } ;
10961096
1097- // pilfered from https://stackoverflow.com/a/8809472/1252649
1097+ // Use cryptographically secure UUID generation
10981098 function generateUUID ( ) {
10991099 logger . log ( '[funnel] Inside generateUUID()' ) ;
1100+
1101+ // Use crypto.randomUUID() if available (Node 14.17+ / modern browsers)
1102+ if ( typeof crypto !== 'undefined' && typeof crypto . randomUUID === 'function' ) {
1103+ const uuid = crypto . randomUUID ( ) ;
1104+ logger . log ( '[funnel] Generated UUID using crypto.randomUUID():' , uuid ) ;
1105+ return uuid ;
1106+ }
1107+
1108+ // Fallback for older environments: use crypto.getRandomValues()
1109+ if ( typeof crypto !== 'undefined' && typeof crypto . getRandomValues === 'function' ) {
1110+ const bytes = new Uint8Array ( 16 ) ;
1111+ crypto . getRandomValues ( bytes ) ;
1112+
1113+ // Set version (4) and variant bits according to RFC 4122
1114+ bytes [ 6 ] = ( bytes [ 6 ] & 0x0f ) | 0x40 ; // Version 4
1115+ bytes [ 8 ] = ( bytes [ 8 ] & 0x3f ) | 0x80 ; // Variant 10
1116+
1117+ const uuid = [
1118+ Array . from ( bytes . slice ( 0 , 4 ) ) . map ( b => b . toString ( 16 ) . padStart ( 2 , '0' ) ) . join ( '' ) ,
1119+ Array . from ( bytes . slice ( 4 , 6 ) ) . map ( b => b . toString ( 16 ) . padStart ( 2 , '0' ) ) . join ( '' ) ,
1120+ Array . from ( bytes . slice ( 6 , 8 ) ) . map ( b => b . toString ( 16 ) . padStart ( 2 , '0' ) ) . join ( '' ) ,
1121+ Array . from ( bytes . slice ( 8 , 10 ) ) . map ( b => b . toString ( 16 ) . padStart ( 2 , '0' ) ) . join ( '' ) ,
1122+ Array . from ( bytes . slice ( 10 , 16 ) ) . map ( b => b . toString ( 16 ) . padStart ( 2 , '0' ) ) . join ( '' ) ,
1123+ ] . join ( '-' ) ;
1124+
1125+ logger . log ( '[funnel] Generated UUID using crypto.getRandomValues():' , uuid ) ;
1126+ return uuid ;
1127+ }
1128+
1129+ // Last resort fallback (should never happen in modern environments)
1130+ logger . warn ( '[funnel] crypto API not available, using timestamp-based UUID (NOT SECURE)' ) ;
11001131 let d = new Date ( ) . getTime ( ) ;
1101- logger . log ( '[funnel] Date timestamp:' , d ) ;
11021132 if ( typeof performance !== 'undefined' && typeof performance . now === 'function' ) {
1103- d += performance . now ( ) ; // use high-precision timer if available
1104- logger . log ( '[funnel] After adding performance.now():' , d ) ;
1133+ d += performance . now ( ) ;
11051134 }
11061135 const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' . replace ( / [ x y ] / g, ( c ) => {
1107- // tslint:disable-next-line:no-bitwise
11081136 const r = ( d + Math . random ( ) * 16 ) % 16 | 0 ;
11091137 d = Math . floor ( d / 16 ) ;
1110- // tslint:disable-next-line:no-bitwise
11111138 return ( c === 'x' ? r : ( r & 0x3 ) | 0x8 ) . toString ( 16 ) ;
11121139 } ) ;
1113- logger . log ( '[funnel] Generated UUID inside function :' , uuid ) ;
1140+ logger . log ( '[funnel] Generated UUID (fallback) :' , uuid ) ;
11141141 return uuid ;
11151142 }
11161143}
0 commit comments