import { fromDate } from "../lib/utils" ; import type { Adapter } from "../../adapters" ; import type { InternalOptions } from "../../lib/types" ; import type { OutgoingResponse } from ".." ; import type { Session } from "../.." ; import type { SessionStore } from "../lib/cookie" ; interface SessionParams { options : InternalOptions ; sessionStore : SessionStore ; } /**
 * Return a session object (without any private fields)
 * for Single Page App clients
 */ export default async function session ( params ) { const { options , sessionStore } = params ; const { adapter , jwt , events , callbacks , logger , session : { strategy : sessionStrategy , maxAge : sessionMaxAge } , } = options ; const response = { body : { } , headers : [ { key : "Content-Type" , value : "application/json" } ] , cookies : [ ] , } ; const sessionToken = sessionStore . value ; if ( ! sessionToken ) return response ; if ( sessionStrategy === "jwt" ) { try { const decodedToken = await jwt . decode ( { ... jwt , token : sessionToken , } ) ; const newExpires = fromDate ( sessionMaxAge ) ; const session = { user : { name : decodedToken ?. name , email : decodedToken ?. email , image : decodedToken ?. picture , } , expires : newExpires . toISOString ( ) , } ; const token = await callbacks . jwt ( { token : decodedToken } ) ; const newSession = await callbacks . session ( { session , token } ) ; response . body = newSession ; const newToken = await jwt . encode ( { ... jwt , token , maxAge : options . session . maxAge , } ) ; const sessionCookies = sessionStore . chunk ( newToken , { expires : newExpires , } ) ; response . cookies ?. push ( ... sessionCookies ) ; await events . session ?. ( { session : newSession , token } ) ; } catch ( error ) { logger . error ( "JWT_SESSION_ERROR" , error as Error ) ; response . cookies ?. push ( ... sessionStore . clean ( ) ) ; } } else { try { const { getSessionAndUser , deleteSession , updateSession } = adapter as Adapter ; let userAndSession = await getSessionAndUser ( sessionToken ) ; if ( userAndSession && userAndSession . session . expires . valueOf ( ) < Date . now ( ) ) { await deleteSession ( sessionToken ) ; userAndSession = null ; } if ( userAndSession ) { const { user , session } = userAndSession ; const sessionUpdateAge = options . session . updateAge ; const sessionIsDueToBeUpdatedDate = session . expires . valueOf ( ) - sessionMaxAge * 1000 + sessionUpdateAge * 1000 ; const newExpires = fromDate ( sessionMaxAge ) ; if ( sessionIsDueToBeUpdatedDate <= Date . now ( ) ) { await updateSession ( { sessionToken , expires : newExpires } ) ; } const sessionPayload = await callbacks . session ( { session : { user : { name : user . name , email : user . email , image : user . image , } , expires : session . expires . toISOString ( ) , } , user , } ) ; response . body = sessionPayload ; response . cookies ?. push ( { name : options . cookies . sessionToken . name , value : sessionToken , options : { ... options . cookies . sessionToken . options , expires : newExpires , } , } ) ; await events . session ?. ( { session : sessionPayload } ) ; } else if ( sessionToken ) { response . cookies ?. push ( ... sessionStore . clean ( ) ) ; } } catch ( error ) { logger . error ( "SESSION_ERROR" , error as Error ) ; } } return response ; }