1
- import { NextAuthHandler } from "../core"
2
- import { detectHost } from "../utils/detect-host"
3
- import { setCookie } from "./utils"
1
+ import { AuthHandler } from "../core"
2
+ import { getURL , getBody } from "../utils/node"
4
3
5
4
import type {
6
5
GetServerSidePropsContext ,
@@ -10,60 +9,49 @@ import type {
10
9
import type { NextAuthOptions , Session } from ".."
11
10
import type {
12
11
CallbacksOptions ,
13
- NextAuthAction ,
14
12
NextAuthRequest ,
15
13
NextAuthResponse ,
16
14
} from "../core/types"
17
15
18
- async function NextAuthNextHandler (
16
+ async function NextAuthHandler (
19
17
req : NextApiRequest ,
20
18
res : NextApiResponse ,
21
19
options : NextAuthOptions
22
20
) {
23
- const { nextauth, ...query } = req . query
24
-
25
- options . secret ??= options . jwt ?. secret ?? process . env . NEXTAUTH_SECRET
26
- options . trustHost ??= ! ! ( process . env . AUTH_TRUST_HOST ?? process . env . VERCEL )
27
-
28
- const handler = await NextAuthHandler ( {
29
- req : {
30
- host : detectHost (
31
- options . trustHost ,
32
- req . headers [ "x-forwarded-host" ] ,
33
- process . env . NEXTAUTH_URL ??
34
- ( process . env . NODE_ENV !== "production" && "http://localhost:3000" )
35
- ) ,
36
- body : req . body ,
37
- query,
38
- cookies : req . cookies ,
39
- headers : req . headers ,
40
- method : req . method ,
41
- action : nextauth ?. [ 0 ] as NextAuthAction ,
42
- providerId : nextauth ?. [ 1 ] ,
43
- error : ( req . query . error as string | undefined ) ?? nextauth ?. [ 1 ] ,
44
- } ,
45
- options,
21
+ const url = getURL (
22
+ req . url ,
23
+ options . trustHost ,
24
+ req . headers [ "x-forwarded-host" ] ?? req . headers . host
25
+ )
26
+
27
+ if ( url instanceof Error ) return res . status ( 400 ) . end ( )
28
+
29
+ const request = new Request ( url , {
30
+ headers : new Headers ( req . headers as any ) ,
31
+ method : req . method ,
32
+ ...getBody ( req ) ,
46
33
} )
47
34
48
- res . status ( handler . status ?? 200 )
35
+ options . secret ??= options . jwt ?. secret ?? process . env . NEXTAUTH_SECRET
36
+ const response = await AuthHandler ( request , options )
37
+ const { status, headers } = response
38
+ res . status ( status )
49
39
50
- handler . cookies ?. forEach ( ( cookie ) => setCookie ( res , cookie ) )
40
+ for ( const [ key , val ] of headers . entries ( ) ) {
41
+ const value = key === "set-cookie" ? val . split ( "," ) : val
Has a conversation. Original line has a conversation.
42
+ res . setHeader ( key , value )
43
+ }
51
44
52
- handler . headers ?. forEach ( ( h ) => res . setHeader ( h . key , h . value ) )
45
+ // If the request expects a return URL, send it as JSON
46
+ // instead of doing an actual redirect.
47
+ const redirect = headers . get ( "Location" )
53
48
54
- if ( handler . redirect ) {
55
- // If the request expects a return URL, send it as JSON
56
- // instead of doing an actual redirect.
57
- if ( req . body ?. json !== "true" ) {
58
- // Could chain. .end() when lowest target is Node 14
59
- // https://github.com/nodejs/node/issues/33148
60
- res . status ( 302 ) . setHeader ( "Location" , handler . redirect )
61
- return res . end ( )
62
- }
63
- return res . json ( { url : handler . redirect } )
49
+ if ( req . body ?. json === "true" && redirect ) {
50
+ res . removeHeader ( "Location" )
51
+ return res . json ( { url : redirect } )
64
52
}
65
53
66
- return res . send ( handler . body )
54
+ return res . send ( await response . text ( ) )
67
55
}
68
56
69
57
function NextAuth ( options : NextAuthOptions ) : any
@@ -81,10 +69,10 @@ function NextAuth(
81
69
) {
82
70
if ( args . length === 1 ) {
83
71
return async ( req : NextAuthRequest , res : NextAuthResponse ) =>
84
- await NextAuthNextHandler ( req , res , args [ 0 ] )
72
+ await NextAuthHandler ( req , res , args [ 0 ] )
85
73
}
86
74
87
- return NextAuthNextHandler ( args [ 0 ] , args [ 1 ] , args [ 2 ] )
75
+ return NextAuthHandler ( args [ 0 ] , args [ 1 ] , args [ 2 ] )
88
76
}
89
77
90
78
export default NextAuth
@@ -93,7 +81,7 @@ let experimentalWarningShown = false
93
81
let experimentalRSCWarningShown = false
94
82
95
83
type GetServerSessionOptions = Partial < Omit < NextAuthOptions , "callbacks" > > & {
96
- callbacks ?: Omit < NextAuthOptions [ ' callbacks' ] , "session" > & {
84
+ callbacks ?: Omit < NextAuthOptions [ " callbacks" ] , "session" > & {
97
85
session ?: ( ...args : Parameters < CallbacksOptions [ "session" ] > ) => any
98
86
}
99
87
}
@@ -156,47 +144,34 @@ export async function unstable_getServerSession<
156
144
options = Object . assign ( args [ 2 ] , { providers : [ ] } )
157
145
}
158
146
159
- options . secret ??= process . env . NEXTAUTH_SECRET
160
- options . trustHost ??= ! ! ( process . env . AUTH_TRUST_HOST ?? process . env . VERCEL )
161
-
162
- const session = await NextAuthHandler < Session | { } | string > ( {
163
- options,
164
- req : {
165
- host : detectHost (
166
- options . trustHost ,
167
- req . headers [ "x-forwarded-host" ] ,
168
- process . env . NEXTAUTH_URL ??
169
- ( process . env . NODE_ENV !== "production" && "http://localhost:3000" )
170
- ) ,
171
- action : "session" ,
172
- method : "GET" ,
173
- cookies : req . cookies ,
174
- headers : req . headers ,
175
- } ,
176
- } )
147
+ const urlOrError = getURL (
148
+ "/api/auth/session" ,
149
+ options . trustHost ,
150
+ req . headers [ "x-forwarded-host" ] ?? req . headers . host
151
+ )
152
+
153
+ if ( urlOrError instanceof Error ) throw urlOrError
177
154
178
- const { body, cookies, status = 200 } = session
155
+ options . secret ??= process . env . NEXTAUTH_SECRET
156
+ const response = await AuthHandler (
157
+ new Request ( urlOrError , { headers : req . headers } ) ,
158
+ options
159
+ )
179
160
180
- cookies ?. forEach ( ( cookie ) => setCookie ( res , cookie ) )
161
+ const { status = 200 , headers } = response
181
162
182
- if ( body && typeof body !== "string" && Object . keys ( body ) . length ) {
183
- if ( status === 200 ) {
184
- // @ts -expect-error
185
- if ( isRSC ) delete body . expires
186
- return body as R
187
- }
188
- throw new Error ( ( body as any ) . message )
163
+ for ( const [ key , val ] of headers . entries ( ) ) {
164
+ const value = key === "set-cookie" ? val . split ( "," ) : val
165
+ res . setHeader ( key , value )
189
166
}
190
167
191
- return null
192
- }
168
+ const data = await response . json ( )
193
169
194
- declare global {
195
- // eslint-disable-next-line @typescript-eslint/no-namespace
196
- namespace NodeJS {
197
- interface ProcessEnv {
198
- NEXTAUTH_URL ?: string
199
- VERCEL ?: "1"
200
- }
170
+ if ( ! data || ! Object . keys ( data ) . length ) return null
171
+
172
+ if ( status === 200 ) {
173
+ if ( isRSC ) delete data . expires
174
+ return data as R
201
175
}
176
+ throw new Error ( data . message )
202
177
}