diff --git a/.env.local.example b/.env.local.example new file mode 100644 index 0000000..0230c5f --- /dev/null +++ b/.env.local.example @@ -0,0 +1,28 @@ +NEXTAUTH_URL=http://localhost:3000 +NEXTAUTH_SECRET= # Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32 + +APPLE_ID= +APPLE_TEAM_ID= +APPLE_PRIVATE_KEY= +APPLE_KEY_ID= + +AUTH0_ID= +AUTH0_SECRET= +AUTH0_ISSUER= + +FACEBOOK_ID= +FACEBOOK_SECRET= + +GITHUB_ID= +GITHUB_SECRET= + +GOOGLE_ID= +GOOGLE_SECRET= + +TWITTER_ID= +TWITTER_SECRET= + +EMAIL_SERVER=smtp://username:password@smtp.example.com:587 +EMAIL_FROM=NextAuth + +DATABASE_URL=sqlite://localhost/:memory:?synchronize=true diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..63f8770 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# https://docs.github.com/en/github/administering-a-repository/displaying-a-sponsor-button-in-your-repository + +open_collective: nextauth +github: [balazsorban44] diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e6b58d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +.DS_Store + +node_modules/ +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.yarn-integrity +.npm + +.eslintcache + +*.tsbuildinfo +next-env.d.ts + +.next +.vercel +.env*.local \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..eee418e --- /dev/null +++ b/LICENSE @@ -0,0 +1,15 @@ +ISC License + +Copyright (c) 2018-2021, Iain Collins + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..2e8e934 --- /dev/null +++ b/README.md @@ -0,0 +1,113 @@ +> The example repository is maintained from a [monorepo](https://github.com/nextauthjs/next-auth/tree/main/apps/example-nextjs). Pull Requests should be opened against [`nextauthjs/next-auth`](https://github.com/nextauthjs/next-auth). + +

+
+ +

NextAuth.js Example App

+

+ Open Source. Full Stack. Own Your Data. +

+

+ + npm + + + Bundle Size + + + Downloads + + + TypeScript + +

+

+ +## Overview + +NextAuth.js is a complete open source authentication solution. + +This is an example application that shows how `next-auth` is applied to a basic Next.js app. + +The deployed version can be found at [`next-auth-example.vercel.app`](https://next-auth-example.vercel.app) + +### About NextAuth.js + +NextAuth.js is an easy to implement, full-stack (client/server) open source authentication library originally designed for [Next.js](https://nextjs.org) and [Serverless](https://vercel.com). Our goal is to [support even more frameworks](https://github.com/nextauthjs/next-auth/issues/2294) in the future. + +Go to [next-auth.js.org](https://next-auth.js.org) for more information and documentation. + +> *NextAuth.js is not officially associated with Vercel or Next.js.* + +## Getting Started + +### 1. Clone the repository and install dependencies + +``` +git clone https://github.com/nextauthjs/next-auth-example.git +cd next-auth-example +npm install +``` + +### 2. Configure your local environment + +Copy the .env.local.example file in this directory to .env.local (which will be ignored by Git): + +``` +cp .env.local.example .env.local +``` + +Add details for one or more providers (e.g. Google, Twitter, GitHub, Email, etc). + +#### Database + +A database is needed to persist user accounts and to support email sign in. However, you can still use NextAuth.js for authentication without a database by using OAuth for authentication. If you do not specify a database, [JSON Web Tokens](https://jwt.io/introduction) will be enabled by default. + +You **can** skip configuring a database and come back to it later if you want. + +For more information about setting up a database, please check out the following links: + +* Docs: [next-auth.js.org/adapters/overview](https://next-auth.js.org/adapters/overview) + +### 3. Configure Authentication Providers + +1. Review and update options in `pages/api/auth/[...nextauth].js` as needed. + +2. When setting up OAuth, in the developer admin page for each of your OAuth services, you should configure the callback URL to use a callback path of `{server}/api/auth/callback/{provider}`. + + e.g. For Google OAuth you would use: `http://localhost:3000/api/auth/callback/google` + + A list of configured providers and their callback URLs is available from the endpoint `/api/auth/providers`. You can find more information at https://next-auth.js.org/configuration/providers/oauth + +3. You can also choose to specify an SMTP server for passwordless sign in via email. + +### 4. Start the application + +To run your site locally, use: + +``` +npm run dev +``` + +To run it in production mode, use: + +``` +npm run build +npm run start +``` + +### 5. Preparing for Production + +Follow the [Deployment documentation](https://next-auth.js.org/deployment) + +## Acknowledgements + + +Powered By Vercel + +

