Skip to content

Commit

Permalink
feat(nextjs): introduce next-auth v5 (#7443)
Browse files Browse the repository at this point in the history
Next.js 13.4 [is out](https://nextjs.org/blog/next-13-4).

For discussing project-related issues, please use #8487

The new version of NextAuth.js is based on `@auth/core`.

If you want to test it out, you can do so already, installing `next-auth@experimental`:

- **Documentation**: https://authjs.dev/reference/nextjs
- **Migration guide**: https://authjs.dev/guides/upgrade-to-v5

BREAKING CHANGE:
Follow the [migration guide](https://authjs.dev/guides/upgrade-to-v5)
  • Loading branch information
balazsorban44 committed Oct 24, 2023
1 parent 06cc2df commit 65aa467
Show file tree
Hide file tree
Showing 261 changed files with 3,614 additions and 18,092 deletions.
2 changes: 1 addition & 1 deletion .github/pr-labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ fauna: ["packages/adapter-fauna/**/*"]
firebase: ["packages/adapter-firebase/**/*"]
hasura: ["packages/adapter-hasura/**/*"]
frameworks: ["packages/frameworks-*/**/*"]
legacy: ["packages/next-auth/**/*"]
mikro-orm: ["packages/adapter-mikro-orm/**/*"]
mongodb: ["packages/adapter-mongodb/**/*"]
neo4j: ["packages/adapter-neo4j/**/*"]
next-auth: ["packages/next-auth/**/*"]
pg: ["packages/adapter-pg/**/*"]
playgrounds: ["apps/playgrounds/**/*"]
pouchdb: ["packages/adapter-pouchdb/**/*"]
Expand Down
13 changes: 6 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,6 @@ dist
.cache-loader
packages/next-auth/providers
packages/next-auth/src/providers/oauth-types.ts
packages/next-auth/client
packages/next-auth/css
packages/next-auth/utils
packages/next-auth/core
packages/next-auth/jwt
packages/next-auth/react
packages/next-auth/next
packages/*/*.js
packages/*/*.d.ts
packages/*/*.d.ts.map
Expand Down Expand Up @@ -90,7 +83,13 @@ packages/core/providers
packages/core/src/lib/pages/styles.ts
docs/docs/reference/core
docs/docs/reference/sveltekit
docs/docs/reference/nextjs

# Next.js
packages/next-auth/lib
packages/next-auth/providers
# copied from @auth/core
packages/next-auth/src/providers

# SvelteKit
packages/frameworks-sveltekit/index.*
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ coverage
dist
packages/**/*.cjs
packages/**/*.js
!packages/*/scripts/*.js

# @auth/core
packages/core/src/providers/oauth-types.ts
Expand Down
3 changes: 1 addition & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"files.exclude": {
"packages/core/{lib,providers,*.js,*.d.ts,*.d.ts.map}": true,
"packages/next-auth/{client,core,css,jwt,next,providers,react,utils,*.js,*.d.ts}": true
},
"typescript.tsdk": "node_modules/typescript/lib",
"openInGitHub.remote.branch": "main"
}
}
7 changes: 7 additions & 0 deletions apps/dev/nextjs/app/api/protected/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { auth } from "auth"
import { NextResponse } from "next/server"

export const GET = auth(function GET(req) {
if (req.auth) return NextResponse.json(req.auth)
return NextResponse.json({ message: "Not authenticated" }, { status: 401 })
})
15 changes: 15 additions & 0 deletions apps/dev/nextjs/app/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { handlers } from "auth"
const { GET: AuthGET, POST } = handlers
export { POST }

import type { NextRequest } from "next/server"

// Showcasing advanced initialization in Route Handlers
export async function GET(request: NextRequest) {
// Do something with request
const response = await AuthGET(request)
// Do something with response
return response
}

// export const runtime = "edge"
16 changes: 16 additions & 0 deletions apps/dev/nextjs/app/client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use client"

import { signIn, useSession } from "next-auth/react"

export default function Client() {
const { data: session, update, status } = useSession()
return (
<div>
<pre>
{status === "loading" ? "Loading..." : JSON.stringify(session, null, 2)}
</pre>
<button onClick={() => signIn("github")}>Sign in</button>
<button onClick={() => update(`New Name`)}>Update session</button>
</div>
)
}
3 changes: 3 additions & 0 deletions apps/dev/nextjs/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Page() {
return <h1>This page is protected.</h1>
}
58 changes: 51 additions & 7 deletions apps/dev/nextjs/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,56 @@
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
import { auth, signIn, signOut, update } from "auth"
import Footer from "components/footer"
import { Header } from "components/header"
import styles from "components/header.module.css"
import "./styles.css"

export default function RootLayout(props: { children: React.ReactNode }) {
return (
<html>
<head></head>
<body>{children}</body>
<body>
<AppHeader />
<main>{props.children}</main>
<div>
<form
action={async () => {
"use server"
update({ user: { name: "New Name" } })
}}
>
<button>Update name</button>
</form>
</div>
<Footer />
</body>
</html>
)
}

export async function AppHeader() {
const session = await auth()
return (
<Header
session={session}
signIn={
<form
action={async () => {
"use server"
await signIn("github")
}}
>
<button className={styles.buttonPrimary}>Sign in</button>
</form>
}
signOut={
<form
action={async () => {
"use server"
await signOut()
}}
>
<button className={styles.button}>Sign out</button>
</form>
}
/>
)
}
23 changes: 23 additions & 0 deletions apps/dev/nextjs/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { SessionProvider } from "next-auth/react"
import { auth } from "auth"
import Client from "./client"

export default async function Page() {
const session = await auth()
return (
<>
{/*
NOTE: The `auth()` result is not run through the `session` callback, be careful passing down data
to a client component, this will be exposed via the /api/auth/session endpoint
*/}
<SessionProvider session={session} basePath="/auth">
<Client />
</SessionProvider>
<h1>NextAuth.js Example</h1>
<p>
This is an example site to demonstrate how to use{" "}
<a href="https://nextjs.authjs.dev">NextAuth.js</a> for authentication.
</p>
</>
)
}
6 changes: 0 additions & 6 deletions apps/dev/nextjs/app/server-component/page.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ body {
max-width: 680px;
margin: 0 auto;
background: #fff;
color: #333;
color: var(--color-text);
}

