Skip to content

Commit 6deccf6

Browse files
authoredSep 28, 2022
fix(core): return JSON for non-HTML server route errors (#5442)
* fix(core): return JSON for non-HTML server route errors * refactor: throw in `unstable_getServerSession` * test: expect `unstable_getServerSession` to throw * refactor: destructure * fix unrelated test formatting * catch error page
1 parent f770b90 commit 6deccf6

File tree

4 files changed

+34
-21
lines changed

4 files changed

+34
-21
lines changed
 

‎packages/next-auth/src/core/index.ts

+12-4
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,21 @@ export async function NextAuthHandler<
9494
assertionResult.forEach(logger.warn)
9595
} else if (assertionResult instanceof Error) {
9696
// Bail out early if there's an error in the user config
97-
const { pages, theme } = userOptions
9897
logger.error(assertionResult.code, assertionResult)
9998

99+
const htmlPages = ["signin", "signout", "error", "verify-request"]
100+
if (!htmlPages.includes(req.action) || req.method !== "GET") {
101+
const message = `There is a problem with the server configuration. Check the server logs for more information.`
102+
return {
103+
status: 500,
104+
headers: [{ key: "Content-Type", value: "application/json" }],
105+
body: { message } as any,
106+
}
107+
}
108+
const { pages, theme } = userOptions
109+
100110
const authOnErrorPage =
101-
pages?.error &&
102-
req.action === "signin" &&
103-
req.query?.callbackUrl.startsWith(pages.error)
111+
pages?.error && req.query?.callbackUrl?.startsWith(pages.error)
104112

105113
if (!pages?.error || authOnErrorPage) {
106114
if (authOnErrorPage) {

‎packages/next-auth/src/next/index.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,14 @@ export async function unstable_getServerSession(
118118
},
119119
})
120120

121-
const { body, cookies } = session
121+
const { body, cookies, status = 200 } = session
122122

123123
cookies?.forEach((cookie) => setCookie(res, cookie))
124124

125-
if (body && typeof body !== "string" && Object.keys(body).length)
126-
return body as Session
125+
if (body && typeof body !== "string" && Object.keys(body).length) {
126+
if (status === 200) return body as Session
127+
throw new Error((body as any).message)
128+
}
127129

128130
return null
129131
}

‎packages/next-auth/tests/getServerSession.test.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,19 @@ describe("Treat secret correctly", () => {
4747
})
4848

4949
it("Error if missing NEXTAUTH_SECRET and secret", async () => {
50-
const session = await unstable_getServerSession(req, res, {
51-
providers: [],
52-
logger,
53-
})
50+
const configError = new Error(
51+
"There is a problem with the server configuration. Check the server logs for more information."
52+
)
53+
await expect(
54+
unstable_getServerSession(req, res, { providers: [], logger })
55+
).rejects.toThrowError(configError)
5456

55-
expect(session).toEqual(null)
5657
expect(logger.error).toBeCalledTimes(1)
5758
expect(logger.error).toBeCalledWith("NO_SECRET", expect.any(MissingSecret))
5859
})
5960

6061
it("Only logs warning once and in development", async () => {
62+
process.env.NEXTAUTH_SECRET = "secret"
6163
// Expect console.warn to NOT be called due to NODE_ENV=production
6264
await unstable_getServerSession(req, res, { providers: [], logger })
6365
expect(console.warn).toBeCalledTimes(0)
@@ -71,6 +73,7 @@ describe("Treat secret correctly", () => {
7173
// Expect console.warn to be still only be called ONCE
7274
await unstable_getServerSession(req, res, { providers: [], logger })
7375
expect(console.warn).toBeCalledTimes(1)
76+
delete process.env.NEXTAUTH_SECRET
7477
})
7578
})
7679

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
11
import { NextMiddleware } from "next/server"
2-
import { NextAuthMiddlewareOptions, withAuth } from "../next/middleware"
2+
import { NextAuthMiddlewareOptions, withAuth } from "../src/next/middleware"
33

44
it("should not match pages as public paths", async () => {
55
const options: NextAuthMiddlewareOptions = {
66
pages: {
77
signIn: "/",
8-
error: "/"
8+
error: "/",
99
},
10-
secret: "secret"
10+
secret: "secret",
1111
}
1212

1313
const nextUrl: any = {
1414
pathname: "/protected/pathA",
1515
search: "",
16-
origin: "http://127.0.0.1"
16+
origin: "http://127.0.0.1",
1717
}
1818
const req: any = { nextUrl, headers: { authorization: "" } }
1919

2020
const handleMiddleware = withAuth(options) as NextMiddleware
21-
const res = await handleMiddleware(req, null)
21+
const res = await handleMiddleware(req, null as any)
2222
expect(res).toBeDefined()
23-
expect(res.status).toBe(307)
23+
expect(res?.status).toBe(307)
2424
})
2525

2626
it("should not redirect on public paths", async () => {
2727
const options: NextAuthMiddlewareOptions = {
28-
secret: "secret"
28+
secret: "secret",
2929
}
3030
const nextUrl: any = {
3131
pathname: "/_next/foo",
3232
search: "",
33-
origin: "http://127.0.0.1"
33+
origin: "http://127.0.0.1",
3434
}
3535
const req: any = { nextUrl, headers: { authorization: "" } }
3636

3737
const handleMiddleware = withAuth(options) as NextMiddleware
38-
const res = await handleMiddleware(req, null)
38+
const res = await handleMiddleware(req, null as any)
3939
expect(res).toBeUndefined()
4040
})

0 commit comments

Comments
 (0)
Please sign in to comment.