Thanks to Vercel sponsoring this project by allowing it to be deployed for free for the entire NextAuth.js Team

+ +## License + +ISC + diff --git a/components/access-denied.tsx b/components/access-denied.tsx new file mode 100644 index 0000000..4c9c0d7 --- /dev/null +++ b/components/access-denied.tsx @@ -0,0 +1,20 @@ +import { signIn } from "next-auth/react" + +export default function AccessDenied() { + return ( + <> +

Access Denied

+

+ { + e.preventDefault() + signIn() + }} + > + You must be signed in to view this page + +

+ + ) +} diff --git a/components/footer.module.css b/components/footer.module.css new file mode 100644 index 0000000..020bec6 --- /dev/null +++ b/components/footer.module.css @@ -0,0 +1,14 @@ +.footer { + margin-top: 2rem; +} + +.navItems { + margin-bottom: 1rem; + padding: 0; + list-style: none; +} + +.navItem { + display: inline-block; + margin-right: 1rem; +} diff --git a/components/footer.tsx b/components/footer.tsx new file mode 100644 index 0000000..ee22829 --- /dev/null +++ b/components/footer.tsx @@ -0,0 +1,28 @@ +import Link from "next/link" +import styles from "./footer.module.css" +import packageJSON from "../package.json" + +export default function Footer() { + return ( + + ) +} diff --git a/components/header.module.css b/components/header.module.css new file mode 100644 index 0000000..773478c --- /dev/null +++ b/components/header.module.css @@ -0,0 +1,92 @@ +/* Set min-height to avoid page reflow while session loading */ +.signedInStatus { + display: block; + min-height: 4rem; + width: 100%; +} + +.loading, +.loaded { + position: relative; + top: 0; + opacity: 1; + overflow: hidden; + border-radius: 0 0 0.6rem 0.6rem; + padding: 0.6rem 1rem; + margin: 0; + background-color: rgba(0, 0, 0, 0.05); + transition: all 0.2s ease-in; +} + +.loading { + top: -2rem; + opacity: 0; +} + +.signedInText, +.notSignedInText { + position: absolute; + padding-top: 0.8rem; + left: 1rem; + right: 6.5rem; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + display: inherit; + z-index: 1; + line-height: 1.3rem; +} + +.signedInText { + padding-top: 0rem; + left: 4.6rem; +} + +.avatar { + border-radius: 2rem; + float: left; + height: 2.8rem; + width: 2.8rem; + background-color: white; + background-size: cover; + background-repeat: no-repeat; +} + +.button, +.buttonPrimary { + float: right; + margin-right: -0.4rem; + font-weight: 500; + border-radius: 0.3rem; + cursor: pointer; + font-size: 1rem; + line-height: 1.4rem; + padding: 0.7rem 0.8rem; + position: relative; + z-index: 10; + background-color: transparent; + color: #555; +} + +.buttonPrimary { + background-color: #346df1; + border-color: #346df1; + color: #fff; + text-decoration: none; + padding: 0.7rem 1.4rem; +} + +.buttonPrimary:hover { + box-shadow: inset 0 0 5rem rgba(0, 0, 0, 0.2); +} + +.navItems { + margin-bottom: 2rem; + padding: 0; + list-style: none; +} + +.navItem { + display: inline-block; + margin-right: 1rem; +} diff --git a/components/header.tsx b/components/header.tsx new file mode 100644 index 0000000..37cd264 --- /dev/null +++ b/components/header.tsx @@ -0,0 +1,94 @@ +import Link from "next/link" +import { signIn, signOut, useSession } from "next-auth/react" +import styles from "./header.module.css" + +// The approach used in this component shows how to build a sign in and sign out +// component that works on pages which support both client and server side +// rendering, and avoids any flash incorrect content on initial page load. +export default function Header() { + const { data: session, status } = useSession() + const loading = status === "loading" + + return ( +
+ +
+

+ {!session && ( + <> + + You are not signed in + + { + e.preventDefault() + signIn() + }} + > + Sign in + + + )} + {session?.user && ( + <> + {session.user.image && ( + + )} + + Signed in as +
+ {session.user.email ?? session.user.name} +
+ { + e.preventDefault() + signOut() + }} + > + Sign out + + + )} +

+
+ +
+ ) +} diff --git a/components/layout.tsx b/components/layout.tsx new file mode 100644 index 0000000..9ee0bb2 --- /dev/null +++ b/components/layout.tsx @@ -0,0 +1,13 @@ +import Header from "./header" +import Footer from "./footer" +import type { ReactNode } from "react" + +export default function Layout({ children }: { children: ReactNode }) { + return ( + <> +
+
{children}
+