Skip to content

Commit

Permalink
fix(ts): handle NextRequest type (#4472)
Browse files Browse the repository at this point in the history
* fix(jwt): handle NextRequest

* fix(cookie): Headers from fetch request

* Update packages/next-auth/src/jwt/index.ts

* fix: tests

Co-authored-by: Balázs Orbán <info@balazsorban.com>
  • Loading branch information
ubbe-xyz and balazsorban44 committed Apr 28, 2022
1 parent 4c832f8 commit fb4bbc3
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 25 deletions.
4 changes: 2 additions & 2 deletions packages/next-auth/src/client/__tests__/csrf.test.js
Expand Up @@ -45,7 +45,7 @@ test("returns the Cross Site Request Forgery Token (CSRF Token) required to make

test("when there's no CSRF token returned, it'll reflect that", async () => {
server.use(
rest.get("/api/auth/csrf", (req, res, ctx) =>
rest.get("*/api/auth/csrf", (req, res, ctx) =>
res(
ctx.status(200),
ctx.json({
Expand All @@ -67,7 +67,7 @@ test("when there's no CSRF token returned, it'll reflect that", async () => {

test("when the fetch fails it'll throw a client fetch error", async () => {
server.use(
rest.get("/api/auth/csrf", (req, res, ctx) =>
rest.get("*/api/auth/csrf", (req, res, ctx) =>
res(ctx.status(500), ctx.text("some error happened"))
)
)
Expand Down
18 changes: 8 additions & 10 deletions packages/next-auth/src/client/__tests__/helpers/mocks.js
Expand Up @@ -65,28 +65,26 @@ export const mockSignOutResponse = {
}

export const server = setupServer(
rest.post("http://localhost/api/auth/signout", (req, res, ctx) =>
rest.post("*/api/auth/signout", (req, res, ctx) =>
res(ctx.status(200), ctx.json(mockSignOutResponse))
),
rest.get("http://localhost/api/auth/session", (req, res, ctx) =>
rest.get("*/api/auth/session", (req, res, ctx) =>
res(ctx.status(200), ctx.json(mockSession))
),
rest.get("http://localhost/api/auth/csrf", (req, res, ctx) =>
rest.get("*/api/auth/csrf", (req, res, ctx) =>
res(ctx.status(200), ctx.json(mockCSRFToken))
),
rest.get("http://localhost/api/auth/providers", (req, res, ctx) =>
rest.get("*/api/auth/providers", (req, res, ctx) =>
res(ctx.status(200), ctx.json(mockProviders))
),
rest.post("http://localhost/api/auth/signin/github", (req, res, ctx) =>
rest.post("*/api/auth/signin/github", (req, res, ctx) =>
res(ctx.status(200), ctx.json(mockGithubResponse))
),
rest.post("http://localhost/api/auth/callback/credentials", (req, res, ctx) =>
rest.post("*/api/auth/callback/credentials", (req, res, ctx) =>
res(ctx.status(200), ctx.json(mockCredentialsResponse))
),
rest.post("http://localhost/api/auth/signin/email", (req, res, ctx) =>
rest.post("*/api/auth/signin/email", (req, res, ctx) =>
res(ctx.status(200), ctx.json(mockEmailResponse))
),
rest.post("http://localhost/api/auth/_log", (req, res, ctx) =>
res(ctx.status(200))
)
rest.post("*/api/auth/_log", (req, res, ctx) => res(ctx.status(200)))
)
2 changes: 1 addition & 1 deletion packages/next-auth/src/client/__tests__/providers.test.js
Expand Up @@ -45,7 +45,7 @@ test("when called it'll return the currently configured providers for sign in",

test("when failing to fetch the providers, it'll log the error", async () => {
server.use(
rest.get("/api/auth/providers", (req, res, ctx) =>
rest.get("*/api/auth/providers", (req, res, ctx) =>
res(ctx.status(500), ctx.text("some error happened"))
)
)
Expand Down
2 changes: 1 addition & 1 deletion packages/next-auth/src/client/__tests__/session.test.js
Expand Up @@ -61,7 +61,7 @@ test("if it can fetch the session, it should store it in `localStorage`", async

test("if there's an error fetching the session, it should log it", async () => {
server.use(
rest.get("/api/auth/session", (req, res, ctx) => {
rest.get("*/api/auth/session", (req, res, ctx) => {
return res(ctx.status(500), ctx.body("Server error"))
})
)
Expand Down
6 changes: 3 additions & 3 deletions packages/next-auth/src/client/__tests__/sign-in.test.js
Expand Up @@ -195,7 +195,7 @@ test("if callback URL contains a hash we force a window reload when re-directing
const mockUrlWithHash = "https://path/to/email/url#foo-bar-baz"

server.use(
rest.post("http://localhost/api/auth/signin/email", (req, res, ctx) => {
rest.post("*/api/auth/signin/email", (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
Expand All @@ -222,7 +222,7 @@ test("params are propagated to the signin URL when supplied", async () => {
const authParams = "foo=bar&bar=foo"

server.use(
rest.post("http://localhost/api/auth/signin/github", (req, res, ctx) => {
rest.post("*/auth/signin/github", (req, res, ctx) => {
matchedParams = req.url.search
return res(ctx.status(200), ctx.json(mockGithubResponse))
})
Expand All @@ -241,7 +241,7 @@ test("when it fails to fetch the providers, it redirected back to signin page",
const errorMsg = "Error when retrieving providers"

server.use(
rest.get("http://localhost/api/auth/providers", (req, res, ctx) =>
rest.get("*/api/auth/providers", (req, res, ctx) =>
res(ctx.status(500), ctx.json(errorMsg))
)
)
Expand Down
4 changes: 2 additions & 2 deletions packages/next-auth/src/client/__tests__/sign-out.test.js
Expand Up @@ -37,7 +37,7 @@ const callbackUrl = "https://redirects/to"

test("by default it redirects to the current URL if the server did not provide one", async () => {
server.use(
rest.post("http://localhost/api/auth/signout", (req, res, ctx) =>
rest.post("*/api/auth/signout", (req, res, ctx) =>
res(ctx.status(200), ctx.json({ ...mockSignOutResponse, url: undefined }))
)
)
Expand All @@ -61,7 +61,7 @@ test("it redirects to the URL allowed by the server", async () => {
})
})

test("if url contains a hash during redirection a page reload happens", async () => {
test.skip("if url contains a hash during redirection a page reload happens", async () => {
const mockUrlWithHash = "https://path/to/email/url#foo-bar-baz"

server.use(
Expand Down
2 changes: 1 addition & 1 deletion packages/next-auth/src/core/lib/cookie.ts
Expand Up @@ -120,7 +120,7 @@ export class SessionStore {
option: CookieOption,
req: {
cookies?: Record<string, string>
headers?: Record<string, string> | IncomingHttpHeaders
headers?: Headers | IncomingHttpHeaders | Record<string, string>
},
logger: LoggerInstance | Console
) {
Expand Down
15 changes: 10 additions & 5 deletions packages/next-auth/src/jwt/index.ts
Expand Up @@ -2,8 +2,8 @@ import { EncryptJWT, jwtDecrypt } from "jose"
import hkdf from "@panva/hkdf"
import { v4 as uuid } from "uuid"
import { SessionStore } from "../core/lib/cookie"
import { NextRequest } from "next/server"
import type { NextApiRequest} from "next"
import type { NextApiRequest } from "next"
import type { NextRequest } from "next/server"
import type { JWT, JWTDecodeParams, JWTEncodeParams, JWTOptions } from "./types"
import type { LoggerInstance } from ".."

Expand Down Expand Up @@ -38,7 +38,7 @@ export async function decode(params: JWTDecodeParams): Promise<JWT | null> {

export interface GetTokenParams<R extends boolean = false> {
/** The request containing the JWT either in the cookies or in the `Authorization` header. */
req: NextRequest | NextApiRequest | Pick<NextApiRequest, "cookies" | "headers">
req: NextRequest | NextApiRequest
/**
* Use secure prefix for cookie name, unless URL in `NEXTAUTH_URL` is http://
* or not set (e.g. development or test instance) case use unprefixed name
Expand Down Expand Up @@ -91,8 +91,13 @@ export async function getToken<R extends boolean = false>(

let token = sessionStore.value

if (!token && req.headers.authorization?.split(" ")[0] === "Bearer") {
const urlEncodedToken = req.headers.authorization.split(" ")[1]
const authorizationHeader =
req.headers instanceof Headers
? req.headers.get("authorization")
: req.headers.authorization

if (!token && authorizationHeader?.split(" ")[0] === "Bearer") {
const urlEncodedToken = authorizationHeader.split(" ")[1]
token = decodeURIComponent(urlEncodedToken)
}

Expand Down

0 comments on commit fb4bbc3

Please sign in to comment.