li,
Expand Down
52 changes: 52 additions & 0 deletions apps/dev/nextjs/auth.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import type { NextAuthConfig } from "next-auth"
import Auth0 from "next-auth/providers/auth0"
import Credentials from "next-auth/providers/credentials"
import Facebook from "next-auth/providers/facebook"
import GitHub from "next-auth/providers/github"
import Google from "next-auth/providers/google"
import Twitter from "next-auth/providers/twitter"

declare module "next-auth" {
/**
* Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
*/
interface Session {
user: {
/** The user's postal address. */
address: string
} & User
}

interface User {
foo: string
}
}

export default {
debug: false,
providers: [
GitHub({ account() {} }),
Auth0,
Facebook,
Google,
Twitter,
Credentials({
credentials: { password: { label: "Password", type: "password" } },
authorize(c) {
if (c.password !== "password") return null
return {
id: "test",
foo: "bar",
name: "Test User",
email: "test@example.com",
}
},
}),
],
callbacks: {
jwt({ token, trigger, session }) {
if (trigger === "update") token.name = session.user.name
return token
},
},
} satisfies NextAuthConfig
19 changes: 19 additions & 0 deletions apps/dev/nextjs/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import NextAuth from "next-auth"
import Email from "next-auth/providers/email"
import authConfig from "auth.config"
import { PrismaClient } from "@prisma/client"
import { PrismaAdapter } from "@auth/prisma-adapter"

globalThis.prisma ??= new PrismaClient()

// authConfig.providers.push(
// // Start server with `pnpm email`
// // @ts-expect-error
// Email({ server: "smtp://127.0.0.1:1025?tls.rejectUnauthorized=false" })
// )

export const { handlers, auth, signIn, signOut, update } = NextAuth({
// adapter: PrismaAdapter(globalThis.prisma),
session: { strategy: "jwt" },
...authConfig,
})
20 changes: 0 additions & 20 deletions apps/dev/nextjs/components/access-denied.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Link from "next/link"
import styles from "./footer.module.css"
import packageJSON from "package.json"
import packageJSON from "next-auth/package.json"

export default function Footer() {
return (
Expand All @@ -11,7 +11,7 @@ export default function Footer() {
<a href="https://authjs.dev">Documentation</a>
</li>
<li className={styles.navItem}>
<a href="https://www.npmjs.com/package/@auth/core">NPM</a>
<a href="https://www.npmjs.com/package/next-auth">NPM</a>
</li>
<li className={styles.navItem}>
<a href="https://github.com/nextauthjs/next-auth-example">GitHub</a>
Expand Down
Loading

1 comment on commit 65aa467

@vercel
Copy link

@vercel vercel bot commented on 65aa467 Oct 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.