diff --git a/examples/nextauth-upstash-redis/.eslintrc.json b/examples/nextauth-upstash-redis/.eslintrc.json index bffb357..3722418 100644 --- a/examples/nextauth-upstash-redis/.eslintrc.json +++ b/examples/nextauth-upstash-redis/.eslintrc.json @@ -1,3 +1,3 @@ { - "extends": "next/core-web-vitals" + "extends": ["next/core-web-vitals", "next/typescript"] } diff --git a/examples/nextauth-upstash-redis/.gitignore b/examples/nextauth-upstash-redis/.gitignore index 8f322f0..18da01b 100644 --- a/examples/nextauth-upstash-redis/.gitignore +++ b/examples/nextauth-upstash-redis/.gitignore @@ -3,7 +3,16 @@ # dependencies /node_modules /.pnp +<<<<<<< HEAD .pnp.js +======= +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions +>>>>>>> upgrade-nextjs15 # testing /coverage @@ -24,8 +33,13 @@ npm-debug.log* yarn-debug.log* yarn-error.log* +<<<<<<< HEAD # local env files .env*.local +======= +# env files (can opt-in for commiting if needed) +.env* +>>>>>>> upgrade-nextjs15 # vercel .vercel diff --git a/examples/nextauth-upstash-redis/README.md b/examples/nextauth-upstash-redis/README.md index 4c032d4..4df1c5f 100644 --- a/examples/nextauth-upstash-redis/README.md +++ b/examples/nextauth-upstash-redis/README.md @@ -8,32 +8,4 @@ preview_url: "https://upstash-redis-with-nextauth.vercel.app" author: "moinulmoin" --- -This is an example of how to do [Next.js](https://nextjs.org/) Authentication with [NextAuth.js](https://next-auth.js.org/) and [Serverless Redis by Upstash](https://upstash.com/). - -## Getting Started - -- Download or Clone this repository - -- Install all dependencies - -```bash -npm install -# or -yarn install -# or -pnpm install -``` - -- Copy `.env.example` to `.env.local` and check the `.env.example` file to fill in the environment variables - -- Run the development server: - -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -``` - -Open [http://localhost:3000](http://localhost:3000) to see the app. +Source code of the [Next.js Authentication with Auth.js and Upstash Redis](https://moinulmoin.com/blog/nextjs-authentication-with-nextauth-and-upstash-redis) article. diff --git a/examples/nextauth-upstash-redis/app/api/auth/[...nextauth]/route.ts b/examples/nextauth-upstash-redis/app/api/auth/[...nextauth]/route.ts index 7b38c1b..73228a0 100644 --- a/examples/nextauth-upstash-redis/app/api/auth/[...nextauth]/route.ts +++ b/examples/nextauth-upstash-redis/app/api/auth/[...nextauth]/route.ts @@ -1,6 +1,2 @@ -import NextAuth from "next-auth"; -import { authOptions } from "@/lib/auth"; - -const handler = NextAuth(authOptions); - -export { handler as GET, handler as POST }; +import { handlers } from "@/lib/auth"; +export const { GET, POST } = handlers; diff --git a/examples/nextauth-upstash-redis/app/components/do-auth.tsx b/examples/nextauth-upstash-redis/app/components/do-auth.tsx deleted file mode 100644 index 231f5b7..0000000 --- a/examples/nextauth-upstash-redis/app/components/do-auth.tsx +++ /dev/null @@ -1,42 +0,0 @@ -"use client"; - -import { Session } from "next-auth"; -import { signIn, signOut } from "next-auth/react"; -import Image from "next/image"; -import React, { useState } from "react"; - -export function DoAuth({ session }: { session: Session | null }) { - const [loading, setLoading] = useState(false); - return ( - <> - {session ? ( -
-
-
- {session.user?.name -
- {session.user?.name} - {session.user?.email} -
- -
- ) : ( - - )} - - ); -} diff --git a/examples/nextauth-upstash-redis/app/fonts/GeistMonoVF.woff b/examples/nextauth-upstash-redis/app/fonts/GeistMonoVF.woff new file mode 100644 index 0000000..f2ae185 Binary files /dev/null and b/examples/nextauth-upstash-redis/app/fonts/GeistMonoVF.woff differ diff --git a/examples/nextauth-upstash-redis/app/fonts/GeistVF.woff b/examples/nextauth-upstash-redis/app/fonts/GeistVF.woff new file mode 100644 index 0000000..1b62daa Binary files /dev/null and b/examples/nextauth-upstash-redis/app/fonts/GeistVF.woff differ diff --git a/examples/nextauth-upstash-redis/app/globals.css b/examples/nextauth-upstash-redis/app/globals.css index b5c61c9..6b717ad 100644 --- a/examples/nextauth-upstash-redis/app/globals.css +++ b/examples/nextauth-upstash-redis/app/globals.css @@ -1,3 +1,21 @@ @tailwind base; @tailwind components; @tailwind utilities; + +:root { + --background: #ffffff; + --foreground: #171717; +} + +@media (prefers-color-scheme: dark) { + :root { + --background: #0a0a0a; + --foreground: #ededed; + } +} + +body { + color: var(--foreground); + background: var(--background); + font-family: Arial, Helvetica, sans-serif; +} diff --git a/examples/nextauth-upstash-redis/app/layout.tsx b/examples/nextauth-upstash-redis/app/layout.tsx index 52b7638..a36cde0 100644 --- a/examples/nextauth-upstash-redis/app/layout.tsx +++ b/examples/nextauth-upstash-redis/app/layout.tsx @@ -1,18 +1,35 @@ -import "./globals.css"; import type { Metadata } from "next"; -import { Inter } from "next/font/google"; +import localFont from "next/font/local"; +import "./globals.css"; -const inter = Inter({ subsets: ["latin"] }); +const geistSans = localFont({ + src: "./fonts/GeistVF.woff", + variable: "--font-geist-sans", + weight: "100 900", +}); +const geistMono = localFont({ + src: "./fonts/GeistMonoVF.woff", + variable: "--font-geist-mono", + weight: "100 900", +}); export const metadata: Metadata = { - title: "NextAuth.js + Serverless Redis by Upstash", - description: "Next.js Authentication with NextAuth.js + Serverless Redis by Upstash", + title: "Create Next App", + description: "Generated by create next app", }; -export default function RootLayout({ children }: { children: React.ReactNode }) { - return ( - - {children} - - ); +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + {children} + + + ); } diff --git a/examples/nextauth-upstash-redis/app/page.tsx b/examples/nextauth-upstash-redis/app/page.tsx index 8d4f4eb..7781c3a 100644 --- a/examples/nextauth-upstash-redis/app/page.tsx +++ b/examples/nextauth-upstash-redis/app/page.tsx @@ -1,26 +1,71 @@ -import { getServerSession } from "next-auth"; -import { DoAuth } from "./components/do-auth"; -import { authOptions } from "@/lib/auth"; +import { auth, signIn, signOut } from "@/lib/auth"; +import Form from "next/form"; export default async function Home() { - const session = await getServerSession(authOptions); - return ( -
-

- - Next.js - {" "} - Authentication with{" "} - - NextAuth.js{" "} - {" "} - +{" "} - - Serverless Redis by Upstash - -

+ const session = await auth(); + return ( +
+

+ + Next.js + {" "} + Authentication with{" "} + + Auth.js{" "} + {" "} + +{" "} + + Upstash Redis + +

- -
- ); + {session ? ( +
+
+ {session.user?.name} + {session.user?.email} +
+ +
+ ) : ( + + )} +
+ ); +} + +function SignOutButton() { + return ( +
{ + "use server"; + await signOut(); + }} + > + +
+ ); +} + +function SignInButton() { + return ( +
{ + "use server"; + await signIn("github", { redirectTo: "/" }); + }} + > + +
+ ); } diff --git a/examples/nextauth-upstash-redis/.env.example b/examples/nextauth-upstash-redis/example.env similarity index 60% rename from examples/nextauth-upstash-redis/.env.example rename to examples/nextauth-upstash-redis/example.env index 35409e0..b9a89ce 100644 --- a/examples/nextauth-upstash-redis/.env.example +++ b/examples/nextauth-upstash-redis/example.env @@ -1,13 +1,10 @@ # create github oauth app and get the client id and secret https://github.com/settings/developers -GITHUB_CLIENT_ID="GITHUB_CLIENT_ID" -GITHUB_CLIENT_SECRET="GITHUB_CLIENT_SECRET" +AUTH_GITHUB_ID="GITHUB_CLIENT_ID" +AUTH_GITHUB_SECRET="GITHUB_CLIENT_SECRET" # create acount on https://upstash.com/ and create a redis database and get the url and token from @upstash/redis tab UPSTASH_REDIS_REST_URL="UPSTASH_REDIS_URL" UPSTASH_REDIS_REST_TOKEN="UPSTASH_REDIS_TOKEN" -# generate one here: https://generate-secret.vercel.app/32 -NEXTAUTH_SECRET="YOUR_SECRET" - -# Site URL -NEXTAUTH_URL="SITE_URL" +# You can add it by using `npx auth secret`. Read more: https://cli.authjs.dev +AUTH_SECRET="" diff --git a/examples/nextauth-upstash-redis/lib/auth.ts b/examples/nextauth-upstash-redis/lib/auth.ts index 146a90a..6f94665 100644 --- a/examples/nextauth-upstash-redis/lib/auth.ts +++ b/examples/nextauth-upstash-redis/lib/auth.ts @@ -1,16 +1,11 @@ -import GithubProvider from "next-auth/providers/github"; import { UpstashRedisAdapter } from "@auth/upstash-redis-adapter"; import { Redis } from "@upstash/redis"; -import { type Adapter } from "next-auth/adapters"; +import NextAuth from "next-auth"; +import GitHub from "next-auth/providers/github"; const redis = Redis.fromEnv(); -export const authOptions = { - adapter: UpstashRedisAdapter(redis) as Adapter, - providers: [ - GithubProvider({ - clientId: process.env.GITHUB_CLIENT_ID as string, - clientSecret: process.env.GITHUB_CLIENT_SECRET as string, - }), - ], -}; +export const { handlers, signIn, signOut, auth } = NextAuth({ + adapter: UpstashRedisAdapter(redis), + providers: [GitHub], +}); diff --git a/examples/nextauth-upstash-redis/middleware.ts b/examples/nextauth-upstash-redis/middleware.ts new file mode 100644 index 0000000..36f3f3a --- /dev/null +++ b/examples/nextauth-upstash-redis/middleware.ts @@ -0,0 +1,2 @@ +export { auth as middleware } from "@/lib/auth"; + diff --git a/examples/nextauth-upstash-redis/next.config.js b/examples/nextauth-upstash-redis/next.config.js deleted file mode 100644 index 3766389..0000000 --- a/examples/nextauth-upstash-redis/next.config.js +++ /dev/null @@ -1,9 +0,0 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - reactStrictMode: true, - images: { - domains: ["avatars.githubusercontent.com"], - }, -}; - -module.exports = nextConfig; diff --git a/examples/nextauth-upstash-redis/next.config.ts b/examples/nextauth-upstash-redis/next.config.ts new file mode 100644 index 0000000..e9ffa30 --- /dev/null +++ b/examples/nextauth-upstash-redis/next.config.ts @@ -0,0 +1,7 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ +}; + +export default nextConfig; diff --git a/examples/nextauth-upstash-redis/package.json b/examples/nextauth-upstash-redis/package.json index daea139..1cd811f 100644 --- a/examples/nextauth-upstash-redis/package.json +++ b/examples/nextauth-upstash-redis/package.json @@ -9,20 +9,21 @@ "lint": "next lint" }, "dependencies": { - "@auth/upstash-redis-adapter": "^1.0.0", - "@types/node": "20.4.9", - "@types/react": "18.2.20", - "@types/react-dom": "18.2.7", - "@upstash/redis": "^1.22.0", - "autoprefixer": "10.4.14", - "eslint": "8.46.0", - "eslint-config-next": "13.4.13", - "next": "13.4.13", - "next-auth": "^4.22.5", - "postcss": "8.4.27", - "react": "18.2.0", - "react-dom": "18.2.0", - "tailwindcss": "3.3.3", - "typescript": "5.1.6" + "@auth/upstash-redis-adapter": "^2.7.2", + "@upstash/redis": "^1.34.3", + "next": "15.0.1", + "next-auth": "5.0.0-beta.25", + "react": "19.0.0-rc-69d4b800-20241021", + "react-dom": "19.0.0-rc-69d4b800-20241021" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "eslint": "^8", + "eslint-config-next": "15.0.1", + "postcss": "^8", + "tailwindcss": "^3.4.1", + "typescript": "^5" } -} \ No newline at end of file +} diff --git a/examples/nextauth-upstash-redis/postcss.config.js b/examples/nextauth-upstash-redis/postcss.config.js deleted file mode 100644 index 33ad091..0000000 --- a/examples/nextauth-upstash-redis/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -} diff --git a/examples/nextauth-upstash-redis/postcss.config.mjs b/examples/nextauth-upstash-redis/postcss.config.mjs new file mode 100644 index 0000000..1a69fd2 --- /dev/null +++ b/examples/nextauth-upstash-redis/postcss.config.mjs @@ -0,0 +1,8 @@ +/** @type {import('postcss-load-config').Config} */ +const config = { + plugins: { + tailwindcss: {}, + }, +}; + +export default config; diff --git a/examples/nextauth-upstash-redis/public/next.svg b/examples/nextauth-upstash-redis/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/examples/nextauth-upstash-redis/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/examples/nextauth-upstash-redis/public/vercel.svg b/examples/nextauth-upstash-redis/public/vercel.svg deleted file mode 100644 index d2f8422..0000000 --- a/examples/nextauth-upstash-redis/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/examples/nextauth-upstash-redis/tailwind.config.js b/examples/nextauth-upstash-redis/tailwind.config.js deleted file mode 100644 index 8c4d1b2..0000000 --- a/examples/nextauth-upstash-redis/tailwind.config.js +++ /dev/null @@ -1,18 +0,0 @@ -/** @type {import('tailwindcss').Config} */ -module.exports = { - content: [ - './pages/**/*.{js,ts,jsx,tsx,mdx}', - './components/**/*.{js,ts,jsx,tsx,mdx}', - './app/**/*.{js,ts,jsx,tsx,mdx}', - ], - theme: { - extend: { - backgroundImage: { - 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', - 'gradient-conic': - 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', - }, - }, - }, - plugins: [], -} diff --git a/examples/nextauth-upstash-redis/tailwind.config.ts b/examples/nextauth-upstash-redis/tailwind.config.ts new file mode 100644 index 0000000..021c393 --- /dev/null +++ b/examples/nextauth-upstash-redis/tailwind.config.ts @@ -0,0 +1,19 @@ +import type { Config } from "tailwindcss"; + +const config: Config = { + content: [ + "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", + "./src/components/**/*.{js,ts,jsx,tsx,mdx}", + "./src/app/**/*.{js,ts,jsx,tsx,mdx}", + ], + theme: { + extend: { + colors: { + background: "var(--background)", + foreground: "var(--foreground)", + }, + }, + }, + plugins: [], +}; +export default config; diff --git a/examples/nextauth-upstash-redis/tsconfig.json b/examples/nextauth-upstash-redis/tsconfig.json index e06a445..d8b9323 100644 --- a/examples/nextauth-upstash-redis/tsconfig.json +++ b/examples/nextauth-upstash-redis/tsconfig.json @@ -1,15 +1,14 @@ { "compilerOptions": { - "target": "es5", + "target": "ES2017", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, - "forceConsistentCasingInFileNames": true, "noEmit": true, "esModuleInterop": true, "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve",