@@ -9,46 +9,21 @@ export function expiresAt(expiresIn: number) {
99 return timeNow + expiresIn
1010}
1111
12- // Counter for SSR-safe UUID generation
13- let ssrUuidCounter = 0
14-
1512/**
16- * Generates a UUID v4 string .
13+ * Generates a unique identifier for internal callback subscriptions .
1714 *
18- * This function is SSR-aware to handle Next.js 16 pre-rendering constraints:
19- * - In browsers: Uses crypto.randomUUID() or crypto.getRandomValues() for cryptographic randomness
20- * - During SSR: Uses a deterministic fallback (timestamp + counter)
15+ * This function uses JavaScript Symbols to create guaranteed-unique identifiers
16+ * for auth state change callbacks. Symbols are ideal for this use case because:
17+ * - They are guaranteed unique by the JavaScript runtime
18+ * - They work in all environments (browser, SSR, Node.js)
19+ * - They avoid issues with Next.js 16 deterministic rendering requirements
20+ * - They are perfect for internal, non-serializable identifiers
2121 *
22- * Note: The SSR fallback is safe because:
23- * 1. UUIDs from this function are only used for internal subscription IDs, not security-critical operations
24- * 2. During SSR/pre-rendering, auth callbacks don't actually fire
25- * 3. Once in the browser, proper cryptographic APIs are always used
22+ * Note: This function is only used for internal subscription management,
23+ * not for security-critical operations like session tokens.
2624 */
27- export function uuid ( ) {
28- // Modern browsers and Node.js 19+ - use native crypto.randomUUID()
29- if ( typeof crypto !== 'undefined' && typeof crypto . randomUUID === 'function' ) {
30- return crypto . randomUUID ( )
31- }
32-
33- // Browsers with crypto.getRandomValues() support
34- if ( typeof crypto !== 'undefined' && typeof crypto . getRandomValues === 'function' ) {
35- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' . replace ( / [ x y ] / g, function ( c ) {
36- const array = new Uint8Array ( 1 )
37- crypto . getRandomValues ( array )
38- const r = array [ 0 ] % 16
39- const v = c == 'x' ? r : ( r & 0x3 ) | 0x8
40- return v . toString ( 16 )
41- } )
42- }
43-
44- // SSR/pre-render fallback - deterministic but unique within session
45- // This only generates subscription IDs during pre-render; real UUIDs use crypto in browser
46- const timestamp = Date . now ( )
47- const counter = ssrUuidCounter ++
48- const random1 = Math . floor ( timestamp / 1000000 ) % 10000
49- const random2 = ( timestamp % 1000000 ) % 10000
50-
51- return `ssr-${ timestamp . toString ( 16 ) } -${ counter . toString ( 16 ) } -${ random1 . toString ( 16 ) } -${ random2 . toString ( 16 ) } `
25+ export function generateCallbackId ( ) : symbol {
26+ return Symbol ( 'auth-callback' )
5227}
5328
5429export const isBrowser = ( ) => typeof window !== 'undefined' && typeof document !== 'undefined'
0 commit comments