Compare commits
24 Commits
@blitzjs/g
...
siddharth/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95617216f7 | ||
|
|
e40872efbb | ||
|
|
f76eab6bf6 | ||
|
|
8c7c7a8055 | ||
|
|
61d03b6724 | ||
|
|
33c1252b62 | ||
|
|
b55cbcfa65 | ||
|
|
875b34fcb8 | ||
|
|
47d10c8595 | ||
|
|
5a88801e75 | ||
|
|
cae963ec7d | ||
|
|
6544d052bd | ||
|
|
857ede3445 | ||
|
|
3d8a8d87ae | ||
|
|
5a52fa76d9 | ||
|
|
9a6525fff7 | ||
|
|
87afb00289 | ||
|
|
8ad4dfd0eb | ||
|
|
9ee73fe3d5 | ||
|
|
5bd03a7dfa | ||
|
|
5ab010f289 | ||
|
|
bd3694a103 | ||
|
|
2dc401436d | ||
|
|
4b23aa4f8b |
6
.changeset/polite-papayas-joke.md
Normal file
6
.changeset/polite-papayas-joke.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@blitzjs/auth": major
|
||||
"blitz": patch
|
||||
---
|
||||
|
||||
Migrate `next-auth` adapter to use `@auth/core`
|
||||
@@ -1,4 +1,3 @@
|
||||
const { withNextAuthAdapter } = require("@blitzjs/auth")
|
||||
const { withBlitz } = require("@blitzjs/next")
|
||||
|
||||
/**
|
||||
@@ -11,4 +10,4 @@ const config = {
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = withBlitz(withNextAuthAdapter(config))
|
||||
module.exports = withBlitz(config)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/core": "0.10.0",
|
||||
"@blitzjs/auth": "2.0.0-beta.31",
|
||||
"@blitzjs/config": "2.0.0-beta.31",
|
||||
"@blitzjs/next": "2.0.0-beta.31",
|
||||
@@ -33,7 +34,6 @@
|
||||
"@prisma/client": "4.6.1",
|
||||
"blitz": "2.0.0-beta.31",
|
||||
"next": "13.3.0",
|
||||
"next-auth": "4.18.7",
|
||||
"prisma": "4.6.1",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { api } from "src/blitz-server"
|
||||
import GithubProvider from "next-auth/providers/github"
|
||||
import { NextAuthAdapter, BlitzNextAuthOptions } from "@blitzjs/auth/next-auth"
|
||||
import GithubProvider from "@auth/core/providers/github"
|
||||
import { AuthAdapter } from "@blitzjs/auth/adapters/authjs"
|
||||
import db, { User } from "db"
|
||||
import { Role } from "types"
|
||||
|
||||
@@ -13,20 +13,23 @@ const providers = [
|
||||
]
|
||||
|
||||
export default api(
|
||||
NextAuthAdapter({
|
||||
AuthAdapter({
|
||||
successRedirectUrl: "/",
|
||||
errorRedirectUrl: "/error",
|
||||
providers,
|
||||
trustHost: true,
|
||||
secret: process.env.AUTH_SECRET,
|
||||
callback: async (user, account, profile, session) => {
|
||||
console.log("USER SIDE PROFILE_DATA", { user, account, profile })
|
||||
let newUser: User
|
||||
if (!user) throw new Error("No user found")
|
||||
try {
|
||||
newUser = await db.user.findFirstOrThrow({ where: { name: { equals: user.name } } })
|
||||
} catch (e) {
|
||||
newUser = await db.user.create({
|
||||
data: {
|
||||
email: user.email as string,
|
||||
name: user.name as string,
|
||||
email: user.email ?? "",
|
||||
name: user.name ?? "",
|
||||
role: "USER",
|
||||
},
|
||||
})
|
||||
|
||||
@@ -5,7 +5,6 @@ import { useCurrentUser } from "src/users/hooks/useCurrentUser"
|
||||
import logout from "src/auth/mutations/logout"
|
||||
import { useMutation } from "@blitzjs/rpc"
|
||||
import { BlitzPage } from "@blitzjs/next"
|
||||
import { Routes } from ".blitz"
|
||||
import styles from "src/styles/Home.module.css"
|
||||
|
||||
/*
|
||||
@@ -32,6 +31,8 @@ const UserInfo = () => {
|
||||
User id: <code>{currentUser.id}</code>
|
||||
<br />
|
||||
User role: <code>{currentUser.role}</code>
|
||||
<br />
|
||||
User email: <code>{currentUser.email}</code>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
@@ -44,11 +45,11 @@ const UserInfo = () => {
|
||||
<Link href={"/login"} className={styles.loginButton}>
|
||||
<strong>Login</strong>
|
||||
</Link>
|
||||
<Link href="/api/auth/github/login" passHref legacyBehavior>
|
||||
<a className="button small">
|
||||
<a href="/api/auth/github/signin">
|
||||
<p className="button small">
|
||||
<strong>Sign in with GitHub</strong>
|
||||
</a>
|
||||
</Link>
|
||||
</p>
|
||||
</a>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -79,8 +80,6 @@ const Home: BlitzPage = () => {
|
||||
|
||||
<h1>Your database & authentication is ready. Try it by signing up.</h1>
|
||||
|
||||
{/* Auth */}
|
||||
|
||||
<div className={styles.buttonContainer}>
|
||||
<Suspense fallback="Loading...">
|
||||
<UserInfo />
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useQuery } from "@blitzjs/rpc"
|
||||
import getCurrentUser from "src/users/queries/getCurrentUser"
|
||||
|
||||
export const useCurrentUser = () => {
|
||||
console.log("useCurrentUser")
|
||||
const [user] = useQuery(getCurrentUser, null)
|
||||
return user
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
import webdriver from "../../utils/next-webdriver"
|
||||
|
||||
let app: any
|
||||
let appPort: number
|
||||
let appPort: number = 3000
|
||||
|
||||
const runTests = () => {
|
||||
describe("Auth", () => {
|
||||
@@ -263,7 +263,7 @@ describe("Auth Tests", () => {
|
||||
describe("dev mode", () => {
|
||||
beforeAll(async () => {
|
||||
try {
|
||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||
appPort = await findPort()
|
||||
app = await blitzLaunchApp(appPort, {cwd: process.cwd()})
|
||||
} catch (error) {
|
||||
|
||||
@@ -14,7 +14,7 @@ import fetch from "node-fetch"
|
||||
import {fromBase64} from "b64-lite"
|
||||
|
||||
let app: any
|
||||
let appPort: number
|
||||
let appPort: number = 3000
|
||||
const HEADER_CSRF = "anti-csrf"
|
||||
const COOKIE_PUBLIC_DATA_TOKEN = "auth-tests-cookie-prefix_sPublicDataToken"
|
||||
const COOKIE_SESSION_TOKEN = "auth-tests-cookie-prefix_sSessionToken"
|
||||
@@ -132,7 +132,7 @@ describe("Auth Tests", () => {
|
||||
describe("dev mode", async () => {
|
||||
beforeAll(async () => {
|
||||
try {
|
||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||
appPort = await findPort()
|
||||
app = await blitzLaunchApp(appPort, {cwd: process.cwd()})
|
||||
} catch (error) {
|
||||
|
||||
@@ -15,7 +15,7 @@ import webdriver from "../../utils/next-webdriver"
|
||||
import {join} from "path"
|
||||
|
||||
let app: any
|
||||
let appPort: number
|
||||
let appPort: number = 3000
|
||||
const appDir = join(__dirname, "../")
|
||||
|
||||
const runTests = (mode?: string) => {
|
||||
@@ -50,7 +50,7 @@ describe("getInitialProps Tests", () => {
|
||||
describe("dev mode", () => {
|
||||
beforeAll(async () => {
|
||||
try {
|
||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||
appPort = await findPort()
|
||||
app = await blitzLaunchApp(appPort, {cwd: process.cwd()})
|
||||
} catch (error) {
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import {join} from "path"
|
||||
|
||||
let app: any
|
||||
let appPort: number
|
||||
let appPort: number = 3000
|
||||
const appDir = join(__dirname, "../")
|
||||
|
||||
const runTests = () => {
|
||||
|
||||
@@ -7,7 +7,7 @@ import fetch from "node-fetch"
|
||||
import {fromBase64} from "b64-lite"
|
||||
|
||||
let app: any
|
||||
let appPort: number
|
||||
let appPort: number = 3000
|
||||
const HEADER_CSRF = "anti-csrf"
|
||||
const COOKIE_PUBLIC_DATA_TOKEN = "auth-tests-cookie-prefix_sPublicDataToken"
|
||||
const COOKIE_SESSION_TOKEN = "auth-tests-cookie-prefix_sSessionToken"
|
||||
@@ -156,7 +156,7 @@ describe("Auth Tests", () => {
|
||||
describe("dev mode", async () => {
|
||||
beforeAll(async () => {
|
||||
try {
|
||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||
appPort = await findPort()
|
||||
app = await blitzLaunchApp(appPort, {cwd: process.cwd()})
|
||||
} catch (error) {
|
||||
|
||||
@@ -15,7 +15,7 @@ import webdriver from "../../utils/next-webdriver"
|
||||
import {join} from "path"
|
||||
|
||||
let app: any
|
||||
let appPort: number
|
||||
let appPort: number = 3000
|
||||
const appDir = join(__dirname, "../")
|
||||
|
||||
const runTests = (mode?: string) => {
|
||||
@@ -40,7 +40,7 @@ describe("No Suspense Tests", () => {
|
||||
describe("dev mode", () => {
|
||||
beforeAll(async () => {
|
||||
try {
|
||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||
appPort = await findPort()
|
||||
app = await blitzLaunchApp(appPort, {cwd: process.cwd()})
|
||||
} catch (error) {
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
import webdriver from "../../utils/next-webdriver"
|
||||
|
||||
let app: any
|
||||
let appPort: number
|
||||
let appPort: number = 3000
|
||||
|
||||
const runTests = () => {
|
||||
describe("get query data", () => {
|
||||
@@ -114,7 +114,7 @@ describe("React Query Utils Tests", () => {
|
||||
describe("dev mode", () => {
|
||||
beforeAll(async () => {
|
||||
try {
|
||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||
appPort = await findPort()
|
||||
app = await blitzLaunchApp(appPort, {cwd: process.cwd()})
|
||||
} catch (error) {
|
||||
|
||||
@@ -15,7 +15,7 @@ import webdriver from "../../utils/next-webdriver"
|
||||
import {join} from "path"
|
||||
|
||||
let app: any
|
||||
let appPort: number
|
||||
let appPort: number = 3000
|
||||
const appDir = join(__dirname, "../")
|
||||
|
||||
const runTests = (mode?: string) => {
|
||||
@@ -39,7 +39,7 @@ describe("Trailing Slash Tests", () => {
|
||||
describe("dev mode", () => {
|
||||
beforeAll(async () => {
|
||||
try {
|
||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||
appPort = await findPort()
|
||||
app = await blitzLaunchApp(appPort, {cwd: process.cwd()})
|
||||
} catch (error) {
|
||||
|
||||
@@ -44,5 +44,10 @@
|
||||
"ignoredRules": [
|
||||
"EXTERNAL_MISMATCH"
|
||||
]
|
||||
},
|
||||
"pnpm": {
|
||||
"patchedDependencies": {
|
||||
"@auth/core@0.10.0": "patches/@auth__core@0.10.0.patch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
packages/blitz-auth/.gitignore
vendored
Normal file
1
packages/blitz-auth/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
adapters
|
||||
@@ -5,7 +5,11 @@ const config: BuildConfig = {
|
||||
"./src/index-browser",
|
||||
"./src/index-server",
|
||||
"./src/server/secure-password",
|
||||
"./src/server/adapters/next-auth",
|
||||
{
|
||||
builder: "mkdist",
|
||||
input: "./src/adapters/",
|
||||
outDir: "./adapters",
|
||||
},
|
||||
],
|
||||
externals: ["index-browser.cjs", "index-browser.mjs", "react"],
|
||||
declaration: true,
|
||||
|
||||
1
packages/blitz-auth/next-auth.d.ts
vendored
1
packages/blitz-auth/next-auth.d.ts
vendored
@@ -1 +0,0 @@
|
||||
export * from "./dist/next-auth"
|
||||
@@ -1 +0,0 @@
|
||||
module.exports = require("./dist/next-auth.cjs")
|
||||
@@ -24,7 +24,7 @@
|
||||
"files": [
|
||||
"dist/**",
|
||||
"secure-password.*",
|
||||
"next-auth.*"
|
||||
"adapters/**"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/b64-lite": "1.3.0",
|
||||
@@ -50,9 +50,9 @@
|
||||
"url": "0.11.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@auth/core": "*",
|
||||
"blitz": "2.0.0-beta.31",
|
||||
"next": "*",
|
||||
"next-auth": "*",
|
||||
"secure-password": "4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
@@ -62,11 +62,12 @@
|
||||
"secure-password": {
|
||||
"optional": true
|
||||
},
|
||||
"next-auth": {
|
||||
"@auth/core": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@auth/core": "0.10.0",
|
||||
"@blitzjs/config": "2.0.0-beta.31",
|
||||
"@testing-library/react": "13.4.0",
|
||||
"@testing-library/react-hooks": "8.0.1",
|
||||
@@ -77,7 +78,6 @@
|
||||
"@types/react-dom": "17.0.14",
|
||||
"blitz": "2.0.0-beta.31",
|
||||
"next": "13.3.0",
|
||||
"next-auth": "4.18.7",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"secure-password": "4.0.0",
|
||||
|
||||
1
packages/blitz-auth/src/.gitignore
vendored
Normal file
1
packages/blitz-auth/src/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!adapters
|
||||
2
packages/blitz-auth/src/adapters/authjs.ts
Normal file
2
packages/blitz-auth/src/adapters/authjs.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./authjs/adapter"
|
||||
export * from "./authjs/types"
|
||||
@@ -11,25 +11,26 @@ import {
|
||||
secureProxyMiddleware,
|
||||
truncateString,
|
||||
} from "blitz"
|
||||
import {isLocalhost, SessionContext} from "../../../index-server"
|
||||
|
||||
// next-auth internals
|
||||
import {toInternalRequest, toResponse} from "./internals/utils/web"
|
||||
import {getBody, getURL, setHeaders} from "./internals/utils/node"
|
||||
import type {RequestInternal, AuthOptions, User} from "next-auth"
|
||||
import type {Cookie} from "next-auth/core/lib/cookie"
|
||||
import type {AuthAction, InternalOptions} from "./internals/core/types"
|
||||
|
||||
import type {
|
||||
ApiHandlerIncomingMessage,
|
||||
BlitzNextAuthApiHandler,
|
||||
BlitzNextAuthOptions,
|
||||
} from "./types"
|
||||
import {Provider} from "next-auth/providers"
|
||||
import {isLocalhost} from "../utils"
|
||||
|
||||
import {init} from "next-auth/core/init"
|
||||
import getAuthorizationUrl from "next-auth/core/lib/oauth/authorization-url"
|
||||
import oAuthCallback from "next-auth/core/lib/oauth/callback"
|
||||
// next-auth internals
|
||||
import {getBody, getURL, setHeaders} from "./internals/core/node"
|
||||
import type {AuthAction, InternalOptions, RequestInternal} from "./internals/core/types"
|
||||
import type {OAuthConfig} from "@auth/core/providers"
|
||||
import type {Cookie} from "@auth/core/lib/cookie"
|
||||
|
||||
import {init} from "@auth/core/lib/init"
|
||||
import emailSignIn from "@auth/core/lib/email/signin"
|
||||
import {getAuthorizationUrl} from "@auth/core/lib/oauth/authorization-url"
|
||||
import {handleOAuth} from "@auth/core/lib/oauth/callback"
|
||||
import {handleState} from "@auth/core/lib/oauth/handle-state"
|
||||
import {toInternalRequest, toResponse} from "@auth/core/lib/web"
|
||||
import {assertConfig} from "@auth/core/lib/assert"
|
||||
|
||||
const INTERNAL_REDIRECT_URL_KEY = "_redirectUrl"
|
||||
|
||||
@@ -42,41 +43,38 @@ function switchURL(callbackUrl: string) {
|
||||
return `${url.protocol}//${url.host}${switchPathNameString}${url.search}${url.hash}`
|
||||
}
|
||||
|
||||
export function NextAuthAdapter<P extends Provider[]>(
|
||||
export function AuthAdapter<P extends OAuthConfig<any>[]>(
|
||||
config: BlitzNextAuthOptions<P>,
|
||||
): BlitzNextAuthApiHandler {
|
||||
return async function authHandler(req, res) {
|
||||
assert(
|
||||
req.query.nextauth,
|
||||
"req.query.nextauth is not defined. Page must be named [...auth].ts/js.",
|
||||
"req.query.nextauth is not defined. Page must be named [...nextauth].ts/js.",
|
||||
)
|
||||
assert(
|
||||
Array.isArray(req.query.nextauth),
|
||||
"req.query.nextauth must be an array. Page must be named [...auth].ts/js.",
|
||||
"req.query.nextauth must be an array. Page must be named [...nextauth].ts/js.",
|
||||
)
|
||||
if (!req.query.nextauth?.length) {
|
||||
return res.status(404).end()
|
||||
}
|
||||
const action = req.query.nextauth[1] as AuthAction
|
||||
if (!action || !["login", "callback"].includes(action)) {
|
||||
if (!action || !["signin", "callback"].includes(action)) {
|
||||
return res.status(404).end()
|
||||
}
|
||||
|
||||
const cookieSessionMiddleware = cookieSession({
|
||||
secret: process.env.SESSION_SECRET_KEY || "default-dev-secret",
|
||||
secure: process.env.NODE_ENV === "production" && !isLocalhost(req),
|
||||
})
|
||||
|
||||
const middleware: RequestMiddleware<ApiHandlerIncomingMessage, MiddlewareResponse<Ctx>>[] = [
|
||||
connectMiddleware(cookieSessionMiddleware as RequestMiddleware),
|
||||
]
|
||||
|
||||
if (config.secureProxy) {
|
||||
middleware.push(secureProxyMiddleware)
|
||||
}
|
||||
|
||||
const headers = new Headers(req.headers as any)
|
||||
const url = getURL(req.url, headers)
|
||||
log.debug("NEXT_AUTH_URL", url)
|
||||
if (url instanceof Error) {
|
||||
if (process.env.NODE_ENV !== "production") throw url
|
||||
const errorLogger = config.logger?.error ?? console.error
|
||||
@@ -92,37 +90,46 @@ export function NextAuthAdapter<P extends Provider[]>(
|
||||
method: req.method,
|
||||
...getBody(req),
|
||||
})
|
||||
|
||||
log.debug("NEXT_AUTH_REQUEST")
|
||||
const internalRequest = await toInternalRequest(request)
|
||||
log.debug("NEXT_AUTH_INTERNAL_REQUEST", internalRequest)
|
||||
if (internalRequest instanceof Error) {
|
||||
console.error((request as any).code, request)
|
||||
return new Response(`Error: This action with HTTP ${request.method} is not supported.`, {
|
||||
status: 400,
|
||||
return res.status(500).json({
|
||||
message:
|
||||
"There was a problem with the server configuration. Check the server logs for more information.",
|
||||
})
|
||||
}
|
||||
let {providerId} = internalRequest
|
||||
if (providerId?.includes("?")) {
|
||||
providerId = providerId.split("?")[0]
|
||||
const assertionResult = assertConfig(internalRequest, config)
|
||||
if (Array.isArray(assertionResult)) {
|
||||
assertionResult.forEach(log.error)
|
||||
} else if (assertionResult instanceof Error) {
|
||||
// Bail out early if there's an error in the user config
|
||||
log.error(assertionResult.message)
|
||||
return res.status(500).json({
|
||||
message:
|
||||
"There was a problem with the server configuration. Check the server logs for more information.",
|
||||
code: assertionResult.name,
|
||||
})
|
||||
}
|
||||
const callbackUrl = req.body?.callbackUrl ?? req.query?.callbackUrl?.toString()
|
||||
const {options, cookies} = await init({
|
||||
// @ts-ignore
|
||||
url: new URL(
|
||||
// @ts-ignore
|
||||
internalRequest.url!,
|
||||
internalRequest.url,
|
||||
process.env.APP_ORIGIN || process.env.BLITZ_DEV_SERVER_ORIGIN,
|
||||
),
|
||||
authOptions: config as unknown as AuthOptions,
|
||||
authOptions: config,
|
||||
action,
|
||||
providerId,
|
||||
callbackUrl: req.body?.callbackUrl ?? (req.query?.callbackUrl as string),
|
||||
providerId: internalRequest.providerId.includes("?")
|
||||
? internalRequest.providerId.split("?")[0]
|
||||
: internalRequest.providerId,
|
||||
callbackUrl,
|
||||
cookies: internalRequest.cookies,
|
||||
isPost: req.method === "POST",
|
||||
csrfDisabled: config.csrf?.enabled ?? false,
|
||||
})
|
||||
|
||||
options.provider.callbackUrl = switchURL(options.provider.callbackUrl)
|
||||
|
||||
log.debug("NEXT_AUTH_INTERNAL_OPTIONS", options)
|
||||
|
||||
await AuthHandler(middleware, config, internalRequest, action, options, cookies)
|
||||
.then(async ({middleware}) => {
|
||||
await handleRequestWithMiddleware<ApiHandlerIncomingMessage, MiddlewareResponse<Ctx>>(
|
||||
@@ -145,7 +152,14 @@ export function NextAuthAdapter<P extends Provider[]>(
|
||||
}
|
||||
}
|
||||
|
||||
async function AuthHandler<P extends Provider[]>(
|
||||
function defaultNormalizer(email?: string) {
|
||||
if (!email) throw new Error("Missing email from request body.")
|
||||
let [local, domain] = email.toLowerCase().trim().split("@")
|
||||
domain = domain?.split(",")[0]
|
||||
return `${local}@${domain}`
|
||||
}
|
||||
|
||||
export async function AuthHandler<P extends OAuthConfig<any>[]>(
|
||||
middleware: RequestMiddleware<ApiHandlerIncomingMessage, MiddlewareResponse<Ctx>>[],
|
||||
config: BlitzNextAuthOptions<P>,
|
||||
internalRequest: RequestInternal,
|
||||
@@ -156,23 +170,34 @@ async function AuthHandler<P extends Provider[]>(
|
||||
if (!options.provider) {
|
||||
throw new OAuthError("MISSING_PROVIDER_ERROR")
|
||||
}
|
||||
if (action === "login") {
|
||||
middleware.push(async (req, res, next) => {
|
||||
if (action === "signin") {
|
||||
middleware.push(async (req, res, _next) => {
|
||||
try {
|
||||
const _signin = await getAuthorizationUrl({options: options, query: req.query})
|
||||
if (_signin.cookies) cookies.push(..._signin.cookies)
|
||||
const session = res.blitzCtx.session as SessionContext
|
||||
assert(session, "Missing Blitz sessionMiddleware!")
|
||||
await session.$setPublicData({
|
||||
[INTERNAL_REDIRECT_URL_KEY]: _signin.redirect,
|
||||
} as any)
|
||||
const response = toResponse(_signin)
|
||||
setHeaders(response.headers, res)
|
||||
res.setHeader("Location", _signin.redirect)
|
||||
res.statusCode = 302
|
||||
res.end()
|
||||
if (options.provider.type === "oauth" || options.provider.type === "oidc") {
|
||||
const _signin = await getAuthorizationUrl(req.query, options)
|
||||
log.debug("NEXT_AUTH_SIGNIN", _signin)
|
||||
if (_signin.cookies) cookies.push(..._signin.cookies)
|
||||
await res.blitzCtx.session.$setPublicData({
|
||||
[INTERNAL_REDIRECT_URL_KEY]: _signin.redirect,
|
||||
} as any)
|
||||
const response = toResponse(_signin)
|
||||
setHeaders(response.headers, res)
|
||||
log.debug("NEXT_AUTH_SIGNIN_REDIRECT", _signin.redirect)
|
||||
res.setHeader("Location", _signin.redirect)
|
||||
res.statusCode = 302
|
||||
res.end()
|
||||
} else if (options.provider.type === "email") {
|
||||
const normalizer = options.provider.normalizeIdentifier ?? defaultNormalizer
|
||||
const email = normalizer(internalRequest.body?.email)
|
||||
const redirect = await emailSignIn(email, options, internalRequest)
|
||||
res.setHeader("Location", redirect)
|
||||
res.statusCode = 302
|
||||
res.end()
|
||||
} else {
|
||||
throw new OAuthError("UNSUPPORTED_PROVIDER_ERROR")
|
||||
}
|
||||
} catch (e) {
|
||||
log.error("OAUTH_SIGNIN_Error in NextAuthAdapter " + (e as Error).toString())
|
||||
log.error("OAUTH_SIGNIN_Error in AuthAdapter " + (e as Error).toString())
|
||||
console.log(e)
|
||||
const authErrorQueryStringKey = config.errorRedirectUrl.includes("?")
|
||||
? "&authError="
|
||||
@@ -187,19 +212,27 @@ async function AuthHandler<P extends Provider[]>(
|
||||
return {middleware}
|
||||
} else if (action === "callback") {
|
||||
middleware.push(
|
||||
// eslint-disable-next-line no-shadow
|
||||
connectMiddleware(async (req, res, next) => {
|
||||
connectMiddleware(async (req, res, _next) => {
|
||||
try {
|
||||
const {profile, account, OAuthProfile} = await oAuthCallback({
|
||||
query: internalRequest.query,
|
||||
body: internalRequest.body || {code: req.query.code, state: req.query.state},
|
||||
method: "POST",
|
||||
options: options as any,
|
||||
cookies: internalRequest.cookies,
|
||||
})
|
||||
const session = res.blitzCtx.session as SessionContext
|
||||
assert(session, "Missing Blitz sessionMiddleware!")
|
||||
const callback = await config.callback(profile as User, account, OAuthProfile!, session)
|
||||
const {proxyRedirect, randomState} = handleState(
|
||||
req.query,
|
||||
options.provider,
|
||||
options.isOnRedirectProxy,
|
||||
)
|
||||
if (proxyRedirect) {
|
||||
log.debug("proxy redirect", {proxyRedirect, randomState})
|
||||
res.setHeader("Location", proxyRedirect)
|
||||
res.statusCode = 302
|
||||
res.end()
|
||||
}
|
||||
const {cookies, profile, account, user} = await handleOAuth(
|
||||
req.query,
|
||||
internalRequest.cookies,
|
||||
options,
|
||||
)
|
||||
log.debug("NEXT_AUTH_CALLBACK", {cookies, profile, account, user})
|
||||
const session = res.blitzCtx.session
|
||||
const callback = await config.callback(user, account, profile as any, session)
|
||||
let _redirect = config.successRedirectUrl
|
||||
if (callback instanceof Object) {
|
||||
_redirect = callback.redirectUrl
|
||||
@@ -208,13 +241,12 @@ async function AuthHandler<P extends Provider[]>(
|
||||
redirect: _redirect,
|
||||
cookies: cookies,
|
||||
})
|
||||
|
||||
setHeaders(response.headers, res)
|
||||
res.setHeader("Location", _redirect)
|
||||
res.statusCode = 302
|
||||
res.end()
|
||||
} catch (e) {
|
||||
log.error("OAUTH_CALLBACK_Error in NextAuthAdapter " + (e as Error).toString())
|
||||
log.error("OAUTH_CALLBACK_Error in AuthAdapter " + (e as Error).toString())
|
||||
console.log(e)
|
||||
const authErrorQueryStringKey = config.errorRedirectUrl.includes("?")
|
||||
? "&authError="
|
||||
@@ -0,0 +1,3 @@
|
||||
# Auth Core Internals for Blitz
|
||||
|
||||
This directory contains the internals of the Auth Core being used by the blitz adapter.
|
||||
@@ -1,6 +1,7 @@
|
||||
import type {CallbacksOptions, CookiesOptions, EventCallbacks} from "next-auth"
|
||||
import type {Adapter} from "next-auth/adapters"
|
||||
import type {JWTOptions} from "next-auth/jwt"
|
||||
import type {AuthConfig} from "@auth/core"
|
||||
import {EventCallbacks, PagesOptions, CookiesOptions, CallbacksOptions} from "@auth/core/types"
|
||||
import type {Adapter} from "@auth/core/adapters"
|
||||
import type {JWTOptions} from "@auth/core/jwt"
|
||||
import type {
|
||||
OAuthConfig,
|
||||
ProviderType,
|
||||
@@ -9,7 +10,7 @@ import type {
|
||||
AuthorizationEndpointHandler,
|
||||
EmailConfig,
|
||||
CredentialsConfig,
|
||||
} from "next-auth/providers"
|
||||
} from "@auth/core/providers"
|
||||
|
||||
export interface OAuthConfigInternal<P>
|
||||
extends Omit<OAuthConfig<P>, "authorization" | "token" | "userinfo"> {
|
||||
@@ -33,7 +34,7 @@ export type AuthAction =
|
||||
| "providers"
|
||||
| "session"
|
||||
| "csrf"
|
||||
| "login"
|
||||
| "signin"
|
||||
| "signout"
|
||||
| "callback"
|
||||
| "verify-request"
|
||||
@@ -61,26 +62,40 @@ export interface LoggerInstance extends Record<string, Function> {
|
||||
debug: (code: string, metadata: unknown) => void
|
||||
}
|
||||
|
||||
export interface InternalOptions<
|
||||
TProviderType = ProviderType,
|
||||
WithVerificationToken = TProviderType extends "email" ? true : false,
|
||||
> {
|
||||
export interface RequestInternal {
|
||||
url: URL
|
||||
method: "GET" | "POST"
|
||||
cookies?: Partial<Record<string, string>>
|
||||
headers?: Record<string, any>
|
||||
query?: Record<string, any>
|
||||
body?: Record<string, any>
|
||||
action: AuthAction
|
||||
providerId?: string
|
||||
error?: string
|
||||
}
|
||||
|
||||
export interface InternalOptions<TProviderType = ProviderType> {
|
||||
providers: InternalProvider[]
|
||||
url: URL
|
||||
action: AuthAction
|
||||
provider: InternalProvider<TProviderType>
|
||||
csrfToken?: string
|
||||
csrfTokenVerified?: boolean
|
||||
secret: string
|
||||
theme: Theme
|
||||
debug: boolean
|
||||
logger: LoggerInstance
|
||||
session: Required<LoggerInstance>
|
||||
pages: any
|
||||
session: NonNullable<Required<AuthConfig["session"]>>
|
||||
pages: Partial<PagesOptions>
|
||||
jwt: JWTOptions
|
||||
events: Partial<EventCallbacks>
|
||||
adapter: WithVerificationToken extends true
|
||||
? Adapter<WithVerificationToken>
|
||||
: Adapter<WithVerificationToken> | undefined
|
||||
adapter: Required<Adapter> | undefined
|
||||
callbacks: CallbacksOptions
|
||||
cookies: CookiesOptions
|
||||
callbackUrl: string
|
||||
/**
|
||||
* If true, the OAuth callback is being proxied by the server to the original URL.
|
||||
* See also {@link OAuthConfigInternal.redirectProxyUrl}.
|
||||
*/
|
||||
isOnRedirectProxy: boolean
|
||||
}
|
||||
@@ -1,19 +1,22 @@
|
||||
import type {Ctx, MiddlewareResponse} from "blitz"
|
||||
import type {IncomingMessage} from "http"
|
||||
import type {AuthOptions, Profile, User} from "next-auth"
|
||||
import {SessionContext} from "../../../index-server"
|
||||
import oAuthCallback from "next-auth/core/lib/oauth/callback"
|
||||
import {OAuthConfig, Provider} from "next-auth/providers"
|
||||
import type {Account, Profile, User} from "@auth/core/types"
|
||||
import type {AuthConfig} from "@auth/core"
|
||||
import type {SessionContext} from "../../index-server"
|
||||
import type {OAuthConfig} from "@auth/core/providers"
|
||||
|
||||
export type BlitzNextAuthOptions<P extends Provider[]> = Omit<AuthOptions, "providers"> & {
|
||||
export type BlitzNextAuthOptions<P extends OAuthConfig<any>[]> = Omit<AuthConfig, "providers"> & {
|
||||
providers: P
|
||||
successRedirectUrl: string
|
||||
errorRedirectUrl: string
|
||||
secureProxy?: boolean
|
||||
csrf?: {
|
||||
enabled: boolean
|
||||
}
|
||||
callback: (
|
||||
user: User,
|
||||
account: Awaited<ReturnType<typeof oAuthCallback>>["account"],
|
||||
profile: P[0] extends OAuthConfig<any> ? Parameters<P[0]["profile"]>[0] : Profile,
|
||||
user: User | undefined,
|
||||
account: Account | undefined,
|
||||
profile: P[number] extends OAuthConfig<infer T> ? T : Profile,
|
||||
session: SessionContext,
|
||||
) => Promise<void | {redirectUrl: string}>
|
||||
}
|
||||
1
packages/blitz-auth/src/adapters/index.ts
Normal file
1
packages/blitz-auth/src/adapters/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./passport/adapter"
|
||||
@@ -1,7 +1,7 @@
|
||||
/* @eslint-disable no-redeclare */
|
||||
import cookieSession from "cookie-session"
|
||||
import passport from "passport"
|
||||
import {isLocalhost} from "../../index"
|
||||
import {isLocalhost} from "../utils"
|
||||
import {
|
||||
assert,
|
||||
connectMiddleware,
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
secureProxyMiddleware,
|
||||
truncateString,
|
||||
} from "blitz"
|
||||
import {SessionContext} from "../../../shared"
|
||||
import type {SessionContext} from "../../shared"
|
||||
import {
|
||||
BlitzPassportConfig,
|
||||
ApiHandler,
|
||||
@@ -1,6 +1,6 @@
|
||||
import type {AuthenticateOptions, Strategy} from "passport"
|
||||
import type {IncomingMessage, ServerResponse} from "http"
|
||||
import type {PublicData} from "../../../shared"
|
||||
import type {PublicData} from "../../shared"
|
||||
import type {Ctx, MiddlewareResponse} from "blitz"
|
||||
|
||||
export interface BlitzPassportConfigCallbackParams {
|
||||
9
packages/blitz-auth/src/adapters/utils/index.ts
Normal file
9
packages/blitz-auth/src/adapters/utils/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export function isLocalhost(req: any): boolean {
|
||||
let {host} = req.headers
|
||||
let localhost = false
|
||||
if (host) {
|
||||
host = host.split(":")[0]
|
||||
localhost = host === "localhost"
|
||||
}
|
||||
return localhost
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import "./global"
|
||||
|
||||
export * from "./adapters"
|
||||
export * from "./index-browser"
|
||||
export * from "./server"
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from "./passport/adapter"
|
||||
export * from "./next-auth/webpack"
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from "./next-auth/adapter"
|
||||
export * from "./next-auth/types"
|
||||
@@ -1,3 +0,0 @@
|
||||
# Next-auth Internals
|
||||
|
||||
This directory contains the internals of the Next-auth being used by the blitz adapter.
|
||||
@@ -1,39 +0,0 @@
|
||||
export interface InternalUrl {
|
||||
/** @default "http://localhost:3000" */
|
||||
origin: string
|
||||
/** @default "localhost:3000" */
|
||||
host: string
|
||||
/** @default "/api/auth" */
|
||||
path: string
|
||||
/** @default "http://localhost:3000/api/auth" */
|
||||
base: string
|
||||
/** @default "http://localhost:3000/api/auth" */
|
||||
toString: () => string
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Can we remove this?
|
||||
* Returns an `URL` like object to make requests/redirects from server-side
|
||||
*/
|
||||
export default function parseUrl(url?: string | URL): InternalUrl {
|
||||
const defaultUrl = new URL("http://localhost:3000/api/auth")
|
||||
|
||||
if (url && !url.toString().startsWith("http")) {
|
||||
url = `https://${url}`
|
||||
}
|
||||
|
||||
const _url = new URL(url ?? defaultUrl)
|
||||
const path = (_url.pathname === "/" ? defaultUrl.pathname : _url.pathname)
|
||||
// Remove trailing slash
|
||||
.replace(/\/$/, "")
|
||||
|
||||
const base = `${_url.origin}${path}`
|
||||
|
||||
return {
|
||||
origin: _url.origin,
|
||||
host: _url.host,
|
||||
path,
|
||||
base,
|
||||
toString: () => base,
|
||||
}
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
import {OAuthError} from "blitz"
|
||||
import {serialize, parse as parseCookie} from "cookie"
|
||||
import type {ResponseInternal, RequestInternal} from "next-auth/core"
|
||||
import type {AuthAction} from "next-auth/core/types"
|
||||
|
||||
const decoder = new TextDecoder()
|
||||
|
||||
async function streamToString(stream: any): Promise<string> {
|
||||
const chunks: Uint8Array[] = []
|
||||
return await new Promise((resolve, reject) => {
|
||||
stream.on("data", (chunk: WithImplicitCoercion<ArrayBuffer | SharedArrayBuffer>) =>
|
||||
chunks.push(Buffer.from(chunk)),
|
||||
)
|
||||
stream.on("error", (err: any) => reject(err))
|
||||
stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")))
|
||||
})
|
||||
}
|
||||
|
||||
async function readJSONBody(
|
||||
body: ReadableStream | Buffer,
|
||||
): Promise<Record<string, any> | undefined> {
|
||||
try {
|
||||
if ("getReader" in body) {
|
||||
const reader = body.getReader()
|
||||
const bytes: number[] = []
|
||||
while (true) {
|
||||
const {value, done} = await reader.read()
|
||||
if (done) break
|
||||
bytes.push(...value)
|
||||
}
|
||||
const b = new Uint8Array(bytes)
|
||||
return JSON.parse(decoder.decode(b))
|
||||
}
|
||||
|
||||
// node-fetch
|
||||
|
||||
if (typeof Buffer !== "undefined" && Buffer.isBuffer(body)) {
|
||||
return JSON.parse(body.toString("utf8"))
|
||||
}
|
||||
|
||||
return JSON.parse(await streamToString(body))
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
// prettier-ignore
|
||||
const actions = [ "providers", "session", "csrf", "login", "signout", "callback", "verify-request", "error", "_log"]
|
||||
|
||||
export async function toInternalRequest(req: Request): Promise<RequestInternal | Error> {
|
||||
try {
|
||||
// TODO: url.toString() should not include action and providerId
|
||||
// see init.ts
|
||||
const url = new URL(req.url.replace(/\/$/, ""))
|
||||
const {pathname} = url
|
||||
|
||||
const action = actions.find((a) => pathname.includes(a)) as AuthAction | undefined
|
||||
if (!action) {
|
||||
throw new OAuthError("Cannot detect action.")
|
||||
}
|
||||
|
||||
const providerIdOrAction = pathname.split("/").pop()
|
||||
let providerId
|
||||
if (
|
||||
providerIdOrAction &&
|
||||
!action.includes(providerIdOrAction) &&
|
||||
["login", "callback"].includes(action)
|
||||
) {
|
||||
providerId = providerIdOrAction
|
||||
}
|
||||
|
||||
return {
|
||||
//@ts-ignore
|
||||
url,
|
||||
action,
|
||||
providerId,
|
||||
method: req.method ?? "GET",
|
||||
headers: Object.fromEntries(req.headers),
|
||||
body: req.body ? await readJSONBody(req.body) : undefined,
|
||||
cookies: parseCookie(req.headers.get("cookie") ?? "") ?? {},
|
||||
error: url.searchParams.get("error") ?? undefined,
|
||||
query: Object.fromEntries(url.searchParams),
|
||||
}
|
||||
} catch (error) {
|
||||
return error as Error
|
||||
}
|
||||
}
|
||||
|
||||
export function toResponse(res: ResponseInternal): Response {
|
||||
const headers = new Headers(res.headers as unknown as HeadersInit)
|
||||
|
||||
res.cookies?.forEach((cookie) => {
|
||||
const {name, value, options} = cookie
|
||||
const cookieHeader = serialize(name, value, options)
|
||||
if (headers.has("Set-Cookie")) {
|
||||
headers.append("Set-Cookie", cookieHeader)
|
||||
} else {
|
||||
headers.set("Set-Cookie", cookieHeader)
|
||||
}
|
||||
})
|
||||
|
||||
const body =
|
||||
headers.get("content-type") === "application/json" ? JSON.stringify(res.body) : res.body
|
||||
|
||||
const response = new Response(body, {
|
||||
headers,
|
||||
status: res.redirect ? 302 : res.status ?? 200,
|
||||
})
|
||||
|
||||
if (res.redirect) {
|
||||
response.headers.set("Location", res.redirect)
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
//@ts-nocheck
|
||||
import path from "path"
|
||||
|
||||
export function withNextAuthAdapter(nextConfig) {
|
||||
const config = Object.assign({}, nextConfig)
|
||||
try {
|
||||
const nextAuthPath = path.dirname(require.resolve("next-auth"))
|
||||
const webpack = (config) => {
|
||||
config.resolve.alias = {
|
||||
...config.resolve.alias,
|
||||
"next-auth/core/lib/oauth/callback": path.join(nextAuthPath, "core/lib/oauth/callback.js"),
|
||||
"next-auth/core/lib/oauth/authorization-url": path.join(
|
||||
nextAuthPath,
|
||||
"core/lib/oauth/authorization-url.js",
|
||||
),
|
||||
"next-auth/core/init": path.join(nextAuthPath, "core/init.js"),
|
||||
}
|
||||
return config
|
||||
}
|
||||
if (typeof nextConfig.webpack === "function") {
|
||||
config.webpack = (config, options) => {
|
||||
return nextConfig.webpack(webpack(config), options)
|
||||
}
|
||||
}
|
||||
config.webpack = webpack
|
||||
return config
|
||||
} catch (e) {
|
||||
return config
|
||||
}
|
||||
}
|
||||
@@ -190,7 +190,7 @@ export async function getBlitzContext(): Promise<Ctx> {
|
||||
const req = new IncomingMessage(new Socket()) as IncomingMessage & {
|
||||
cookies: {[key: string]: string}
|
||||
}
|
||||
req.headers = Object.fromEntries(headers())
|
||||
req.headers = Object.fromEntries(headers() as any)
|
||||
const csrfToken = cookies().get(COOKIE_CSRF_TOKEN())
|
||||
if (csrfToken) {
|
||||
req.headers[HEADER_CSRF] = csrfToken.value
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
export * from "./auth-utils"
|
||||
export * from "./auth-plugin"
|
||||
export * from "./adapters"
|
||||
|
||||
export {
|
||||
SessionContextClass,
|
||||
getAllSessionHandlesForUser,
|
||||
|
||||
39
patches/@auth__core@0.10.0.patch
Normal file
39
patches/@auth__core@0.10.0.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
diff --git a/package.json b/package.json
|
||||
index dbd1f7f8e24dd70d74bb1bd5ad7bb1a244919ead..72b04f35527ec98dba059ba9e03eb35c08a27c1c 100644
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -57,6 +57,34 @@
|
||||
},
|
||||
"./types": {
|
||||
"types": "./types.d.ts"
|
||||
+ },
|
||||
+ "./lib/init": {
|
||||
+ "types": "./lib/init.d.ts",
|
||||
+ "import": "./lib/init.js"
|
||||
+ },
|
||||
+ "./lib/email/signin":{
|
||||
+ "types": "./lib/email/signin.d.ts",
|
||||
+ "import": "./lib/email/signin.js"
|
||||
+ },
|
||||
+ "./lib/oauth/authorization-url": {
|
||||
+ "types": "./lib/oauth/authorization-url.d.ts",
|
||||
+ "import": "./lib/oauth/authorization-url.js"
|
||||
+ },
|
||||
+ "./lib/oauth/callback": {
|
||||
+ "types": "./lib/oauth/callback.d.ts",
|
||||
+ "import": "./lib/oauth/callback.js"
|
||||
+ },
|
||||
+ "./lib/oauth/handle-state": {
|
||||
+ "types": "./lib/oauth/handle-state.d.ts",
|
||||
+ "import": "./lib/oauth/handle-state.js"
|
||||
+ },
|
||||
+ "./lib/assert": {
|
||||
+ "types": "./lib/assert.d.ts",
|
||||
+ "import": "./lib/assert.js"
|
||||
+ },
|
||||
+ "./lib/web": {
|
||||
+ "types": "./lib/web.d.ts",
|
||||
+ "import": "./lib/web.js"
|
||||
}
|
||||
},
|
||||
"license": "ISC",
|
||||
82
pnpm-lock.yaml
generated
82
pnpm-lock.yaml
generated
@@ -4,6 +4,11 @@ settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
patchedDependencies:
|
||||
"@auth/core@0.10.0":
|
||||
hash: jkkk4das3mr53z5xj5wygbcfda
|
||||
path: patches/@auth__core@0.10.0.patch
|
||||
|
||||
importers:
|
||||
.:
|
||||
dependencies:
|
||||
@@ -125,6 +130,9 @@ importers:
|
||||
|
||||
apps/toolkit-app:
|
||||
dependencies:
|
||||
"@auth/core":
|
||||
specifier: 0.10.0
|
||||
version: 0.10.0(patch_hash=jkkk4das3mr53z5xj5wygbcfda)
|
||||
"@blitzjs/auth":
|
||||
specifier: 2.0.0-beta.31
|
||||
version: link:../../packages/blitz-auth
|
||||
@@ -152,9 +160,6 @@ importers:
|
||||
next:
|
||||
specifier: 13.3.0
|
||||
version: 13.3.0(@babel/core@7.20.2)(react-dom@18.2.0)(react@18.2.0)
|
||||
next-auth:
|
||||
specifier: 4.18.7
|
||||
version: 4.18.7(next@13.3.0)(react-dom@18.2.0)(react@18.2.0)
|
||||
prisma:
|
||||
specifier: 4.6.1
|
||||
version: 4.6.1
|
||||
@@ -1578,6 +1583,9 @@ importers:
|
||||
specifier: 0.11.0
|
||||
version: 0.11.0
|
||||
devDependencies:
|
||||
"@auth/core":
|
||||
specifier: 0.10.0
|
||||
version: 0.10.0(patch_hash=jkkk4das3mr53z5xj5wygbcfda)
|
||||
"@blitzjs/config":
|
||||
specifier: 2.0.0-beta.31
|
||||
version: link:../config
|
||||
@@ -1608,9 +1616,6 @@ importers:
|
||||
next:
|
||||
specifier: 13.3.0
|
||||
version: 13.3.0(@babel/core@7.20.2)(react-dom@18.2.0)(react@18.2.0)
|
||||
next-auth:
|
||||
specifier: 4.18.7
|
||||
version: 4.18.7(next@13.3.0)(react-dom@18.2.0)(react@18.2.0)
|
||||
react:
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0
|
||||
@@ -2358,6 +2363,25 @@ packages:
|
||||
"@jridgewell/gen-mapping": 0.1.1
|
||||
"@jridgewell/trace-mapping": 0.3.17
|
||||
|
||||
/@auth/core@0.10.0(patch_hash=jkkk4das3mr53z5xj5wygbcfda):
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-mmvAzFUcDHG0m6avQ6/sYI3wtQtt3Tjbk4wCr27OlCeNnlzqK8lDQJIDFbJOTXEu/dNUx8sUQ0xMp7A6GAaHQw==,
|
||||
}
|
||||
peerDependencies:
|
||||
nodemailer: ^6.8.0
|
||||
peerDependenciesMeta:
|
||||
nodemailer:
|
||||
optional: true
|
||||
dependencies:
|
||||
"@panva/hkdf": 1.1.1
|
||||
cookie: 0.5.0
|
||||
jose: 4.11.2
|
||||
oauth4webapi: 2.3.0
|
||||
preact: 10.11.3
|
||||
preact-render-to-string: 5.2.3(preact@10.11.3)
|
||||
patched: true
|
||||
|
||||
/@babel/code-frame@7.16.7:
|
||||
resolution:
|
||||
{
|
||||
@@ -5717,10 +5741,10 @@ packages:
|
||||
"@nodelib/fs.scandir": 2.1.5
|
||||
fastq: 1.13.0
|
||||
|
||||
/@panva/hkdf@1.0.2:
|
||||
/@panva/hkdf@1.1.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-MSAs9t3Go7GUkMhpKC44T58DJ5KGk2vBo+h1cqQeqlMfdGkxaVB78ZWpv9gYi/g2fa4sopag9gJsNvS8XGgWJA==,
|
||||
integrity: sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==,
|
||||
}
|
||||
|
||||
/@pkgr/utils@2.3.1:
|
||||
@@ -16715,34 +16739,6 @@ packages:
|
||||
}
|
||||
dev: false
|
||||
|
||||
/next-auth@4.18.7(next@13.3.0)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-kR3s1JVPMaDuSAlFxcGyv7Ec3fdE6za71r1F77IOII5zJmW2wfkIA2xj223fM0D20ip2pzFpHfk/qN4L6l5XMA==,
|
||||
}
|
||||
engines: {node: ^12.19.0 || ^14.15.0 || ^16.13.0 || ^18.12.0}
|
||||
peerDependencies:
|
||||
next: ^12.2.5 || ^13
|
||||
nodemailer: ^6.6.5
|
||||
react: ^17.0.2 || ^18
|
||||
react-dom: ^17.0.2 || ^18
|
||||
peerDependenciesMeta:
|
||||
nodemailer:
|
||||
optional: true
|
||||
dependencies:
|
||||
"@babel/runtime": 7.18.3
|
||||
"@panva/hkdf": 1.0.2
|
||||
cookie: 0.5.0
|
||||
jose: 4.11.2
|
||||
next: 13.3.0(@babel/core@7.20.2)(react-dom@18.2.0)(react@18.2.0)
|
||||
oauth: 0.9.15
|
||||
openid-client: 5.2.1
|
||||
preact: 10.11.3
|
||||
preact-render-to-string: 5.2.6(preact@10.11.3)
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
uuid: 8.3.2
|
||||
|
||||
/next-router-mock@0.9.1(next@13.3.0)(react@18.2.0):
|
||||
resolution:
|
||||
{
|
||||
@@ -17068,6 +17064,12 @@ packages:
|
||||
integrity: sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==,
|
||||
}
|
||||
|
||||
/oauth4webapi@2.3.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-JGkb5doGrwzVDuHwgrR4nHJayzN4h59VCed6EW8Tql6iHDfZIabCJvg6wtbn5q6pyB2hZruI3b77Nudvq7NmvA==,
|
||||
}
|
||||
|
||||
/oauth@0.10.0:
|
||||
resolution:
|
||||
{
|
||||
@@ -17080,6 +17082,7 @@ packages:
|
||||
{
|
||||
integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==,
|
||||
}
|
||||
dev: false
|
||||
|
||||
/object-assign@4.1.1:
|
||||
resolution:
|
||||
@@ -17106,6 +17109,7 @@ packages:
|
||||
integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==,
|
||||
}
|
||||
engines: {node: ">= 6"}
|
||||
dev: false
|
||||
|
||||
/object-inspect@1.12.2:
|
||||
resolution:
|
||||
@@ -17200,6 +17204,7 @@ packages:
|
||||
integrity: sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ==,
|
||||
}
|
||||
engines: {node: ^10.13.0 || >=12.0.0}
|
||||
dev: false
|
||||
|
||||
/on-finished@2.3.0:
|
||||
resolution:
|
||||
@@ -17297,6 +17302,7 @@ packages:
|
||||
lru-cache: 6.0.0
|
||||
object-hash: 2.2.0
|
||||
oidc-token-hash: 5.0.1
|
||||
dev: false
|
||||
|
||||
/optionator@0.8.3:
|
||||
resolution:
|
||||
@@ -17990,10 +17996,10 @@ packages:
|
||||
picocolors: 1.0.0
|
||||
source-map-js: 1.0.2
|
||||
|
||||
/preact-render-to-string@5.2.6(preact@10.11.3):
|
||||
/preact-render-to-string@5.2.3(preact@10.11.3):
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==,
|
||||
integrity: sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==,
|
||||
}
|
||||
peerDependencies:
|
||||
preact: ">=10"
|
||||
|
||||
Reference in New Issue
Block a user