1
1
import logger , { setLogger } from "../utils/logger"
2
2
import { toInternalRequest , toResponse } from "../utils/web"
3
- import * as routes from "./routes"
4
- import renderPage from "./pages"
5
3
import { init } from "./init"
6
4
import { assertConfig } from "./lib/assert"
7
5
import { SessionStore } from "./lib/cookie"
6
+ import renderPage from "./pages"
7
+ import * as routes from "./routes"
8
8
9
- import type { AuthAction , AuthOptions } from "./types "
9
+ import { UntrustedHost } from "./errors "
10
10
import type { Cookie } from "./lib/cookie"
11
11
import type { ErrorType } from "./pages/error"
12
+ import type { AuthAction , AuthOptions } from "./types"
12
13
14
+ /** @internal */
13
15
export interface RequestInternal {
14
- /** @default "http://localhost:3000" */
15
- host ?: string
16
- method ? : string
16
+ url : URL
17
+ /** @default "GET" */
18
+ method : string
17
19
cookies ?: Partial < Record < string , string > >
18
20
headers ?: Record < string , any >
19
21
query ?: Record < string , any >
@@ -23,22 +25,20 @@ export interface RequestInternal {
23
25
error ?: string
24
26
}
25
27
26
- export interface NextAuthHeader {
27
- key : string
28
- value : string
29
- }
30
-
31
- // TODO: Rename to `ResponseInternal`
28
+ /** @internal */
32
29
export interface ResponseInternal <
33
30
Body extends string | Record < string , any > | any [ ] = any
34
31
> {
35
32
status ?: number
36
- headers ?: NextAuthHeader [ ]
33
+ headers ?: Record < string , string >
37
34
body ?: Body
38
35
redirect ?: string
39
36
cookies ?: Cookie [ ]
40
37
}
41
38
39
+ const configErrorMessage =
40
+ "There is a problem with the server configuration. Check the server logs for more information."
41
+
42
42
async function AuthHandlerInternal <
43
43
Body extends string | Record < string , any > | any [ ]
44
44
> ( params : {
@@ -47,10 +47,9 @@ async function AuthHandlerInternal<
47
47
/** REVIEW: Is this the best way to skip parsing the body in Node.js? */
48
48
parsedBody ?: any
49
49
} ) : Promise < ResponseInternal < Body > > {
50
- const { options : userOptions , req } = params
51
- setLogger ( userOptions . logger , userOptions . debug )
50
+ const { options : authOptions , req } = params
52
51
53
- const assertionResult = assertConfig ( { options : userOptions , req } )
52
+ const assertionResult = assertConfig ( { options : authOptions , req } )
54
53
55
54
if ( Array . isArray ( assertionResult ) ) {
56
55
assertionResult . forEach ( logger . warn )
@@ -60,14 +59,13 @@ async function AuthHandlerInternal<
60
59
61
60
const htmlPages = [ "signin" , "signout" , "error" , "verify-request" ]
62
61
if ( ! htmlPages . includes ( req . action ) || req . method !== "GET" ) {
63
- const message = `There is a problem with the server configuration. Check the server logs for more information.`
64
62
return {
65
63
status : 500 ,
66
- headers : [ { key : "Content-Type" , value : "application/json" } ] ,
67
- body : { message } as any ,
64
+ headers : { "Content-Type" : "application/json" } ,
65
+ body : { message : configErrorMessage } as any ,
68
66
}
69
67
}
70
- const { pages, theme } = userOptions
68
+ const { pages, theme } = authOptions
71
69
72
70
const authOnErrorPage =
73
71
pages ?. error && req . query ?. callbackUrl ?. startsWith ( pages . error )
@@ -90,13 +88,13 @@ async function AuthHandlerInternal<
90
88
}
91
89
}
92
90
93
- const { action, providerId, error, method = "GET" } = req
91
+ const { action, providerId, error, method } = req
94
92
95
93
const { options, cookies } = await init ( {
96
- userOptions ,
94
+ authOptions ,
97
95
action,
98
96
providerId,
99
- host : req . host ,
97
+ url : req . url ,
100
98
callbackUrl : req . body ?. callbackUrl ?? req . query ?. callbackUrl ,
101
99
csrfToken : req . body ?. csrfToken ,
102
100
cookies : req . cookies ,
@@ -123,7 +121,7 @@ async function AuthHandlerInternal<
123
121
}
124
122
case "csrf" :
125
123
return {
126
- headers : [ { key : "Content-Type" , value : "application/json" } ] ,
124
+ headers : { "Content-Type" : "application/json" } ,
127
125
body : { csrfToken : options . csrfToken } as any ,
128
126
cookies,
129
127
}
@@ -240,7 +238,7 @@ async function AuthHandlerInternal<
240
238
}
241
239
break
242
240
case "_log" :
243
- if ( userOptions . logger ) {
241
+ if ( authOptions . logger ) {
244
242
try {
245
243
const { code, level, ...metadata } = req . body ?? { }
246
244
logger [ level ] ( code , metadata )
@@ -269,7 +267,28 @@ export async function AuthHandler(
269
267
request : Request ,
270
268
options : AuthOptions
271
269
) : Promise < Response > {
270
+ setLogger ( options . logger , options . debug )
271
+
272
+ if ( ! options . trustHost ) {
273
+ const error = new UntrustedHost (
274
+ `Host must be trusted. URL was: ${ request . url } `
275
+ )
276
+ logger . error ( error . code , error )
277
+
278
+ return new Response ( JSON . stringify ( { message : configErrorMessage } ) , {
279
+ status : 500 ,
280
+ headers : { "Content-Type" : "application/json" } ,
281
+ } )
282
+ }
283
+
272
284
const req = await toInternalRequest ( request )
285
+ if ( req instanceof Error ) {
286
+ logger . error ( ( req as any ) . code , req )
287
+ return new Response (
288
+ `Error: This action with HTTP ${ request . method } is not supported.` ,
289
+ { status : 400 }
290
+ )
291
+ }
273
292
const internalResponse = await AuthHandlerInternal ( { req, options } )
274
293
275
294
const response = await toResponse ( internalResponse )
0 commit comments