[
  {
    "path": ".eslintrc.json",
    "content": "{\n  \"extends\": \"next/core-web-vitals\"\n}\n"
  },
  {
    "path": ".gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# next.js\n/.next/\n/out/\n\n# production\n/build\n\n# misc\n.DS_Store\n*.pem\n\n# debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# local env files\n.env*.local\n\n# vercel\n.vercel\n\n# typescript\n*.tsbuildinfo\nnext-env.d.ts\n"
  },
  {
    "path": "README.md",
    "content": "# \"NextAuth.js Login Authentication\"\n\n## With Next.js App Router\n\n---\n\n### Author Links\n\n👋 Hello, I'm Dave Gray.\n\n👉 [My Courses](https://courses.davegray.codes/)\n\n✅ [Check out my YouTube Channel with hundreds of tutorials](https://www.youtube.com/DaveGrayTeachesCode).\n\n🚩 [Subscribe to my channel](https://bit.ly/3nGHmNn)\n\n☕ [Buy Me A Coffee](https://buymeacoffee.com/DaveGray)\n\n🚀 Follow Me:\n\n- [Twitter](https://twitter.com/yesdavidgray)\n- [LinkedIn](https://www.linkedin.com/in/davidagray/)\n- [Blog](https://yesdavidgray.com)\n- [Reddit](https://www.reddit.com/user/DaveOnEleven)\n\n---\n\n### Description\n\n📺 [YouTube Video](https://youtu.be/w2h54xz6Ndw) for this repository.\n\n---\n\n### 🎓 Academic Honesty\n\n**DO NOT COPY FOR AN ASSIGNMENT** - Avoid plagiarism and adhere to the spirit of this [Academic Honesty Policy](https://www.freecodecamp.org/news/academic-honesty-policy/).\n\n---\n\n### ⚙ Free Web Dev Tools\n- 🔗 [Google Chrome Web Browser](https://google.com/chrome/)\n- 🔗 [Visual Studio Code (aka VS Code)](https://code.visualstudio.com/)\n- 🔗 [ES7 React Snippets](https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets)\n\n### 📚 References\n- 🔗 [NextAuth.js Official Site](https://next-auth.js.org/)\n- 🔗 [Next.js Official Site](https://nextjs.org/)\n\n\n"
  },
  {
    "path": "next.config.js",
    "content": "/** @type {import('next').NextConfig} */\nconst nextConfig = {\n    images: {\n        remotePatterns: [\n            {\n                protocol: 'https',\n                hostname: 'avatars.githubusercontent.com',\n                port: '',\n                pathname: '/u/**',\n            },\n        ],\n    },\n}\n\nmodule.exports = nextConfig\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"next-auth-tut\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"next dev\",\n    \"build\": \"next build\",\n    \"start\": \"next start\",\n    \"lint\": \"next lint\"\n  },\n  \"dependencies\": {\n    \"@types/node\": \"20.3.2\",\n    \"@types/react\": \"18.2.14\",\n    \"@types/react-dom\": \"18.2.6\",\n    \"autoprefixer\": \"10.4.14\",\n    \"eslint\": \"8.43.0\",\n    \"eslint-config-next\": \"13.4.7\",\n    \"next\": \"13.4.7\",\n    \"next-auth\": \"^4.22.1\",\n    \"postcss\": \"8.4.24\",\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"tailwindcss\": \"3.3.2\",\n    \"typescript\": \"5.1.6\"\n  }\n}\n"
  },
  {
    "path": "postcss.config.js",
    "content": "module.exports = {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n}\n"
  },
  {
    "path": "src/app/api/auth/[...nextauth]/options.ts",
    "content": "import type { NextAuthOptions } from 'next-auth'\nimport GitHubProvider from 'next-auth/providers/github'\nimport CredentialsProvider from 'next-auth/providers/credentials'\n\nexport const options: NextAuthOptions = {\n    providers: [\n        GitHubProvider({\n            clientId: process.env.GITHUB_ID as string,\n            clientSecret: process.env.GITHUB_SECRET as string,\n        }),\n        CredentialsProvider({\n            name: \"Credentials\",\n            credentials: {\n                username: {\n                    label: \"Username:\",\n                    type: \"text\",\n                    placeholder: \"your-cool-username\"\n                },\n                password: {\n                    label: \"Password:\",\n                    type: \"password\",\n                    placeholder: \"your-awesome-password\"\n                }\n            },\n            async authorize(credentials) {\n                // This is where you need to retrieve user data \n                // to verify with credentials\n                // Docs: https://next-auth.js.org/configuration/providers/credentials\n                const user = { id: \"42\", name: \"Dave\", password: \"nextauth\" }\n\n                if (credentials?.username === user.name && credentials?.password === user.password) {\n                    return user\n                } else {\n                    return null\n                }\n            }\n        })\n    ],\n}"
  },
  {
    "path": "src/app/api/auth/[...nextauth]/route.ts",
    "content": "import NextAuth from 'next-auth'\nimport { options } from './options'\n\nconst handler = NextAuth(options)\n\nexport { handler as GET, handler as POST }"
  },
  {
    "path": "src/app/client/page.tsx",
    "content": "'use client'\n// Remember you must use an AuthProvider for \n// client components to useSession\nimport { useSession } from 'next-auth/react'\nimport { redirect } from 'next/navigation'\nimport UserCard from '../components/UserCard'\n\nexport default function ClientPage() {\n    const { data: session } = useSession({\n        required: true,\n        onUnauthenticated() {\n            redirect('/api/auth/signin?callbackUrl=/client')\n        }\n    })\n\n    return (\n        <section className=\"flex flex-col gap-6\">\n            <UserCard user={session?.user} pagetype={\"Client\"} />\n        </section>\n    )\n}"
  },
  {
    "path": "src/app/components/Navbar.tsx",
    "content": "import Link from \"next/link\"\n\nexport default function Navbar() {\n    return (\n        <nav className=\"bg-blue-800 p-4\">\n            <ul className=\"flex justify-evenly text-2xl font-bold\">\n                <li><Link href=\"/\">Home</Link></li>\n                <li><Link href=\"/api/auth/signin\">Sign In</Link></li>\n                <li><Link href=\"/api/auth/signout\">Sign Out</Link></li>\n                <li><Link href=\"/server\">Server</Link></li>\n                <li><Link href=\"/client\">Client</Link></li>\n                <li><Link href=\"/extra\">Extra</Link></li>\n            </ul>\n        </nav>\n    )\n}\n\n"
  },
  {
    "path": "src/app/components/UserCard.tsx",
    "content": "import Image from \"next/image\"\n\ntype User = {\n    name?: string | null | undefined;\n    email?: string | null | undefined;\n    image?: string | null | undefined;\n} | undefined\n\ntype Props = {\n    user: User,\n    pagetype: string,\n}\n\nexport default function Card({ user, pagetype }: Props) {\n\n    //console.log(user)\n\n    const greeting = user?.name ? (\n        <div className=\"flex flex-col items-center p-6 bg-white rounded-lg font-bold text-5xl text-black\">\n            Hello {user?.name}!\n        </div>\n    ) : null\n\n    // const emailDisplay = user?.email ? (\n    //     <div className=\"flex flex-col items-center p-6 bg-white rounded-lg font-bold text-5xl text-black\">\n    //         {user?.email}\n    //     </div>\n    // ) : null\n\n    const userImage = user?.image ? (\n        <Image\n            className=\"border-4 border-black dark:border-slate-500 drop-shadow-xl shadow-black rounded-full mx-auto mt-8\"\n            src={user?.image}\n            width={200}\n            height={200}\n            alt={user?.name ?? \"Profile Pic\"}\n            priority={true}\n        />\n    ) : null\n\n    return (\n        <section className=\"flex flex-col gap-4\">\n            {greeting}\n            {/* {emailDisplay} */}\n            {userImage}\n            <p className=\"text-2xl text-center\">{pagetype} Page!</p>\n        </section>\n    )\n}"
  },
  {
    "path": "src/app/context/AuthProvider.tsx",
    "content": "'use client'\n\nimport { SessionProvider } from 'next-auth/react'\n\nexport default function AuthProvider({ children }: {\n    children: React.ReactNode\n}) {\n    return (\n        <SessionProvider>\n            {children}\n        </SessionProvider>\n    )\n}\n"
  },
  {
    "path": "src/app/extra/page.tsx",
    "content": "export default async function ExtraPage() {\n\n    return <h1 className=\"text-5xl\">Extra Page!</h1>\n\n}"
  },
  {
    "path": "src/app/globals.css",
    "content": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n:root {\n  --foreground-rgb: 0, 0, 0;\n  --background-start-rgb: 214, 219, 220;\n  --background-end-rgb: 255, 255, 255;\n}\n\n@media (prefers-color-scheme: dark) {\n  :root {\n    --foreground-rgb: 255, 255, 255;\n    --background-start-rgb: 0, 0, 0;\n    --background-end-rgb: 0, 0, 0;\n  }\n}\n\nbody {\n  color: rgb(var(--foreground-rgb));\n  background: linear-gradient(\n      to bottom,\n      transparent,\n      rgb(var(--background-end-rgb))\n    )\n    rgb(var(--background-start-rgb));\n}\n"
  },
  {
    "path": "src/app/layout.tsx",
    "content": "import './globals.css'\nimport { Inter } from 'next/font/google'\nimport Navbar from './components/Navbar'\nimport AuthProvider from './context/AuthProvider'\n\nconst inter = Inter({ subsets: ['latin'] })\n\nexport const metadata = {\n  title: 'NextAuth Tutorial',\n  description: 'Learn NextAuth.js by Dave Gray',\n}\n\nexport default function RootLayout({\n  children,\n}: {\n  children: React.ReactNode\n}) {\n  return (\n    <html lang=\"en\">\n      <body className={inter.className}>\n        <AuthProvider>\n          <Navbar />\n          <main className=\"flex justify-center items-start p-6 min-h-screen\">\n            {children}\n          </main>\n        </AuthProvider>\n      </body>\n    </html>\n  )\n}\n"
  },
  {
    "path": "src/app/page.tsx",
    "content": "import { options } from \"./api/auth/[...nextauth]/options\"\nimport { getServerSession } from \"next-auth/next\"\nimport UserCard from \"./components/UserCard\"\n\nexport default async function Home() {\n  const session = await getServerSession(options)\n\n  return (\n    <>\n      {session ? (\n        <UserCard user={session?.user} pagetype={\"Home\"} />\n      ) : (\n        <h1 className=\"text-5xl\">You Shall Not Pass!</h1>\n      )}\n    </>\n  )\n}\n"
  },
  {
    "path": "src/app/server/page.tsx",
    "content": "import { options } from \"../api/auth/[...nextauth]/options\"\nimport { getServerSession } from \"next-auth/next\"\nimport UserCard from \"../components/UserCard\"\nimport { redirect } from \"next/navigation\"\n\nexport default async function ServerPage() {\n    const session = await getServerSession(options)\n\n    if (!session) {\n        redirect('/api/auth/signin?callbackUrl=/server')\n    }\n\n    return (\n        <section className=\"flex flex-col gap-6\">\n            <UserCard user={session?.user} pagetype={\"Server\"} />\n        </section>\n    )\n\n}\n"
  },
  {
    "path": "src/middleware.ts",
    "content": "// Without a defined matcher, this one line applies next-auth \n// to the entire project\nexport { default } from \"next-auth/middleware\"\n\n// Applies next-auth only to matching routes - can be regex\n// Ref: https://nextjs.org/docs/app/building-your-application/routing/middleware#matcher\nexport const config = { matcher: [\"/extra\", \"/dashboard\"] }"
  },
  {
    "path": "tailwind.config.js",
    "content": "/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  content: [\n    './src/pages/**/*.{js,ts,jsx,tsx,mdx}',\n    './src/components/**/*.{js,ts,jsx,tsx,mdx}',\n    './src/app/**/*.{js,ts,jsx,tsx,mdx}',\n  ],\n  theme: {\n    extend: {\n      backgroundImage: {\n        'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',\n        'gradient-conic':\n          'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',\n      },\n    },\n  },\n  plugins: [],\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"noEmit\": true,\n    \"esModuleInterop\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"jsx\": \"preserve\",\n    \"incremental\": true,\n    \"plugins\": [\n      {\n        \"name\": \"next\"\n      }\n    ],\n    \"paths\": {\n      \"@/*\": [\"./src/*\"]\n    }\n  },\n  \"include\": [\"next-env.d.ts\", \"**/*.ts\", \"**/*.tsx\", \".next/types/**/*.ts\"],\n  \"exclude\": [\"node_modules\"]\n}\n"
  }
]