From 77de2abd146863e42541dbcc40ea2631c3144d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Sun, 10 Jan 2021 20:20:21 +0100 Subject: [PATCH] feat: improve package development experience (#1064) * chore(deps): add next and react to dev dependencies * chore: move build configs to avoid crash with next dev * chore: add next js dev app * chore: remove .txt extension from LICENSE file * chore: update CONTRIBUTING.md * chore: watch css under development * style(lint): run linter on index.css * chore: fix some imports for dev server * refactor: simplify client code * chore: mention VSCode extension for linting * docs: reword CONTRIBUTING.md * chore: ignore linting pages and components --- CONTRIBUTING.md | 69 +- LICENSE.txt => LICENSE | 0 babel.config.json | 12 - components/access-denied.js | 16 + components/footer.js | 18 + components/footer.module.css | 14 + components/header.js | 103 + components/header.module.css | 92 + components/layout.js | 14 + config/babel.config.json | 12 + postcss.config.js => config/postcss.config.js | 0 {scripts => config}/wrap-css.js | 0 jsconfig.json | 9 + package-lock.json | 3922 ++++++++++++++++- package.json | 16 +- pages/_app.js | 31 + pages/api-example.js | 17 + pages/api/auth/[...nextauth].js | 83 + pages/api/examples/jwt.js | 9 + pages/api/examples/protected.js | 12 + pages/api/examples/session.js | 7 + pages/client.js | 22 + pages/index.js | 12 + pages/policy.js | 30 + pages/protected-ssr.js | 37 + pages/protected.js | 33 + pages/server.js | 38 + pages/styles.css | 30 + src/client/index.js | 18 +- src/css/index.css | 26 +- src/css/index.js | 7 +- src/index.js | 1 + 32 files changed, 4470 insertions(+), 240 deletions(-) rename LICENSE.txt => LICENSE (100%) delete mode 100644 babel.config.json create mode 100644 components/access-denied.js create mode 100644 components/footer.js create mode 100644 components/footer.module.css create mode 100644 components/header.js create mode 100644 components/header.module.css create mode 100644 components/layout.js create mode 100644 config/babel.config.json rename postcss.config.js => config/postcss.config.js (100%) rename {scripts => config}/wrap-css.js (100%) create mode 100644 jsconfig.json create mode 100644 pages/_app.js create mode 100644 pages/api-example.js create mode 100644 pages/api/auth/[...nextauth].js create mode 100644 pages/api/examples/jwt.js create mode 100644 pages/api/examples/protected.js create mode 100644 pages/api/examples/session.js create mode 100644 pages/client.js create mode 100644 pages/index.js create mode 100644 pages/policy.js create mode 100644 pages/protected-ssr.js create mode 100644 pages/protected.js create mode 100644 pages/server.js create mode 100644 pages/styles.css create mode 100644 src/index.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1461b58f65..08458ddca5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,70 +17,47 @@ Anyone can be a contributor. Either you found a typo, or you have an awesome fea * Pull Requests should be raised for any change * Pull Requests need approval of a [core contributor](https://next-auth.js.org/contributors#core-team) before merging * Rebasing in Pull Requests is preferred to keep a clean commit history (see below) -* Running `npm run lint:fix` before committing can make resolving conflicts easier +* Run `npm run lint:fix` before committing to make resolving conflicts easier (VSCode users, check out [this extension](https://marketplace.visualstudio.com/items?itemName=chenxsan.vscode-standardjs) to fix lint issues in development) * We encourage you to test your changes, and if you have the opportunity, please make those tests part of the Pull Request * If you add new functionality, please provide the corresponding documentation as well and make it part of the Pull Request ### Setting up local environment -A quick and dirty guide on how to setup *next-auth* locally to work on it and test out any changes: +A quick guide on how to setup *next-auth* locally to work on it and test out any changes: 1. Clone the repo: +```sh +git clone git@github.com:nextauthjs/next-auth.git +cd next-auth +``` - git clone git@github.com:nextauthjs/next-auth.git - cd next-auth/ - -2. Install packages and run the build command: - - npm i - npm run build - -3. Link your project back to your local copy of next auth: - - cd ../your-application - npm link ../next-auth +2. Install packages: +```sh +npm i +``` -4. Finally link React between the repo and the version installed in your project: +3. Populate `.env.local`: + + Copy `.env.example` to `.env.local`, and add your env variables for each provider you want to test. - cd ../next-auth - npm link ../your-application/node_modules/react +>NOTE: You can configure providers of the dev app in `pages/api/auth/[...nextauth].js` -*This is an annoying step and not obvious, but is needed because of how React has been written (otherwise React crashes when you try to use the `useSession()` hook in your project).* +4. Start the dev application/server and CSS watching: +```sh +npm run dev +``` -That's it! +Your dev application will be available on ```http://localhost:3000``` -Notes: You may need to repeat both `npm link` steps if you install / update additional dependencies with `npm i`. +That's it! 🎉 If you need an example project to link to, you can use [next-auth-example](https://github.com/iaincollins/next-auth-example). #### Hot reloading -You might find it helpful to use the `npm run watch` command in the next-auth project, which will automatically (and silently) rebuild JS and CSS files as you edit them. - - cd next-auth/ - npm run watch - -If you are working on `next-auth/src/client/index.js` hot reloading will work as normal in your Next.js app. +When running `npm run dev`, you start a Next.js dev server on `http://localhost:3000`, which includes hot reloading out of the box. Make changes on any of the files in `src` and see the changes immediately. -However, if you are working on anything else (e.g. `next-auth/src/server/*` etc) then you will need to *stop and start* your app for changes to apply as **Next.js will not hot reload those changes by default**. To facilitate this, you can try [this webpack plugin](https://www.npmjs.com/package/webpack-clear-require-cache-plugin). Note that the `next.config.js` syntax in the plugin README may be out of date. It should look like this: - -``` -const clearRequireCachePlugin = require('webpack-clear-require-cache-plugin') - -module.exports = { - webpack: (config, { - buildId, dev, isServer, defaultLoaders, webpack, - }) => { - config.plugins.push(clearRequireCachePlugin([ - /\.next\/server\/static\/development\/pages/, - /\.next\/server\/ssr-module-cache.js/, - /next-auth/, - ])) - - return config - }, -} -``` +>NOTE: When working on CSS, you will need to manually refresh the page after changes. (Improving this through a PR is very welcome!) #### Databases @@ -90,7 +67,7 @@ It will use port `3306`, `5432`, and `27017` on localhost respectively; please m You can start them with `npm run db:start` and stop them with `npm run db:stop`. -You will need Docker installed to be able to start / stop the databases. +You will need Docker and Docker Compose installed to be able to start / stop the databases. When stopping the databases, it will reset their contents. diff --git a/LICENSE.txt b/LICENSE similarity index 100% rename from LICENSE.txt rename to LICENSE diff --git a/babel.config.json b/babel.config.json deleted file mode 100644 index e6753269e1..0000000000 --- a/babel.config.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "presets": [ - ["@babel/preset-env", { "targets": { "esmodules": true } } ] - ], - "comments": false, - "overrides": [ - { - "test": [ "./src/server/pages/**" ], - "presets": [ "preact" ] - } - ] -} \ No newline at end of file diff --git a/components/access-denied.js b/components/access-denied.js new file mode 100644 index 0000000000..ed0ae49180 --- /dev/null +++ b/components/access-denied.js @@ -0,0 +1,16 @@ +import { signIn } from 'next-auth/client' + +export default function AccessDenied () { + return ( + <> +

Access Denied

+

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

+ + ) +} diff --git a/components/footer.js b/components/footer.js new file mode 100644 index 0000000000..5ae7461587 --- /dev/null +++ b/components/footer.js @@ -0,0 +1,18 @@ +import Link from 'next/link' +import styles from './footer.module.css' +import { version } from 'package.json' + +export default function Footer () { + return ( + + ) +} diff --git a/components/footer.module.css b/components/footer.module.css new file mode 100644 index 0000000000..bf8bfb82c6 --- /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; +} \ No newline at end of file diff --git a/components/header.js b/components/header.js new file mode 100644 index 0000000000..b80b0416ea --- /dev/null +++ b/components/header.js @@ -0,0 +1,103 @@ +import Link from 'next/link' +import { signIn, signOut, useSession } from 'next-auth/client' +import * as client from 'next-auth/client' +import styles from './header.module.css' + +// The approach used in this component shows how to built 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 [session, loading] = useSession() + + return ( +
+ +
+

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

+
+ +
+ ) +} diff --git a/components/header.module.css b/components/header.module.css new file mode 100644 index 0000000000..18ec82f0e0 --- /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 .6rem .6rem; + padding: .6rem 1rem; + margin: 0; + background-color: rgba(0,0,0,.05); + transition: all 0.2s ease-in; +} + +.loading { + top: -2rem; + opacity: 0; +} + +.signedInText, +.notSignedInText { + position: absolute; + padding-top: .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: -.4rem; + font-weight: 500; + border-radius: .3rem; + cursor: pointer; + font-size: 1rem; + line-height: 1.4rem; + padding: .7rem .8rem; + position: relative; + z-index: 10; + background-color: transparent; + color: #555; +} + +.buttonPrimary { + background-color: #346df1; + border-color: #346df1; + color: #fff; + text-decoration: none; + padding: .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; +} \ No newline at end of file diff --git a/components/layout.js b/components/layout.js new file mode 100644 index 0000000000..6c4fcc7da5 --- /dev/null +++ b/components/layout.js @@ -0,0 +1,14 @@ +import Header from 'components/header' +import Footer from 'components/footer' + +export default function Layout ({ children }) { + return ( + <> +
+
+ {children} +
+