@@ -2,10 +2,10 @@ import { Auth, raw, skipCSRFCheck } from "@auth/core"
22import { headers as nextHeaders , cookies } from "next/headers"
33import { redirect } from "next/navigation"
44
5- import { detectOrigin } from "./env.js"
6-
5+ import type { AuthAction } from "@auth/core/types.js"
76import type { NextAuthConfig } from "./index.js"
87import type { NextAuthResult , Session } from "../index.js"
8+ import type { headers } from "next/headers"
99
1010type SignInParams = Parameters < NextAuthResult [ "signIn" ] >
1111export async function signIn (
@@ -22,7 +22,7 @@ export async function signIn(
2222 } = options instanceof FormData ? Object . fromEntries ( options ) : options
2323
2424 const callbackUrl = redirectTo ?. toString ( ) ?? headers . get ( "Referer" ) ?? "/"
25- const base = authUrl ( detectOrigin ( headers ) , "signin" )
25+ const base = createActionURL ( "signin" , headers , config . basePath )
2626
2727 if ( ! provider ) {
2828 const url = `${ base } ?${ new URLSearchParams ( { callbackUrl } ) } `
@@ -70,7 +70,7 @@ export async function signOut(
7070 const headers = new Headers ( nextHeaders ( ) )
7171 headers . set ( "Content-Type" , "application/x-www-form-urlencoded" )
7272
73- const url = authUrl ( detectOrigin ( headers ) , "signout" )
73+ const url = createActionURL ( "signout" , headers , config . basePath )
7474 const callbackUrl = options ?. redirectTo ?? headers . get ( "Referer" ) ?? "/"
7575 const body = new URLSearchParams ( { callbackUrl } )
7676 const req = new Request ( url , { method : "POST" , headers, body } )
@@ -92,7 +92,7 @@ export async function update(
9292 const headers = new Headers ( nextHeaders ( ) )
9393 headers . set ( "Content-Type" , "application/json" )
9494
95- const url = authUrl ( detectOrigin ( headers ) , "session" )
95+ const url = createActionURL ( "session" , headers , config . basePath )
9696 const body = JSON . stringify ( { data } )
9797 const req = new Request ( url , { method : "POST" , headers, body } )
9898
@@ -103,10 +103,25 @@ export async function update(
103103 return res . body
104104}
105105
106- /** Determine an action's URL */
107- function authUrl ( base : URL , action : string ) {
108- let pathname
109- if ( base . pathname === "/" ) pathname ??= `/api/auth/${ action } `
110- else pathname ??= `${ base . pathname } /${ action } `
111- return new URL ( pathname , base . origin )
106+ /**
107+ * Extract the origin and base path from either `AUTH_URL` or `NEXTAUTH_URL` environment variables,
108+ * or the request's headers and the {@link NextAuthConfig.basePath} option.
109+ */
110+ export function createActionURL (
111+ action : AuthAction ,
112+ h : Headers | ReturnType < typeof headers > ,
113+ basePath ?: string
114+ ) {
115+ const envUrl = process . env . AUTH_URL ?? process . env . NEXTAUTH_URL
116+ if ( envUrl ) {
117+ const { origin, pathname } = new URL ( envUrl )
118+ const separator = pathname . endsWith ( "/" ) ? "" : "/"
119+ return `${ origin } ${ pathname } ${ separator } ${ action } `
120+ }
121+ const host = h . get ( "x-forwarded-host" ) ?? h . get ( "host" )
122+ const protocol = h . get ( "x-forwarded-proto" ) === "http" ? "http" : "https"
123+ // @ts -expect-error `basePath` value is default'ed to "/api/auth" in `setEnvDefaults`
124+ const { origin, pathname } = new URL ( basePath , `${ protocol } ://${ host } ` )
125+ const separator = pathname . endsWith ( "/" ) ? "" : "/"
126+ return `${ origin } ${ pathname } ${ separator } ${ action } `
112127}
0 commit comments