@@ -21,9 +21,11 @@ type ConfigError =
2121
2222let twitterWarned = false
2323
24- function isValidHttpUrl ( url : string ) {
24+ function isValidHttpUrl ( url : string , baseUrl : string ) {
2525 try {
26- return / ^ h t t p s ? : / . test ( new URL ( url ) . protocol )
26+ return / ^ h t t p s ? : / . test (
27+ new URL ( url , url . startsWith ( "/" ) ? baseUrl : undefined ) . protocol
28+ )
2729 } catch {
2830 return false
2931 }
@@ -57,23 +59,24 @@ export function assertConfig(
5759
5860 const callbackUrlParam = req . query ?. callbackUrl as string | undefined
5961
60- if ( callbackUrlParam && ! isValidHttpUrl ( callbackUrlParam ) ) {
62+ const url = parseUrl ( req . host )
63+
64+ if ( callbackUrlParam && ! isValidHttpUrl ( callbackUrlParam , url . base ) ) {
6165 return new InvalidCallbackUrl (
6266 `Invalid callback URL. Received: ${ callbackUrlParam } `
6367 )
6468 }
6569
70+ // This is below the callbackUrlParam check because it would obscure the error
6671 if ( ! req . host ) return "NEXTAUTH_URL"
6772
68- const url = parseUrl ( req . host )
69-
7073 const { callbackUrl : defaultCallbackUrl } = defaultCookies (
7174 options . useSecureCookies ?? url . base . startsWith ( "https://" )
7275 )
7376 const callbackUrlCookie =
7477 req . cookies ?. [ options . cookies ?. callbackUrl ?. name ?? defaultCallbackUrl . name ]
7578
76- if ( callbackUrlCookie && ! isValidHttpUrl ( callbackUrlCookie ) ) {
79+ if ( callbackUrlCookie && ! isValidHttpUrl ( callbackUrlCookie , url . base ) ) {
7780 return new InvalidCallbackUrl (
7881 `Invalid callback URL. Received: ${ callbackUrlCookie } `
7982 )
0 commit comments