11import type { BetterAuthOptions } from 'better-auth'
22import type { H3Event } from 'h3'
3- // @ts -expect-error Nuxt generates this virtual module in app builds.
43import { createDatabase , db } from '#auth/database'
5- // @ts -expect-error Nuxt generates this virtual module in app builds.
64import { createSecondaryStorage } from '#auth/secondary-storage'
75import createServerAuth from '#auth/server'
86import { betterAuth } from 'better-auth'
@@ -12,12 +10,42 @@ import { withoutProtocol } from 'ufo'
1210import { resolveCustomSecondaryStorageRequirement } from './custom-secondary-storage'
1311
1412type AuthOptions = ReturnType < typeof createServerAuth >
15- type AuthInstance = ReturnType < typeof betterAuth < AuthOptions > >
13+ type UserAuthConfig = AuthOptions & {
14+ trustedOrigins ?: BetterAuthOptions [ 'trustedOrigins' ]
15+ secondaryStorage ?: BetterAuthOptions [ 'secondaryStorage' ]
16+ }
17+ type ResolvedAuthOptions = UserAuthConfig & {
18+ secret : string
19+ baseURL : string
20+ trustedOrigins ?: BetterAuthOptions [ 'trustedOrigins' ]
21+ database ?: BetterAuthOptions [ 'database' ]
22+ }
23+ type AuthInstance = ReturnType < typeof betterAuth < ResolvedAuthOptions > >
1624
1725const _authCache = new Map < string , AuthInstance > ( )
26+ const requestAuthKey = Symbol . for ( 'nuxt-better-auth.requestAuth' )
1827let _baseURLInferenceLogged = false
1928let _customSecondaryStorageMisconfigWarned = false
2029
30+ interface RequestAuthContext {
31+ [ requestAuthKey ] ?: AuthInstance
32+ }
33+
34+ const fallbackRequestAuthContext = new WeakMap < object , RequestAuthContext > ( )
35+
36+ function getRequestAuthContext ( event : H3Event ) : RequestAuthContext {
37+ const eventWithContext = event as H3Event & { context ?: unknown }
38+ if ( eventWithContext . context && typeof eventWithContext . context === 'object' )
39+ return eventWithContext . context as RequestAuthContext
40+
41+ let context = fallbackRequestAuthContext . get ( event as object )
42+ if ( ! context ) {
43+ context = { }
44+ fallbackRequestAuthContext . set ( event as object , context )
45+ }
46+ return context
47+ }
48+
2149function normalizeLoopbackOrigin ( origin : string ) : string {
2250 if ( ! import . meta. dev )
2351 return origin
@@ -252,15 +280,13 @@ export function serverAuth(event?: H3Event): AuthInstance {
252280 const requestOrigin = resolveEventOrigin ( event )
253281 const hasExplicitSiteUrl = runtimeConfig . public . siteUrl && typeof runtimeConfig . public . siteUrl === 'string'
254282 const cacheKey = hasExplicitSiteUrl ? '__explicit__' : siteUrl
283+ const requestContext = event ? getRequestAuthContext ( event ) : undefined
255284
256- const cached = _authCache . get ( cacheKey )
257- if ( cached )
258- return cached
285+ if ( requestContext ?. [ requestAuthKey ] )
286+ return requestContext [ requestAuthKey ]
259287
260- const database = createDatabase ( )
261- const userConfig = createServerAuth ( { runtimeConfig, db, requestOrigin } ) as BetterAuthOptions & {
262- secondaryStorage ?: BetterAuthOptions [ 'secondaryStorage' ]
263- }
288+ const database = createDatabase ( event )
289+ const userConfig = createServerAuth ( { runtimeConfig, db, requestOrigin } ) as UserAuthConfig
264290 const trustedOrigins = withDevTrustedOrigins ( userConfig . trustedOrigins , Boolean ( hasExplicitSiteUrl ) )
265291
266292 const hubSecondaryStorage = ( runtimeConfig . auth as { hubSecondaryStorage ?: boolean | 'custom' } ) ?. hubSecondaryStorage
@@ -272,15 +298,30 @@ export function serverAuth(event?: H3Event): AuthInstance {
272298 console . warn ( customSecondaryStorage . message )
273299 }
274300
275- const auth = betterAuth ( {
301+ if ( ! database ) {
302+ const cached = _authCache . get ( cacheKey )
303+ if ( cached ) {
304+ if ( requestContext )
305+ requestContext [ requestAuthKey ] = cached
306+ return cached
307+ }
308+ }
309+
310+ const authOptions : ResolvedAuthOptions = {
276311 ...userConfig ,
277- ...( database && { database } ) ,
278- ...( hubSecondaryStorage === true && { secondaryStorage : createSecondaryStorage ( ) } ) ,
312+ ...( database ? { database } : { } ) ,
313+ ...( hubSecondaryStorage === true ? { secondaryStorage : createSecondaryStorage ( ) } : { } ) ,
279314 secret : runtimeConfig . betterAuthSecret ,
280315 baseURL : siteUrl ,
281316 trustedOrigins,
282- } )
317+ }
318+ const auth = betterAuth ( authOptions )
319+
320+ if ( requestContext )
321+ requestContext [ requestAuthKey ] = auth
322+
323+ if ( ! database )
324+ _authCache . set ( cacheKey , auth )
283325
284- _authCache . set ( cacheKey , auth )
285326 return auth
286327}
0 commit comments