Skip to content

Commit

Permalink
fix(next-auth): cannot parse action at /session (#10218)
Browse files Browse the repository at this point in the history
* fix(next-auth): cannot parse action at /session

fix: support apps hosted on subpaths

* refactor: use createActionURL from core directly

---------

Co-authored-by: Nico Domino <yo@ndo.dev>
Co-authored-by: Thang Vu <hi@thvu.dev>
  • Loading branch information
3 people committed Mar 16, 2024
1 parent 5bca263 commit 3c035ec
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 30 deletions.
52 changes: 25 additions & 27 deletions packages/next-auth/src/lib/actions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Auth, raw, skipCSRFCheck } from "@auth/core"
import { Auth, raw, skipCSRFCheck, createActionURL } from "@auth/core"
import { headers as nextHeaders, cookies } from "next/headers"
import { redirect } from "next/navigation"

Expand All @@ -23,7 +23,14 @@ export async function signIn(
} = options instanceof FormData ? Object.fromEntries(options) : options

const callbackUrl = redirectTo?.toString() ?? headers.get("Referer") ?? "/"
const signInURL = createActionURL("signin", headers, config.basePath)
const signInURL = createActionURL(
"signin",
// @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default
headers.get("x-forwarded-proto"),
headers,
process.env,
config.basePath
)

if (!provider) {
signInURL.searchParams.append("callbackUrl", callbackUrl)
Expand Down Expand Up @@ -78,7 +85,14 @@ export async function signOut(
const headers = new Headers(nextHeaders())
headers.set("Content-Type", "application/x-www-form-urlencoded")

const url = createActionURL("signout", headers, config.basePath)
const url = createActionURL(
"signout",
// @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default
headers.get("x-forwarded-proto"),
headers,
process.env,
config.basePath
)
const callbackUrl = options?.redirectTo ?? headers.get("Referer") ?? "/"
const body = new URLSearchParams({ callbackUrl })
const req = new Request(url, { method: "POST", headers, body })
Expand All @@ -100,7 +114,14 @@ export async function update(
const headers = new Headers(nextHeaders())
headers.set("Content-Type", "application/json")

const url = createActionURL("session", headers, config.basePath)
const url = createActionURL(
"session",
// @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default
headers.get("x-forwarded-proto"),
headers,
process.env,
config.basePath
)
const body = JSON.stringify({ data })
const req = new Request(url, { method: "POST", headers, body })

Expand All @@ -110,26 +131,3 @@ export async function update(

return res.body
}

/**
* Extract the origin and base path from either `AUTH_URL` or `NEXTAUTH_URL` environment variables,
* or the request's headers and the {@link NextAuthConfig.basePath} option.
*/
export function createActionURL(
action: AuthAction,
h: Headers | ReturnType<typeof headers>,
basePath?: string
): URL {
const envUrl = process.env.AUTH_URL ?? process.env.NEXTAUTH_URL
if (envUrl) {
const { origin, pathname } = new URL(envUrl)
const separator = pathname.endsWith("/") ? "" : "/"
return new URL(`${origin}${pathname}${separator}${action}`)
}
const host = h.get("x-forwarded-host") ?? h.get("host")
const protocol = h.get("x-forwarded-proto") === "http" ? "http" : "https"
// @ts-expect-error `basePath` value is default'ed to "/api/auth" in `setEnvDefaults`
const { origin, pathname } = new URL(basePath, `${protocol}://${host}`)
const separator = pathname.endsWith("/") ? "" : "/"
return new URL(`${origin}${pathname}${separator}${action}`)
}
12 changes: 9 additions & 3 deletions packages/next-auth/src/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Auth, type AuthConfig } from "@auth/core"
import { Auth, createActionURL, type AuthConfig } from "@auth/core"
import { headers } from "next/headers"
import { NextResponse } from "next/server"
import { reqWithEnvURL } from "./env.js"
import { createActionURL } from "./actions.js"

import type { AuthAction, Awaitable, Session } from "@auth/core/types"
import type {
Expand Down Expand Up @@ -60,7 +59,14 @@ export interface NextAuthConfig extends Omit<AuthConfig, "raw"> {
}

async function getSession(headers: Headers, config: NextAuthConfig) {
const url = createActionURL("session", headers, config.basePath)
const url = createActionURL(
"session",
// @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default
headers.get("x-forwarded-proto"),
headers,
process.env,
config.basePath
)
const request = new Request(url, {
headers: { cookie: headers.get("cookie") ?? "" },
})
Expand Down

0 comments on commit 3c035ec

Please sign in to comment.