Skip to content

Commit 5e90e2c

Browse files
committed
replace Math.random UUID generation w/ crypto.UUID
1 parent 343bdd7 commit 5e90e2c

File tree

1 file changed

+34
-7
lines changed

1 file changed

+34
-7
lines changed

packages/db/src/impl/common/BaseUserDB.ts

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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(/[xy]/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

Comments
 (0)