mirror of
https://github.com/SrIzan10/next-auth.git
synced 2026-05-01 10:55:20 +00:00
* WIP use `Request` and `Response` for core * bump Next.js * rename ts types * refactor * simplify * upgrade Next.js * implement body reader * use `Request`/`Response` in `next-auth/next` * make linter happy * revert * fix tests * remove workaround for middleware return type * return session in protected api route example * don't export internal handler * fall back host to localhost * refactor `getBody` * refactor `next-auth/next` * chore: add `@edge-runtime/jest-environment` * fix tests, using Node 18 as runtime * fix test * remove patch * fix neo4j build * remove new-line * reduce file changes in the PR * fix tests * fix tests * refactor * refactor * add host tests * refactor tests * fix body reading * fix tests * use 302 * fix test * fix again * fix tests * handle when body is `Buffer` * move comment
165 lines
4.5 KiB
TypeScript
165 lines
4.5 KiB
TypeScript
import { mockLogger } from "./utils"
|
|
import type {
|
|
InternalOptions,
|
|
LoggerInstance,
|
|
InternalProvider,
|
|
CallbacksOptions,
|
|
Account,
|
|
Awaitable,
|
|
Profile,
|
|
Session,
|
|
User,
|
|
CookiesOptions,
|
|
} from "../src"
|
|
import { createState } from "../src/core/lib/oauth/state-handler"
|
|
import { InternalUrl } from "../src/utils/parse-url"
|
|
import { JWT, JWTOptions, encode, decode } from "../src/jwt"
|
|
import { CredentialInput } from "../src/providers"
|
|
|
|
let logger: LoggerInstance
|
|
let url: InternalUrl
|
|
let provider: InternalProvider<"oauth">
|
|
let jwt: JWTOptions
|
|
let callbacks: CallbacksOptions
|
|
let cookies: CookiesOptions
|
|
let options: InternalOptions<"oauth">
|
|
|
|
beforeEach(() => {
|
|
logger = mockLogger()
|
|
|
|
url = {
|
|
origin: "http://localhost:3000",
|
|
host: "localhost:3000",
|
|
path: "/api/auth",
|
|
base: "http://localhost:3000/api/auth",
|
|
toString: () => "http://localhost:3000/api/auth",
|
|
}
|
|
|
|
provider = {
|
|
type: "oauth",
|
|
id: "testId",
|
|
name: "testName",
|
|
signinUrl: "/",
|
|
callbackUrl: "/",
|
|
checks: ["pkce", "state"],
|
|
}
|
|
|
|
jwt = {
|
|
secret: "secret",
|
|
maxAge: 0,
|
|
encode,
|
|
decode,
|
|
}
|
|
|
|
callbacks = {
|
|
signIn: function (params: {
|
|
user: User
|
|
account: Account
|
|
profile: Profile & Record<string, unknown>
|
|
email: { verificationRequest?: boolean | undefined }
|
|
credentials?: Record<string, CredentialInput> | undefined
|
|
}): Awaitable<string | boolean> {
|
|
throw new Error("Function not implemented.")
|
|
},
|
|
redirect: function (params: {
|
|
url: string
|
|
baseUrl: string
|
|
}): Awaitable<string> {
|
|
throw new Error("Function not implemented.")
|
|
},
|
|
session: function (params: {
|
|
session: Session
|
|
user: User
|
|
token: JWT
|
|
}): Awaitable<Session> {
|
|
throw new Error("Function not implemented.")
|
|
},
|
|
jwt: function (params: {
|
|
token: JWT
|
|
user?: User | undefined
|
|
account?: Account | undefined
|
|
profile?: Profile | undefined
|
|
isNewUser?: boolean | undefined
|
|
}): Awaitable<JWT> {
|
|
throw new Error("Function not implemented.")
|
|
},
|
|
}
|
|
|
|
cookies = {
|
|
sessionToken: { name: "", options: undefined },
|
|
callbackUrl: { name: "", options: undefined },
|
|
csrfToken: { name: "", options: undefined },
|
|
pkceCodeVerifier: { name: "", options: undefined },
|
|
state: { name: "", options: {} },
|
|
nonce: { name: "", options: undefined },
|
|
}
|
|
|
|
options = {
|
|
url,
|
|
action: "session",
|
|
provider,
|
|
secret: "",
|
|
debug: false,
|
|
logger,
|
|
session: { strategy: "jwt", maxAge: 0, updateAge: 0 },
|
|
pages: {},
|
|
jwt,
|
|
events: {},
|
|
callbacks,
|
|
cookies,
|
|
callbackUrl: "",
|
|
providers: [],
|
|
theme: {},
|
|
}
|
|
})
|
|
|
|
describe("createState", () => {
|
|
it("returns a state, and cookie", async () => {
|
|
const state = await createState(options)
|
|
|
|
expect(state?.value).not.toBeNull()
|
|
expect(state?.cookie).not.toBeNull()
|
|
})
|
|
it("does not return a state when the provider does not support state", async () => {
|
|
options.provider.checks = ["pkce"]
|
|
|
|
const state = await createState(options)
|
|
|
|
expect(state).toBeUndefined()
|
|
})
|
|
it("sets the cookie expiration to a default of 15 minutes when the max age option is not provided", async () => {
|
|
const state = await createState(options)
|
|
|
|
const defaultMaxAge = 60 * 15 // 15 minutes in seconds
|
|
const expires = new Date()
|
|
expires.setTime(expires.getTime() + defaultMaxAge * 1000)
|
|
|
|
validateCookieExpiration({ state, expires })
|
|
expect(state?.cookie.options.maxAge).toBeUndefined()
|
|
})
|
|
|
|
it("sets the cookie expiration and max age to the provided max age from the options", async () => {
|
|
const maxAge = 60 * 20 // 20 minutes
|
|
cookies.state.options.maxAge = maxAge
|
|
|
|
const state = await createState(options)
|
|
|
|
const expires = new Date()
|
|
expires.setTime(expires.getTime() + maxAge * 1000)
|
|
|
|
validateCookieExpiration({ state, expires })
|
|
expect(state?.cookie.options.maxAge).toEqual(maxAge)
|
|
})
|
|
})
|
|
|
|
// comparing the parts instead of getTime() because the milliseconds
|
|
// will not match since the two Date objects are created milliseconds apart
|
|
const validateCookieExpiration = ({ state, expires }) => {
|
|
const cookieExpires = state?.cookie.options.expires
|
|
expect(cookieExpires.getFullYear()).toEqual(expires.getFullYear())
|
|
expect(cookieExpires.getMonth()).toEqual(expires.getMonth())
|
|
expect(cookieExpires.getFullYear()).toEqual(expires.getFullYear())
|
|
expect(cookieExpires.getHours()).toEqual(expires.getHours())
|
|
expect(cookieExpires.getMinutes()).toEqual(expires.getMinutes())
|
|
}
|