Compare commits

...

108 Commits

Author SHA1 Message Date
Thang Vu
4dbbe5b2d9 chore(release): bump package version(s) [skip ci] 2022-10-23 22:17:19 +07:00
Balázs Orbán
d9df582fa8 feat(client): add refetchWhenOffline option (#4940)
* feat(client): add `refetchWhenOffline` option

* docs(client): document `refetchWhenOffline` option

* add TODO comment for next major

* feat: improve refetch hook logic

* fix: add todo back

* chore: small refactoring

Co-authored-by: Thang Vu <hi@thvu.dev>
2022-10-23 22:09:30 +07:00
Matsuoka
af840b2106 feat(providers): Add Todoist provider (#5253)
* feat: Add Todoist provider

* fix: use openid-client

* chore: add Todoist provider to issue template

Co-authored-by: Thang Vu <hi@thvu.dev>
2022-10-23 17:16:06 +07:00
jcdogo
ba89907d5a feat: Add allowDangerousEmailAccountLinking option for OAuth providers (#5513)
* Add opt-in for dangerous linking

* Add documentation for allowDangerousEmailAccountLinking option.

* Add link to FAQ.

* Fix nullish coalescing operator linting error.
2022-10-23 17:08:25 +07:00
Steven Tey
08eaeba79f docs: Fixed typo (#5609) 2022-10-21 10:07:13 +01:00
Usman Sabuwala (Max Programming)
c31eabfcc6 docs: Update the nodemailer well known page URL (#5573) 2022-10-19 22:28:40 +02:00
Balázs Orbán
4423673424 docs: update patreon.md 2022-10-18 21:32:51 +01:00
X
281d0948b9 docs: Typo error on Example (#5590)
Removed unwanted ")" from Example
2022-10-18 21:32:33 +01:00
Lluis Agusti
5246183c55 chore: docs updates (#5581)
* chore: fix version label

* upgrade docusaurus

* fix

* fix

* fix links, NextAuth -> NextAuth.js

* NextJS -> Next.js

* fix guides

* add docusaurus type

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-10-15 16:39:33 +01:00
Lluis Agusti
cb56cd44ca refactor(docs): re-structure (#4498)
* docs: beta initial commit

* docs(oauth): finish initial tutorial

* docs(oauth-tutorial): finish guide

* docs(docusaurus): just log broken links

* docs: re-organising beta

* docs(beta): sort documents for sorting

* docs: more re-structure

* docs: more re-structure (2)

* fix: more WIP

* fix: more WIP

* chore: more updates

* chore: wip

* chore: wip

* fix lock file

* docs(getting-started): credentials

* chore: remove json-server file

* chore: cleanup

* remove mongodb from dev app

* chore: cleanup

* revert

* chore: cleanup

* chore: more cleanup changes

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-10-15 15:45:33 +01:00
Mischa Spiegelmock
6758e1c6d1 refactor(core): allow trusting the forwarded host header (#5561)
* Non vercel-specific way to forward host header

* Update packages/next-auth/src/utils/detect-host.ts

Co-authored-by: Balázs Orbán <info@balazsorban.com>

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-10-15 14:17:20 +02:00
Thang Vu
462cca1087 chore(release): bump package version(s) [skip ci] 2022-10-14 08:52:04 +07:00
Thang Vu
ab48fcfe5b chore: remove codeql run on main push 2022-10-14 08:37:59 +07:00
Thang Vu
fe7aaeded8 fix(ts): TS Module Augmentation (#5556)
* fix: TS Module Augmentation

* match type to AdapterUser

* refactor authorize callback

* Apply suggestions from code review

* Apply suggestions from code review

* Apply suggestions from code review

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-10-13 09:39:12 +07:00
Anthony Shew
c53c09ea5c docs: options.md grammar fixes (#5562)
Update options.md

Just some grammar!
2022-10-12 20:07:53 +01:00
Matteo Giardino
4bcba45294 docs(client): typo (#5545) 2022-10-11 01:44:15 +01:00
David Walsh
eb5a9bad9d chore(dev): update SvelteKit playground to 1.0.0-next.511 (#5531)
* Update playground-sveltekit to sveltekit rc 511

* Remove prettier config and format

* Fix adapter comment
2022-10-10 18:20:51 +02:00
Balázs Orbán
9a6d95c17c chore: fix TS lint 2022-10-10 02:11:46 +02:00
Balázs Orbán
5b2fc7b570 chore: fix neo4j build 2022-10-10 02:04:09 +02:00
Balázs Orbán
6f459225fa Merge branch 'main' of github.com:nextauthjs/next-auth 2022-10-10 00:30:25 +02:00
Balázs Orbán
f38ee19a8a chore(dev): improve DX 2022-10-10 00:30:22 +02:00
Ranjan Purbey
38a03ed7d8 feat(providers): Add Pinterest Provider (#5485)
* feat(providers): Add Pinterest Provider

* Apply suggestions from code review

* Update pinterest.ts

* Update pinterest.ts

* Apply suggestions from code review

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-10-09 23:18:45 +01:00
Chris Abernethy
e1eb684cc6 fix(providers): change EVE Online to OAuth2 (#5459) 2022-10-10 00:16:17 +02:00
Thang Vu
777b7b2f23 chore(release): bump package version(s) [skip ci] 2022-10-09 22:52:53 +07:00
Balázs Orbán
6132c3fa75 fix(ts): match TS types better with implementation (#4953)
* refactor(ts): export `AdapterAccount` from `next-auth/adapters`

* chore: run linter, remove prisma warning

* fix(ts): match TS with implementation closer

* remove unused import

* rename error

* add missing dev dependency

* fix type

* fix type

* fix more types and tests

* remove unused `id`

* skip upstash tests in CI

* revert some changes

* fix type

* revert some change

* revert some change

* revert some change

* revert some changes

* update lock file

* revert line change

* revert some change

* improve adapter & oauth typing

* fix test, revert

* apply review suggestion

* Add test for new rejection logics

* Update assert.test.ts

* fix: Hubspot config

* restore some ts-expect-error

* fix: tests in mirko-orm

* fix: remove redundant id: string

* fix: use ts-expect-errors

* fix: simplify provider type

* fix: normalize user options

* restore ts-expect-errors

Co-authored-by: Thang Vu <hi@thvu.dev>
2022-10-09 21:54:01 +07:00
Usman Sabuwala (Max Programming)
94beef77e6 docs: Remove extra space in code (#5515) 2022-10-09 13:40:38 +02:00
Philipp
490d59dd17 fix(middleware): improve handling of custom Next.js basePath (#5109)
* fix(middleware): improve handling of custom nextjs basePath

* fix(middleware): improve extraction of nextjs base path from req.nextUrl

* adapt to req.nextUrl.basePath

* Fix indent

* Add middleware test for custom-base and simplified code a little bit

* Fix indent

* Add another test

* Rename basePath and nextJsBasePath

* Fix lint error
2022-10-09 11:31:28 +07:00
Thang Vu
26a8c5fc6d chore: lint in apps (#5507) 2022-10-06 22:14:12 +01:00
Colby Fayock
e26ec74720 docs(tutorial): Creating a Custom Adapter (#5506)
* Add new item to tutorials page

* Update tutorials.md

* Apply suggestions from code review

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-10-06 22:12:20 +01:00
Max Peintner
d13997e140 feat(providers): ZITADEL provider (#5479)
* feat: zitadel provider

* Update packages/next-auth/src/providers/zitadel.ts

Co-authored-by: Balázs Orbán <info@balazsorban.com>

* Update packages/next-auth/src/providers/zitadel.ts

Co-authored-by: Balázs Orbán <info@balazsorban.com>

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-10-06 09:44:21 +02:00
Balázs Orbán
d6efda077d chore(release): bump package version(s) [skip ci] 2022-10-05 19:30:28 +02:00
Eric Carboni
0a4b99de3b chore(docs): update middleware documentation link (#5492)
closes #5489
2022-10-04 19:25:56 +02:00
Daniel
2d2dfecc9d docs(core): update documentation callbacks to include user id as example (#5465)
* Add user id to `session` and `jwt` callback

* Minor changes

- Notes on why the id is not exposed by default is already documented in the `session` section.

* Apply suggestions from code review

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-10-03 16:03:33 +02:00
Thang Vu
2a2c3d7a45 chore: add security guidelines to PR & issue template (#5470)
* chore: add security guidelines to pr & issue template

* Apply suggestions from code review

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-10-03 15:59:19 +02:00
kesoji
82786ac440 chore: remove duplicate key in pacakges/tsconfig/package.json (#5469)
fix: remove duplicate key
2022-10-02 20:51:17 +02:00
Vedant Nandwana
dfe3e02132 docs(adapters): Add TS type to prisma client (#5463)
* docs(adapters): Add prisma client docs for typescript users

Add documentation for connecting prisma client w/ prisma adapter for typescript users.

* docs(adapters): remove prismadb.js for prismadb.ts

remove prismadb.js as it is identical to the prismadb.ts

* Apply suggestions from code review

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-10-01 22:17:41 +02:00
Itunu Lamina
92b38ed740 docs: fix 'JWKKeySupport' typo (#5452)
update 'JWKKeySupport' typo error
2022-09-29 15:34:23 +02:00
Tom Freudenberg
97feae7916 fix(types): export SessionContext #5437 (#5438)
Co-authored-by: Lluis Agusti <hi@llu.lu>

Fixes #5437
2022-09-28 18:48:42 +02:00
Balázs Orbán
24945895e9 chore(release): bump package version(s) [skip ci] 2022-09-28 18:10:38 +02:00
Balázs Orbán
6deccf610f fix(core): return JSON for non-HTML server route errors (#5442)
* fix(core): return JSON for non-HTML server route errors

* refactor: throw in `unstable_getServerSession`

* test: expect `unstable_getServerSession` to throw

* refactor: destructure

* fix unrelated test formatting

* catch error page
2022-09-28 17:01:39 +01:00
Etienne Martin
f770b90219 fix(react): safe use of localStorage API (#5444)
fix: safe use of localstorage

Co-authored-by: Etienne <>
2022-09-28 16:54:07 +01:00
Balázs Orbán
87f4786917 chore: bump release package 2022-09-28 13:51:41 +02:00
Balázs Orbán
191ef06471 chore(release): bump package version(s) [skip ci] 2022-09-28 13:00:32 +02:00
Philip
75e6d8f0aa docs(adapters): Update prisma.md (#5366)
* Update prisma.md

The referenced official doc page describes how to fix the `warn(prisma-client) There are already 10 instances of Prisma Client actively running.` error in development mode.

* Update prisma.md

Implemented best practice for Prisma Client creation.

* Fixed typo in Prisma db filename.
2022-09-28 11:15:55 +01:00
Yixuan Xu
17999edd30 chore(example): fix hydrate problem in react18 (#5439) 2022-09-28 10:50:40 +02:00
Tom Freudenberg
54b1845e58 fix(core): don't lock next in peerDependencies #5427 (#5430)
* Update peerDependencies #5427

* Apply suggestions from code review

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-09-27 00:04:50 +01:00
Tomas Pozo
879faf9fab docs(middleware): add tip on additional matcher patterns (#5404)
* docs(middleware): add tip on additional matcher patterns

* Apply suggestions from code review

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-09-26 13:39:32 +02:00
Balázs Orbán
3e3c36891e docs(example): use generic type in AppProps
closes #5401
2022-09-25 10:57:44 +01:00
Balázs Orbán
ac5d8a9795 chore(release): bump package version(s) [skip ci] 2022-09-25 11:42:17 +02:00
Matt Oliver
965c6267e2 feat(core): make session token with DB session strategy customizable (#5328)
* Add option for custom generateSessionToken

* Apply suggestions from code review

* Apply suggestions from code review

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-09-25 10:26:59 +01:00
Sébastien Vanvelthem
bfc429d20b fix: update jose to fix nextjs edge error with middleware (#5372)
fix: update jose to fix nextjs edge error
2022-09-25 15:46:02 +07:00
Balázs Orbán
2d8e910a19 chore(release): bump package version(s) [skip ci] 2022-09-25 10:29:56 +02:00
voinik
d16e04848e fix(adapters): check token during email verification in Upstash Adapter (#5377)
* Check token during email verification

* Undo accidental linter fix

* Update index.ts

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-09-25 09:10:55 +01:00
Balázs Orbán
ff3a52895b chore(release): bump package version(s) [skip ci] 2022-09-25 09:42:51 +02:00
Balázs Orbán
e6e03e8842 feat(adapters): update Mikro ORM adapter schema
BREAKING CHANGE:

See https://github.com/nextauthjs/next-auth/pull/5316
2022-09-25 09:29:17 +02:00
Thomas Large
715aad9474 chore: Add Next to peerDeps & bump to 12.2.5 in devDeps (#5384) 2022-09-24 13:39:07 +07:00
Jonas Strassel
902bf92a85 fix(mikro-orm): re-enable tests (#5316) 2022-09-21 23:36:23 +07:00
Eng Zer Jun
44f2a47e6e fix(middleware): use includes() for NextAuth pages (#5104)
* fix(middleware): use `includes()` for NextAuth pages

Some users could be setting their `signIn` and `error` pages option to
`/` to disable the automatically generated pages, as suggested in [1].

This commit reverts the behaviour for matching `signIn` and `error`
pages in `handleMiddleware` to pre-v4.10.3.

```
const signInPage = "/"
const errorPage = "/"
const publicPaths = [signInPage, errorPage, "/_next", "/favicon.ico"]

// pathname = "/" will return true
publicPaths.some((p) => pathname.startsWith(p))
```

Fixes: aedabc8d ("fix: avoid redirect on always public paths")
Reference [1]: https://github.com/nextauthjs/next-auth/discussions/2330#discussioncomment-1678298
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>

* test(middleware): add tests for public paths

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
Co-authored-by: Thang Vu <thvu@hey.com>
2022-09-18 11:07:46 +07:00
dependabot[bot]
a3b92dbaec chore(deps): bump jose from 4.5.0 to 4.9.3 in /apps/playground-sveltekit (#5359)
Bumps [jose](https://github.com/panva/jose) from 4.5.0 to 4.9.3.
- [Release notes](https://github.com/panva/jose/releases)
- [Changelog](https://github.com/panva/jose/blob/main/CHANGELOG.md)
- [Commits](https://github.com/panva/jose/compare/v4.5.0...v4.9.3)

---
updated-dependencies:
- dependency-name: jose
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-17 01:55:54 +02:00
Steve Burtenshaw
bdd3ab2816 docs(middleware): remove reference to nested (#5355)
Fixes #5180
2022-09-16 10:30:58 +02:00
Dulmandakh
ba55f06585 chore(deps): bump cookie to 0.5.0 (#5339) 2022-09-14 18:31:00 +02:00
Steve Burtenshaw
d2b877fb28 docs(client): onUnauthenticated reference (#5340) 2022-09-14 17:26:02 +02:00
Yuriy Gromchenko
658b22d9fb docs(atlassian): update provider scope (#5337) 2022-09-14 17:23:01 +02:00
Mircea Trofimciuc
a0beb02f77 feat(providers): Add HubSpot Provider (#4633)
* Typos fix

* Added HubSpot Provider

* updates to profile

* Update docs/docs/providers/hubspot.md

Co-authored-by: Thang Vu <31528554+ThangHuuVu@users.noreply.github.com>

* fixed typo and outsourced required fields

* removing redirectURL from the provider config

* replaced with "client_secret_post" client method

Co-authored-by: Thang Vu <31528554+ThangHuuVu@users.noreply.github.com>
2022-09-11 10:43:28 +07:00
Thang Vu
5727c5f4e6 chore: tweak tsconfig files 2022-09-10 09:39:26 +07:00
Balázs Orbán
8104cb1287 chore: fix builds/tests/eslint (#4780)
* chore(deps): upgrade `typescript`

* chore(ts): don't exclude test files in tsconfig

* test: expect error when overriding `NODE_ENV`

* chore: remove unused import

* format

* chore: use pnpm@7 in action

* chore: fix eslint

* chore: remove pnpm from engines

* chore: fix configs/builds

* fix: make eslint works

* Update pnpm-lock.yaml

* fix: build failure

* fix: add react to paths

* ignore upstash for now

* add eslintignore, add a bunch of tsconfig.eslint.json

* ignore mikro orm for now

* Delete tsconfig.eslint.json

* Update package.json

* Update pnpm-lock.yaml

* move eslint back to package.json

* move eslintrc.js out

Co-authored-by: Thang Vu <thvu@hey.com>
Co-authored-by: Thang Vu <thang.vu@binance.com>
2022-09-09 13:51:40 +02:00
Balázs Orbán
44aaa6f1c3 chore: turbo cleanup (#4951)
* clean up `package.json` files

* chore(ts): make sure `next-auth/next` does not conflict with `next`

* simplify `turbo.json`

* fix: apply suggestion

* simplify doc dev command

* ignore upstash redis again

* ignore mikro orm for now

* chore: dev command

* update lock file

* update css path for dev only

* Update apps/dev/package.json

Co-authored-by: Thang Vu <thvu@hey.com>
2022-09-08 16:43:16 +02:00
Roberto Romero
ba20974b5f fix(providers): use client_secret_post token auth for LinkedIn (#5236)
* Send client_id and client_secret to linkedin

Linkedin now requires client_id and client_secret to be
sent in the oauth callback. Fixes #5220

* Update linkedin.ts

Co-authored-by: Thang Vu <thvu@hey.com>
Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-09-07 17:57:45 +02:00
Anton Starikovich
14b4ed1d8a feat(adapters): let user configure MongoDB database name (#5290)
* feat: added providing database name in options

* fix: added database name providing in readme

* Apply suggestions from code review

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-09-07 17:56:00 +02:00
Michael Angelo
6b3a82d1f5 docs(providers): Update v4 Strava Doc (#5299)
update
2022-09-07 17:43:13 +02:00
Cristian Muñoz
600aaaa7e6 docs: Update Getting Started Example (#5295) 2022-09-07 17:42:38 +02:00
Michael Angelo
f1d3bc26f9 fix(providers): convert Strava Provider to TS (#5241)
* update strava

* add localhost fallback

* lint & small updates

* Update docs/versioned_docs/version-v3/providers/strava.md

Co-authored-by: Lluis Agusti <hi@llu.lu>

* fix

* Delete yarn.lock

* Apply suggestions from code review

Co-authored-by: Lluis Agusti <hi@llu.lu>
Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-09-06 17:06:51 +01:00
Silvio
78664aab37 docs: close the callback object (#5251)
* Update role-based-login-strategy.md

* Apply suggestions from code review

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-09-06 17:02:46 +01:00
namacha
aeb3a44b27 docs(tutorial): fixed title of code block (#5282) 2022-09-02 18:32:42 +02:00
Jonny
d3571e01ba fix: Change getToken parameter type to required (#5245)
* changed getToken parameter type to required

* removed redundant nullish coalescing operator

Co-authored-by: Thang Vu <thvu@hey.com>
2022-09-02 12:34:40 +07:00
Esteban Dalel R
3b7c9886c3 docs: fix grammar error (#5254) 2022-09-01 12:04:30 +01:00
dependabot[bot]
39fec738c6 chore(deps-dev): bump vite from 2.8.4 to 2.9.13 in /apps/playground-sveltekit (#5255)
chore(deps-dev): bump vite in /apps/playground-sveltekit

Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 2.8.4 to 2.9.13.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v2.9.13/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-01 12:04:04 +01:00
Daniel
fa58143c6b docs(adapters): Update upstash-redis.md (#5261)
* Update upstash-redis.md

* Update docs/docs/adapters/upstash-redis.md

Co-authored-by: Lluis Agusti <hi@llu.lu>

* Apply suggestions from code review

* Apply suggestions from code review

Co-authored-by: Lluis Agusti <hi@llu.lu>
Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-09-01 12:03:52 +01:00
Sean McEmerson
26fb89e3c4 docs: fix broken link (#5263)
Update firebase.md

Fix broken link
2022-09-01 10:44:08 +02:00
Melanie Seltzer
a82cbf5ddf fix: return null in unstable_getServerSession if there's an error (#5218)
* fix: return null in unstable_getServerSession if there's an error

* Remove status check and instead check body is not a string

* Combine similar tests
2022-08-31 09:19:14 +07:00
josef
24db833685 docs(svelte): upgrade SvelteKit playground to use latest SvelteKit routes (#5229)
* feat: migrate routes

* feat: ugrade to latest SvelteKit (443)
2022-08-28 13:32:55 +01:00
Adalberto Prado
c57a810042 docs(nextjs): change typo from js to ts (#5217) 2022-08-26 23:47:09 +01:00
Brian Muenzenmeyer
d980fa986b chore(types): fix typo in comment (#5207) 2022-08-23 18:58:50 +02:00
Greg Rickaby
4676352ae0 docs(providers): Enhance Reddit App Instructions (#5199)
docs(reddit): Enhance App Instructions

Add step-by-step instructions for creating Reddit App. Add screenshot.
2022-08-22 14:50:38 +01:00
rinuya
c8780122b3 docs: typo in "unstable_getServerSession" (#5191)
fixed a typo
2022-08-22 14:44:56 +01:00
Junichi Sato
3131971e2c fix: Use consistent error type between doc, logger and error class (#5046)
* Keep error from being logged twice

The same errors have been logged, firstly before throwing
OAuthCallbackError, later in the catch-clause of it.

This commit removes the former and lets the latter survive,
because logging functionality seems better to reside in the
same neighborhood.

* doc: Merge CALLBACK_OAUTH_ERROR to OAUTH_CALLBACK_ERROR

* doc: This particular error from openid-client comes with SIGNIN_OAUTH_ERROR

* Provide logger with `providerId`

Co-authored-by: Thang Vu <thvu@hey.com>

Co-authored-by: Thang Vu <thvu@hey.com>
2022-08-22 14:46:30 +07:00
heyitsbryanm
448ec1017a docs(adapters): Adds warning to backup database (#5160)
prisma migrate deleted mine, hah.
2022-08-16 17:25:29 +01:00
Soumyajit Pathak
0e9404ebc1 docs: clarify cookie policies in FAQ (#5158)
* fix typo in faq

Added missing “not” in same root different subdomain config section warning text

* Apply suggestions from code review

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-08-16 17:24:50 +01:00
James
d349ae2b1b Feature/nonce check type (#4100)
* feat: add nonce check type

* Update types import for nonce-handler.ts

* Update packages/next-auth/src/core/lib/oauth/callback.ts

Co-authored-by: Thang Vu <thvu@hey.com>

* Add further info to debug msg as per PR suggestion

* Cast OauthChecks as OpenIDCallbackChecks

* Update order of imports as per PR suggestion

Co-authored-by: Hamid Adelyar <hamid.adelyar@bjss.com>
Co-authored-by: hamidbjss <98807568+hamidbjss@users.noreply.github.com>
Co-authored-by: Thang Vu <thvu@hey.com>
2022-08-16 17:07:42 +07:00
Thang Vu
32f4d5000e docs(faq): note default behavior for account linking (#5113) 2022-08-13 15:58:10 +07:00
Dragate
7f2dbfc65b docs: Fix file paths (#5146)
* Correct auth config path

* Fix some relative paths
2022-08-12 21:36:08 +02:00
Moritz Kneilmann
a03657e615 fix(providers): Add appid param to Azure AD wellKnown URL (#5138)
This fixes: #5137
Relevent documentation:
> If the application has custom signing keys as a result of using the claims-mapping feature, append an appid query parameter that contains the application ID to get a jwks_uri that points to the signing key information of the application, which should be used for validation.

https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens#validating-the-signature
2022-08-12 14:26:21 +02:00
Youssef Hajjari
3e312d0df1 docs: Typo fix (#5132) 2022-08-11 12:02:01 +02:00
Shudhanshu Choudhary
d9167bbffe docs: Typo fix (#5114)
* fix typo

* Update docs/docs/configuration/options.md

* fix path for mongodb file

Co-authored-by: Thang Vu <thvu@hey.com>
2022-08-08 21:15:54 +02:00
Shudhanshu Choudhary
526a6c1adc docs: typo in configuration/options.md (#5112)
* fix typo

* Update docs/docs/configuration/options.md

Co-authored-by: Thang Vu <thvu@hey.com>
2022-08-07 15:30:37 +07:00
Eng Zer Jun
ad03a4efc1 docs(middleware): fix default value of pages option (#5091)
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2022-08-06 10:17:01 +02:00
Lluis Agusti
424af6cbc5 docs(getting-started): reword NextAuth.js + install (#5081)
* docs: update references to NextAuth

* docs(getting-started): use install snippet
2022-08-04 01:34:09 +02:00
Stephen Gbolagade
a3c6786f78 docs(getting-started): add how to install next-auth (#5040)
Contains the following squashed commits:

* Added how to install next-auth
* Update docs/docs/getting-started/example.md
* Update docs/docs/getting-started/example.md
* Updated with suggestions in mind
* Update example.md
2022-08-03 12:29:06 +02:00
dependabot[bot]
385037ab33 chore(deps): bump next-auth from 4.9.0 to 4.10.3 in /apps/playground-sveltekit (#5071)
chore(deps): bump next-auth in /apps/playground-sveltekit

Bumps [next-auth](https://github.com/nextauthjs/next-auth) from 4.9.0 to 4.10.3.
- [Release notes](https://github.com/nextauthjs/next-auth/releases)
- [Changelog](https://github.com/nextauthjs/next-auth/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nextauthjs/next-auth/compare/next-auth@v4.9.0...next-auth@v4.10.3)

---
updated-dependencies:
- dependency-name: next-auth
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-03 00:32:42 +02:00
Balázs Orbán
26a03da621 chore(release): bump version [skip ci] 2022-08-01 13:55:08 +02:00
Balázs Orbán
afb1fcdae3 fix(providers): add normalizeIdentifier to EmailProvider
* fix(providers): add `normalizeIdentifier` to EmailProvider

* docs: document `normalizeIdentifier`

* fix: allow throwing error from normalizer

* test: add e-mail tests

* chore: log provider id

* test: merge client+config jest configs and add coverage report

* test: show coverage for untested files

* fix: only allow first domain in email. Add tests

* chore: add `coverage` to tsconfig exclude list

* cleanup

* revert

Co-authored-by: Thang Vu <thvu@hey.com>
2022-08-01 13:43:19 +02:00
Gavin Fogel
a21db8950f fix(ts): fix jsdoc link to documentation (#5039) 2022-07-28 06:54:01 +02:00
Daniel González Reina
e8371ab23a docs(providers): update custom Reddit provider to v4 (#4985)
* Update custom reddit provider to v4

* Reuse RedditProvider's default options

* Apply suggestions from code review

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-07-26 10:43:45 +02:00
Visor Web Technologies
9cdeb2ce7d docs: Fixed Typo (#5025) 2022-07-26 10:39:33 +02:00
Thang Vu
89829d8a88 chore: fix unstable_getServerSession usages in dev app (#5017)
chore: fix unstable_getServerSession usages in dev app
2022-07-25 23:08:59 +02:00
Balázs Orbán
aedabc8d3f fix: avoid redirect on always public paths (#5000)
* type safe babel config

* avoid auth redirect for `_next`

* force render default error page on user miconfig

* add slash to _next path

* use `.some`

* add docs

* change from localhost

* add favicon to public path
2022-07-24 00:45:56 +02:00
Balázs Orbán
9f2cdad457 docs: add Thang as point of contact 2022-07-22 20:31:19 +02:00
Yoann Fleury
b107ca4946 docs: update path to gitlab provider (#4997) 2022-07-22 19:33:03 +02:00
352 changed files with 18829 additions and 4281 deletions

40
.eslintrc.js Normal file
View File

@@ -0,0 +1,40 @@
const path = require("path")
module.exports = {
root: true,
parser: "@typescript-eslint/parser",
overrides: [
{
files: ["*.ts", "*.tsx"],
extends: ["standard-with-typescript", "prettier"],
rules: {
camelcase: "off",
"@typescript-eslint/naming-convention": "off",
"@typescript-eslint/strict-boolean-expressions": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/restrict-template-expressions": "off",
},
parserOptions: {
project: [
path.resolve(__dirname, "./packages/**/tsconfig.eslint.json"),
path.resolve(__dirname, "./apps/**/tsconfig.json"),
],
},
},
],
extends: ["prettier"],
globals: {
localStorage: "readonly",
location: "readonly",
fetch: "readonly",
},
rules: {
camelcase: "off",
},
plugins: ["jest"],
env: {
"jest/globals": true,
},
ignorePatterns: [".eslintrc.js"],
}

View File

@@ -5,6 +5,7 @@ body:
- type: markdown
attributes:
value: |
**NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub.
Thanks for taking the time to fill out this issue after reading/searching through the [documentation](https://next-auth.js.org) first!
Is this your first time contributing? Check out this video: https://www.youtube.com/watch?v=cuoNzXFLitc

View File

@@ -5,6 +5,7 @@ body:
- type: markdown
attributes:
value: |
**NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub.
Thanks for taking the time to fill out this [Provider](https://next-auth.js.org/providers/overview) related issue!
Is this your first time contributing? Check out this video: https://www.youtube.com/watch?v=cuoNzXFLitc
@@ -67,6 +68,7 @@ body:
- "Slack"
- "Spotify"
- "Strava"
- "Todoist"
- "Trakt"
- "Twitch"
- "Twitter"

View File

@@ -5,6 +5,7 @@ body:
- type: markdown
attributes:
value: |
**NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub.
Thanks for taking the time to fill out this [Adapter](https://next-auth.js.org/adapters/overview) related issue!
Is this your first time contributing? Check out this video: https://www.youtube.com/watch?v=cuoNzXFLitc

View File

@@ -9,6 +9,7 @@ body:
- type: markdown
attributes:
value: |
**NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub.
Thank you very much for reaching out to us regarding the awesome feature that you believe should be included in the NextAuth.js library.
_NOTE: Feature requests are converted to [discussions (Ideas 💡)](https://github.com/nextauthjs/next-auth/discussions/categories/ideas). Make sure your idea hasn't been asked yet, and upvote the existing one before opening a new instead._

View File

@@ -17,6 +17,7 @@ body:
- type: markdown
attributes:
value: |
**NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub.
Make sure you [link]() to external documentation if necessary and provide inline code examples like so:
```js

View File

@@ -9,6 +9,7 @@ body:
- type: markdown
attributes:
value: |
**NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub.
We are glad that you have a question about this library. Please provide the following information:
- type: textarea

View File

@@ -5,9 +5,14 @@ Please fill out the information below to expedite the review and (hopefully)
merge of your pull request!
-->
> _NOTE_:
>
> - It's a good idea to open an issue first to discuss potential changes.
> - Please make sure that you are _NOT_ opening a PR to fix a potential security vulnerability. Instead, please follow the [Security guidelines](../Security.md) to disclose the issue to us confidentially.
## ☕️ Reasoning
What changes are being made? What feature/bug is being fixed here?
<!-- What changes are being made? What feature/bug is being fixed here? -->
## 🧢 Checklist
@@ -23,6 +28,7 @@ Fixes: INSERT_ISSUE_LINK_HERE
## 📌 Resources
- [Contributing guidelines](./CONTRIBUTING.md)
- [Code of conduct](./CODE_OF_CONDUCT.md)
- [Security guidelines](../Security.md)
- [Contributing guidelines](../CONTRIBUTING.md)
- [Code of conduct](../CODE_OF_CONDUCT.md)
- [Contributing to Open Source](https://kcd.im/pull-request)

View File

@@ -2,7 +2,7 @@ name: Code Analysis
on:
push:
branches: [main, beta, next]
branches: [beta, next]
pull_request:
branches: [main]
schedule:

1
.gitignore vendored
View File

@@ -35,6 +35,7 @@ packages/next-auth/core
packages/next-auth/jwt
packages/next-auth/react
packages/next-auth/adapters.d.ts
packages/next-auth/adapters.js
packages/next-auth/index.d.ts
packages/next-auth/index.js
packages/next-auth/next

View File

@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting me@iaincollins.com or info@balazsorban.com and yo@ndo.dev.
reported by contacting hi@thvu.dev, info@balazsorban.com, yo@ndo.dev and me@iaincollins.com.
All complaints will be reviewed and investigated and will result in a response
that is deemed necessary and appropriate to the circumstances. The project team
is obligated to maintain confidentiality with regard to the reporter of an

View File

@@ -26,7 +26,6 @@ Anyone can be a contributor. Either you found a typo, or you have an awesome fea
A quick guide on how to setup _next-auth_ locally to work on it and test out any changes:
1. Clone the repo:
```sh
@@ -34,13 +33,21 @@ git clone git@github.com:nextauthjs/next-auth.git
cd next-auth
```
1. Install packages. Developing requires Node.js v16:
2. Set up the correct pnpm version, using [Corepack](https://nodejs.org/api/corepack.html). Run the following in the project'a root:
```sh
corepack enable pnpm
```
(Now, if you run `pnpm --version`, it should print the same verion as the `packageManager` property in the [`package.json` file](https://github.com/nextauthjs/next-auth/blob/main/package.json))
3. Install packages. Developing requires Node.js v16:
```sh
pnpm install
```
3. Populate `.env.local`:
4. Populate `.env.local`:
Copy `apps/dev/.env.local.example` to `apps/dev/.env.local`, and add your env variables for each provider you want to test.
@@ -52,11 +59,12 @@ cp .env.local.example .env.local
> NOTE: You can add any environment variables to .env.local that you would like to use in your dev app.
> You can find the next-auth config under`apps/dev/pages/api/auth/[...nextauth].js`.
4. Start the developer application/server:
5. Start the developer application/server:
```sh
pnpm dev
```
Your developer application will be available on `http://localhost:3000`
That's it! 🎉

View File

@@ -13,9 +13,9 @@ If you contact us regarding a serious issue:
- We will disclose the issue (and credit you, with your consent) once a fix to resolve the issue has been released.
- If 90 days has elapsed and we still don't have a fix, we will disclose the issue publicly.
The best way to report an issue is by contacting us via email at info@balazsorban.com or me@iaincollins.com and yo@ndo.dev, or raise a public issue requesting someone get in touch with you via whatever means you prefer for more details. (Please do not disclose sensitive details publicly at this stage.)
The best way to report an issue is by contacting us via email at hi@thvu.dev, info@balazsorban.com, yo@ndo.dev and me@iaincollins.com, or raise a public issue requesting someone get in touch with you via whatever means you prefer for more details. (Please do not disclose sensitive details publicly at this stage.)
> For less serious issues (e.g. RFC compliance for unsupported flows or potential issues that may cause a problem in the future) it is appropriate to submit these these publically as bug reports or feature requests or to raise a question to open a discussion around them.
> For less serious issues (e.g. RFC compliance for unsupported flows or potential issues that may cause a problem in the future) it is appropriate to submit these publicly as bug reports or feature requests or to raise a question to open a discussion around them.
## Supported Versions

View File

@@ -5,5 +5,4 @@ module.exports = {
return config
},
typescript: { ignoreBuildErrors: true },
experimental: { externalDir: true },
}

View File

@@ -5,10 +5,8 @@
"private": true,
"scripts": {
"clean": "rm -rf .next",
"copy:css": "cpx \"../../packages/next-auth/css/**/*\" src/css --watch",
"watch:css": "cd ../../packages/next-auth && pnpm watch:css",
"dev": "concurrently \"pnpm dev:next\" \"pnpm watch:css\" \"pnpm copy:css\"",
"dev:next": "next dev",
"dev": "next dev",
"lint": "next lint",
"build": "next build",
"start": "next start",
"email": "fake-smtp-server",
@@ -21,7 +19,8 @@
"@next-auth/typeorm-legacy-adapter": "workspace:*",
"@prisma/client": "^3",
"faunadb": "^4",
"next": "12.2.0",
"next": "12.3.1",
"next-auth": "workspace:*",
"nodemailer": "^6",
"react": "^18",
"react-dom": "^18"
@@ -29,8 +28,6 @@
"devDependencies": {
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"concurrently": "^7",
"cpx": "^1.5.0",
"fake-smtp-server": "^0.8.0",
"pg": "^8.7.3",
"prisma": "^3",

View File

@@ -18,6 +18,7 @@ import Freshbooks from "next-auth/providers/freshbooks"
import GitHub from "next-auth/providers/github"
import Gitlab from "next-auth/providers/gitlab"
import Google from "next-auth/providers/google"
import Hubspot from "next-auth/providers/hubspot"
import IDS4 from "next-auth/providers/identity-server4"
import Instagram from "next-auth/providers/instagram"
import Keycloak from "next-auth/providers/keycloak"
@@ -29,53 +30,44 @@ import Osu from "next-auth/providers/osu"
import Patreon from "next-auth/providers/patreon"
import Slack from "next-auth/providers/slack"
import Spotify from "next-auth/providers/spotify"
import Todoist from "next-auth/providers/todoist"
import Trakt from "next-auth/providers/trakt"
import Twitch from "next-auth/providers/twitch"
import Twitter, { TwitterLegacy } from "next-auth/providers/twitter"
import Vk from "next-auth/providers/vk"
import Wikimedia from "next-auth/providers/wikimedia"
import WorkOS from "next-auth/providers/workos"
import Zitadel from "next-auth/providers/zitadel"
// Adapters
import { PrismaClient } from "@prisma/client"
import { PrismaAdapter } from "@next-auth/prisma-adapter"
import { Client as FaunaClient } from "faunadb"
import { FaunaAdapter } from "@next-auth/fauna-adapter"
import { TypeORMLegacyAdapter } from "@next-auth/typeorm-legacy-adapter"
// Add an adapter you want to test here.
const adapters = {
prisma() {
const client = globalThis.prisma || new PrismaClient()
if (process.env.NODE_ENV !== "production") globalThis.prisma = client
return PrismaAdapter(client)
},
typeorm() {
return TypeORMLegacyAdapter({
type: "sqlite",
name: "next-auth-test-memory",
database: "./typeorm/dev.db",
synchronize: true,
})
},
fauna() {
const client =
globalThis.fauna ||
new FaunaClient({
secret: process.env.FAUNA_SECRET,
domain: process.env.FAUNA_DOMAIN,
})
if (process.env.NODE_ENV !== "production") global.fauna = client
return FaunaAdapter(client)
},
noop() {
return undefined
},
}
// // Prisma
// import { PrismaClient } from "@prisma/client"
// import { PrismaAdapter } from "@next-auth/prisma-adapter"
// const client = globalThis.prisma || new PrismaClient()
// if (process.env.NODE_ENV !== "production") globalThis.prisma = client
// const adapter = PrismaAdapter(client)
// // Fauna
// import { Client as FaunaClient } from "faunadb"
// import { FaunaAdapter } from "@next-auth/fauna-adapter"
// const opts = { secret: process.env.FAUNA_SECRET, domain: process.env.FAUNA_DOMAIN }
// const client = globalThis.fauna || new FaunaClient(opts)
// if (process.env.NODE_ENV !== "production") globalThis.fauna = client
// const adapter = FaunaAdapter(client)
// // TypeORM
// import { TypeORMLegacyAdapter } from "@next-auth/typeorm-legacy-adapter"
// const adapter = TypeORMLegacyAdapter({
// type: "sqlite",
// name: "next-auth-test-memory",
// database: "./typeorm/dev.db",
// synchronize: true,
// })
export const authOptions: NextAuthOptions = {
adapter: adapters.noop(),
debug: true,
// adapter,
debug: process.env.NODE_ENV !== "production",
theme: {
logo: "https://next-auth.js.org/img/logo/logo-sm.png",
brandColor: "#1786fb",
@@ -102,6 +94,7 @@ export const authOptions: NextAuthOptions = {
GitHub({ clientId: process.env.GITHUB_ID, clientSecret: process.env.GITHUB_SECRET }),
Gitlab({ clientId: process.env.GITLAB_ID, clientSecret: process.env.GITLAB_SECRET }),
Google({ clientId: process.env.GOOGLE_ID, clientSecret: process.env.GOOGLE_SECRET }),
Hubspot({ clientId: process.env.HUBSPOT_ID, clientSecret: process.env.HUBSPOT_SECRET }),
IDS4({ clientId: process.env.IDS4_ID, clientSecret: process.env.IDS4_SECRET, issuer: process.env.IDS4_ISSUER }),
Instagram({ clientId: process.env.INSTAGRAM_ID, clientSecret: process.env.INSTAGRAM_SECRET }),
Keycloak({ clientId: process.env.KEYCLOAK_ID, clientSecret: process.env.KEYCLOAK_SECRET, issuer: process.env.KEYCLOAK_ISSUER }),
@@ -113,6 +106,7 @@ export const authOptions: NextAuthOptions = {
Patreon({ clientId: process.env.PATREON_ID, clientSecret: process.env.PATREON_SECRET }),
Slack({ clientId: process.env.SLACK_ID, clientSecret: process.env.SLACK_SECRET }),
Spotify({ clientId: process.env.SPOTIFY_ID, clientSecret: process.env.SPOTIFY_SECRET }),
Todoist({ clientId: process.env.TODOIST_ID, clientSecret: process.env.TODOIST_SECRET }),
Trakt({ clientId: process.env.TRAKT_ID, clientSecret: process.env.TRAKT_SECRET }),
Twitch({ clientId: process.env.TWITCH_ID, clientSecret: process.env.TWITCH_SECRET }),
Twitter({ version: "2.0", clientId: process.env.TWITTER_ID, clientSecret: process.env.TWITTER_SECRET }),
@@ -120,6 +114,7 @@ export const authOptions: NextAuthOptions = {
Vk({ clientId: process.env.VK_ID, clientSecret: process.env.VK_SECRET }),
Wikimedia({ clientId: process.env.WIKIMEDIA_ID, clientSecret: process.env.WIKIMEDIA_SECRET }),
WorkOS({ clientId: process.env.WORKOS_ID, clientSecret: process.env.WORKOS_SECRET }),
Zitadel({ issuer: process.env.ZITADEL_ISSUER, clientId: process.env.ZITADEL_CLIENT_ID, clientSecret: process.env.ZITADEL_CLIENT_SECRET }),
],
}

View File

@@ -1,13 +1,15 @@
// This is an example of to protect an API route
import { unstable_getServerSession } from "next-auth/next"
import { authOptions } from "../auth/[...nextauth]"
export default async (req, res) => {
const session = await unstable_getServerSession(req, res, options)
const session = await unstable_getServerSession(req, res, authOptions)
if (session) {
res.send({
content:
"This is protected content. You can access this content because you are signed in.",
session,
})
} else {
res.send({

View File

@@ -1,5 +1,6 @@
// This is an example of how to access a session from an API route
import { unstable_getServerSession } from "next-auth/next"
import { authOptions } from '../auth/[...nextauth]';
export default async (req, res) => {
const session = await unstable_getServerSession(req, res, authOptions)

View File

@@ -1,5 +1,6 @@
import { unstable_getServerSession } from "next-auth/next"
import Layout from "../components/layout"
import { authOptions } from './api/auth/[...nextauth]';
export default function Page() {
// As this page uses Server Side Rendering, the `session` will be already
@@ -40,8 +41,8 @@ export async function getServerSideProps(context) {
return {
props: {
session: await unstable_getServerSession(
contex.req,
contex.res,
context.req,
context.res,
authOptions
),
},

View File

@@ -15,10 +15,6 @@
"incremental": true,
"jsx": "preserve",
"baseUrl": ".",
"paths": {
"next-auth": ["../../packages/next-auth/src"],
"next-auth/*": ["../../packages/next-auth/src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules", "jest.config.js"]

18
apps/dev/types/nextauth.d.ts vendored Normal file
View File

@@ -0,0 +1,18 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import NextAuth from "next-auth"
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
}
}

View File

@@ -1,110 +1,20 @@
# Logs
.DS_Store
node_modules/
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.yarn-integrity
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
*.tsbuildinfo
next-env.d.ts
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
.vercel
.now
.env.local
.DS_Store
.env*.local

View File

@@ -2,12 +2,16 @@ import { SessionProvider } from "next-auth/react"
import "./styles.css"
import type { AppProps } from "next/app"
import type { Session } from "next-auth"
// Use of the <SessionProvider> is mandatory to allow components that call
// `useSession()` anywhere in your application to access the `session` object.
export default function App({ Component, pageProps }: AppProps) {
export default function App({
Component,
pageProps: { session, ...pageProps },
}: AppProps<{ session: Session }>) {
return (
<SessionProvider session={pageProps.session} refetchInterval={0}>
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
)

View File

@@ -4,8 +4,7 @@ import Layout from "../components/layout"
import AccessDenied from "../components/access-denied"
export default function ProtectedPage() {
const { data: session, status } = useSession()
const loading = status === "loading"
const { data: session } = useSession()
const [content, setContent] = useState()
// Fetch content from protected route
@@ -19,9 +18,7 @@ export default function ProtectedPage() {
}
fetchData()
}, [session])
// When rendering client side don't display anything until loading is complete
if (typeof window !== "undefined" && loading) return null
// If no session exists, display access denied message
if (!session) {

View File

@@ -1,4 +1,4 @@
VITE_GITHUB_CLIENT_ID=
VITE_GITHUB_CLIENT_SECRET=
VITE_NEXTAUTH_URL=
VITE_NEXTAUTH_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
NEXTAUTH_SECRET=
PUBLIC_NEXTAUTH_URL=http://localhost:5173

View File

@@ -7,7 +7,7 @@ module.exports = {
"prettier",
],
plugins: ["svelte3", "@typescript-eslint"],
ignorePatterns: ["*.cjs"],
ignorePatterns: ["*.cjs", "build/**/*"],
overrides: [{ files: ["*.svelte"], processor: "svelte3/svelte3" }],
settings: {
"svelte3/typescript": () => require("typescript"),

View File

@@ -4,84 +4,71 @@ NextAuth.js is committed to bringing easy authentication to other frameworks. ht
SvelteKit support with NextAuth.js is currently experimental. This directory contains a minimal, proof-of-concept application. Parts of this is expected to be abstracted away into a package like `@next-auth/sveltekit`
## Running this Demo
- Copy `.env.example` to `.env`
- In `.env`, set `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET`
- See [https://docs.github.com/en/developers/apps/building-oauth-apps/creating-an-oauth-app](https://docs.github.com/en/developers/apps/building-oauth-apps/creating-an-oauth-app))
- When creating the OAuth app, set "Homepage URL" to `http://localhost:5173` and Authorization callack URL to `http://localhost:5173/api/auth/callback/github`
- In `.env`, set `NEXTAUTH_SECRET` to any random string
- Build and run the application: `yarn build && yarn start`
## Existing Project
### Add API route
### Add API Route
To add NextAuth.js to a project create a file called `[...nextauth].js` in routes/api/auth. This contains the dynamic route handler for NextAuth.js which will also contain all of your global NextAuth.js configurations.
To add NextAuth.js to a project create a file called `[...nextauth]/+server.js` in routes/api/auth. This contains the dynamic route handler for NextAuth.js which will also contain all of your global NextAuth.js configurations.
```ts
import NextAuth from "$lib"
import GithubProvider from "next-auth/providers/github"
import { NextAuth, options } from "$lib/next-auth"
const nextAuthOptions = {
// Configure one or more authentication providers
providers: [
GithubProvider({
clientId: import.meta.env.VITE_GITHUB_CLIENT_ID,
clientSecret: import.meta.env.VITE_GITHUB_CLIENT_SECRET,
}),
// ...add more providers here
],
}
export const { get, post } = NextAuth(nextAuthOptions)
export const { GET, POST } = NextAuth(options)
```
### Add [hook](https://kit.svelte.dev/docs/hooks)
```ts
import { getServerSession } from "$lib"
import GithubProvider from "next-auth/providers/github"
import type { Handle } from "@sveltejs/kit"
import { getServerSession, options as nextAuthOptions } from "$lib/next-auth"
const nextAuthOptions = {
providers: [
GithubProvider({
clientId: import.meta.env.VITE_GITHUB_CLIENT_ID,
clientSecret: import.meta.env.VITE_GITHUB_CLIENT_SECRET,
}),
],
}
export async function handle({ event, resolve }) {
export const handle: Handle = async function handle({
event,
resolve,
}): Promise<Response> {
const session = await getServerSession(event.request, nextAuthOptions)
event.locals.session = session
return resolve(event)
}
```
export function getSession(event) {
return event.locals.session || {}
### Load Session from Primary Layout
```ts
// src/lib/routes/+layout.server.ts
import type { LayoutServerLoad } from "./$types"
export const load: LayoutServerLoad = ({ locals }) => {
return {
session: locals.session,
}
}
```
### Protecting a route
### Protecting a Route
```html
<script context="module">
export async function load({ session }) {
const { user } = session
```ts
// src/lib/routes/protected/+page.ts
import { redirect } from "@sveltejs/kit"
import type { PageLoad } from "./$types"
if (!user) {
return {
status: 302,
redirect: "/",
}
}
return {
props: {
session,
},
}
export const load: PageLoad = async ({ parent }) => {
const { session } = await parent()
if (!session?.user) {
throw redirect(302, "/")
}
</script>
<script>
export let session
</script>
<p>Session expiry: {session.expires}</p>
return {}
}
```
## Packaging lib

View File

@@ -1,36 +1,40 @@
{
"name": "sveltekit-nextauth",
"private": true,
"version": "0.0.1",
"scripts": {
"dev": "svelte-kit dev",
"build": "svelte-kit build",
"preview": "svelte-kit preview",
"check": "svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .",
"format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ."
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"start": "HOST=127.0.0.1 PORT=5173 ORIGIN=http://localhost:5173 node ./build",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --check . && eslint .",
"format": "prettier --write ."
},
"devDependencies": {
"@sveltejs/adapter-auto": "next",
"@sveltejs/kit": "next",
"@types/cookie": "^0.4.1",
"@typescript-eslint/eslint-plugin": "^5.10.1",
"@typescript-eslint/parser": "^5.10.1",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-svelte3": "^3.2.1",
"prettier": "^2.5.1",
"prettier-plugin-svelte": "^2.5.0",
"@sveltejs/adapter-auto": "^1.0.0-next.80",
"@sveltejs/adapter-node": "1.0.0-next.96",
"@sveltejs/kit": "1.0.0-next.511",
"@types/cookie": "^0.5.1",
"@typescript-eslint/eslint-plugin": "^5.35.1",
"@typescript-eslint/parser": "^5.35.1",
"eslint": "^8.22.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte3": "^4.0.0",
"prettier": "^2.7.1",
"prettier-plugin-svelte": "^2.7.0",
"svelte": "^3.49.0",
"svelte-check": "^2.2.6",
"svelte-preprocess": "^4.10.1",
"tslib": "^2.3.1",
"typescript": "~4.5.4"
"svelte-check": "^2.8.1",
"svelte-preprocess": "^4.10.7",
"tslib": "^2.4.0",
"typescript": "~4.8.2",
"vite": "^3.1.0"
},
"type": "module",
"dependencies": {
"cookie": "0.4.1",
"next-auth": "workspace:*"
"cookie": "0.5.0",
"next-auth": "latest"
},
"prettier": {
"semi": false,

View File

@@ -1,13 +1,30 @@
/// <reference types="@sveltejs/kit" />
import type {
User as NextAuthUser,
Session as NextAuthSession,
} from "next-auth"
// optionally extend the `user`
interface User extends NextAuthUser {
// add custom fields here
}
interface AppSession extends NextAuthSession {
user: User
}
// See https://kit.svelte.dev/docs/typescript
// for information about these interfaces
declare namespace App {
interface Locals {}
declare global {
declare namespace App {
interface Locals {
session: AppSession
}
interface Platform {}
interface Platform {}
interface Session {}
interface Session extends AppSession {}
interface Stuff {}
interface Stuff {}
}
}

View File

@@ -2,12 +2,11 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="description" content="" />
<link rel="icon" href="%svelte.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%svelte.head%
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body>
<div>%svelte.body%</div>
<div>%sveltekit.body%</div>
</body>
</html>

View File

@@ -1,8 +0,0 @@
/// <reference types="@sveltejs/kit" />
interface ImportMetaEnv {
VITE_GITHUB_CLIENT_ID: string
VITE_GITHUB_CLIENT_SECRET: string
VITE_NEXTAUTH_URL: string
VITE_NEXTAUTH_SECRET: string
}

View File

@@ -0,0 +1,14 @@
import type { Handle } from "@sveltejs/kit"
import { getServerSession, options as nextAuthOptions } from "$lib/next-auth"
export const handle: Handle = async function handle({
event,
resolve,
}): Promise<Response> {
const session = await getServerSession(event.request, nextAuthOptions)
if (session) {
event.locals.session = session
}
return resolve(event)
}

View File

@@ -1,24 +0,0 @@
import { getServerSession } from "$lib"
import type { Session } from "next-auth"
import type { NextAuthOptions } from "next-auth"
import GithubProvider from "next-auth/providers/github"
const nextAuthOptions: NextAuthOptions = {
providers: [
GithubProvider({
clientId: import.meta.env.VITE_GITHUB_CLIENT_ID,
clientSecret: import.meta.env.VITE_GITHUB_CLIENT_SECRET,
}),
],
}
export async function handle({ event, resolve }): Promise<Response> {
const session = await getServerSession(event.request, nextAuthOptions)
event.locals.session = session
return resolve(event)
}
export function getSession(event): Session {
return event.locals.session || {}
}

View File

@@ -1,4 +0,0 @@
import NextAuth, { getServerSession } from "./next-auth"
export default NextAuth
export { getServerSession }

View File

@@ -1,74 +1,103 @@
import type { RequestEvent } from "@sveltejs/kit"
import type { IncomingRequest, NextAuthOptions, Session } from "next-auth"
import type { NextAuthAction } from "next-auth/lib/types"
import type { OutgoingResponse } from "next-auth/core"
import type { ServerLoadEvent } from "@sveltejs/kit"
import type { RequestInternal } from "next-auth"
import type { NextAuthAction, NextAuthOptions } from "next-auth/core/types"
import type { OutgoingResponse as NextAuthResponse } from "next-auth/core"
import { NextAuthHandler } from "next-auth/core"
import GithubProvider from "next-auth/providers/github"
import cookie from "cookie"
import getFormBody from "./utils/get-form-body"
import {
GITHUB_CLIENT_ID,
GITHUB_CLIENT_SECRET,
NEXTAUTH_SECRET,
} from "$env/static/private"
import { PUBLIC_NEXTAUTH_URL } from "$env/static/public"
async function toSvelteKitResponse(
// @ts-expect-error import is exported on .default during SSR
const github = GithubProvider?.default || GithubProvider
export const options: NextAuthOptions = {
providers: [
github({
clientId: GITHUB_CLIENT_ID,
clientSecret: GITHUB_CLIENT_SECRET,
}),
],
}
const toSvelteKitResponse = async <
T extends string | any[] | Record<string, any>
>(
request: Request,
nextAuthResponse: OutgoingResponse<unknown>
) {
const { headers, cookies, body, redirect, status = 200 } = nextAuthResponse
nextAuthResponse: NextAuthResponse<T>
): Promise<Response> => {
const { cookies, redirect } = nextAuthResponse
const response = {
status,
headers: {},
const headers = new Headers()
for (const header of nextAuthResponse?.headers || []) {
// pass headers along from next-auth
headers.set(header.key, header.value)
}
headers?.forEach((header) => {
response.headers[header.key] = header.value
})
// set-cookie header
if (cookies?.length) {
headers.set(
"set-cookie",
cookies
?.map((item) => cookie.serialize(item.name, item.value, item.options))
.join(",") as string
)
}
response.headers["set-cookie"] = cookies?.map((item) => {
return cookie.serialize(item.name, item.value, item.options)
})
let body = undefined
let status = nextAuthResponse.status || 200
if (redirect) {
let formData = null
let formData: FormData | null = null
try {
formData = await request.formData()
formData = getFormBody(formData)
} catch {
// no formData passed
}
if (formData?.json !== "true") {
response.status = 302
response.headers["Location"] = redirect
const { json } = Object.fromEntries(formData ?? [])
if (json !== "true") {
status = 302
headers.set("Location", redirect)
} else {
response["body"] = { url: redirect }
body = { url: redirect }
}
} else {
response["body"] = body
body = nextAuthResponse.body
}
return response
// @ts-expect-error - body is a known HTML document or JSON object
return new Response(body, {
status,
headers,
})
}
async function SKNextAuthHandler(
{ request, url, params }: RequestEvent,
const SKNextAuthHandler = async (
{ request, url, params }: ServerLoadEvent,
options: NextAuthOptions
) {
const nextauth = params.nextauth.split("/")
let body = null
): Promise<Response> => {
const [action, provider] = params.nextauth!.split("/")
let body: FormData | undefined
try {
body = await request.formData()
body = getFormBody(body)
} catch {
// no formData passed
}
options.secret = import.meta.env.VITE_NEXTAUTH_SECRET
const req: IncomingRequest = {
host: import.meta.env.VITE_NEXTAUTH_URL,
body,
options.secret = NEXTAUTH_SECRET
const req: RequestInternal = {
host: PUBLIC_NEXTAUTH_URL,
body: Object.fromEntries(body ?? []),
query: Object.fromEntries(url.searchParams),
headers: request.headers,
method: request.method,
cookies: cookie.parse(request.headers.get("cookie") ?? ""),
action: nextauth[0] as NextAuthAction,
providerId: nextauth[1],
error: nextauth[1],
cookies: cookie.parse(request.headers.get("cookie") || ""),
action: action as NextAuthAction,
providerId: provider,
error: provider,
}
const response = await NextAuthHandler({
@@ -79,19 +108,18 @@ async function SKNextAuthHandler(
return toSvelteKitResponse(request, response)
}
export async function getServerSession(
export const getServerSession = async (
request: Request,
options: NextAuthOptions
): Promise<Session | null> {
options.secret = import.meta.env.VITE_NEXTAUTH_SECRET
const session = await NextAuthHandler<Session>({
): Promise<App.Session | null> => {
options.secret = NEXTAUTH_SECRET
const session = await NextAuthHandler<App.Session>({
req: {
host: import.meta.env.VITE_NEXTAUTH_URL,
host: PUBLIC_NEXTAUTH_URL,
action: "session",
method: "GET",
cookies: cookie.parse(request.headers.get("cookie") ?? ""),
cookies: cookie.parse(request.headers.get("cookie") || ""),
headers: request.headers,
},
options,
@@ -99,16 +127,18 @@ export async function getServerSession(
const { body } = session
if (body && Object.keys(body).length) return body as Session
if (body && Object.keys(body).length) {
return body as App.Session
}
return null
}
export default (
export const NextAuth = (
options: NextAuthOptions
): {
get: (req: RequestEvent) => Promise<unknown>
post: (req: RequestEvent) => Promise<unknown>
GET: (event: ServerLoadEvent) => Promise<unknown>
POST: (event: ServerLoadEvent) => Promise<unknown>
} => ({
get: (req) => SKNextAuthHandler(req, options),
post: (req) => SKNextAuthHandler(req, options),
GET: (event) => SKNextAuthHandler(event, options),
POST: (event) => SKNextAuthHandler(event, options),
})

View File

@@ -1,15 +0,0 @@
// https://dev.to/danawoodman/getting-form-body-data-in-your-sveltekit-endpoints-4a85
export default function getFormBody(
body: FormData | null
): Record<string, any> {
if (!body) return {}
// @ts-expect-error: Entries property type missing
return [...body.entries()].reduce((data, [k, v]) => {
const value = v
if (k in data)
data[k] = Array.isArray(data[k]) ? [...data[k], value] : [data[k], value]
else data[k] = value
return data
}, {})
}

View File

@@ -0,0 +1,7 @@
import type { LayoutServerLoad } from "./$types"
export const load: LayoutServerLoad = ({ locals }) => {
return {
session: locals.session,
}
}

View File

@@ -1,21 +1,24 @@
<script lang="ts">
import { session } from "$app/stores"
import { page } from "$app/stores"
</script>
<div>
<header>
<div class="signedInStatus">
<p class="nojs-show loaded">
{#if Object.keys($session).length}
{#if $session.user.image}
{#if Object.keys($page.data.session || {}).length}
{#if $page.data.session.user.image}
<span
style="background-image: url('{$session.user.image}')"
style="background-image: url('{$page.data.session.user.image}')"
class="avatar"
/>
{/if}
<span class="signedInText">
<small>Signed in as</small><br />
<strong>{$session.user.email || $session.user.name}</strong>
<strong
>{$page.data.session.user.email ||
$page.data.session.user.name}</strong
>
</span>
<a href="/api/auth/signout" class="button">Sign out</a>
{:else}
@@ -38,7 +41,8 @@
:global(body) {
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
"Noto Color Emoji";
padding: 0 1rem 1rem 1rem;
max-width: 680px;
margin: 0 auto;

View File

@@ -1,11 +0,0 @@
import NextAuth from "$lib"
import GithubProvider from "next-auth/providers/github"
export const { get, post } = NextAuth({
providers: [
GithubProvider({
clientId: import.meta.env.VITE_GITHUB_CLIENT_ID,
clientSecret: import.meta.env.VITE_GITHUB_CLIENT_SECRET,
}),
],
})

View File

@@ -0,0 +1,3 @@
import { NextAuth, options } from "$lib/next-auth"
export const { GET, POST } = NextAuth(options)

View File

@@ -1,27 +0,0 @@
<script context="module" lang="ts">
export async function load({ session }) {
const { user } = session
if (!user) {
return {
status: 302,
redirect: "/",
}
}
return {
props: {
session,
},
}
}
</script>
<script lang="ts">
export let session
</script>
<h1>Protected page</h1>
<p>
This is a protected content. You can access this content because you are
signed in.
</p>
<p>Session expiry: {session.expires}</p>

View File

@@ -0,0 +1,10 @@
<script lang="ts">
import { page } from "$app/stores"
</script>
<h1>Protected page</h1>
<p>
This is a protected content. You can access this content because you are
signed in.
</p>
<p>Session expiry: {$page.data.session.expires}</p>

View File

@@ -0,0 +1,10 @@
import { redirect } from "@sveltejs/kit"
import type { PageLoad } from "./$types"
export const load: PageLoad = async ({ parent }) => {
const { session } = await parent()
if (!session?.user) {
throw redirect(302, "/")
}
return {}
}

View File

@@ -1,4 +1,4 @@
import adapter from "@sveltejs/adapter-auto"
import adapter from "@sveltejs/adapter-node" // or use https://github.com/sveltejs/kit/tree/master/packages/adapter-auto
import preprocess from "svelte-preprocess"
/** @type {import('@sveltejs/kit').Config} */
@@ -6,7 +6,6 @@ const config = {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: preprocess(),
kit: {
adapter: adapter(),
},

View File

@@ -1,36 +1,17 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"moduleResolution": "node",
"module": "es2020",
"lib": ["es2020", "DOM"],
"target": "es2020",
/**
svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript
to enforce using \`import type\` instead of \`import\` for Types.
*/
"importsNotUsedAsValues": "error",
/**
TypeScript doesn't know about import usages in the template because it only sees the
script of a Svelte file. Therefore preserve all value imports. Requires TS 4.5 or higher.
*/
"preserveValueImports": true,
"isolatedModules": true,
"resolveJsonModule": true,
/**
To have warnings/errors of the Svelte compiler at the correct position,
enable source maps by default.
*/
"sourceMap": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"allowJs": true,
"checkJs": true,
"paths": {
"$lib": ["src/lib"],
"$lib/*": ["src/lib/*"]
}
},
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.ts", "src/**/*.svelte"]
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}

View File

@@ -0,0 +1,8 @@
import { sveltekit } from "@sveltejs/kit/vite"
import type { UserConfig } from "vite"
const config: UserConfig = {
plugins: [sveltekit()],
}
export default config

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,7 @@ This is the Dgraph Adapter for [`next-auth`](https://next-auth.js.org).
npm install next-auth @next-auth/dgraph-adapter
```
2. Add this adapter to your `pages/api/[...nextauth].js` next-auth configuration object.
2. Add this adapter to your `pages/api/auth/[...nextauth].js` next-auth configuration object.
```javascript title="pages/api/auth/[...nextauth].js"
import NextAuth from "next-auth"

View File

@@ -17,7 +17,7 @@ You can find the Fauna schema and seed information in the docs at [next-auth.js.
npm install next-auth @next-auth/fauna-adapter faunadb
```
2. Add this adapter to your `pages/api/[...nextauth].js` next-auth configuration object.
2. Add this adapter to your `pages/api/auth/[...nextauth].js` next-auth configuration object.
```javascript title="pages/api/auth/[...nextauth].js"
import NextAuth from "next-auth"

View File

@@ -25,7 +25,7 @@ import { FirestoreAdapter } from "@next-auth/firebase-adapter"
// For more information on each option (and a full list of options) go to
// https://next-auth.js.org/configuration/options
export default NextAuth({
// https://next-auth.js.org/providers/overview
// https://next-auth.js.org/providers
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_ID,

View File

@@ -53,12 +53,12 @@ if (process.env.NODE_ENV === "development") {
export default clientPromise
```
3. Add this adapter to your `pages/api/[...nextauth].js` next-auth configuration object.
3. Add this adapter to your `pages/api/auth/[...nextauth].js` next-auth configuration object.
```js
import NextAuth from "next-auth"
import { MongoDBAdapter } from "@next-auth/mongodb-adapter"
import clientPromise from "lib/mongodb"
import clientPromise from "../../../lib/mongodb"
// For more information on each option (and a full list of options) go to
// https://next-auth.js.org/configuration/options

View File

@@ -15,7 +15,7 @@ This is the Neo4j Adapter for [`next-auth`](https://next-auth.js.org). This pack
npm install next-auth @next-auth/neo4j-adapter neo4j-driver
```
2. Add this adapter to your `pages/api/[...nextauth].js` next-auth configuration object.
2. Add this adapter to your `pages/api/auth/[...nextauth].js` next-auth configuration object.
```javascript title="pages/api/auth/[...nextauth].js"
import neo4j from "neo4j-driver"

View File

@@ -12,15 +12,28 @@ npm install next-auth @prisma/client @next-auth/prisma-adapter
npm install prisma --save-dev
```
Create a file with your Prisma Client:
```typescript title="lib/prismadb.ts"
import { PrismaClient } from "@prisma/client"
declare global {
var prisma: PrismaClient | undefined
}
const client = globalThis.prisma || new PrismaClient()
if (process.env.NODE_ENV !== "production") globalThis.prisma = client
export default client
```
Configure your NextAuth.js to use the Prisma Adapter:
```javascript title="pages/api/auth/[...nextauth].js"
import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google"
import { PrismaAdapter } from "@next-auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"
const prisma = new PrismaClient()
import prisma from "../../../lib/prismadb"
export default NextAuth({
adapter: PrismaAdapter(prisma),
@@ -107,6 +120,8 @@ When using the MySQL connector for Prisma, the [Prisma `String` type](https://ww
### Create the database schema with Prisma Migrate
**Warning:** Make sure to back up your database before running using Prisma Migrate.
```
npx prisma migrate dev
```

View File

@@ -19,7 +19,7 @@ npm install next-auth @next-auth/sequelize-adapter sequelize
You'll also have to manually install [the driver for your database](https://sequelize.org/master/manual/getting-started.html) of choice.
:::
2. Add this adapter to your `pages/api/[...nextauth].js` next-auth configuration object.
2. Add this adapter to your `pages/api/auth/[...nextauth].js` next-auth configuration object.
```javascript title="pages/api/auth/[...nextauth].js"
import NextAuth from "next-auth"

View File

@@ -17,12 +17,12 @@ Configure your NextAuth.js to use the Upstash Redis Adapter:
import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google"
import { UpstashRedisAdapter } from "@next-auth/upstash-redis-adapter"
import upstashRedisClient from "@upstash/redis"
import { Redis } from "@upstash/redis"
const redis = upstashRedisClient(
process.env.UPSTASH_REDIS_URL,
process.env.UPSTASH_REDIS_TOKEN
)
const redis = new Redis({
url: process.env.UPSTASH_REDIS_URL,
token: process.env.UPSTASH_REDIS_TOKEN
})
export default NextAuth({
adapter: UpstashRedisAdapter(redis),

View File

@@ -112,15 +112,16 @@ Requests to `/api/auth/signin`, `/api/auth/session` and calls to `getSession()`,
- As with database persisted session expiry times, token expiry time is extended whenever a session is active.
- The arguments _user_, _account_, _profile_ and _isNewUser_ are only passed the first time this callback is called on a new session, after the user signs in. In subsequent calls, only `token` will be available.
The contents _user_, _account_, _profile_ and _isNewUser_ will vary depending on the provider and on if you are using a database or not. You can persist data such as User ID, OAuth Access Token in this token. To make it available in the browser, check out the [`session()` callback](#session-callback) as well.
The contents _user_, _account_, _profile_ and _isNewUser_ will vary depending on the provider and if you are using a database. You can persist data such as User ID, OAuth Access Token in this token, see the example below for `access_token` and `user.id`. To expose it on the client side, check out the [`session()` callback](#session-callback) as well.
```js title="pages/api/auth/[...nextauth].js"
...
callbacks: {
async jwt({ token, account }) {
// Persist the OAuth access_token to the token right after signin
async jwt({ token, account, profile }) {
// Persist the OAuth access_token and or the user id to the token right after signin
if (account) {
token.accessToken = account.access_token
token.id = profile.id
}
return token
}
@@ -134,7 +135,7 @@ Use an if branch to check for the existence of parameters (apart from `token`).
## Session callback
The session callback is called whenever a session is checked. By default, only a subset of the token is returned for increased security. If you want to make something available you added to the token through the `jwt()` callback, you have to explicitly forward it here to make it available to the client.
The session callback is called whenever a session is checked. By default, **only a subset of the token is returned for increased security**. If you want to make something available you added to the token (like `access_token` and `user.id` from above) via the `jwt()` callback, you have to explicitly forward it here to make it available to the client.
e.g. `getSession()`, `useSession()`, `/api/auth/session`
@@ -145,8 +146,10 @@ e.g. `getSession()`, `useSession()`, `/api/auth/session`
...
callbacks: {
async session({ session, token, user }) {
// Send properties to the client, like an access_token from a provider.
// Send properties to the client, like an access_token and user id from a provider.
session.accessToken = token.accessToken
session.user.id = token.id
return session
}
}
@@ -155,7 +158,7 @@ callbacks: {
:::tip
When using JSON Web Tokens the `jwt()` callback is invoked before the `session()` callback, so anything you add to the
JSON Web Token will be immediately available in the session callback, like for example an `access_token` from a provider.
JSON Web Token will be immediately available in the session callback, like for example an `access_token` or `id` from a provider.
:::
:::warning

View File

@@ -12,11 +12,11 @@ Otherwise, if you only want to get the session token, see [`getToken`](/tutorial
`unstable_getServerSession` requires passing the same object you would pass to `NextAuth` when initializing NextAuth.js. To do so, you can export your NextAuth.js options in the following way:
In `[...nextauth.js]`:
In `[...nextauth].ts`:
```ts
import { NextAuth } from 'next-auth'
import type { NextAuthOptions } from 'next-auth'
export const authOptions: NextAuthOptions = {
// your configs
}
@@ -26,7 +26,7 @@ export default NextAuth(authOptions);
In `getServerSideProps`:
```js
import { authOptions } from 'pages/api/[...nextauth]'
import { authOptions } from 'pages/api/auth/[...nextauth]'
import { unstable_getServerSession } from "next-auth/next"
export async function getServerSideProps(context) {
@@ -50,7 +50,7 @@ export async function getServerSideProps(context) {
```
In API routes:
```js
import { authOptions } from 'pages/api/[...nextauth]'
import { authOptions } from 'pages/api/auth/[...nextauth]'
import { unstable_getServerSession } from "next-auth/next"
@@ -137,12 +137,16 @@ Callbacks are asynchronous functions you can use to control what happens when an
Specify URLs to be used if you want to create custom sign in, and error pages. Pages specified will override the corresponding built-in page.
:::note
This should match the `pages` configuration that's found in `[...nextauth].ts`.
:::
#### Example (default value)
```js
pages: {
signIn: '/auth/signin',
error: '/auth/error',
signIn: '/api/auth/signin',
error: '/api/auth/error',
}
```
@@ -156,7 +160,7 @@ See the documentation for the [pages option](/configuration/pages) for more info
#### Description
The same `secret` used in the [NextAuth config](/configuration/options#options).
The same `secret` used in the [NextAuth.js config](/configuration/options#options).
#### Example (default value)

View File

@@ -13,12 +13,12 @@ When deploying to production, set the `NEXTAUTH_URL` environment variable to the
NEXTAUTH_URL=https://example.com
```
If your Next.js application uses a custom base path, specify the route to the API endpoint in full. More informations about the usage of custom base path [here](/getting-started/client#custom-base-path).
If your Next.js application uses a custom base path, specify the route to the API endpoint in full. More information about the usage of custom base path [here](/getting-started/client#custom-base-path).
_e.g. `NEXTAUTH_URL=https://example.com/custom-route/api/auth`_
:::tip
When you're using a custom base path, you will need to pass the `basePath` page prop to the `<SessionProvider>`. More informations [here](/getting-started/client#custom-base-path).
When you're using a custom base path, you will need to pass the `basePath` page prop to the `<SessionProvider>`. More information [here](/getting-started/client#custom-base-path).
:::
:::note
@@ -68,7 +68,7 @@ A random string is used to hash tokens, sign/encrypt cookies and generate crypto
If you set [`NEXTAUTH_SECRET`](#nextauth_secret) as an environment variable, you don't have to define this option.
If no value specified specified in development (and there is no `NEXTAUTH_SECRET` variable either), it uses a hash for all configuration options, including OAuth Client ID / Secrets for entropy.
If no value is specified in development (and there is no `NEXTAUTH_SECRET` variable either), it uses a hash for all configuration options, including OAuth Client ID / Secrets for entropy.
:::warning
Not providing any `secret` or `NEXTAUTH_SECRET` will throw [an error](/errors#no_secret) in production.
@@ -114,6 +114,12 @@ session: {
// Use it to limit write operations. Set to 0 to always update the database.
// Note: This option is ignored if using JSON Web Tokens
updateAge: 24 * 60 * 60, // 24 hours
// The session token is usually either a random UUID or string, however if you
// need a more customized session token string, you can define your own generate function.
generateSessionToken: () => {
return randomUUID?.() ?? randomBytes(32).toString("hex")
}
}
```
@@ -326,7 +332,7 @@ Set debug to `true` to enable debug messages for authentication and database ope
#### Description
Override any of the logger levels (`undefined` levels will use the built-in logger), and intercept logs in NextAuth. You can use this to send NextAuth logs to a third-party logging service.
Override any of the logger levels (`undefined` levels will use the built-in logger), and intercept logs in NextAuth.js. You can use this to send NextAuth.js logs to a third-party logging service.
The `code` parameter for `error` and `warn` are explained in the [Warnings](/warnings) and [Errors](/errors) pages respectively.
@@ -478,6 +484,15 @@ cookies: {
secure: useSecureCookies,
},
},
nonce: {
name: `${cookiePrefix}next-auth.nonce`,
options: {
httpOnly: true,
sameSite: "lax",
path: "/",
secure: useSecureCookies,
},
},
}
```

View File

@@ -80,7 +80,7 @@ TWITTER_ID=YOUR_TWITTER_CLIENT_ID
TWITTER_SECRET=YOUR_TWITTER_CLIENT_SECRET
```
4. Now you can add the provider settings to the NextAuth options object. You can add as many OAuth providers as you like, as you can see `providers` is an array.
4. Now you can add the provider settings to the NextAuth.js options object. You can add as many OAuth providers as you like, as you can see `providers` is an array.
```js title="pages/api/auth/[...nextauth].js"
import TwitterProvider from "next-auth/providers/"
@@ -156,7 +156,7 @@ interface OAuthConfig {
*/
id: string
version: string
profile(profile: P, tokens: TokenSet): Awaitable<User & { id: string }>
profile(profile: P, tokens: TokenSet): Awaitable<User>
checks?: ChecksType | ChecksType[]
clientId: string
clientSecret: string
@@ -173,6 +173,7 @@ interface OAuthConfig {
region?: string
issuer?: string
client?: Partial<ClientMetadata>
allowDangerousEmailAccountLinking?: boolean
}
```
@@ -278,6 +279,10 @@ If your Provider is OpenID Connect (OIDC) compliant, we recommend using the `wel
An advanced option, hopefully you won't need it in most cases. `next-auth` uses `openid-client` under the hood, see the docs on this option [here](https://github.com/panva/node-openid-client/blob/main/docs/README.md#new-clientmetadata-jwks-options).
### `allowDangerousEmailAccountLinking` option
Normally, when you sign in with an OAuth provider and another account with the same email address already exists, the accounts are not linked automatically. Automatic account linking on sign in is not secure between arbitrary providers and is disabled by default (see our [Security FAQ](https://next-auth.js.org/faq#security)). However, it may be desirable to allow automatic account linking if you trust that the provider involved has securely verified the email address associated with the account. Just set `allowDangerousEmailAccountLinking: true` in your provider configuration to enable automatic account linking.
## Using a custom provider
You can use an OAuth provider that isn't built-in by using a custom object.
@@ -404,6 +409,18 @@ GoogleProvider({
})
```
An example of how to enable automatic account linking:
```js title=/api/auth/[...nextauth].js
import GoogleProvider from "next-auth/providers/google"
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
allowDangerousEmailAccountLinking: true,
})
```
### Adding a new built-in provider
If you think your custom provider might be useful to others, we encourage you to open a PR and add it to the built-in list so others can discover it much more easily!

View File

@@ -76,7 +76,11 @@ Please check your OAuth provider and make sure your URLs and other options are
If you are using an OAuth v1 provider, check your OAuth v1 provider settings, especially the OAuth token and OAuth token secret.
#### CALLBACK_OAUTH_ERROR
3. `openid-client` version mismatch
If you are seeing `expected 200 OK with body but no body was returned`, it might have happened due to `openid-client` (which is peer dependency) node version mismatch. For instance, `openid-client` requires `>=14.2.0` for `lts/fermium` and has similar limits for the other versions. For the full list of the compatible node versions please see [package.json](https://github.com/panva/node-openid-client/blob/2a84e46992e1ebeaf685c3f87b65663d126e81aa/package.json#L78).
#### OAUTH_CALLBACK_ERROR
This can occur during the handling of the callback if the `code_verifier` cookie was not found or an invalid state was returned from the OAuth provider.
@@ -132,7 +136,7 @@ The `callbackUrl` provided was either invalid or not defined. See [specifying a
#### JWT_SESSION_ERROR
JWKKeySupport: the key does not support HS512 verify algorithm
JWTKeySupport: the key does not support HS512 verify algorithm
The algorithm used for generating your key isn't listed as supported. You can generate a HS512 key using
@@ -152,7 +156,7 @@ This error occurs when there was an issue deleting the session from the database
---
### Other
### Configuration
#### MISSING_NEXTAUTH_API_ROUTE_ERROR
@@ -164,6 +168,18 @@ Make sure the file is there and the filename is written correctly.
In production, we expect you to define a `secret` property in your configuration. In development, this is shown as a warning for convenience. [Read more](/configuration/options#secret)
#### oauth_callback_error expected 200 OK with body but no body was returned
This error might happen with some of the providers. It happens due to `openid-client`(which is peer dependency) node version mismatch. For instance, `openid-client` requires `>=14.2.0` for `lts/fermium` and has similar limits for the other versions. For the full list of the compatible node versions please see [package.json](https://github.com/panva/node-openid-client/blob/2a84e46992e1ebeaf685c3f87b65663d126e81aa/package.json#L78)
#### AUTH_ON_ERROR_PAGE_ERROR
You have a custom error page defined that was rendered due to an error, but the page also required authentication. To avoid an infinite redirect loop, NextAuth.js bailed out and rendered its default error page instead.
If you are using a Middleware, make sure you include the same `pages` configuration in your `middleware.ts` and `[...nextauth].ts` files. Or use the `matcher` option to only require authentication for certain sites (and exclude your custom error page).
If you do not use a Middleware, make sure you don't try redirecting the user to the sign-in page when hitting your custom error page.
Useful links:
- https://next-auth.js.org/configuration/nextjs#pages
- https://next-auth.js.org/configuration/pages
- https://nextjs.org/docs/advanced-features/middleware#matcher

View File

@@ -83,7 +83,7 @@ NextAuth.js was originally designed for use with Next.js and Serverless. However
**Same root domain, different subdomains**: If you use NextAuth.js on a website with a different subdomain than the rest of your website (e.g. `auth.example.com` vs. `www.example.com`) you will need to set a custom cookie domain policy for the Session Token cookie. (See also: [Cookies](/configuration/options#cookies)).
:::warning
Changing the default cookies domain policy is advanced and can lead to security issues if done correctly. Make sure you're aware of the security implication before proceeding.
Changing the default cookies domain policy can lead to security issues if done incorrectly. Make sure you're aware of the implications before proceeding.
:::
A working example can be found at <a href="https://github.com/vercel/examples/tree/main/solutions/subdomain-auth" target="_blank">this example repo</a>.
@@ -236,6 +236,10 @@ Automatic account linking is not a planned feature of NextAuth.js, however there
Providing support for secure account linking and unlinking of additional providers - which can only be done if a user is already signed in already - was originally a feature in v1.x but has not been present since v2.0, is planned to return in a future release.
:::note
If the user first signs in using Email and then tries to sign in again using an OAuth provider, NextAuth.js default behavior is to allow account linking even if the OAuth account's email address does not match the previous email address of the user.
:::
</p>
</details>
@@ -329,7 +333,7 @@ JSON Web Tokens can be used for session tokens, but are also used for lots of ot
Avoid storing any data in a token that might be problematic if it were to be decrypted in the future.
- If you do not explicitly specify a secret for for NextAuth.js, existing sessions will be invalidated any time your NextAuth.js configuration changes, as NextAuth.js will default to an auto-generated secret. Since v4 this only impacts development and generating a secret is required in production.
- If you do not explicitly specify a secret for NextAuth.js, existing sessions will be invalidated any time your NextAuth.js configuration changes, as NextAuth.js will default to an auto-generated secret. Since v4 this only impacts development and generating a secret is required in production.
</p>

View File

@@ -58,7 +58,7 @@ export default function Component() {
`useSession()` returns an object containing two values: `data` and `status`:
- **`data`**: This can be three values: [`Session`](https://github.com/nextauthjs/next-auth/blob/8ff4b260143458c5d8a16b80b11d1b93baa0690f/types/index.d.ts#L437-L444) / `undefined` / `null`.
- when the session hasn't been fetched yet, `data` will `undefined`
- when the session hasn't been fetched yet, `data` will be `undefined`
- in case it failed to retrieve the session, `data` will be `null`
- in case of success, `data` will be [`Session`](https://github.com/nextauthjs/next-auth/blob/8ff4b260143458c5d8a16b80b11d1b93baa0690f/types/index.d.ts#L437-L444).
- **`status`**: enum mapping to three possible session states: `"loading" | "authenticated" | "unauthenticated"`
@@ -67,7 +67,7 @@ export default function Component() {
Due to the way how Next.js handles `getServerSideProps` and `getInitialProps`, every protected page load has to make a server-side request to check if the session is valid and then generate the requested page (SSR). This increases server load, and if you are good with making the requests from the client, there is an alternative. You can use `useSession` in a way that makes sure you always have a valid session. If after the initial loading state there was no session found, you can define the appropriate action to respond.
The default behavior is to redirect the user to the sign-in page, from where - after a successful login - they will be sent back to the page they started on. You can also define an `onFail()` callback, if you would like to do something else:
The default behavior is to redirect the user to the sign-in page, from where - after a successful login - they will be sent back to the page they started on. You can also define an `onUnauthenticated()` callback, if you would like to do something else:
#### Example
@@ -290,7 +290,7 @@ export default ({ email }) => (
### Specifying a `callbackUrl`
The `callbackUrl` specifies to which URL the user will be redirected after signing in. It defaults to the current URL of a user.
The `callbackUrl` specifies to which URL the user will be redirected after signing in. Defaults to the page URL the sign-in is initiated from.
You can specify a different `callbackUrl` by specifying it as the second argument of `signIn()`. This works for all providers.
@@ -491,6 +491,8 @@ If set to any value other than zero, it specifies in seconds how often the clien
The value for `refetchInterval` should always be lower than the value of the session `maxAge` [session option](/configuration/options#session).
By default, session polling will keep trying, even when the device has no internet access. To circumvent this, you can also set `refetchWhenOffline` to `false`. This will use [`navigator.onLine`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine) to only poll when the device is online.
#### Refetch On Window Focus
The `refetchOnWindowFocus` option can be used to control whether it automatically updates the session state when you switch a focus on tabs/windows.

View File

@@ -11,6 +11,17 @@ The easiest way to get started is to clone the [example app](https://github.com/
## Existing Project
### Install NextAuth
```bash npm2yarn2pnpm
npm install next-auth
```
:::info
If you are using TypeScript, NextAuth.js comes with its types definitions within the package. To learn more about TypeScript for `next-auth`, check out the [TypeScript documentation](/getting-started/typescript)
:::
### Add API route
To add NextAuth.js to a project create a file called `[...nextauth].js` in `pages/api/auth`. This contains the dynamic route handler for NextAuth.js which will also contain all of your global NextAuth.js configurations.
@@ -19,7 +30,7 @@ To add NextAuth.js to a project create a file called `[...nextauth].js` in `page
import NextAuth from "next-auth"
import GithubProvider from "next-auth/providers/github"
export default NextAuth({
export const authOptions = {
// Configure one or more authentication providers
providers: [
GithubProvider({
@@ -28,7 +39,9 @@ export default NextAuth({
}),
// ...add more providers here
],
})
}
export default NextAuth(authOptions)
```
All requests to `/api/auth/*` (`signIn`, `callback`, `signOut`, etc.) will automatically be handled by NextAuth.js.
@@ -97,7 +110,7 @@ To protect an API Route, you can use the [`unstable_getServerSession()`](/config
```javascript title="pages/api/restricted.js" showLineNumbers
import { unstable_getServerSession } from "next-auth/next"
import { authOptions } from "./api/auth/[...nextauth]"
import { authOptions } from "./auth/[...nextauth]"
export default async (req, res) => {
const session = await unstable_getServerSession(req, res, authOptions)
@@ -109,7 +122,7 @@ export default async (req, res) => {
})
} else {
res.send({
error: "You must be sign in to view the protected content on this page.",
error: "You must be signed in to view the protected content on this page.",
})
}
}

View File

@@ -319,7 +319,7 @@ Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.8
**This does not require any changes from the user - these are adapter specific changes only**
The Adapter API has been rewritten and significantly simplified in NextAuth v4. The adapters now have less work to do as some functionality has been migrated to the core of NextAuth, like hashing the [verification token](/adapters/models/#verification-token).
The Adapter API has been rewritten and significantly simplified in NextAuth.js v4. The adapters now have less work to do as some functionality has been migrated to the core of NextAuth, like hashing the [verification token](/adapters/models/#verification-token).
If you are an adapter maintainer or are interested in writing your own adapter, you can find more information about this change in https://github.com/nextauthjs/next-auth/pull/2361 and release https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.22.

View File

@@ -7,11 +7,8 @@ title: Guides
We have internal guides in three levels of difficulty.
```mdx-code-block
import DocCardList from '@theme/DocCardList';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
<DocCardList items={useCurrentSidebarCategory().items}/>
```
- [Basics](/guides/basics)
- [Fullstack](/guides/fullstack)
- [Testing](/guides/testing)
If you can't find what you're looking for here, maybe take a look at our third-party [tutorials](/tutorials) page.

View File

@@ -24,7 +24,11 @@ providers: [
AtlassianProvider({
clientId: process.env.ATLASSIAN_CLIENT_ID,
clientSecret: process.env.ATLASSIAN_CLIENT_SECRET,
scope: "write:jira-work read:jira-work read:jira-user offline_access read:me"
authorization: {
params: {
scope: "write:jira-work read:jira-work read:jira-user offline_access read:me"
}
}
})
]
...

View File

@@ -50,7 +50,7 @@ providers: [
// You can pass any HTML attribute to the <input> tag through the object.
credentials: {
username: { label: "Username", type: "text", placeholder: "jsmith" },
password: { label: "Password", type: "password" }
password: { label: "Password", type: "password" }
},
async authorize(credentials, req) {
// Add logic here to look up the user from the credentials supplied

View File

@@ -15,6 +15,7 @@ The Email provider can be used in conjunction with (or instead of) one or more O
On initial sign in, a **Verification Token** is sent to the email address provided. By default this token is valid for 24 hours. If the Verification Token is used within that time (i.e. by clicking on the link in the email) an account is created for the user and they are signed in.
If someone provides the email address of an _existing account_ when signing in, an email is sent and they are signed into the account associated with that email address when they follow the link in the email.
:::tip
@@ -32,7 +33,7 @@ You can override any of the options to suit your own use case.
## Configuration
1. NextAuth.js does not include `nodemailer` as a dependency, so you'll need to install it yourself if you want to use the Email Provider. Run `npm install nodemailer` or `yarn add nodemailer`.
2. You will need an SMTP account; ideally for one of the [services known to work with `nodemailer`](http://nodemailer.com/smtp/well-known/).
2. You will need an SMTP account; ideally for one of the [services known to work with `nodemailer`](https://community.nodemailer.com/2-0-0-beta/setup-smtp/well-known-services/).
3. There are two ways to configure the SMTP server connection.
You can either use a connection string or a `nodemailer` configuration object.
@@ -71,7 +72,7 @@ EMAIL_SERVER_PORT=587
EMAIL_FROM=noreply@example.com
```
Now you can add the provider settings to the NextAuth options object in the Email Provider.
Now you can add the provider settings to the NextAuth.js options object in the Email Provider.
```js title="pages/api/auth/[...nextauth].js"
import EmailProvider from "next-auth/providers/email";
@@ -223,3 +224,31 @@ providers: [
})
],
```
## Normalizing the email address
By default, NextAuth.js will normalize the email address. It treats values as case-insensitive (which is technically not compliant to the [RFC 2821 spec](https://datatracker.ietf.org/doc/html/rfc2821), but in practice this causes more problems than it solves, eg. when looking up users by e-mail from databases.) and also removes any secondary email address that was passed in as a comma-separated list. You can apply your own normalization via the `normalizeIdentifier` method on the `EmailProvider`. The following example shows the default behavior:
```ts
EmailProvider({
// ...
normalizeIdentifier(identifier: string): string {
// Get the first two elements only,
// separated by `@` from user input.
let [local, domain] = identifier.toLowerCase().trim().split("@")
// The part before "@" can contain a ","
// but we remove it on the domain part
domain = domain.split(",")[0]
return `${local}@${domain}`
// You can also throw an error, which will redirect the user
// to the error page with error=EmailSignin in the URL
// if (identifier.split("@").length > 2) {
// throw new Error("Only one email allowed")
// }
},
})
```
:::warning
Always make sure this returns a single e-mail address, even if multiple ones were passed in.
:::

View File

@@ -15,7 +15,7 @@ https://gitlab.com/-/profile/applications
The **Gitlab Provider** comes with a set of default options:
- [Gitlab Provider options](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/providers/gitlab.js)
- [Gitlab Provider options](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/providers/gitlab.ts)
You can override any of the options to suit your own use case.

View File

@@ -0,0 +1,43 @@
---
id: hubspot
title: HubSpot
---
:::note
HubSpot returns a limited amount of information on the token holder (see [docs](https://legacydocs.hubspot.com/docs/methods/oauth2/get-access-token-information)). One other issue is that the name and profile photo cannot be fetched through API as discussed [here](https://community.hubspot.com/t5/APIs-Integrations/Profile-photo-is-not-retrieved-with-User-API/m-p/325521).
:::
## Documentation
https://developers.hubspot.com/docs/api/oauth-quickstart-guide
## Configuration
You need to have an APP in your Developer Account as described at https://developers.hubspot.com/docs/api/developer-tools-overview
## Options
The **HubSpot Provider** comes with a set of default options:
- [HubSpot Provider options](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/providers/hubspot.ts)
You can override any of the options to suit your own use case.
## Example
```js
import HubspotProvider from "next-auth/providers/hubspot";
...
providers: [
HubspotProvider({
clientId: process.env.HUBSPOT_CLIENT_ID,
clientSecret: process.env.HUBSPOT_CLIENT_SECRET
})
]
...
```
:::warning
The **Redirect URL** under the **Auth** tab on the HubSpot App Settings page must match the callback url which would be http://localhost:3000/api/auth/callback/hubspot for local development. Only one callback URL per Client ID and Client Secret pair is allowed, so it might be easier to create a new app for local development then fiddle with the url changes.
:::

View File

@@ -30,7 +30,7 @@ providers: [
PatreonProvider({
clientId: process.env.PATREON_ID,
clientSecret: process.env.PATREON_SECRET,
}))
})
]
...
```

View File

@@ -0,0 +1,37 @@
---
id: pinterest
title: Pinterest
---
## Documentation
https://developers.pinterest.com/docs/getting-started/authentication/
## Configuration
https://developers.pinterest.com/apps/
## Options
The **Pinterest Provider** comes with a set of default options:
- [Pinterest Provider options](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/providers/pinterest.ts)
You can override any of the options to suit your own use case.
## Example
```ts
import PinterestProvider from "next-auth/providers/pinterest"
...
providers: [
PinterestProvider({
clientId: process.env.PINTEREST_ID,
clientSecret: process.env.PINTEREST_SECRET
})
]
...
:::tip
To use in production, make sure the app has standard API access and not trial access
:::

View File

@@ -7,9 +7,16 @@ title: Reddit
https://www.reddit.com/dev/api/
## Configuration
## App Configuration
https://www.reddit.com/prefs/apps/
1. Visit https://www.reddit.com/prefs/apps/ and create a new web app
2. Provide a name for your web app
3. Provide a redirect uri ending with `/api/auth/callback/reddit`:
![next-auth-reddit-provider-config](https://user-images.githubusercontent.com/200280/185804449-88f8d0f2-35fa-4eb5-8ecc-5e0a6c813954.png)
4. All other fields are optional
5. Click the "create app" button
## Options
@@ -46,27 +53,15 @@ This Provider template only has a one hour access token to it and only has the "
```js
providers: [
{
id: "reddit",
name: "Reddit",
RedditProvider({
clientId: process.env.REDDIT_CLIENT_ID,
clientSecret: process.env.REDDIT_CLIENT_SECRET,
scope: "identity mysubreddits read", //Check Reddit API Documentation for more. The identity scope is required.
type: "oauth",
version: "2.0",
params: { grant_type: "authorization_code" },
accessTokenUrl: " https://www.reddit.com/api/v1/access_token",
authorizationUrl:
"https://www.reddit.com/api/v1/authorize?response_type=code&duration=permanent",
profileUrl: "https://oauth.reddit.com/api/v1/me",
profile: (profile) => {
return {
id: profile.id,
name: profile.name,
email: null,
}
authorization: {
params: {
duration: 'permanent',
},
},
},
}),
]
```

View File

@@ -13,7 +13,7 @@ The **Strava Provider** comes with a set of default options:
- [Strava Provider options](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/providers/strava.js)
You can override any of the options to suit your own use case.
You can override any of the options to suit your own use case. Ensure the redirect_uri configuration fits your needs accordingly.
## Example

View File

@@ -0,0 +1,35 @@
---
id: todoist
title: Todoist
---
## Documentation
https://developer.todoist.com/guides/#oauth
## Configuration
https://developer.todoist.com/appconsole.html
## Options
The **Todoist Provider** comes with a set of default options:
- [Todoist Provider options](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/providers/todoist.ts)
You can override any of the options to suit your own use case.
## Example
```js
import TodoistProvider from "next-auth/providers/todoist";
...
providers: [
TodoistProvider({
clientId: process.env.TODOIST_ID,
clientSecret: process.env.TODOIST_SECRET
})
]
...
```

View File

@@ -0,0 +1,87 @@
---
id: zitadel
title: Zitadel
---
## Documentation
https://docs.zitadel.com/docs/apis/openidoauth/endpoints
## Configuration
https://docs.zitadel.com/docs/guides/integrate/oauth-recommended-flows
The Redirect URIs used when creating the credentials must include your full domain and end in the callback path. For example:
- For production: `https://{YOUR_DOMAIN}/api/auth/callback/zitadel`
- For development: `http://localhost:3000/api/auth/callback/zitadel`
Make sure to enable **dev mode** in ZITADEL console to allow redirects for local development.
## Options
The **ZITADEL Provider** comes with a set of default options:
- [ZITADEL Provider options](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/providers/zitadel.ts)
You can override any of the options to suit your own use case.
## Example
```js
import ZitadelProvider from "next-auth/providers/zitadel";
...
providers: [
ZitadelProvider({
issuer: process.env.ZITADEL_ISSUER,
clientId: process.env.ZITADEL_CLIENT_ID,
clientSecret: process.env.ZITADEL_CLIENT_SECRET,
})
]
...
```
If you need access to ZITADEL APIs or need additional information, make sure to add the corresponding scopes.
To get the full list of supported claims take a look [here](https://docs.zitadel.com/docs/apis/openidoauth/endpoints).
```js
const options = {
...
providers: [
ZitadelProvider({
clientId: process.env.ZITADEL_CLIENT_ID,
authorization: {
params: {
scope: `openid email profile urn:zitadel:iam:org:project:id:${process.env.ZITADEL_PROJECT_ID}:aud`
}
}
})
],
...
}
```
:::
:::tip
ZITADEL also returns a `email_verified` boolean property in the profile.
You can use this property to restrict access to people with verified accounts.
```js
const options = {
...
callbacks: {
async signIn({ account, profile }) {
if (account.provider === "zitadel") {
return profile.email_verified;
}
return true; // Do different verification for other providers that don't have `email_verified`
},
}
...
}
```
:::

View File

@@ -16,7 +16,7 @@ If you contact us regarding a serious issue:
- We will disclose the issue (and credit you, with your consent) once a fix to resolve the issue has been released.
- If 90 days has elapsed and we still don't have a fix, we will disclose the issue publicly.
The best way to report an issue is by contacting us via email at info@balazsorban.com or me@iaincollins.com and yo@ndo.dev, or raise a public issue requesting someone get in touch with you via whatever means you prefer for more details. (Please do not disclose sensitive details publicly at this stage.)
The best way to report an issue is by contacting us via email at hi@thvu.dev, info@balazsorban.com, yo@ndo.dev and me@iaincollins.com, or raise a public issue requesting someone get in touch with you via whatever means you prefer for more details. (Please do not disclose sensitive details publicly at this stage.)
:::note
For less serious issues (e.g. RFC compliance for unsupported flows or potential issues that may cause a problem in the future) it is appropriate to submit these these publically as bug reports or feature requests or to raise a question to open a discussion around them.

View File

@@ -105,6 +105,11 @@ This tutorial covers:
## Database
#### [Create a NextAuth.js Custom Adapter with HarperDB & Next.js](https://spacejelly.dev/posts/how-to-create-a-nextauth-js-custom-adapter-with-harperdb-next-js/) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
- Use a custom database in a Custom Adapter for persisted NextAuth.js sessions using HarperDB as an example.
- Video tutorial also available: <https://www.youtube.com/watch?v=pu7xBv7sZ8s>
#### [Using NextAuth.js with Prisma and PlanetScale serverless databases](https://github.com/planetscale/nextjs-planetscale-starter) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
- How to set up a PlanetScale database to fetch and store user / account data with the Prisma adapter.

View File

@@ -62,11 +62,7 @@ export default NextAuth({
async session({ session, token }) {
return { ...session, user: { username: token.username } }
},
},
secret: process.env.NEXTAUTH_SECRET,
jwt: {
secret: process.env.JWT_SECRET,
},
}
})
```
@@ -77,7 +73,6 @@ This is then passed back to any API routes and retrieved as such:
```js title="/pages/api/doLDAPWork.js"
token = await jwt.getToken({
req,
secret: process.env.NEXTAUTH_SECRET,
})
const { username, password } = token
```

View File

@@ -17,7 +17,7 @@ Using a [JWT callback](https://next-auth.js.org/configuration/callbacks#jwt-call
Below is a sample implementation using Google's Identity Provider. Please note that the OAuth 2.0 request in the `refreshAccessToken()` function will vary between different providers, but the core logic should remain similar.
```js title="pages/auth/[...nextauth.js]"
```js title="pages/api/auth/[...nextauth].js"
import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google"

View File

@@ -29,6 +29,7 @@ callbacks: {
async session({ session, token, user }) {
session.user.role = user.role; // Add role value to user object so it is passed along with session
return session;
}
},
```

View File

@@ -42,18 +42,30 @@ export default function Page() {
### Next.js (Middleware)
With NextAuth.js 4.2.0 and Next.js 12, you can now protect your pages via the middleware pattern more easily. If you would like to protect all pages, you can create a `_middleware.js` file in your root `pages` directory which looks like this.
With NextAuth.js 4.2.0 and Next.js 12, you can now protect your pages via the middleware pattern more easily. If you would like to protect all pages, you can create a `middleware.js` file in your root `pages` directory which looks like this:
```js title="/middleware.js"
export { default } from "next-auth/middleware"
```
Otherwise, if you only want to protect a subset of pages, you could put it in a subdirectory as well, for example in `/pages/admin/_middleware.js` would protect all pages under `/admin`.
If you only want to secure certain pages, export a `config` object with a `matcher`:
```js
export { default } from "next-auth/middleware"
export const config = { matcher: ["/dashboard"] }
```
For the time being, the `withAuth` middleware only supports `"jwt"` as [session strategy](https://next-auth.js.org/configuration/options#session).
More details can be found [here](https://next-auth.js.org/configuration/nextjs#middleware).
:::tip
To inclue all `dashboard` nested routes (sub pages like `/dashboard/settings`, `/dashboard/profile`) you can pass `matcher: "/dashboard/:path*"` to `config`.
For other patterns check out the [Next.js Middleware documentation](https://nextjs.org/docs/advanced-features/middleware#matcher).
:::
### Server Side
You can protect server side rendered pages using the `unstable_getServerSession` method. This is different from the old `getSession()` method, in that it does not do an extra fetch out over the internet to confirm data from itself, increasing performance significantly.
@@ -122,7 +134,7 @@ You can protect API routes using the `unstable_getServerSession()` method.
```js title="pages/api/get-session-example.js"
import { unstable_getServerSession } from "next-auth/next"
import { authOptions } from "./api/auth/[...nextauth]"
import { authOptions } from "./auth/[...nextauth]"
export default async (req, res) => {
const session = await unstable_getServerSession(req, res, authOptions)

View File

@@ -1,3 +1,4 @@
/** @type {import("@docusaurus/types").Config} */
module.exports = {
title: "NextAuth.js",
tagline: "Authentication for Next.js",
@@ -6,6 +7,8 @@ module.exports = {
favicon: "img/favicon.ico",
organizationName: "nextauthjs",
projectName: "next-auth",
// TODO: remove this once BETA is ready
onBrokenLinks: "log",
themeConfig: {
prism: {
theme: require("prism-react-renderer/themes/vsDark"),
@@ -30,6 +33,33 @@ module.exports = {
src: "img/logo/logo-xs.png",
},
items: [
// TODO: This is the new navigation for the BETA Docs.
// Add an env var at build time to switch between this nav
// and the old at build time.
// {
// to: "/beta/getting-started/introduction",
// activeBasePath: "/beta/getting-started/",
// label: "Getting started",
// position: "left",
// },
// {
// to: "/beta/guides/overview",
// activeBasePath: "/beta/guides/",
// label: "Guides",
// position: "left",
// },
// {
// to: "/beta/reference/index",
// activeBasePath: "/beta/reference",
// label: "Reference",
// position: "left",
// },
// {
// to: "/beta/concepts/faq",
// activeBasePath: "/beta/concepts",
// label: "Concepts",
// position: "left",
// },
{
to: "/getting-started/introduction",
activeBasePath: "docs",
@@ -166,6 +196,10 @@ module.exports = {
v3: {
label: "v3",
},
beta: {
label: "v4-unreleased",
banner: "unreleased",
},
},
},
theme: {

View File

@@ -1,10 +1,11 @@
{
"name": "next-auth-docs",
"version": "0.2.0",
"private": true,
"repository": {
"type": "git",
"url": "git://github.com/nextauthjs/docs.git"
"url": "git://github.com/nextauthjs/next-auth.git"
},
"name": "next-auth-docs",
"version": "0.2.0",
"scripts": {
"start": "npm run generate-providers && docusaurus start --no-open --port 8000",
"dev": "npm run start",
@@ -19,9 +20,6 @@
"generate-providers": "node ./scripts/generate-providers.js"
},
"dependencies": {
"@docusaurus/core": "^2.0.0-beta.21",
"@docusaurus/preset-classic": "^2.0.0-beta.21",
"@docusaurus/theme-common": "2.0.0-beta.21",
"@mdx-js/react": "1.6.22",
"@sapphire/docusaurus-plugin-npm2yarn2pnpm": "1.1.3",
"classnames": "^2.3.1",
@@ -35,8 +33,11 @@
"styled-components": "5.3.3"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "2.0.0-beta.20",
"prettier": "^2.6.2"
"@docusaurus/core": "2.1.0",
"@docusaurus/module-type-aliases": "2.1.0",
"@docusaurus/preset-classic": "2.1.0",
"@docusaurus/theme-common": "2.1.0",
"@docusaurus/types": "2.1.0"
},
"browserslist": {
"production": [
@@ -49,9 +50,5 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"prettier": {
"semi": false,
"singleQuote": false
}
}

View File

@@ -49,7 +49,7 @@ const ProviderMarquee = React.memo(() => {
>
{icons.map((icon) => (
<Motion
key={`marquee-example-company-${icon}`}
key={`company-${icon}`}
initDeg={randomIntFromInterval(0, 360)}
direction={Math.random() > 0.5 ? "clockwise" : "counterclockwise"}
velocity={10}

View File

@@ -49,7 +49,7 @@ const features = [
<ul>
<li>Signed, prefixed, server-only cookies</li>
<li>HTTP POST + CSRF Token validation</li>
<li>JWT with JWS / JWE / JWK / JWK</li>
<li>JWT with JWS / JWE / JWK</li>
<li>Tab syncing, auto-revalidation, keepalives</li>
<li>Doesn't rely on client side JavaScript</li>
</ul>

View File

@@ -16,6 +16,15 @@
"value": "1; mode=block"
}
]
},
{
"source": "/beta(.*)",
"headers": [
{
"key": "X-Robots-Tag",
"value": "noindex"
}
]
}
],
"redirects": [

View File

@@ -0,0 +1,361 @@
---
id: faq
title: Frequently Asked Questions
---
## About NextAuth.js
### Is NextAuth.js commercial software?
NextAuth.js is an open source project built by individual contributors.
It is not commercial software and is not associated with a commercial organization.
---
## Compatibility
<details>
<summary>
<h3 style={{display:"inline-block"}}>What databases does NextAuth.js support?</h3>
</summary>
<p>
You can use NextAuth.js with MySQL, MariaDB, Postgres, MongoDB and SQLite or without a database. (See also: [Databases](/configuration/databases))
You can use also NextAuth.js with any database using a custom database adapter, or by using a custom credentials authentication provider - e.g. to support signing in with a username and password stored in an existing database.
</p>
</details>
<details>
<summary>
<h3 style={{display:"inline-block"}}>What authentication services does NextAuth.js support?</h3>
</summary>
<p>
<p>NextAuth.js includes built-in support for signing in with&nbsp;
--------- DISPLAY PROVIDERS HERE ----------
(See also: <a href="/configuration/providers/oauth">Providers</a>)
</p>
NextAuth.js also supports email for passwordless sign in, which is useful for account recovery or for people who are not able to use an account with the configured OAuth services (e.g. due to service outage, account suspension or otherwise becoming locked out of an account).
You can also use a custom based provider to support signing in with a username and password stored in an external database and/or using two factor authentication.
</p>
</details>
<details>
<summary>
<h3 style={{display:"inline-block"}}>Does NextAuth.js support signing in with a username and password?</h3>
</summary>
<p>
NextAuth.js is designed to avoid the need to store passwords for user accounts.
If you have an existing database of usernames and passwords, you can use a custom credentials provider to allow signing in with a username and password stored in an existing database.
_If you use a custom credentials provider user accounts will not be persisted in a database by NextAuth.js (even if one is configured). The option to use JSON Web Tokens for session tokens (which allow sign in without using a session database) must be enabled to use a custom credentials provider._
</p>
</details>
<details>
<summary>
<h3 style={{display:"inline-block"}}>Can I use NextAuth.js with a website that does not use Next.js?</h3>
</summary>
<p>
NextAuth.js is designed for use with Next.js and Serverless.
If you are using a different framework for your website, you can create a website that handles sign in with Next.js and then access those sessions on a website that does not use Next.js as long as the websites are on the same domain.
If you use NextAuth.js on a website with a different subdomain then the rest of your website (e.g. `auth.example.com` vs `www.example.com`) you will need to set a custom cookie domain policy for the Session Token cookie. (See also: [Cookies](/configuration/options#cookies))
NextAuth.js does not currently support automatically signing into sites on different top level domains (e.g. `www.example.com` vs `www.example.org`) using a single session.
</p>
</details>
<details>
<summary>
<h3 style={{display:"inline-block"}}>Can I use NextAuth.js with React Native?</h3>
</summary>
<p>
NextAuth.js is designed as a secure, confidential client and implements a server side authentication flow.
It is not intended to be used in native applications on desktop or mobile applications, which typically implement public clients (e.g. with client / secrets embedded in the application).
</p>
</details>
<details>
<summary>
<h3 style={{display:"inline-block"}}>Is NextAuth.js supporting TypeScript?</h3>
</summary>
<p>
Yes! Check out the [TypeScript docs](/getting-started/typescript)
</p>
</details>
<details>
<summary>
<h3 style={{display:"inline-block"}}>Is NextAuth.js compatible with Next.js 12 Middleware?</h3>
</summary>
<p>
[Next.js Middleware](https://nextjs.org/docs/middleware) is supported. Head over to the [this page](/configuration/nextjs#middleware)
</p>
</details>
---
## Databases
<details>
<summary>
<h3 style={{display:"inline-block"}}>What databases are supported by NextAuth.js?</h3>
</summary>
<p>
NextAuth.js can be used with MySQL, Postgres, MongoDB, SQLite and compatible databases (e.g. MariaDB, Amazon Aurora, Amazon DocumentDB…) or with no database.
It also provides an Adapter API which allows you to connect it to any database.
</p>
</details>
<details>
<summary>
<h3 style={{display:"inline-block"}}>What does NextAuth.js use databases for?</h3>
</summary>
<p>
Databases in NextAuth.js are used for persisting users, OAuth accounts, email sign in tokens and sessions.
Specifying a database is optional if you don't need to persist user data or support email sign in. If you don't specify a database then JSON Web Tokens will be enabled for session storage and used to store session data.
If you are using a database with NextAuth.js, you can still explicitly enable JSON Web Tokens for sessions (instead of using database sessions).
</p>
</details>
<details>
<summary>
<h3 style={{display:"inline-block"}}>Should I use a database?</h3>
</summary>
<p>
- Using NextAuth.js without a database works well for internal tools - where you need to control who is able to sign in, but when you do not need to create user accounts for them in your application.
- Using NextAuth.js with a database is usually a better approach for a consumer facing application where you need to persist accounts (e.g. for billing, to contact customers, etc).
</p>
</details>
<details>
<summary>
<h3 style={{display:"inline-block"}}>What database should I use?</h3>
</summary>
<p>
Managed database solutions for MySQL, Postgres and MongoDB (and compatible databases) are well supported from cloud providers such as Amazon, Google, Microsoft and Atlas.
If you are deploying directly to a particular cloud platform you may also want to consider serverless database offerings they have (e.g. [Amazon Aurora Serverless on AWS](https://aws.amazon.com/rds/aurora/serverless/)).
</p>
</details>
---
## Security
Parts of this section has been moved to its [own page](/security).
<details>
<summary>
<h3 style={{display:"inline-block"}}>How do I get Refresh Tokens and Access Tokens for an OAuth account?</h3>
</summary>
<p>
NextAuth.js provides a solution for authentication, session management and user account creation.
NextAuth.js records Refresh Tokens and Access Tokens on sign in (if supplied by the provider) and it will pass them, along with the User ID, Provider and Provider Account ID, to either:
1. A database - if a database connection string is provided
2. The JSON Web Token callback - if JWT sessions are enabled (e.g. if no database specified)
You can then look them up from the database or persist them to the JSON Web Token.
Note: NextAuth.js does not currently handle Access Token rotation for OAuth providers for you, however you can check out [this tutorial](/tutorials/refresh-token-rotation) if you want to implement it.
We also have an [example repository](https://github.com/nextauthjs/next-auth-refresh-token-example) / project based upon NextAuth.js v4 where we demonstrate how to use a refresh token to refresh the provided access token.
</p>
</details>
<details>
<summary>
<h3 style={{display:"inline-block"}}>When I sign in with another account with the same email address, why are accounts not linked automatically?</h3>
</summary>
<p>
Automatic account linking on sign in is not secure between arbitrary providers - with the exception of allowing users to sign in via an email addresses as a fallback (as they must verify their email address as part of the flow).
When an email address is associated with an OAuth account it does not necessarily mean that it has been verified as belonging to account holder — how email address verification is handled is not part of the OAuth specification and varies between providers (e.g. some do not verify first, some do verify first, others return metadata indicating the verification status).
With automatic account linking on sign in, this can be exploited by bad actors to hijack accounts by creating an OAuth account associated with the email address of another user.
For this reason it is not secure to automatically link accounts between arbitrary providers on sign in, which is why this feature is generally not provided by authentication service and is not provided by NextAuth.js.
Automatic account linking is seen on some sites, sometimes insecurely. It can be technically possible to do automatic account linking securely if you trust all the providers involved to ensure they have securely verified the email address associated with the account, but requires placing trust (and transferring the risk) to those providers to handle the process securely.
Examples of scenarios where this is secure include with an OAuth provider you control (e.g. that only authorizes users internal to your organization) or with a provider you explicitly trust to have verified the users email address.
Automatic account linking is not a planned feature of NextAuth.js, however there is scope to improve the user experience of account linking and of handling this flow, in a secure way. Typically this involves providing a fallback option to sign in via email, which is already possible (and recommended), but the current implementation of this flow could be improved on.
Providing support for secure account linking and unlinking of additional providers - which can only be done if a user is already signed in already - was originally a feature in v1.x but has not been present since v2.0, is planned to return in a future release.
</p>
</details>
---
## Feature Requests
<details>
<summary>
<h3 style={{display:"inline-block"}}>Why doesn't NextAuth.js support [a particular feature]?</h3>
</summary>
<p>
NextAuth.js is an open source project built by individual contributors who are volunteers writing code and providing support in their spare time.
If you would like NextAuth.js to support a particular feature, the best way to help make it happen is to raise a feature request describing the feature and offer to work with other contributors to develop and test it.
If you are not able to develop a feature yourself, you can offer to sponsor someone to work on it.
</p>
</details>
<details>
<summary>
<h3 style={{display:"inline-block"}}>I disagree with a design decision, how can I change your mind?</h3>
</summary>
<p>
Product design decisions on NextAuth.js are made by core team members.
You can raise suggestions as feature requests / requests for enhancement.
Requests that provide the detail requested in the template and follow the format requested may be more likely to be supported, as additional detail prompted in the templates often provides important context.
Ultimately if your request is not accepted or is not actively in development, you are always free to fork the project under the terms of the ISC License.
</p>
</details>
---
## JSON Web Tokens
<details>
<summary>
<h3>Does NextAuth.js use JSON Web Tokens?</h3>
</summary>
<p>
NextAuth.js by default uses JSON Web Tokens for saving the user's session. However, if you use a [database adapter](/adapters/overview), the database will be used to persist the user's session. You can force the usage of JWT when using a database [through the configuration options](/configuration/options#session). Since v4 all our JWT tokens are now encrypted by default with A256GCM.
</p>
</details>
<details>
<summary>
<h3>What are the advantages of JSON Web Tokens?</h3>
</summary>
<p>
JSON Web Tokens can be used for session tokens, but are also used for lots of other things, such as sending signed objects between services in authentication flows.
- Advantages of using a JWT as a session token include that they do not require a database to store sessions, this can be faster and cheaper to run and easier to scale.
- JSON Web Tokens in NextAuth.js are secured using cryptographic encryption (JWE) to store the included information directly in a JWT session token. You may then use the token to pass information between services and APIs on the same domain without having to contact a database to verify the included information.
- You can use JWT to securely store information you do not mind the client knowing even without encryption, as the JWT is stored in a server-readable-only cookie so data in the JWT is not accessible to third party JavaScript running on your site.
</p>
</details>
<details>
<summary>
<h3>What are the disadvantages of JSON Web Tokens?</h3>
</summary>
<p>
- You cannot as easily expire a JSON Web Token - doing so requires maintaining a server side blocklist of invalid tokens (at least until they expire) and checking every token against the list every time a token is presented.
Shorter session expiry times are used when using JSON Web Tokens as session tokens to allow sessions to be invalidated sooner and simplify this problem.
NextAuth.js client includes advanced features to mitigate the downsides of using shorter session expiry times on the user experience, including automatic session token rotation, optionally sending keep alive messages to prevent short lived sessions from expiring if there is an window or tab open, background re-validation, and automatic tab/window syncing that keeps sessions in sync across windows any time session state changes or a window or tab gains or loses focus.
- As with database session tokens, JSON Web Tokens are limited in the amount of data you can store in them. There is typically a limit of around 4096 bytes per cookie, though the exact limit varies between browsers, proxies and hosting services. If you want to support most browsers, then do not exceed 4096 bytes per cookie. If you want to save more data, you will need to persist your sessions in a database (Source: [browsercookielimits.iain.guru](http://browsercookielimits.iain.guru/))
The more data you try to store in a token and the more other cookies you set, the closer you will come to this limit. Since v4 we have implemented cookie chunking so that cookies over the 4kb limit get split and reassembled upon parsing. However since this data needs to be transmitted on every request, if you wish to store more than ~4 KB of data you're probably at the point where you want to store a unique ID in the token and persist the data elsewhere (e.g. in a server-side key/value store).
- Data stored in an encrypted JSON Web Token (JWE) may be compromised at some point.
Even if appropriately configured, information stored in an encrypted JWT should not be assumed to be impossible to decrypt at some point - e.g. due to the discovery of a defect or advances in technology.
Avoid storing any data in a token that might be problematic if it were to be decrypted in the future.
- If you do not explicitly specify a secret for for NextAuth.js, existing sessions will be invalidated any time your NextAuth.js configuration changes, as NextAuth.js will default to an auto-generated secret. Since v4 this only impacts development and generating a secret is required in production.
</p>
</details>
<details>
<summary>
<h3>Are JSON Web Tokens secure?</h3>
</summary>
<p>
By default tokens are not signed (JWS) but are encrypted (JWE). Since v4 we have implemented cookie chunking so that cookies over the 4kb limit get split and reassembled upon parsing.
You can specify other valid algorithms - [as specified in RFC 7518](https://tools.ietf.org/html/rfc7517) - with either a secret (for symmetric encryption) or a public/private key pair (for asymmetric encryption).
NextAuth.js will generate keys for you, but this will generate a warning at start up.
Using explicit public/private keys for signing is strongly recommended.
</p>
</details>
<details>
<summary>
<h3>What signing and encryption standards does NextAuth.js support?</h3>
</summary>
<p>
NextAuth.js includes a largely complete implementation of JSON Object Signing and Encryption (JOSE):
- [RFC 7515 - JSON Web Signature (JWS)](https://tools.ietf.org/html/rfc7515)
- [RFC 7516 - JSON Web Encryption (JWE)](https://tools.ietf.org/html/rfc7516)
- [RFC 7517 - JSON Web Key (JWK)](https://tools.ietf.org/html/rfc7517)
- [RFC 7518 - JSON Web Algorithms (JWA)](https://tools.ietf.org/html/rfc7518)
- [RFC 7519 - JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519)
This incorporates support for:
- [RFC 7638 - JSON Web Key Thumbprint](https://tools.ietf.org/html/rfc7638)
- [RFC 7787 - JSON JWS Unencoded Payload Option](https://tools.ietf.org/html/rfc7797)
- [RFC 8037 - CFRG Elliptic Curve ECDH and Signatures](https://tools.ietf.org/html/rfc8037)
</p>
</details>

View File

@@ -0,0 +1,50 @@
---
title: How OAuth works
---
Authentication Providers in **NextAuth.js** are OAuth definitions that allow your users to sign in with their favorite preexisting logins. You can use any of our many predefined providers, or write your own custom OAuth configuration.
- [Using a built-in OAuth Provider](#built-in-providers) (e.g Github, Twitter, Google, etc...)
- [Using a custom OAuth Provider](#using-a-custom-provider)
:::note
NextAuth.js is designed to work with any OAuth service, it supports **OAuth 1.0**, **1.0A**, **2.0** and **OpenID Connect** and has built-in support for most popular sign-in services.
:::
Without going into too much detail, the OAuth flow generally has 6 parts:
1. The application requests authorization to access service resources from the user
2. If the user authorized the request, the application receives an authorization grant
3. The application requests an access token from the authorization server (API) by presenting authentication of its own identity, and the authorization grant
4. If the application identity is authenticated and the authorization grant is valid, the authorization server (API) issues an access token to the application. Authorization is complete.
5. The application requests the resource from the resource server (API) and presents the access token for authentication
6. If the access token is valid, the resource server (API) serves the resource to the application
```mermaid
sequenceDiagram
participant Browser
participant App Server
participant Auth Server (Github)
Note left of Browser: User clicks on "Sign in"
Browser->>App Server: GET<br/>"api/auth/signin"
App Server->>App Server: Computes the available<br/>sign in providers<br/>from the "providers" option
App Server->>Browser: Redirects to Sign in page
Note left of Browser: Sign in options<br/>are shown the user<br/>(Github, Twitter, etc...)
Note left of Browser: User clicks on<br/>"Sign in with Github"
Browser->>App Server: POST<br/>"api/auth/signin/github"
App Server->>App Server: Computes sign in<br/>options for Github<br/>(scopes, callback URL, etc...)
App Server->>Auth Server (Github): GET<br/>"github.com/login/oauth/authorize"
Note left of Auth Server (Github): Sign in options<br> are supplied as<br/>query params<br/>(clientId, <br/>scope, etc...)
Auth Server (Github)->>Browser: Shows sign in page<br/>in Github.com<br/>to the user
Note left of Browser: User inserts their<br/>credentials in Github
Browser->>Auth Server (Github): Github validates the inserted credentials
Auth Server (Github)->>Auth Server (Github): Generates one time access code<br/>and calls callback<br>URL defined in<br/>App settings
Auth Server (Github)->>App Server: GET<br/>"api/auth/github/callback?code=123"
App Server->>App Server: Grabs code<br/>to exchange it for<br/>access token
App Server->>Auth Server (Github): POST<br/>"github.com/login/oauth/access_token"<br/>{code: 123}
Auth Server (Github)->>Auth Server (Github): Verifies code is<br/>valid and generates<br/>access token
Auth Server (Github)->>App Server: { access_token: 16C7x... }
App Server->>App Server: Generates session token<br/>and stores session
App Server->>Browser: You're now logged in!
```
For more details, check out Aaron Parecki's blog post [OAuth2 Simplified](https://aaronparecki.com/oauth-2-simplified/) or Postman's blog post [OAuth 2.0: Implicit Flow is Dead, Try PKCE Instead](https://blog.postman.com/pkce-oauth-how-to/).

View File

@@ -0,0 +1,55 @@
---
title: Introduction
---
## About NextAuth.js
NextAuth.js is a complete open-source authentication solution for [Next.js](http://nextjs.org/) applications.
It is designed from the ground up to support Next.js and Serverless.
[Check out the example code](/getting-started/example) to see how easy it is to use NextAuth.js for authentication.
### Flexible and easy to use
- Designed to work with any [OAuth service, it supports OAuth 1.0, 1.0A, 2.0 and OpenID Connect](/providers)
- Built-in support for [many popular sign-in services](/configuration/providers/oauth)
- Supports [email / passwordless authentication](/providers/email)
- Supports stateless authentication with [any backend](/adapters/overview) (Active Directory, LDAP, etc)
- Supports both JSON Web Tokens and database sessions
- Designed for Serverless but runs anywhere (AWS Lambda, Docker, Heroku, etc…)
### Own your own data
NextAuth.js can be used with or without a database.
- An open-source solution that allows you to keep control of your data
- Supports Bring Your Own Database (BYOD) and can be used with any database
- Built-in support for [MySQL, MariaDB, Postgres, SQL Server, MongoDB and SQLite](/configuration/databases)
- Works great with databases from popular hosting providers
- Can also be used _without a database_ (e.g. OAuth + JWT)
_Note: Email sign-in requires a database to be configured to store single-use verification tokens._
### Secure by default
- Promotes the use of passwordless sign-in mechanisms
- Designed to be secure by default and encourage best practices for safeguarding user data
- Uses Cross-Site Request Forgery Tokens on POST routes (sign in, sign out)
- Default cookie policy aims for the most restrictive policy appropriate for each cookie
- When JSON Web Tokens are enabled, they are encrypted by default (JWE) with A256GCM
- Auto-generates symmetric signing and encryption keys for developer convenience
- Features tab/window syncing and keepalive messages to support short-lived sessions
- Attempts to implement the latest guidance published by [Open Web Application Security Project](https://owasp.org/)
Advanced options allow you to define your own routines to handle controlling what accounts are allowed to sign in, for encoding and decoding JSON Web Tokens and to set custom cookie security policies and session properties, so you can control who can sign in and how often sessions have to be re-validated.
## Credits
NextAuth.js is an open-source project that is only possible [thanks to contributors](/contributors).
If you would like to financially support the development of NextAuth.js, you can find more information on our [OpenCollective](https://opencollective.com/nextauth) page.
## Getting Started
[Check out the example code](/getting-started/example) to see how easy it is to use NextAuth.js for authentication.

View File

@@ -0,0 +1,291 @@
---
title: OAuth authentication
---
import creatingOauthAppImg from "./img/getting-started-creating-oauth-app.png"
import addingCallbackUrlImg from "./img/getting-started-oauth-callback-url.png"
import gettingClientIdSecretImg from "./img/getting-started-oauth-clientid-secret.png"
import startAppAndSignInImg from "./img/getting-started-app-start.png"
import githubAuthCredentials from "./img/getting-started-github-auth.png"
import nextAuthUserLoggedIn from "./img/getting-started-nextauth-success.png"
We know, authentication is hard. Is a rabbit hole and it's easy to get lost on it. The goal of making NextAuth.js is that you can add authentication easily to your project with just a few lines of code.
The easiest way is to setup NextAuth.js with an [OAuth](https://en.wikipedia.org/wiki/OAuth) provider. In this tutorial we'll be setting NextAuth.js in a **Next.js app** to be able to login with **Github**.
:::info
NextAuth.js comes with a long list of [built-in providers](/reference/Providers/) (Google, Facebook, Twitter, etc...) you can also integrate it with your own OAuth service easily by [building a custom provider](/beta/guides/oauth/custom-provider). NextAuth.js can integrate as well with other frameworks like SvelteKit and Gatsby.
:::
## 1. Configuring NextAuth.js
### Creating the server config
To add NextAuth.js to a [**Next.js**](https://nextjs.org/) project, create the following [API route](https://nextjs.org/docs/api-routes/introduction):
```
pages/api/auth/[...nextauth].ts
```
This route will contain the **dynamic route handler** for NextAuth.js which describes your global auth configuration:
```ts title="pages/api/auth/[...nextauth].js"
import NextAuth from "next-auth"
import GithubProvider from "next-auth/providers/github"
export default NextAuth({
providers: [
GithubProvider({
clientId: /* We'll fill this later */,
clientSecret: /* We'll fill this later*/,
}),
],
})
```
Behind the scenes this creates all the relevant OAuth API routes within `/api/auth/*` so that auth API requests to:
- `/api/auth/callback`
- `/api/auth/signIn`
- `/api/auth/singOut`
- etc...
can be handled by NextAuth.js. In this way, NextAuth.js stays in charge of handling the whole authentication request/response flow of your application for you.
You may notice there are some environment variables in the code example above. `GITHUB_ID` and `GITHUB_SECRET` are provided by the OAuth provider (in this case **Github**) see ["Configuring OAuth Provider"](/getting-started/oauth-tutorial#2-configuring-oauth-provider) section on how to get those.
`NEXTAUTH_SECRET` is a random string used by the library to encrypt tokens and email verification hashes, and **it's mandatory to keep things secure**! 🔥 🔐 . You can use:
```
$ openssl rand -base64 32
```
or https://generate-secret.vercel.app/32 to generate a random value for it.
:::info
NextAuth.js is extremely customizable, [our guides section](/beta/guides/overview) will teach you how you can set it up to handle auth in different ways. All the possible configuration options are [listed here](/reference/server/configuration).
:::
### Exposing the session via provider
To be able to use `useSession` first you'll need to expose the session context, [`<SessionProvider />`](/getting-started/client#sessionprovider), at the top level of your application:
```ts title="pages/_app.ts"
import { SessionProvider } from "next-auth/react"
export default function App({
Component,
pageProps: { session, ...pageProps },
}) {
return (
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
)
}
```
Instances of `useSession` (more on it in the next section) will then have access to the session data and status. The `<SessionProvider />` also takes care of keeping the session updated and synced between browser tabs and windows. 💪🏽
:::tip
Check our [client docs](/reference/client/introduction) to learn all the available options for handling sessions on the browser.
:::
### Consuming the session via hooks
NextAuth.js exposes a [`useSession()`](/getting-started/client#usesession) React Hook so that you can easily check if someone is signed in:
```ts title="pages/overview.tsx"
import { useSession, signIn, signOut } from "next-auth/react"
export default function CamperVanPage() {
const { data: session, status } = useSession()
const userEmail = session.user.email
if (status === "loading") {
return <p>Hang on there...</p>
}
if (status === "authenticated") {
return (
<>
<p>Signed in as {userEmail}</p>
<button onClick={() => signOut()}>Sign out</button>
<img src="https://cdn.pixabay.com/photo/2017/08/11/19/36/vw-2632486_1280.png" />
</img>
)
}
return (
<>
<p>Not signed in.</p>
<button onClick={() => signIn()}>Sign in</button>
</>
)
}
```
You can use the `useSession` hook from anywhere in your application (e.g. in a header component). Behind the scenes, the hook will connect to the `<SessionProvider />` to read the current user session.
### Protecting API Routes
Protecting your custom API Routes (.i.e not allowing a resource to be accessed in case the user is not logged in) is easy! You can use [`getSession()`](/getting-started/client#getsession) to know whether a session exists or not:
```ts title="pages/api/movies/list.ts"
import { getSession } from "next-auth/react"
export default async function listMovies(req, res) {
const session = await getSession({ req })
if (session) {
res.send({
movies: [
{ title: "Alien vs Predator", id: 1 },
{ title: "Reservoir Dogs", id: 2 },
],
})
} else {
res.send({
error: "You must sign in to view movies.",
})
}
}
```
## 2. Configuring OAuth Provider
Ok, we have our Next.js app setup with NextAuth, however, if you run the app right now, it won't work as we haven't configured our OAuth provider (**Github**) yet.
:::info
When using OAuth you're asking for a third-party service (in this case Github, although it could be Google, Twitter, etc...) to handle user authentication for your app.
:::
We need to register our new Next.js app in Github, so that when NextAuth.js forwards the authorization requests to it, Github can recognize your application and prompt the user to sign in.
<img src={creatingOauthAppImg} />
Log in into **Github**, go to `Settings / Developers / OAuth Apps` and click on "New OAuth App".
Next you'll be presented with a screen to add details about your new application. Fill in the required fields, but pay extra attention to the **Authorization Callback URL** one:
<img src={addingCallbackUrlImg} />
The callback URL we insert should have the following pattern:
```
[origin]/api/auth/callback/[provider]
```
In this case, given we want to try our authentication working locally on our machine and we're using **Github** as our OAuth provider, it'll be:
```
http://localhost:3000/api/auth/callback/github
```
:::info
NextAuth.js will already magically create this API endpoint for you when we start the application later. Note that because we're using Next.js, locally it starts our server on the port `3000`, hence the origin is `http://localhost:3000`.
:::
Next you'll be presented with the following screen which presents all the configuration for your new OAuth app. For now, let's we need two things from it: the **Client ID** and **Client Secret** for our new OAuth app:
<img src={gettingClientIdSecretImg} />
The Client ID is always there, a public identifier of your OAuth application within Github. Click on the **Generate a new client Secret** button and should be presented with a new string (which is just a randomized string).
:::warning
🔥 Keep both your Client ID and Client Secret secure and never expose them to the public or shared with people outside your organization. With tem a malicious actor could hijack your application and cause you and your user serious problems!
:::
Now let's copy both the Client ID and Client Secret and paste them in an environment file in the root of your project like so:
```title=".env.local"
GITHUB_ID=12345
GITHUB_SECRET=67890
```
Cool! We have finished the configuring our OAuth provider, now let's wire all together so we can finally see authentication working in our app!
:::info
As noted previously, NextAuth.js has built-in support for multiple OAuth providers, <a href="">here the full list</a>. You can also easily build your own in case the provider you need is not on the list.
Note that, for each provider, the configuration process will be similar to what we just did:
1. Log in to the provider
2. Create create your OAuth application within it
3. Set the callback URL
4. Get the Client ID and Generate a Client Secret
:::
## 3. Wiring all together
Finally, we just need to reference our **Client ID** and **Client Secret** we just generated in the previous in our NextAuth.js config. In this way the library will be able to use them when forwarding users to Github, and Github will be able to recognize the request as generated from our application:
```ts title="pages/api/auth/[...nextauth].js"
import NextAuth from "next-auth"
import GithubProvider from "next-auth/providers/github"
export default NextAuth({
providers: [
GithubProvider({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
],
})
```
Great! We're now ready to run our application locally. Start the Next.js app by running on your terminal the following command and navigating to [`http://localhost:3000`](http://localhost:3000):
```
$ npm run next dev
```
You should see the following page:
<img src={startAppAndSignInImg} />
Click on "Sign in" and then on "Sign in with Github": NextAuth.js will redirect you to Github, and Github will recognize our app [that we just registered](#2-configuring-oauth-provider) and ask the user (in this case you) to enter its credentials to proceed:
<img src={githubAuthCredentials} />
Once inserted and correct, Github will redirect the user to our app and NextAuth.js will take care of any further calls with Github to get access to the user profile and start a user sessions safely in the background:
<img src={nextAuthUserLoggedIn} />
Great! We have completed the whole E2E authentication flow setup so that users can login in our application through Github!
:::info
You can create your own Sign In page instead of using the default one from NextAuth.js. You can learn how to do so in our dedicated guide for it.
:::
## 4. Deploying to production
### Configuring different environments
It's normal to test your application under different environments. Usually you'll have a development environment (when you run the application locally in your machine), a staging environment (for teams members to try the application) and a production environment.
For each environment, you're going to need to create an OAuth application in your provider respectively, as [we did previously](#2-configuring-oauth-provider), and point the **callback URL** to it.
For instance in the previous section, we pointed the callback URL to:
```
http://localhost:3000/api/auth/callback/github
```
as we wanted to test our application in the development environment.
If we were to deploy our app to production, we would need to create again a new **OAuth App** in Github (calling it something like "Van life prod") and point the **callback URL** to our production domain:
```
https://example.com/api/auth/callback/github
```
Finally, we would need just to point the environment variables we set ( `GITHUB_ID` and `GITHUB_SECRET` ) to the credentials of the OAuth app we want our application to run against.
### Setting up `NEXTAUTH_URL`
When deploying your site, **you need to set** the `NEXTAUTH_URL` environment variable to the canonical URL of your website:
```
NEXTAUTH_URL=https://example.com
```
:::warning
In production, this needs to be set as an environment variable on the service you use to deploy your app.
To set environment variables on Vercel, you can use the [dashboard](https://vercel.com/dashboard) or the `vercel env pull` [command](https://vercel.com/docs/build-step#development-environment-variables).
:::
For more information please check out our [deployment page](/deployment).

View File

@@ -0,0 +1,204 @@
---
title: Email authentication
---
import smtpConfig from "./img/dashboard-smtp.png"
import startPageImg from "./img/email-tutorial-start.png"
import checkPageImg from "./img/email-tutorial-check.png"
import mailboxImg from "./img/email-tutorial-mailbox.png"
import loggedInImg from "./img/email-tutorial-logged.png"
Aside from authenticating users in NextAuth.js via [OAuth](/getting-started/oauth-tutorial), you can also enable the option to authenticate them via "magic links". These are links that are sent to the user's email and when clicking on them they'll sign up the user automatically.
Adding support for signing in via email in addition to one or more OAuth services provides a way for users to sign in if they lose access to their OAuth account (e.g. if it is locked or deleted).
The Email provider can be used in conjunction with (or instead of) one or more OAuth providers.
## How it works
On initial sign in, a **Verification Token** is sent to the email address provided. By default this token **is valid for 24 hours**. If the Verification Token is used within that time (i.e. by clicking on the link in the email) an account is created for the user and they are signed in.
:::tip
The Email Provider can be used with both JSON Web Tokens and database sessions, but you [must configure a database adapter](/beta/guides/adapters/setting-up-a-database-adapter) to use it. It is not possible to enable email sign in without using a database.
:::
## 1. Installing `nodemailer`
[`nodemailer`](https://www.npmjs.com/package/nodemailer) is a [peer dependency](https://nodejs.org/en/blog/npm/peer-dependencies/) when using the Email Provider. This means we need to install before we can start sending emails:
```bash npm2yarn2pnpm
npm install -D nodemailer
```
`nodemailer` will enable us to send emails from NodeJS, which the runtime on which Next.js application operate.
## 2. Setting up a SMTP service
Next we need a [SMTP service](https://sendgrid.com/blog/what-is-an-smtp-server/) which will be in charge of sending emails from our application. There's a number of services available for this, however [here are the ones](http://nodemailer.com/smtp/well-known/) known to work with `nodemailer`.
:::info
For this tutorial, we're gonna be using [Sendgrid](https://sendgrid.com/), but any of the services linked above should work the same
:::
First create an account in and then login to the dashboard, then navigate to "Settings → API Keys" and create an API key:
<img src={smtpConfig} />
Next paste the API in your terminal as so, and run the command:
```bash
echo -n '<YOUR_API_KEY>' | openssl base64
```
Next, as [per Sendgrid documentation](https://docs.sendgrid.com/for-developers/sending-email/integrating-with-the-smtp-api), let's add the following [environment variables](https://nextjs.org/docs/basic-features/environment-variables) in our Next.js app:
```bash title=".env.local"
SMTP_USER=apikey
SMTP_PASSWORD={API_KEY}
SMTP_HOST=smtp.sendgrid.net
SMTP_PROT=587
EMAIL_FROM={SENDER_EMAIL}
```
Note that we're also specifying from which domain email are going to be sent from. You're gonna need to verify [a sender identity](https://docs.sendgrid.com/for-developers/sending-email/sender-identity) so that Sendgrid can send emails from your domain.
Nice! We're getting there. Now we need to read supply this values as the configuration for our Email Provider. Open `pages/api/auth/[...nextauth].ts` and do the following:
```ts title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"
import EmailProvider from "next-auth/providers/email"
export default NextAuth({
providers: [
Email({
server: {
host: process.env.EMAIL_SERVER_HOST,
port: Number(process.env.EMAIL_SERVER_PORT),
auth: {
user: process.env.EMAIL_SERVER_USER,
pass: process.env.EMAIL_SERVER_PASSWORD
}
},
from: process.env.EMAIL_FROM
}),
],
})
```
## 3. Setting up an adapter
Finally, we'll need to set up a database adapter to store verification tokens the Email Provider will emit when verifying users.
An **Adapter** in NextAuth.js connects your application to whatever database or backend system you want to use to store data for users, their accounts, sessions, etc...
For this tutorial, we're going to use the **MongoDB** adapter, other any of the other adapters will work just fine.
First, let's start by installing the adapter package:
```bash npm2yarn2pnpm
npm install -D @next-auth/mongodb-adapter mongodb
```
and create a simple MongoDB client:
```ts title="lib/mongodb/client.ts"
// This approach is taken from https://github.com/vercel/next.js/tree/canary/examples/with-mongodb
import { MongoClient } from "mongodb"
const uri = process.env.MONGODB_URI
const options = {
useUnifiedTopology: true,
useNewUrlParser: true,
}
let client
let clientPromise
if (!process.env.MONGODB_URI) {
throw new Error("Please add your Mongo URI to .env.local")
}
if (process.env.NODE_ENV === "development") {
// In development mode, use a global variable so that the value
// is preserved across module reloads caused by HMR (Hot Module Replacement).
if (!global._mongoClientPromise) {
client = new MongoClient(uri, options)
global._mongoClientPromise = client.connect()
}
clientPromise = global._mongoClientPromise
} else {
// In production mode, it's best to not use a global variable.
client = new MongoClient(uri, options)
clientPromise = client.connect()
}
// Export a module-scoped MongoClient promise. By doing this in a
// separate module, the client can be shared across functions.
export default clientPromise
```
And now let's reference this new adapter from our NextAuth.js configuration file:
```diff title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"
import EmailProvider from "next-auth/providers/email"
+ import { MongoDBAdapter } from "@next-auth/mongodb-adapter"
+ import clientPromise from "../../../lib/mongodb/client"
export default NextAuth({
secret: process.env.NEXTAUTH_SECRET,
providers: [
+ adapter: MongoDBAdapter(clientPromise),
EmailProvider({
server: {
host: process.env.EMAIL_SERVER_HOST,
port: process.env.EMAIL_SERVER_PORT,
auth: {
user: process.env.EMAIL_SERVER_USER,
pass: process.env.EMAIL_SERVER_PASSWORD
}
},
from: process.env.EMAIL_FROM
}),
],
})
```
## 4. Wiring all together
Now that everything is properly configured, let's try to sign in via email on our application.
Let's start by running a Next.js application with NextAuth, making sure the **EmailProvider** and a Database Adapter are properly configured as per the instructions above.
For this tutorial we're gonna be using NextAuth example app. Launch the app and click on "Sign in", we're redirected to the Sign In page:
<img src={startPageImg} alt="Screenshot of sign in page" />
:::info
You can customize the look and feel of your Sign in page pretty easily with NextAuth. Refer to our [pages guide](/beta/guides/basics/pages) for that!
:::
Then we insert the email address we want to log-in with in the Email credentials section and click on "Sign in with Email".
NextAuth will then display another page hinting the user to check their email:
<img src={checkPageImg} alt="Screenshot of check email page" />
Let's now check our email, and look for one sent from NextAuth (check your spam folder just in case):
<img src={mailboxImg} alt="Screenshot of mailbox" />
Nice! We got one, coming from the sender specified in the `EMAIL_FROM` environment variable from our configuration above and that's is the sender we verified in Sengrid.
Click on "Sign in" and a new browser tab will open, you should then land on your application as authenticated!
<img src={loggedInImg} alt="Screenshot of logged in" />
Easy right? We had to configure Sendgrid and install a database adapter so the user sessions can be saved somewhere, but once done NextAuth will deal with all the user session management for us in a secure way!
:::info
A user account (i.e. an entry in the Users table) will not be created for the user until the first time they verify their email address. If an email address is already associated with an account, the user will be signed in to that account when they use the link in the email.
:::

View File

@@ -0,0 +1,55 @@
---
title: Credentials authentication
---
NextAuth.js is built in a way that is flexible to integrate it with any authentication back-end you or your company may already have.
This library has been designed to handle the user session client-wise, to support multiple authentication methods (OAuth, Email, etc...) so that you're not forced to run your own authentication service.
In case you already have an authentication service, you can use the Credentials Provider, which will just forward the credentials inserted by the user in the login form to your service.
For this tutorial, we're going to use [NextAuth.js example app](https://github.com/nextauthjs/next-auth-example) as a base.
:::warning
The functionality provided for credentials based authentication is intentionally limited to discourage use of passwords due to the inherent security risks associated with them and the additional complexity associated with supporting usernames and passwords.
:::
Integrating the Credentials Provider is as simple as initializing it in the NextAuth.js configuration file:
```ts title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"
export default NextAuth({
providers: [
CredentialsProvider({
async authorize(credentials) {
const authResponse = await fetch('/users/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(credentials)
})
if (!authResponse.ok) {
return null
}
const user = await authResponse.json()
return user
},
}),
],
})
```
Note that we only need to define an `authorize` method that is in charge of receiving the credentials inserted by the user and call the authorization service.
:::info
If you're using TypeScript, you can [augment the `User` interface](/getting-started/typescript#module-augmentation) to match the response of your `authorize` callback, so whenever you read the user in other callbacks (like the `jwt`) the type will match correctly.
:::

View File

@@ -0,0 +1,162 @@
---
title: TypeScript
---
NextAuth.js has its own type definitions to use in your TypeScript projects safely. Even if you don't use TypeScript, IDEs like VSCode will pick this up to provide you with a better developer experience. While you are typing, you will get suggestions about what certain objects/functions look like, and sometimes links to documentation, examples, and other valuable resources.
Check out the example repository showcasing how to use `next-auth` on a Next.js application with TypeScript:
https://github.com/nextauthjs/next-auth-typescript-example
---
## Adapters
If you're writing your own custom Adapter, you can take advantage of the types to make sure your implementation conforms to what's expected:
```ts
import type { Adapter } from "next-auth/adapters"
function MyAdapter(): Adapter {
return {
// your adapter methods here
}
}
```
When writing your own custom Adapter in plain JavaScript, note that you can use **JSDoc** to get helpful editor hints and auto-completion like so:
```js
/** @return { import("next-auth/adapters").Adapter } */
function MyAdapter() {
return {
// your adapter methods here
}
}
```
:::note
This will work in code editors with a strong TypeScript integration like VSCode or WebStorm. It might not work if you're using more lightweight editors like VIM or Atom.
:::
## Module Augmentation
`next-auth` comes with certain types/interfaces that are shared across submodules. Good examples are `Session` and `JWT`. Ideally, you should only need to create these types at a single place, and TS should pick them up in every location where they are referenced. Luckily, Module Augmentation is exactly that, which can do this for us. Define your shared interfaces in a single place, and get type-safety across your application when using `next-auth` (or one of its submodules).
### Main module
Let's look at `Session`:
```ts title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"
export default NextAuth({
callbacks: {
session({ session, token, user }) {
return session // The return type will match the one returned in `useSession()`
},
},
})
```
```ts title="pages/index.ts"
import { useSession } from "next-auth/react"
export default function IndexPage() {
// `session` will match the returned value of `callbacks.session()` from `NextAuth()`
const { data: session } = useSession()
return (
// Your component
)
}
```
To extend/augment this type, create a `types/next-auth.d.ts` file in your project:
```ts title="types/next-auth.d.ts"
import NextAuth from "next-auth"
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
}
}
}
```
#### Extend default interface properties
By default, TypeScript will merge new interface properties and overwrite existing ones. In this case, the default session user properties will be overwritten, with the new one defined above.
If you want to keep the default session user properties, you need to add them back into the newly declared interface:
```ts title="types/next-auth.d.ts"
import NextAuth, { DefaultSession } from "next-auth"
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
} & DefaultSession["user"]
}
}
```
#### Popular interfaces to augment
Although you can augment almost anything, here are some of the more common interfaces that you might want to override in the `next-auth` module:
```ts
/**
* The shape of the user object returned in the OAuth providers' `profile` callback,
* or the second parameter of the `session` callback, when using a database.
*/
interface User {}
/**
* Usually contains information about the provider being used
* and also extends `TokenSet`, which is different tokens returned by OAuth Providers.
*/
interface Account {}
/** The OAuth profile returned from your provider */
interface Profile {}
```
Make sure that the `types` folder is added to [`typeRoots`](https://www.typescriptlang.org/tsconfig/#typeRoots) in your project's `tsconfig.json` file.
### Submodules
The `JWT` interface can be found in the `next-auth/jwt` submodule:
```ts title="types/next-auth.d.ts"
import { JWT } from "next-auth/jwt"
declare module "next-auth/jwt" {
/** Returned by the `jwt` callback and `getToken`, when using JWT sessions */
interface JWT {
/** OpenID ID Token */
idToken?: string
}
}
```
### Useful links
1. [TypeScript documentation: Module Augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation)
2. [Digital Ocean: Module Augmentation in TypeScript](https://www.digitalocean.com/community/tutorials/typescript-module-augmentation)
## Contributing
Contributions of any kind are always welcome, especially for TypeScript. Please keep in mind that we are a small team working on this project in our free time. We will try our best to give support, but if you think you have a solution for a problem, please open a PR!
:::note
When contributing to TypeScript, if the actual JavaScript user API does not change in a breaking manner, we reserve the right to push any TypeScript change in a minor release. This ensures that we can keep on a faster release cycle.
:::

View File

@@ -0,0 +1,13 @@
# Databases
NextAuth.js offers multiple database adapters. Check out [the overview](/adapters/overview).
> As of **v4** NextAuth.js no longer ships with an adapter included by default. If you would like to persist any information, you need to install one of the many available adapters yourself. See the individual adapter documentation pages for more details.
To learn more about databases in NextAuth.js and how they are used, check out [databases in the FAQ](/faq#databases).
---
## How to use a database
See the [documentation for adapters](/adapters/overview) for more information on advanced configuration, including how to use NextAuth.js with other databases using a [custom adapter](/tutorials/creating-a-database-adapter).

View File

@@ -0,0 +1,26 @@
# Security
## Reporting a Vulnerability
NextAuth.js practices responsible disclosure.
We request that you contact us directly to report serious issues that might impact the security of sites using NextAuth.js.
If you contact us regarding a serious issue:
- We will endeavor to get back to you within 72 hours.
- We will aim to publish a fix within 30 days.
- We will disclose the issue (and credit you, with your consent) once a fix to resolve the issue has been released.
- If 90 days has elapsed and we still don't have a fix, we will disclose the issue publicly.
The best way to report an issue is by contacting us via email at info@balazsorban.com or me@iaincollins.com and yo@ndo.dev, or raise a public issue requesting someone get in touch with you via whatever means you prefer for more details. (Please do not disclose sensitive details publicly at this stage.)
:::note
For less serious issues (e.g. RFC compliance for unsupported flows or potential issues that may cause a problem in the future) it is appropriate to make these public as bug reports or feature requests or to raise a question to open a discussion around them.
:::
## Supported Versions
Security updates are only released for the current version.
Old releases are not maintained and do not receive updates.

View File

@@ -0,0 +1,612 @@
---
title: Upgrade Guide (v4)
---
NextAuth.js version 4 includes a few breaking changes from the last major version (3.x). So we're here to help you upgrade your applications as smoothly as possible. It should be possible to upgrade from any version of 3.x to the latest 4 release by following the next few migration steps.
:::note
Version 4 has been released to GA 🚨
We encourage users to try it out and report any and all issues they come across.
:::
You can upgrade to the new version by running:
```bash npm2yarn
npm install next-auth
```
## `next-auth/jwt`
We no longer have a default export in `next-auth/jwt`.
To comply with this, change the following:
```diff
- import jwt from "next-auth/jwt"
+ import { getToken } from "next-auth/jwt"
```
## `next-auth/react`
We've renamed the client-side import source to `next-auth/react`. To comply with this change, you will simply have to rename anywhere you were using `next-auth/client`.
For example:
```diff
- import { useSession } from "next-auth/client"
+ import { useSession } from "next-auth/react"
```
We've also made the following changes to the names of the exports:
- `setOptions`: Not exposed anymore, use [`SessionProvider` props](https://next-auth.js.org/getting-started/client#options)
- `options`: Not exposed anymore, [use `SessionProvider` props](https://next-auth.js.org/getting-started/client#options)
- `session`: Renamed to `getSession`
- `providers`: Renamed to `getProviders`
- `csrfToken`: Renamed to `getCsrfToken`
- `signin`: Renamed to `signIn`
- `signout`: Renamed to `signOut`
- `Provider`: Renamed to `SessionProvider`
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.12
## `SessionProvider`
Version 4 makes using the `SessionProvider` mandatory. This means that you will have to wrap any part of your application using `useSession` in this provider, if you were not doing so already. The `SessionProvider` has also undergone a few further changes:
- `Provider` is renamed to `SessionProvider`
- The options prop is now flattened as the props of SessionProvider.
- `keepAlive` has been renamed to `refetchInterval`.
- `clientMaxAge` has been removed in favor of `refetchInterval`, as they overlap in functionality, with the difference that `refetchInterval` will keep re-fetching the session periodically in the background.
The best practice for wrapping your app in Providers is to do so in your `pages/_app.jsx` file.
An example use-case with these new changes:
```jsx
import { SessionProvider } from "next-auth/react"
export default function App({
Component,
pageProps: { session, ...pageProps },
}) {
return (
// `session` comes from `getServerSideProps` or `getInitialProps`.
// Avoids flickering/session loading on first load.
<SessionProvider session={session} refetchInterval={5 * 60}>
<Component {...pageProps} />
</SessionProvider>
)
}
```
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.12
## Providers
Providers now need to be imported individually.
```diff
- import Provider from "next-auth/providers"
- Providers.Auth0({...})
- Providers.Google({...})
+ import Auth0Provider from "next-auth/providers/auth0"
+ import GoogleProvider from "next-auth/providers/google"
+ Auth0Provider({...})
+ GoogleProvider({...})
```
1. The `AzureADB2C` provider has been renamed `AzureAD`.
2. The `Basecamp` provider has been removed, see explanation [here](https://github.com/basecamp/api/blob/master/sections/authentication.md#on-authenticating-users-via-oauth).
3. The GitHub provider by default now will not request full write access to user profiles. If you need this scope, please add `user` to the scope option manually.
The following new options are available when defining your Providers in the configuration:
1. `authorization` (replaces `authorizationUrl`, `authorizationParams`, `scope`)
2. `token` replaces (`accessTokenUrl`, `headers`, `params`)
3. `userinfo` (replaces `profileUrl`)
4. `issuer`(replaces `domain`)
For more details on their usage, please see [options](/configuration/providers/oauth#options) section of the OAuth Provider documentation.
When submitting a new OAuth provider to the repository, the `profile` callback is expected to only return these fields from now on: `id`, `name`, `email`, and `image`. If any of these are missing values, they should be set to `null`.
Also worth noting is that `id` is expected to be returned as a `string` type (For example if your provider returns it as a number, you can cast it by using the `.toString()` method). This makes the returned profile object comply across all providers/accounts/adapters, and hopefully cause less confusion in the future.
Implemented in: https://github.com/nextauthjs/next-auth/pull/2411
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.20
## `useSession` Hook
The `useSession` hook has been updated to return an object. This allows you to test states much more cleanly with the new `status` option.
```diff
- const [ session, loading ] = useSession()
+ const { data: session, status } = useSession()
+ const loading = status === "loading"
```
[Check the docs](https://next-auth.js.org/getting-started/client#usesession) for the possible values of both `session.status` and `session.data`.
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.18
## Named Parameters
We have changed the arguments to our callbacks to the named parameters pattern. This way you don't have to use dummy `_` placeholders or other tricks.
### Callbacks
The signatures for the callback methods now look like this:
```diff
- signIn(user, account, profileOrEmailOrCredentials)
+ signIn({ user, account, profile, email, credentials })
```
```diff
- redirect(url, baseUrl)
+ redirect({ url, baseUrl })
```
```diff
- session(session, tokenOrUser)
+ session({ session, token, user })
```
```diff
- jwt(token, user, account, OAuthProfile, isNewUser)
+ jwt({ token, user, account, profile, isNewUser })
```
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.17
### Events
Two event signatures have changed to also use the named parameters pattern, `signOut` and `updateUser`.
```diff
// [...nextauth].js
...
events: {
- signOut(tokenOrSession),
+ signOut({ token, session }), // token if using JWT, session if DB persisted sessions.
- updateUser(user)
+ updateUser({ user })
}
```
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.20
## JWT configuration
We have removed some of the [configuration options](/configuration/options) when using JSON Web Tokens, [here's the PR](https://github.com/nextauthjs/next-auth/pull/3039) for more context.
```diff
export default NextAuth({
// ...
jwt: {
secret,
maxAge,
- encryptionKey
- signingKey
- encryptionKey
- verificationOptions
encode({
token
secret
maxAge
- signingKey
- signingOptions
- encryptionKey
- encryptionOptions
- encryption
}) {},
decode({
token
secret
- maxAge
- signingKey
- verificationKey
- verificationOptions
- encryptionKey
- decryptionKey
- decryptionOptions
- encryption
}) {}
}
})
```
## Logger API
The logger API has been simplified to use at most two parameters, where the second is usually an object (`metadata`) containing an `error` object. If you are not using the logger settings you can ignore this change.
```diff
// [...nextauth.js]
import log from "some-logger-service"
...
logger: {
- error(code, ...message) {},
+ error(code, metadata) {},
- warn(code, ...message) {},
+ warn(code) {}
- debug(code, ...message) {}
+ debug(code, metadata) {}
}
```
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.19
## `nodemailer`
Like `typeorm` and `prisma`, [`nodemailer`](https://npmjs.com/package/nodemailer) is no longer included as a dependency by default. If you are using the Email provider you must install it in your project manually, or use any other Email library in the [`sendVerificationRequest`](/configuration/providers/email#options-1#:~:text=sendVerificationRequest) callback. This reduces bundle size for those not actually using the Email provider. Remember, when using the Email provider, it is mandatory to also use a database adapter due to the fact that verification tokens need to be persisted longer term for the magic link functionality to work.
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.2
## Theme
We have added some basic customization options to our built-in pages like `signin`, `signout`, etc.
These can be set under the `theme` configuration key. This used to be a string which only controlled the color scheme option. Now it is an object with the following options:
```js
theme: {
colorScheme: "auto", // "auto" | "dark" | "light"
brandColor: "", // Hex color value
logo: "" // Absolute URL to logo image
}
```
The hope is that with some minimal configuration / customization options, users won't immediately feel the need to replace the built-in pages with their own.
More details and screenshots of the new theme options can be found under [configuration/pages](https://next-auth.js.org/configuration/pages#theming).
Introduced in https://github.com/nextauthjs/next-auth/pull/2788
## Session
The `session.jwt: boolean` option has been renamed to `session.strategy: "jwt" | "database"`. The goal is to make the user's options more intuitive:
1. No adapter, `strategy: "jwt"`: This is the default. The session is saved in a cookie and never persisted anywhere.
2. With Adapter, `strategy: "database"`: If an Adapter is defined, this will be the implicit setting. No user config is needed.
3. With Adapter, `strategy: "jwt"`: The user can explicitly instruct `next-auth` to use JWT even if a database is available. This can result in faster lookups in compromise of lowered security. Read more about: https://next-auth.js.org/faq#json-web-tokens
Example:
```diff
session: {
- jwt: true,
+ strategy: "jwt",
}
```
Introduced in https://github.com/nextauthjs/next-auth/pull/3144
## Adapters
Most importantly, the core `next-auth` package no longer ships with `typeorm` or any other database adapter by default. This brings the default bundle size down significantly for those not needing to persist user data to a database.
You can find the official Adapters in the `packages` directory in the primary monorepo ([nextauthjs/next-auth](https://github.com/nextauthjs/next-auth)). Although you can still [create your own](/tutorials/creating-a-database-adapter) with a new, [simplified Adapter API](https://github.com/nextauthjs/next-auth/pull/2361).
If you have a database that was created with a `3.x.x` or earlier version of NextAuth.js, you will need to run a migration to update the schema to the new version 4 database model. See the bottom of this migration guide for database specific migration examples.
1. If you use the built-in TypeORM or Prisma adapters, these have been removed from the core `next-auth` package. Thankfully the migration is easy; you just need to install the external packages for your database and change the import in your `[...nextauth].js`.
The `database` option has been removed, you must now do the following instead:
```diff
// [...nextauth].js
import NextAuth from "next-auth"
+ import { TypeORMLegacyAdapter } from "@next-auth/typeorm-legacy-adapter"
...
export default NextAuth({
- database: "yourconnectionstring",
+ adapter: TypeORMLegacyAdapter("yourconnectionstring")
})
```
2. The `prisma-legacy` adapter has been removed, please use the [`@next-auth/prisma-adapter`](https://npmjs.com/package/@next-auth/prisma-adapter) instead.
3. The `typeorm-legacy` adapter has been upgraded to use the newer adapter API, but has retained the `typeorm-legacy` name. We aim to migrate this to individual lighter weight adapters for each database type in the future, or switch out `typeorm`.
4. MongoDB has been moved to its own adapter under `@next-auth/mongodb-adapter`. See the [MongoDB Adapter docs](/adapters/mongodb).
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.8 and https://github.com/nextauthjs/next-auth/pull/2361
### Adapter API
**This does not require any changes from the user - these are adapter specific changes only**
The Adapter API has been rewritten and significantly simplified in NextAuth v4. The adapters now have less work to do as some functionality has been migrated to the core of NextAuth, like hashing the [verification token](/adapters/models/#verification-token).
If you are an adapter maintainer or are interested in writing your own adapter, you can find more information about this change in https://github.com/nextauthjs/next-auth/pull/2361 and release https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.22.
### Schema changes
The way we save data with adapters have slightly changed. With the new Adapter API, we wanted to make it easier to extend your database with additional fields. For example if your User needs an extra `phone` field, it should be enough to add that to your database's schema, and no changes will be necessary in your adapter.
- `created_at`/`createdAt` and `updated_at`/`updatedAt` fields are removed from all Models.
- `user_id`/`userId` consistently named `userId`.
- `compound_id`/`compoundId` is removed from Account.
- `access_token`/`accessToken` is removed from Session.
- `email_verified`/`emailVerified` on User is consistently named `emailVerified`.
- `provider_id`/`providerId` renamed to `provider` on Account
- `provider_type`/`providerType` renamed to `type` on Account
- `provider_account_id`/`providerAccountId` on Account is consistently named `providerAccountId`
- `access_token_expires`/`accessTokenExpires` on Account renamed to `expires_at`
- New fields on Account: `token_type`, `scope`, `id_token`, `session_state`
- `verification_requests` table has been renamed to `verification_tokens`
<!-- REVIEW: Would something like this below be helpful? -->
<details>
<summary>
See the changes
</summary>
<pre>
```diff
User {
id
name
email
- emailVerified
+ email_verified
image
- created_at
- updated_at
}
Account {
id
- compound_id
- user_id
+ userId
- provider_type
+ type
- provider_id
+ provider
- provider_account_id
+ providerAccountId
refresh_token
access_token
- access_token_expires
+ expires_in
+ expires_at
+ token_type
+ scope
+ id_token
+ session_state
- created_at
- updated_at
}
Session {
id
userId
expires
sessionToken
- access_token
- created_at
- updated_at
}
VerificationToken {
id
token
expires
identifier
- created_at
- updated_at
}
```
</pre>
</details>
For more info, see the [Models page](/adapters/models).
### Database migration
NextAuth.js v4 has a slightly different database schema compared to v3. If you're using any of our adapters and want to upgrade, you can use on of the below schemas.
They are designed to be run directly against the database itself. So instead of having one in Prisma syntax, one in TypeORM syntax, etc. we've decided to just make one for each underlying database type. i.e. one for Postgres, one for MySQL, one for MongoDB, etc.
#### MySQL
```sql
/* ACCOUNT */
ALTER TABLE accounts
CHANGE "access_token_expires" "expires_at" int
CHANGE "user_id" "userId" varchar(255)
ADD CONSTRAINT fk_user_id FOREIGN KEY (userId) REFERENCES users(id)
RENAME COLUMN "provider_id" "provider"
RENAME COLUMN "provider_account_id" "providerAccountId"
DROP COLUMN "provider_type"
DROP COLUMN "compound_id"
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
DROP COLUMN "created_at"
DROP COLUMN "updated_at"
ADD COLUMN "token_type" varchar(255) NULL
ADD COLUMN "scope" varchar(255) NULL
ADD COLUMN "id_token" varchar(255) NULL
ADD COLUMN "session_state" varchar(255) NULL
/* Note: These are only needed if you're going to be using the old Twitter OAuth 1.0 provider. */
ADD COLUMN "oauth_token_secret" varchar(255) NULL
ADD COLUMN "oauth_token" varchar(255) NULL
/* USER */
ALTER TABLE users
RENAME COLUMN "email_verified" "emailVerified"
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
DROP COLUMN "created_at"
DROP COLUMN "updated_at"
/* SESSION */
ALTER TABLE sessions
RENAME COLUMN "session_token" "sessionToken"
CHANGE "user_id" "userId" varchar(255)
ADD CONSTRAINT fk_user_id FOREIGN KEY (userId) REFERENCES users(id)
DROP COLUMN "access_token"
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
DROP COLUMN "created_at"
DROP COLUMN "updated_at"
/* VERIFICATION REQUESTS */
ALTER TABLE verification_requests RENAME verification_tokens
ALTER TABLE verification_tokens
DROP COLUMN id
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
DROP COLUMN "created_at"
DROP COLUMN "updated_at"
```
#### Postgres
```sql
/* ACCOUNT */
ALTER TABLE accounts RENAME COLUMN "user_id" TO "userId";
ALTER TABLE accounts RENAME COLUMN "provider_id" TO "provider";
ALTER TABLE accounts RENAME COLUMN "provider_account_id" TO "providerAccountId";
ALTER TABLE accounts RENAME COLUMN "access_token_expires" TO "expires_at";
ALTER TABLE accounts RENAME COLUMN "provider_type" TO "type";
/* Do conversion of TIMESTAMPTZ to BIGINT */
ALTER TABLE accounts ALTER COLUMN "expires_at" TYPE TEXT USING CAST(extract(epoch FROM "expires_at") AS BIGINT)*1000;
/* Keep id as SERIAL with autoincrement when using ORM. Using new v4 uuid format won't work because of incompatibility */
/* ALTER TABLE accounts ALTER COLUMN "id" TYPE TEXT; */
/* ALTER TABLE accounts ALTER COLUMN "userId" TYPE TEXT; */
ALTER TABLE accounts ALTER COLUMN "type" TYPE TEXT;
ALTER TABLE accounts ALTER COLUMN "provider" TYPE TEXT;
ALTER TABLE accounts ALTER COLUMN "providerAccountId" TYPE TEXT;
ALTER TABLE accounts ADD CONSTRAINT fk_user_id FOREIGN KEY ("userId") REFERENCES users(id);
ALTER TABLE accounts
DROP COLUMN IF EXISTS "compound_id";
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
ALTER TABLE accounts
DROP COLUMN IF EXISTS "created_at",
DROP COLUMN IF EXISTS "updated_at";
ALTER TABLE accounts
ADD COLUMN IF NOT EXISTS "token_type" TEXT NULL,
ADD COLUMN IF NOT EXISTS "scope" TEXT NULL,
ADD COLUMN IF NOT EXISTS "id_token" TEXT NULL,
ADD COLUMN IF NOT EXISTS "session_state" TEXT NULL;
/* Note: These are only needed if you're going to be using the old Twitter OAuth 1.0 provider. */
/* ALTER TABLE accounts
ADD COLUMN IF NOT EXISTS "oauth_token_secret" TEXT NULL,
ADD COLUMN IF NOT EXISTS "oauth_token" TEXT NULL; */
/* USER */
ALTER TABLE users RENAME COLUMN "email_verified" TO "emailVerified";
/* Keep id as SERIAL with autoincrement when using ORM. Using new v4 uuid format won't work because of incompatibility */
/* ALTER TABLE users ALTER COLUMN "id" TYPE TEXT; */
ALTER TABLE users ALTER COLUMN "name" TYPE TEXT;
ALTER TABLE users ALTER COLUMN "email" TYPE TEXT;
ALTER TABLE users ALTER COLUMN "image" TYPE TEXT;
/* Do conversion of TIMESTAMPTZ to BIGINT and then TEXT */
ALTER TABLE users ALTER COLUMN "emailVerified" TYPE TEXT USING CAST(CAST(extract(epoch FROM "emailVerified") AS BIGINT)*1000 AS TEXT);
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
ALTER TABLE users
DROP COLUMN IF EXISTS "created_at",
DROP COLUMN IF EXISTS "updated_at";
/* SESSION */
ALTER TABLE sessions RENAME COLUMN "session_token" TO "sessionToken";
ALTER TABLE sessions RENAME COLUMN "user_id" TO "userId";
/* Keep id as SERIAL with autoincrement when using ORM. Using new v4 uuid format won't work because of incompatibility */
/* ALTER TABLE sessions ALTER COLUMN "id" TYPE TEXT; */
/* ALTER TABLE sessions ALTER COLUMN "userId" TYPE TEXT; */
ALTER TABLE sessions ALTER COLUMN "sessionToken" TYPE TEXT;
ALTER TABLE sessions ADD CONSTRAINT fk_user_id FOREIGN KEY ("userId") REFERENCES users(id);
/* Do conversion of TIMESTAMPTZ to BIGINT and then TEXT */
ALTER TABLE sessions ALTER COLUMN "expires" TYPE TEXT USING CAST(CAST(extract(epoch FROM "expires") AS BIGINT)*1000 AS TEXT);
ALTER TABLE sessions DROP COLUMN IF EXISTS "access_token";
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
ALTER TABLE sessions
DROP COLUMN IF EXISTS "created_at",
DROP COLUMN IF EXISTS "updated_at";
/* VERIFICATION REQUESTS */
ALTER TABLE verification_requests RENAME TO verification_tokens;
/* Keep id as ORM needs it */
/* ALTER TABLE verification_tokens DROP COLUMN IF EXISTS id; */
ALTER TABLE verification_tokens ALTER COLUMN "identifier" TYPE TEXT;
ALTER TABLE verification_tokens ALTER COLUMN "token" TYPE TEXT;
/* Do conversion of TIMESTAMPTZ to BIGINT and then TEXT */
ALTER TABLE verification_tokens ALTER COLUMN "expires" TYPE TEXT USING CAST(CAST(extract(epoch FROM "expires") AS BIGINT)*1000 AS TEXT);
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
ALTER TABLE verification_tokens
DROP COLUMN IF EXISTS "created_at",
DROP COLUMN IF EXISTS "updated_at";
```
#### MongoDB
MongoDB is a document database and as such new fields will be automatically populated. You do, however, need to update the names of existing fields which are going to be reused.
```mongo
db.getCollection('accounts').updateMany({}, {
$rename: {
"provider_id": "provider",
"provider_account_id": "providerAccountId",
"user_id": "userId",
"access_token_expires": "expires_at"
}
})
db.getCollection('users').updateMany({}, {
$rename: {
"email_verified": "emailVerified"
}
})
db.getCollection('sessions').updateMany({}, {
$rename: {
"session_token": "sessionToken",
"user_id": "userId"
}
})
```
## Missing `secret`
NextAuth.js used to generate a secret for convenience, when the user did not define one. This might have been useful in development, but can be a concern in production. We have always been clear about that in the docs, but from now on, if you forget to define a `secret` property in production, we will show the user an error page. Read more about this option [here](https://next-auth.js.org/configuration/options#secret)
You can generate a secret to be placed in the `secret` configuration option via the following command:
```bash
$ openssl rand -base64 32
```
Therefore, your NextAuth.js config should look something like this:
```javascript title="/pages/api/auth/[...nextauth].js"
...
export default NextAuth({
...
providers: [...],
secret: "LlKq6ZtYbr+hTC073mAmAh9/h2HwMfsFo4hrfCx5mLg=",
...
})
```
Introduced in https://github.com/nextauthjs/next-auth/issues/3143
## Session `strategy`
We have always supported two different session strategies. The first being our most popular and default strategy - the JWT based one. The second is the database adapter persisted session strategy. Both have their advantages/disadvantages, you can learn more about them on the [FAQ](https://next-auth.js.org/faq) page.
Previously, the way you configured this was through the `jwt: boolean` flag in the `session` option. The names `session` and `jwt` might have been a bit overused in the options, and so for a clearer message, we renamed this option to `strategy: "jwt" | "database"`, it is still in the `session` object. This will hopefully better indicate the purpose of this option as well as make very explicit which type of session you are going to use.
See the [`session` option docs](https://next-auth.js.org/configuration/options#session) for more details.
Introduced in https://github.com/nextauthjs/next-auth/pull/3144
## Summary
We hope this migration goes smoothly for each and every one of you! If you have any questions or get stuck anywhere, feel free to create [a new issue](https://github.com/nextauthjs/next-auth/issues/new) on GitHub.

View File

@@ -0,0 +1,39 @@
# Contributors
## Core team
Without these people, the project could not have become one of the most used authentication library in its category.
- [Balázs Orbán](https://github.com/balazsorban44) - **Lead Maintainer**
- [Thang Vu](https://github.com/ThangHuuVu) - Maintainer (Core)
- [Nico Domino](https://github.com/ndom91) - Maintainer (Core, Documentation)
- [Lluis Agusti](https://github.com/lluia) - Maintainer (Documentation, Testing, TypeScript)
## Special thanks
Special thanks to Lori Karikari for creating most of the original provider configurations to Fredrik Pettersen for creating the original Prisma Adapter, to Gerald Nolan for adding support for Sign in with Apple, and to Jefferson Bledsoe for working on original testing automations.
- [Lori Karikari](https://github.com/LoriKarikari)
- [Fredrik Pettersen](https://github.com/Fumler)
- [Gerald Nolan](https://github.com/geraldnolan)
- [Jefferson Bledsoe](https://github.com/JeffersonBledsoe)
## Other contributors
NextAuth.js as it exists today has been possible thanks to the work of many individual contributors.
Thank you to the [dozens of individual contributors](https://github.com/nextauthjs/next-auth/graphs/contributors) who have help shaped NextAuth.js.
## Open Collective
You can find NextAuth.js on Open Collective. We are very thankful for all of our existing contributors and would be delighted if you or your company would decide to join them.
More information can be found at: https://opencollective.com/nextauth
## History
- NextAuth.js was originally developed by <a href="https://github.com/iaincollins">Iain Collins</a> in 2016 for Next.js.
- In 2020, NextAuth.js was rebuilt from the ground up to support Serverless, with support for MySQL, Postgres and MongoDB, JSON Web Tokens and built in support for over a dozen authentication providers.
- In 2021, efforts have started to move NextAuth.js to other frameworks and to support as many databases and providers as possible.

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Some files were not shown because too many files have changed in this diff Show More