Skip to content

Commit 2a39465

Browse files
authored
Merge commit from fork
`detectOrigin` returned the auto-detected forwarded host whenever `VERCEL`/`AUTH_TRUST_HOST` was set, ignoring an explicitly configured `NEXTAUTH_URL`. A configured canonical URL should always win; only fall back to the forwarded host when no `NEXTAUTH_URL` is set. Adds unit tests for detectOrigin precedence.
1 parent 19d2feb commit 2a39465

2 files changed

Lines changed: 70 additions & 2 deletions

File tree

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
/** Extract the origin from the environment */
22
export function detectOrigin(forwardedHost: any, protocol: any) {
3-
// If we detect a Vercel environment, we can trust the host
3+
// An explicitly configured `NEXTAUTH_URL` always takes precedence, even in
4+
// trusted-host mode (Vercel / `AUTH_TRUST_HOST`), so a configured canonical
5+
// URL is never overridden by the auto-detected forwarded host.
6+
if (process.env.NEXTAUTH_URL) return process.env.NEXTAUTH_URL
7+
8+
// No canonical URL configured. On platforms known to set the host reliably
9+
// (Vercel) or when the deployer has opted into trusting the host
10+
// (`AUTH_TRUST_HOST`), derive the origin from the forwarded host.
411
if (process.env.VERCEL ?? process.env.AUTH_TRUST_HOST)
512
return `${protocol === "http" ? "http" : "https"}://${forwardedHost}`
613

7-
// If `NEXTAUTH_URL` is `undefined` we fall back to "http://localhost:3000"
14+
// `NEXTAUTH_URL` is `undefined` here; callers fall back to
15+
// "http://localhost:3000".
816
return process.env.NEXTAUTH_URL
917
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { detectOrigin } from "../src/utils/detect-origin"
2+
3+
// An explicitly configured `NEXTAUTH_URL` should always take precedence over the
4+
// auto-detected forwarded host, including when trusted-host mode is enabled via
5+
// `AUTH_TRUST_HOST` or a platform default such as `VERCEL`.
6+
7+
const FORWARDED_HOST = "forwarded.example.test"
8+
const CONFIGURED_URL = "https://app.example.test"
9+
10+
const ENV_KEYS = ["NEXTAUTH_URL", "AUTH_TRUST_HOST", "VERCEL"] as const
11+
12+
describe("detectOrigin", () => {
13+
const saved: Record<string, string | undefined> = {}
14+
15+
beforeEach(() => {
16+
for (const key of ENV_KEYS) {
17+
saved[key] = process.env[key]
18+
delete process.env[key]
19+
}
20+
})
21+
22+
afterEach(() => {
23+
for (const key of ENV_KEYS) {
24+
if (saved[key] === undefined) delete process.env[key]
25+
else process.env[key] = saved[key]
26+
}
27+
})
28+
29+
it("prefers NEXTAUTH_URL over the forwarded host when AUTH_TRUST_HOST is set", () => {
30+
process.env.AUTH_TRUST_HOST = "true"
31+
process.env.NEXTAUTH_URL = CONFIGURED_URL
32+
33+
expect(detectOrigin(FORWARDED_HOST, "https")).toBe(CONFIGURED_URL)
34+
})
35+
36+
it("prefers NEXTAUTH_URL over the forwarded host on Vercel", () => {
37+
process.env.VERCEL = "1"
38+
process.env.NEXTAUTH_URL = CONFIGURED_URL
39+
40+
expect(detectOrigin(FORWARDED_HOST, "https")).toBe(CONFIGURED_URL)
41+
})
42+
43+
it("derives the origin from the forwarded host in trusted-host mode when NEXTAUTH_URL is not set", () => {
44+
process.env.AUTH_TRUST_HOST = "true"
45+
46+
expect(detectOrigin("app.example.test", "https")).toBe(
47+
"https://app.example.test"
48+
)
49+
})
50+
51+
it("returns NEXTAUTH_URL when not in trusted-host mode", () => {
52+
process.env.NEXTAUTH_URL = CONFIGURED_URL
53+
54+
expect(detectOrigin(FORWARDED_HOST, "https")).toBe(CONFIGURED_URL)
55+
})
56+
57+
it("returns undefined when neither trusted-host mode nor NEXTAUTH_URL is configured", () => {
58+
expect(detectOrigin(FORWARDED_HOST, "https")).toBeUndefined()
59+
})
60+
})

0 commit comments

Comments
 (0)