Compare commits

...

157 Commits

Author SHA1 Message Date
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
Balázs Orbán
6590993fdc chore(release): bump package version(s) [skip ci] 2022-07-21 16:35:03 +02:00
Balázs Orbán
0ea96796b2 fix: improve logger (#4970)
* fix: add debug warning, only show warnings once

* fix: prefer `debug` for details

* remove url

* test: fix tests

* Update docs/docs/errors.md

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

* Update callback.ts

Co-authored-by: Thang Vu <31528554+ThangHuuVu@users.noreply.github.com>
2022-07-21 16:00:16 +02:00
Misha Kaletsky
8ec940bd6a docs: highlight archiving of next-auth/react-query (#4964)
* docs: highlight archiving of next-auth/react-query

project is read-only and author said users should just copy-paste the implementation: https://github.com/nextauthjs/react-query/issues/7#issuecomment-923099050

* Update docs/docs/getting-started/client.md

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

* Update docs/docs/getting-started/client.md

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

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-07-21 13:59:46 +02:00
Balázs Orbán
e3bcdf83f1 chore: update lock file 2022-07-20 03:18:02 +02:00
Balázs Orbán
4084297334 chore(release): extract release script to its own package 2022-07-20 03:08:03 +02:00
Balázs Orbán
c9827960b1 chore(release): read packages dynamically 2022-07-20 00:36:49 +02:00
Balázs Orbán
946a825865 chore: fix adapters PR auto-labeler 2022-07-19 23:55:03 +02:00
Balázs Orbán
c57d8c997e fix(adapters): set correct peer dependency version of next-auth (#4950)
* fix(adapters): set correct peer dependency version of `next-auth`

* fix fauna peer dependency
2022-07-19 23:46:45 +02:00
Balázs Orbán
e2b92bf04f chore: add newlines to PR comment 2022-07-19 17:45:55 +02:00
Balázs Orbán
8bff050e4e chore(release): bump version [skip ci] 2022-07-19 17:30:40 +02:00
Thang Vu
1a79a1a612 docs: FAQ framework-agnostic & session sharing (#4962)
Split a FAQ into two parts:
Before:
- Can I use NextAuth.js with a website that does not use Next.js?

After:
- Can I use NextAuth.js with a framework different than Next.js?
- Can session generated by NextAuth.js be used by another website?
2022-07-19 17:29:54 +02:00
Balázs Orbán
b7065a602f chore: correct Middleware logic in Next.js example 2022-07-19 17:16:51 +02:00
Balázs Orbán
61b92ec1b6 chore: revert type assertion 2022-07-19 16:57:16 +02:00
Balázs Orbán
282f7ab340 fix(ts): fix Middleware internal type 2022-07-19 16:46:13 +02:00
Balázs Orbán
4f56e414b0 chore: simplify dev app 2022-07-19 16:42:21 +02:00
Yoann Fleury
2725d07eb7 fix(providers): migrate GitLab provider to TS (#4929) 2022-07-17 04:47:15 +02:00
Balázs Orbán
5a8b029523 docs: clarify getToken + secret in example
ref #4954
2022-07-17 04:44:11 +02:00
Balázs Orbán
f62a985848 docs: clarify getToken and secret
Ref: #4954
2022-07-17 04:39:47 +02:00
Balázs Orbán
edd6fb5989 Merge branch 'main' of github.com:nextauthjs/next-auth 2022-07-17 04:29:49 +02:00
Balázs Orbán
fb60554a62 chore(ts): explicitly set next path in next-auth 2022-07-17 04:29:44 +02:00
cobbvanth
9784dfb631 docs: Remove import of "useSession" from wrong location (#4952)
This tutorial snipped erroneously imports useSession from "next-auth/next", when it actually resides in "next-auth/react".
2022-07-16 23:06:00 +02:00
Balázs Orbán
4ff836a8cf test(providers): add fetch polyfill to redis test runs 2022-07-16 17:39:32 +02:00
Balázs Orbán
042955eaaa fix(providers): allow issuer in Azure AD B2C 2022-07-16 14:20:31 +02:00
Balázs Orbán
82e107c0e7 chore: improve dev app DX 2022-07-16 14:19:33 +02:00
dependabot[bot]
f7050347e8 chore(deps-dev): bump svelte from 3.46.4 to 3.49.0 in /apps/playground-sveltekit (#4947)
chore(deps-dev): bump svelte in /apps/playground-sveltekit

Bumps [svelte](https://github.com/sveltejs/svelte) from 3.46.4 to 3.49.0.
- [Release notes](https://github.com/sveltejs/svelte/releases)
- [Changelog](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/svelte/compare/v3.46.4...v3.49.0)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-15 23:17:21 +02:00
Balázs Orbán
c56abbd745 chore: update CODEOWNERS (#4941)
* chore: update codeowners

* reorganize
2022-07-15 12:35:54 +02:00
Thang Vu
3f6d99e8df chore: add Thang to contributor (#4944) 2022-07-15 12:34:36 +02:00
Balázs Orbán
46eedee3c8 fix(ts): remove TS workaround for withAuth (#4926)
* fix(ts): improve Middleware types

* docs: remove TS workaround for Middleware

* ignore lint

* simplify
2022-07-15 04:39:15 +02:00
Balázs Orbán
bb664a27da fix(providers): typo in GitHub provider scope (#4938) 2022-07-15 04:38:42 +02:00
Balázs Orbán
a14fbea0b5 chore: add TODO comment for next major 2022-07-15 02:41:09 +02:00
Balázs Orbán
4705632c6b chore: add TODO comment for next major version 2022-07-15 02:38:59 +02:00
Balázs Orbán
2296471f02 chore: add pnpm to experimental release comment 2022-07-15 02:20:06 +02:00
S. Suzuki
8853000fd5 fix(ts): handleMiddleware return type can be NextMiddlewareResult (#4818)
Co-authored-by: Lluis Agusti <hi@llu.lu>
2022-07-14 00:20:19 +02:00
Balázs Orbán
70ffa6592f chore(release): bump package version(s) [skip ci] 2022-07-13 14:16:44 +02:00
mshd
3666e438a3 refactor(providers): convert GitHub provider to TypeScript (#4908)
* rewrite github provider in typescript

* rename md js endings

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

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

* add eslint disable next line

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-07-13 14:07:24 +02:00
Aliaksei Tayanouski
cdf467eba1 fix(providers): fix VK provider and convert to TS (#3709)
* renamed vk provider file extension to .ts

* lint issue fix

* vk provider fix

* formatting fix

* remove user_id from tokens

* Update src/providers/vk.ts

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

* Update src/providers/vk.ts

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

* user interface additions

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-07-13 14:04:55 +02:00
Balázs Orbán
374dc30f9f chore: bump pnpm version requirement 2022-07-13 14:01:25 +02:00
Balázs Orbán
d9534d807d chore: tweak release script 2022-07-13 13:59:45 +02:00
Balázs Orbán
f4c7401a5d chore: fix release script text 2022-07-13 13:09:08 +02:00
Balázs Orbán
2baa0c30c1 chore: bump turbo 2022-07-13 13:08:58 +02:00
Sagar Gajare
839b9108ea docs: provider link fixed (#4913) 2022-07-13 01:39:13 +02:00
Juho Tapio
0bf955a63d docs: a few typos in CONTRIBUTING.md (#4910)
* docs: fixed a typo

* docs: update link to scripts index

* docks: more typos

* docs: added a comma
2022-07-12 17:58:54 +02:00
Balázs Orbán
83a974d455 docs: update Middleware docs
closes #4867
2022-07-12 17:19:23 +02:00
Nico Domino
8f54b8f729 docs: upgrade docusaurus-plugin-npm2yarn2pnpm (#4909) 2022-07-12 16:52:21 +02:00
nkg
1b91282402 fix(ts): use correct type for nodemailer config in the EmailProvider (#4097)
Co-authored-by: Thang Vu <31528554+ThangHuuVu@users.noreply.github.com>
2022-07-12 02:50:09 +02:00
Ryan Barr
c2a9ab3023 fix(providers): convert Discord Provider to TypeScript (#4170)
* chore(providers): Add typings for Discord Provider

* Update DiscordProfile interface to extend Record.
2022-07-12 02:43:56 +02:00
Chancellor Clark
5bd00f6ff1 feat(adapters): update Firebase adapter to use new API (#3873)
Ports and refactors `@next-auth/firebase-adapter` to use the new Adapter API. Ported from this PR: nextauthjs/adapters#183

BREAKING CHANGE:

- Renames `FirebaseAdapter` export to `FirestoreAdpater`
- This adapter now requires firebase v9+
2022-07-12 01:45:06 +02:00
William Crutchfield
af3c2dd33d fix(ts): typo in Azure Active Directory Provider (#4895) 2022-07-11 18:24:09 +02:00
John Brunton
709edc5153 fix(adapters): use correct peer dependency in Sequelize adapter (#4880) 2022-07-11 18:23:04 +02:00
Balázs Orbán
fa3ea37ebc chore: comment out adapter in dev app 2022-07-11 18:20:53 +02:00
Yoann Fleury
6a364f0353 docs: update CONTRIBUTING for pnpm instead of yarn (#4888)
* docs: update CONTRIBUTING for pnpm instead of yarn

* dev:app -> dev

Co-authored-by: Thang Vu <31528554+ThangHuuVu@users.noreply.github.com>
2022-07-11 10:38:30 +07:00
mshd
c22d613774 feat(providers): Add Wikimedia Oauth Provider (#4813)
* Add Wikimedia Oauth Provider

* add docs

* Update wikimedia.md

* Update wikimedia.md

* Update wikimedia.md

Co-authored-by: Nico Domino <yo@ndo.dev>
2022-07-10 19:38:01 +02:00
Nico Domino
9efafcd36c chore: fix dev app URL parse error (#4887) 2022-07-10 14:30:10 +02:00
Misha Kaletsky
e317b16cd2 docs: getToken link (#4884)
fix(docs): getToken link

without `/` it's considered a relative link so goes to https://next-auth.js.org/configuration/tutorials/securing-pages-and-api-routes#using-gettoken which doesn't exist.
2022-07-09 22:46:38 +02:00
Rudy Boutte
2edc79ed2b fix(docs): options page link (#4876) 2022-07-09 12:56:20 +02:00
Balázs Orbán
637dda9966 chore: tweak release script 2022-07-08 19:55:08 +02:00
Balázs Orbán
10bb32c479 chore(adapters): fix MikroORM adapter dependencies 2022-07-08 19:36:24 +02:00
Balázs Orbán
89e25568b1 chore: accept --dry-run flag in release script 2022-07-08 19:31:04 +02:00
Balázs Orbán
88ad25a16b feat(adapters): update typeorm support (#4844)
We haven't kept up with the recent TypeORM changes, and since they are still <1, it's likely that users kept upgrading, even if there were breaking changes.

BREAKING CHANGE:

[`typeorm`](https://github.com/typeorm/typeorm) is still in active development and has not yet published a stable release. Because of this, you can expect breaking changes in minor versions. This release of the adapter expects `typeorm@0.3.7` and is not validated against previous or future releases.

Run `npm i typeorm@latest` and make sure to read the [release notes](https://github.com/typeorm/typeorm/releases) for breaking changes in TypeORM
2022-07-08 19:26:59 +02:00
Luiz Bett
c1f7ce3436 fix(ts): make colorScheme optional (#4868)
Documentation says if it is not passed it will be "auto", but it is mandatory on this type.
2022-07-08 19:24:30 +02:00
sean-nicholas
c59a4e04d1 fix(middleware): allow secret as option in Middleware (#4846)
*  provide secret via config

* 🐛 make secret optional

* 📝 docs for middleware and env var

* 📝  recommendation at the end of paragraph

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-07-07 14:14:21 +02:00
Joshua Grant
3c210d961b feat(providers): add Duende IdentityServer 6 (#4850)
* add duende identity server 6 provider

* Update docs/versioned_docs/version-v3/providers/duende-identity-server6.md

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

* Update docs/versioned_docs/version-v3/providers/duende-identity-server6.md

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

* Update packages/next-auth/src/providers/duende-identity-server6.ts

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

* Update packages/next-auth/src/providers/duende-identity-server6.ts

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

* Update docs/versioned_docs/version-v3/providers/duende-identity-server6.md

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

* Update apps/dev/pages/api/auth/[...nextauth].ts

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

* Update docs/versioned_docs/version-v3/providers/duende-identity-server6.md

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

* Update docs/versioned_docs/version-v3/providers/duende-identity-server6.md

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

* Update packages/next-auth/src/providers/duende-identity-server6.ts

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

Co-authored-by: Joshua <joshua.grant@tempcover.com>
Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-07-07 14:12:35 +02:00
Balázs Orbán
9457593038 chore: update Next.js example, bump dependencies 2022-07-07 11:31:17 +02:00
dependabot[bot]
5081d25f5c chore(deps): bump next-auth in /apps/playground-sveltekit (#4859)
Bumps [next-auth](https://github.com/nextauthjs/next-auth) from 4.5.0 to 4.9.0.
- [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.5.0...next-auth@v4.9.0)

---
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-07-07 00:34:27 +02:00
Rudy Boutte
384edbab3b docs: Added documentation on how to use a custom base path in NextAuth (#4858) 2022-07-07 00:34:12 +02:00
Balázs Orbán
2adfadefdc chore: bump version 2022-07-06 11:51:37 +02:00
Balázs Orbán
32fa01f939 chore: re-add GITHUB_TOKEN 2022-07-06 11:44:37 +02:00
Balázs Orbán
ae834f1e08 feat(providers): allow styling e-mail through theme option (#4841)
* fix(core): move email handling

* fix: don' use `replaceAll`

* feat(providers): re-use `theme` for e-mail

* docs: mention `theme` option for email

* fix: don't render user e-mail in the email HTML body

* docs: add missing comma

* refactor: fix lint

* refactor: fix lint
2022-07-05 16:02:04 +02:00
Nico Domino
4d4c276627 docs: replace npm2yarn with npm2yarn2pnpm docusaurus plugin (#4805)
* feat: rm npm2yarn add npm2yarn2pnpm plugin

* fix: pnpm-lock.yaml

* chore: test change

* fix: update npm2yarn2pnpm usage

* fix: package.json mistake packages added

* fix: pnpm-lock.yaml

* fix: test debug output

* fix: named import npm2yarn2pnpm

* chore: rm debug:true

* fix: change require statement

* Update pnpm-lock.yaml

* Update pnpm-lock.yaml

* Update pnpm-lock.yaml

* Update pnpm-lock.yaml

* Delete pnpm-lock.yaml

* add pnpm-lock.yaml

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-07-05 11:56:44 +02:00
Junichi Sato
f4c0d5ab5d docs: Correct grammatical error (#4836) 2022-07-05 00:25:46 -04:00
Nico Domino
01cd6b0f7b docs: fix unstable_getServerSession arguments (#4815)
* chore(docs): fix unstable_getServerSession arguments

* chore: add authOptions import
2022-07-03 23:27:37 +02:00
Nico Domino
993c0f46b0 fix: show experimental api warning only in dev and only once (#4816)
Co-authored-by: Lluis Agusti <hi@llu.lu>
2022-07-02 21:00:11 +02:00
252 changed files with 7551 additions and 5149 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"],
}

15
.github/CODEOWNERS vendored
View File

@@ -1,4 +1,11 @@
/types/ @balazsorban44 @lluia
/docs/ @balazsorban44 @ndom91
/adapters/ @balazsorban44 @ndom91
/__tests__/ @lluia
# Learn how to add code owners here:
# https://help.github.com/en/articles/about-code-owners
* @balazsorban44
.github @ThangHuuVu
/apps/ @lluia @ndom91 @ThangHuuVu
/docs/ @lluia @ndom91
/packages/ @ThangHuuVu
/packages/adapter-*/ @ndom91
/**/*test* @lluia
/**/*type* @lluia

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

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

@@ -10,7 +10,7 @@ providers:
adapters:
- packages/next-auth/src/adapters.ts
- packages/*-adapter/**
- packages/adapter-*/**
dgraph:
- packages/adapter-dgraph/**

View File

@@ -4,5 +4,5 @@ outputs:
version:
description: "npm package version"
runs:
using: "node12"
using: "node16"
main: "index.js"

View File

@@ -21,7 +21,7 @@ jobs:
- name: Install pnpm
uses: pnpm/action-setup@v2.2.1
with:
version: 6.32.8
version: 7.5.1
- name: Setup Node
uses: actions/setup-node@v3
with:
@@ -55,7 +55,7 @@ jobs:
- name: Install pnpm
uses: pnpm/action-setup@v2.2.1
with:
version: 6.32.8
version: 7.5.1
- name: Setup Node
uses: actions/setup-node@v3
with:
@@ -70,6 +70,7 @@ jobs:
pnpm release
env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
NPM_TOKEN_PKG: ${{ secrets.NPM_TOKEN_PKG }}
NPM_TOKEN_ORG: ${{ secrets.NPM_TOKEN_ORG }}
release-pr:
@@ -84,7 +85,7 @@ jobs:
- name: Install pnpm
uses: pnpm/action-setup@v2.2.1
with:
version: 6.32.8
version: 7.5.1
- name: Setup Node
uses: actions/setup-node@v3
with:
@@ -107,7 +108,11 @@ jobs:
- name: Comment version on PR
uses: NejcZdovc/comment-pr@v1
with:
message: "🎉 Experimental release [published on npm](https://www.npmjs.com/package/next-auth/v/${{ env.VERSION }})!\n\n```sh\nnpm i next-auth@${{ env.VERSION }}\n```\n```sh\nyarn add next-auth@${{ env.VERSION }}\n```"
message:
"🎉 Experimental release [published 📦️ on npm](https://npmjs.com/package/next-auth/v/${{ env.VERSION }})!\n \
```sh\npnpm add next-auth@${{ env.VERSION }}\n```\n \
```sh\nyarn add next-auth@${{ env.VERSION }}\n```\n \
```sh\nnpm i next-auth@${{ env.VERSION }}\n```"
env:
VERSION: ${{ steps.determine-version.outputs.version }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

2
.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
@@ -44,6 +45,7 @@ packages/next-auth/middleware.js
# Development app
apps/dev/src/css
apps/dev/prisma/migrations
apps/dev/typeorm
# VS
/.vs/slnx.sqlite-journal

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

@@ -17,7 +17,7 @@ Anyone can be a contributor. Either you found a typo, or you have an awesome fea
- The latest changes are always in `main`, so please make your Pull Request against that branch.
- Pull Requests should be raised for any change
- Pull Requests need approval of a [core contributor](https://next-auth.js.org/contributors#core-team) before merging
- We use ESLint/Prettier for linting/formatting, so please run `yarn lint:fix` before committing to make resolving conflicts easier (VSCode users, check out [this ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and [this Prettier extension](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) to fix lint and formatting issues in development)
- We use ESLint/Prettier for linting/formatting, so please run `pnpm lint:fix` before committing to make resolving conflicts easier (VSCode users, check out [this ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and [this Prettier extension](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) to fix lint and formatting issues in development)
- We encourage you to test your changes, and if you have the opportunity, please make those tests part of the Pull Request
- If you add new functionality, please provide the corresponding documentation as well and make it part of the Pull Request
@@ -37,7 +37,7 @@ cd next-auth
1. Install packages. Developing requires Node.js v16:
```sh
yarn
pnpm install
```
3. Populate `.env.local`:
@@ -55,7 +55,7 @@ cp .env.local.example .env.local
4. Start the developer application/server:
```sh
yarn dev:app
pnpm dev
```
Your developer application will be available on `http://localhost:3000`
@@ -65,7 +65,7 @@ If you need an example project to link to, you can use [next-auth-example](https
#### Hot reloading
When running `yarn dev:app`, you start a Next.js developer server on `http://localhost:3000`, which includes hot reloading out of the box. Make changes on any of the files in `src` and see the changes immediately.
When running `pnpm dev`, you start a Next.js developer server on `http://localhost:3000`, which includes hot reloading out-of-the-box. Make changes on any of the files in `src` and see the changes immediately.
> NOTE: When working on CSS, you will have to manually refresh the page after changes. The reason for this is our pages using CSS are server-side rendered (using API routes). (Improving this through a PR is very welcome!)
@@ -75,7 +75,7 @@ When running `yarn dev:app`, you start a Next.js developer server on `http://loc
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! You only need to add two changes:
1. Add your config: [`src/providers/{provider}.js`](https://github.com/nextauthjs/next-auth/tree/main/src/providers) (Make sure you use a named default export, like `export default function YourProvider`!)
1. Add your config: [`src/providers/{provider}.js`](https://github.com/nextauthjs/next-auth/tree/main/packages/next-auth/src/providers) (Make sure you use a named default export, like `export default function YourProvider`!)
2. Add provider documentation: [`www/docs/providers/{provider}.md`](https://github.com/nextauthjs/next-auth/tree/main/www/docs/providers)
That's it! 🎉 Others will be able to discover this provider much more easily now!
@@ -88,13 +88,13 @@ If you would like to contribute to an existing database adapter or help create a
#### Testing
Tests can be run with `yarn test`.
Tests can be run with `pnpm test`.
Automated tests are currently crude and limited in functionality, but improvements are in development.
## For maintainers
We use [a custom script](https://github.com/nextauthjs/next-auth/tree/main/scripts/index.ts) together with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0) to automate releases. This makes the maintenance process easier and less error-prone. Please study the "Conventional Commits" site to understand how to write a good commit message.
We use [a custom script](https://github.com/nextauthjs/next-auth/blob/main/scripts/release/index.ts) together with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0) to automate releases. This makes the maintenance process easier and less error-prone. Please study the "Conventional Commits" site to understand how to write a good commit message.
When accepting Pull Requests, make sure the following:
@@ -103,9 +103,9 @@ When accepting Pull Requests, make sure the following:
- Rewrite the commit message to conform to the `Conventional Commits` style.
- Using `fix` releases a patch (x.x.1)
- Using `feat` releases a minor (x.1.x)
- Using `feat` when `BREAKING CHANGE` is present in the commit messgae releases a major (1.x.x)
- Using `feat` when `BREAKING CHANGE` is present in the commit message releases a major (1.x.x)
- Optionally link issues the PR will resolve (You can add "close" in front of the issue numbers to close the issues automatically, when the PR is merged. `semantic-release` will also comment back to connected issues and PRs, notifying the users that a feature is added/bug fixed, etc.)
### Skipping a release
If a commit contains `[skip release]` in their message will be excluded from the commit analysis and won't participate in the release type determination. This is useful, if the PR being merged should not trigger a new `npm` release.
If a commit contains `[skip release]` in their message, it will be excluded from the commit analysis and won't participate in the release type determination. This is useful, if the PR being merged should not trigger a new `npm` release.

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

@@ -47,6 +47,5 @@ EMAIL_FROM=user@gmail.com
# MongoDB: DATABASE_URL=mongodb://nextauth:password@127.0.0.1:27017/nextauth?synchronize=true
DATABASE_URL=
BOXYHQSAML_ISSUER="https://jackson-demo.boxyhq.com"
BOXYHQSAML_ID="tenant=boxyhq.com&product=saml-demo.boxyhq.com"
BOXYHQSAML_SECRET="dummy"
WIKIMEDIA_ID=
WIKIMEDIA_SECRET=

View File

@@ -30,12 +30,11 @@ export const config = { matcher: ["/middleware-protected"] }
// export default withAuth(
// function middleware(req, ev) {
// console.log(req, ev)
// return undefined // NOTE: `NextMiddleware` should allow returning `void`
// },
// {
// callbacks: {
// authorized: ({ token }) => token.name === "Balázs Orbán",
// }
// },
// }
// )

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",
@@ -16,21 +14,24 @@
},
"license": "ISC",
"dependencies": {
"@next-auth/fauna-adapter": "^1",
"@next-auth/prisma-adapter": "^1",
"@next-auth/fauna-adapter": "workspace:*",
"@next-auth/prisma-adapter": "workspace:*",
"@next-auth/typeorm-legacy-adapter": "workspace:*",
"@prisma/client": "^3",
"faunadb": "^4",
"next": "12.1.7-canary.51",
"next": "12.2.0",
"next-auth": "workspace:*",
"nodemailer": "^6",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@types/react": "^18",
"@types/react-dom": "^18",
"concurrently": "^7",
"cpx": "^1.5.0",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"fake-smtp-server": "^0.8.0",
"prisma": "^3"
"pg": "^8.7.3",
"prisma": "^3",
"sqlite3": "^5.0.8",
"typeorm": "0.3.7"
}
}

View File

@@ -1,218 +1,138 @@
import NextAuth, { NextAuthOptions } from "next-auth"
// import EmailProvider from "next-auth/providers/email"
import GitHubProvider from "next-auth/providers/github"
import Auth0Provider from "next-auth/providers/auth0"
import KeycloakProvider from "next-auth/providers/keycloak"
import TwitterProvider, {
TwitterLegacy as TwitterLegacyProvider,
} from "next-auth/providers/twitter"
import CredentialsProvider from "next-auth/providers/credentials"
import IDS4Provider from "next-auth/providers/identity-server4"
import Twitch from "next-auth/providers/twitch"
import GoogleProvider from "next-auth/providers/google"
import FacebookProvider from "next-auth/providers/facebook"
import FoursquareProvider from "next-auth/providers/foursquare"
// import FreshbooksProvider from "next-auth/providers/freshbooks"
import GitlabProvider from "next-auth/providers/gitlab"
import InstagramProvider from "next-auth/providers/instagram"
import LineProvider from "next-auth/providers/line"
import LinkedInProvider from "next-auth/providers/linkedin"
import MailchimpProvider from "next-auth/providers/mailchimp"
import DiscordProvider from "next-auth/providers/discord"
import AzureADProvider from "next-auth/providers/azure-ad"
import SpotifyProvider from "next-auth/providers/spotify"
import CognitoProvider from "next-auth/providers/cognito"
import SlackProvider from "next-auth/providers/slack"
import Okta from "next-auth/providers/okta"
import NextAuth from "next-auth"
import type { NextAuthOptions } from "next-auth"
// Providers
import Apple from "next-auth/providers/apple"
import Auth0 from "next-auth/providers/auth0"
import AzureAD from "next-auth/providers/azure-ad"
import AzureB2C from "next-auth/providers/azure-ad-b2c"
import OsuProvider from "next-auth/providers/osu"
import AppleProvider from "next-auth/providers/apple"
import PatreonProvider from "next-auth/providers/patreon"
import TraktProvider from "next-auth/providers/trakt"
import WorkOSProvider from "next-auth/providers/workos"
import BoxyHQSAMLProvider from "next-auth/providers/boxyhq-saml"
import BoxyHQSAML from "next-auth/providers/boxyhq-saml"
import Cognito from "next-auth/providers/cognito"
import Credentials from "next-auth/providers/credentials"
import Discord from "next-auth/providers/discord"
import DuendeIDS6 from "next-auth/providers/duende-identity-server6"
import Email from "next-auth/providers/email"
import Facebook from "next-auth/providers/facebook"
import Foursquare from "next-auth/providers/foursquare"
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"
import Line from "next-auth/providers/line"
import LinkedIn from "next-auth/providers/linkedin"
import Mailchimp from "next-auth/providers/mailchimp"
import Okta from "next-auth/providers/okta"
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 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"
// import { PrismaAdapter } from "@next-auth/prisma-adapter"
// import { PrismaClient } from "@prisma/client"
// const prisma = new PrismaClient()
// const adapter = PrismaAdapter(prisma)
// 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"
// import { Client as FaunaClient } from "faunadb"
// import { FaunaAdapter } from "@next-auth/fauna-adapter"
// const client = new FaunaClient({
// secret: process.env.FAUNA_SECRET,
// domain: process.env.FAUNA_DOMAIN,
// })
// const adapter = FaunaAdapter(client)
export const authOptions: NextAuthOptions = {
// adapter,
providers: [
// E-mail
// Start fake e-mail server with `npm run start:email`
// EmailProvider({
// server: {
// host: "127.0.0.1",
// auth: null,
// secure: false,
// port: 1025,
// tls: { rejectUnauthorized: false },
// },
// }),
// Credentials
CredentialsProvider({
name: "Credentials",
credentials: {
password: { label: "Password", type: "password" },
},
async authorize(credentials) {
if (credentials.password === "pw") {
return {
name: "Fill Murray",
email: "bill@fillmurray.com",
image: "https://www.fillmurray.com/64/64",
}
}
return null
},
}),
// OAuth 1
// TwitterLegacyProvider({
// clientId: process.env.TWITTER_LEGACY_ID,
// clientSecret: process.env.TWITTER_LEGACY_SECRET,
// }),
// OAuth 2 / OIDC
TwitterProvider({
// Opt-in to the new Twitter API for now. Should be default in the future.
version: "2.0",
clientId: process.env.TWITTER_ID,
clientSecret: process.env.TWITTER_SECRET,
}),
GitHubProvider({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
Auth0Provider({
clientId: process.env.AUTH0_ID,
clientSecret: process.env.AUTH0_SECRET,
issuer: process.env.AUTH0_ISSUER,
}),
KeycloakProvider({
clientId: process.env.KEYCLOAK_ID,
clientSecret: process.env.KEYCLOAK_SECRET,
issuer: process.env.KEYCLOAK_ISSUER,
}),
Twitch({
clientId: process.env.TWITCH_ID,
clientSecret: process.env.TWITCH_SECRET,
}),
GoogleProvider({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
}),
FacebookProvider({
clientId: process.env.FACEBOOK_ID,
clientSecret: process.env.FACEBOOK_SECRET,
}),
FoursquareProvider({
clientId: process.env.FOURSQUARE_ID,
clientSecret: process.env.FOURSQUARE_SECRET,
}),
// FreshbooksProvider({
// clientId: process.env.FRESHBOOKS_ID,
// clientSecret: process.env.FRESHBOOKS_SECRET,
// }),
GitlabProvider({
clientId: process.env.GITLAB_ID,
clientSecret: process.env.GITLAB_SECRET,
}),
InstagramProvider({
clientId: process.env.INSTAGRAM_ID,
clientSecret: process.env.INSTAGRAM_SECRET,
}),
LineProvider({
clientId: process.env.LINE_ID,
clientSecret: process.env.LINE_SECRET,
}),
LinkedInProvider({
clientId: process.env.LINKEDIN_ID,
clientSecret: process.env.LINKEDIN_SECRET,
}),
MailchimpProvider({
clientId: process.env.MAILCHIMP_ID,
clientSecret: process.env.MAILCHIMP_SECRET,
}),
IDS4Provider({
clientId: process.env.IDS4_ID,
clientSecret: process.env.IDS4_SECRET,
issuer: process.env.IDS4_ISSUER,
}),
DiscordProvider({
clientId: process.env.DISCORD_ID,
clientSecret: process.env.DISCORD_SECRET,
}),
AzureADProvider({
clientId: process.env.AZURE_AD_CLIENT_ID,
clientSecret: process.env.AZURE_AD_CLIENT_SECRET,
tenantId: process.env.AZURE_AD_TENANT_ID,
profilePhotoSize: 48,
}),
SpotifyProvider({
clientId: process.env.SPOTIFY_ID,
clientSecret: process.env.SPOTIFY_SECRET,
}),
CognitoProvider({
clientId: process.env.COGNITO_ID,
clientSecret: process.env.COGNITO_SECRET,
issuer: process.env.COGNITO_ISSUER,
}),
Okta({
clientId: process.env.OKTA_ID,
clientSecret: process.env.OKTA_SECRET,
issuer: process.env.OKTA_ISSUER,
}),
SlackProvider({
clientId: process.env.SLACK_ID,
clientSecret: process.env.SLACK_SECRET,
}),
AzureB2C({
clientId: process.env.AZURE_B2C_ID,
clientSecret: process.env.AZURE_B2C_SECRET,
tenantId: process.env.AZURE_B2C_TENANT_ID,
primaryUserFlow: process.env.AZURE_B2C_PRIMARY_USER_FLOW,
}),
OsuProvider({
clientId: process.env.OSU_CLIENT_ID,
clientSecret: process.env.OSU_CLIENT_SECRET,
}),
AppleProvider({
clientId: process.env.APPLE_ID,
clientSecret: process.env.APPLE_SECRET,
}),
PatreonProvider({
clientId: process.env.PATREON_ID,
clientSecret: process.env.PATREON_SECRET,
}),
TraktProvider({
clientId: process.env.TRAKT_ID,
clientSecret: process.env.TRAKT_SECRET,
}),
WorkOSProvider({
clientId: process.env.WORKOS_ID,
clientSecret: process.env.WORKOS_SECRET,
}),
BoxyHQSAMLProvider({
issuer: process.env.BOXYHQSAML_ISSUER,
clientId: process.env.BOXYHQSAML_ID,
clientSecret: process.env.BOXYHQSAML_SECRET,
}),
],
debug: true,
theme: {
colorScheme: "auto",
logo: "https://next-auth.js.org/img/logo/logo-sm.png",
brandColor: "#1786fb",
// 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
},
}
export const authOptions: NextAuthOptions = {
adapter: adapters.noop(),
debug: true,
theme: {
logo: "https://next-auth.js.org/img/logo/logo-sm.png",
brandColor: "#1786fb",
},
providers: [
Credentials({
credentials: { password: { label: "Password", type: "password" } },
async authorize(credentials) {
if (credentials.password !== "pw") return null
return { name: "Fill Murray", email: "bill@fillmurray.com", image: "https://www.fillmurray.com/64/64" }
},
}),
Apple({ clientId: process.env.APPLE_ID, clientSecret: process.env.APPLE_SECRET }),
Auth0({ clientId: process.env.AUTH0_ID, clientSecret: process.env.AUTH0_SECRET, issuer: process.env.AUTH0_ISSUER }),
AzureAD({ clientId: process.env.AZURE_AD_CLIENT_ID, clientSecret: process.env.AZURE_AD_CLIENT_SECRET, tenantId: process.env.AZURE_AD_TENANT_ID }),
AzureB2C({ clientId: process.env.AZURE_B2C_ID, clientSecret: process.env.AZURE_B2C_SECRET, issuer: process.env.AZURE_B2C_ISSUER }),
BoxyHQSAML({ issuer: "https://jackson-demo.boxyhq.com", clientId: "tenant=boxyhq.com&product=saml-demo.boxyhq.com", clientSecret: "dummy" }),
Cognito({ clientId: process.env.COGNITO_ID, clientSecret: process.env.COGNITO_SECRET, issuer: process.env.COGNITO_ISSUER }),
Discord({ clientId: process.env.DISCORD_ID, clientSecret: process.env.DISCORD_SECRET }),
DuendeIDS6({ clientId: "interactive.confidential", clientSecret: "secret", issuer: "https://demo.duendesoftware.com" }),
Facebook({ clientId: process.env.FACEBOOK_ID, clientSecret: process.env.FACEBOOK_SECRET }),
Foursquare({ clientId: process.env.FOURSQUARE_ID, clientSecret: process.env.FOURSQUARE_SECRET }),
Freshbooks({ clientId: process.env.FRESHBOOKS_ID, clientSecret: process.env.FRESHBOOKS_SECRET }),
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 }),
Line({ clientId: process.env.LINE_ID, clientSecret: process.env.LINE_SECRET }),
LinkedIn({ clientId: process.env.LINKEDIN_ID, clientSecret: process.env.LINKEDIN_SECRET }),
Mailchimp({ clientId: process.env.MAILCHIMP_ID, clientSecret: process.env.MAILCHIMP_SECRET }),
Okta({ clientId: process.env.OKTA_ID, clientSecret: process.env.OKTA_SECRET, issuer: process.env.OKTA_ISSUER }),
Osu({ clientId: process.env.OSU_CLIENT_ID, clientSecret: process.env.OSU_CLIENT_SECRET }),
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 }),
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 }),
TwitterLegacy({ clientId: process.env.TWITTER_LEGACY_ID, clientSecret: process.env.TWITTER_LEGACY_SECRET }),
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 }),
],
}
if (authOptions.adapter) {
authOptions.providers.unshift(
// NOTE: You can start a fake e-mail server with `pnpm email`
// and then go to `http://localhost:1080` in the browser
Email({ server: "smtp://127.0.0.1:1025?tls.rejectUnauthorized=false" })
)
}
export default NextAuth(authOptions)

View File

@@ -2,6 +2,6 @@
import { getToken } from "next-auth/jwt"
export default async (req, res) => {
const token = await getToken({ req, secret: process.env.SECRET })
const token = await getToken({ req })
res.send(JSON.stringify(token, null, 2))
}

View File

@@ -1,8 +1,9 @@
// 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({

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"]

View File

@@ -3,9 +3,14 @@ import { withAuth } from "next-auth/middleware"
// More on how NextAuth.js middleware works: https://next-auth.js.org/configuration/nextjs#middleware
export default withAuth({
callbacks: {
authorized: ({ req, token }) =>
// /admin requires admin role, but /me only requires the user to be logged in.
req.nextUrl.pathname !== "/admin" || token?.userRole === "admin",
authorized({ req, token }) {
// `/admin` requires admin role
if (req.nextUrl.pathname === "/admin") {
return token?.userRole === "admin"
}
// `/me` only requires the user to be logged in
return !!token
},
},
})

View File

@@ -1,19 +1,15 @@
{
"name": "next-auth-example",
"version": "0.0.0",
"private": true,
"description": "An example project for NextAuth.js",
"description": "An example project for NextAuth.js with Next.js",
"repository": "https://github.com/nextauthjs/next-auth-example.git",
"bugs": {
"url": "https://github.com/nextauthjs/next-auth/issues"
},
"homepage": "https://next-auth-example.vercel.app",
"main": "",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start",
"types": "tsc --noEmit"
"start": "next start"
},
"author": "Iain Collins <me@iaincollins.com>",
"contributors": [
@@ -21,20 +17,16 @@
"Nico Domino <yo@ndo.dev>",
"Lluis Agusti <hi@llu.lu>"
],
"license": "ISC",
"dependencies": {
"next": "12.1.7-canary.51",
"next": "latest",
"next-auth": "latest",
"nodemailer": "^6",
"react": "^18",
"react-dom": "^18"
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/node": "^17",
"@types/react": "^18",
"@types/react": "^18.0.15",
"typescript": "^4"
},
"prettier": {
"semi": false
}
}

View File

@@ -1,12 +1,17 @@
import { SessionProvider } from "next-auth/react"
import type { AppProps } from "next/app"
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

@@ -1,10 +1,14 @@
// This is an example of how to read a JSON Web Token from an API route
import { getToken } from "next-auth/jwt"
import type { NextApiRequest, NextApiResponse } from "next"
const secret = process.env.NEXTAUTH_SECRET
export default async (req: NextApiRequest, res: NextApiResponse) => {
const token = await getToken({ req, secret })
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
// If you don't have the NEXTAUTH_SECRET environment variable set,
// you will have to pass your secret as `secret` to `getToken`
const token = await getToken({ req })
res.send(JSON.stringify(token, null, 2))
}

View File

@@ -1,19 +1,23 @@
// This is an example of to protect an API route
import { unstable_getServerSession } from "next-auth/next"
import { authOptions } from "../auth/[...nextauth]"
import type { NextApiRequest, NextApiResponse } from "next"
export default async (req: NextApiRequest, res: NextApiResponse) => {
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const session = await unstable_getServerSession(req, res, authOptions)
if (session) {
res.send({
return res.send({
content:
"This is protected content. You can access this content because you are signed in.",
})
} else {
res.send({
error:
"You must be signed in to view the protected content on this page.",
})
}
res.send({
error: "You must be signed in to view the protected content on this page.",
})
}

View File

@@ -1,8 +1,13 @@
// This is an example of how to access a session from an API route
import { getSession } from "next-auth/react"
import { unstable_getServerSession } from "next-auth"
import { authOptions } from "../auth/[...nextauth]"
import type { NextApiRequest, NextApiResponse } from "next"
export default async (req: NextApiRequest, res: NextApiResponse) => {
const session = await getSession({ req })
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const session = await unstable_getServerSession(req, res, authOptions)
res.send(JSON.stringify(session, null, 2))
}

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,12 +1,13 @@
import { unstable_getServerSession } from "next-auth/next"
import { authOptions } from "./api/auth/[...nextauth]"
import Layout from "../components/layout"
import type { NextPageContext } from "next"
export default function ServerSidePage({ session }) {
import type { GetServerSidePropsContext } from "next"
import type { Session } from "next-auth"
export default function ServerSidePage({ session }: { session: Session }) {
// As this page uses Server Side Rendering, the `session` will be already
// populated on render without needing to go through a loading stage.
return (
<Layout>
<h1>Server Side Rendering</h1>
@@ -28,15 +29,20 @@ export default function ServerSidePage({ session }) {
The disadvantage of Server Side Rendering is that this page is slower to
render.
</p>
<pre>{JSON.stringify(session, null, 2)}</pre>
</Layout>
)
}
// Export the `session` prop to use sessions with Server Side Rendering
export async function getServerSideProps(context: NextPageContext) {
export async function getServerSideProps(context: GetServerSidePropsContext) {
return {
props: {
session: await unstable_getServerSession(context.req, context.res, authOptions),
session: await unstable_getServerSession(
context.req,
context.res,
authOptions
),
},
}
}

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

@@ -6,82 +6,60 @@ SvelteKit support with NextAuth.js is currently experimental. This directory con
## 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,38 @@
{
"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",
"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",
"svelte": "^3.44.0",
"svelte-check": "^2.2.6",
"svelte-preprocess": "^4.10.1",
"tslib": "^2.3.1",
"typescript": "~4.5.4"
"@sveltejs/adapter-auto": "1.0.0-next.66",
"@sveltejs/kit": "1.0.0-next.443",
"@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.8.1",
"svelte-preprocess": "^4.10.7",
"tslib": "^2.4.0",
"typescript": "~4.8.2",
"vite": "^2.9.13"
},
"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

@@ -1,13 +1,12 @@
<!DOCTYPE html>
<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%
</head>
<body>
<div>%svelte.body%</div>
</body>
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body>
<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

@@ -1,24 +1,12 @@
import { getServerSession } from "$lib"
import type { Session } from "next-auth"
import type { NextAuthOptions } from "next-auth"
import GithubProvider from "next-auth/providers/github"
import type { Handle } from "@sveltejs/kit"
import { getServerSession, options as nextAuthOptions } from "$lib/next-auth"
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> {
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): 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,29 +1,53 @@
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 {
GITHUB_CLIENT_ID,
GITHUB_CLIENT_SECRET,
NEXTAUTH_SECRET,
} from "$env/static/private"
import { PUBLIC_NEXTAUTH_URL } from "$env/static/public"
import getFormBody from "./utils/get-form-body"
async function toSvelteKitResponse(
request: Request,
nextAuthResponse: OutgoingResponse<unknown>
) {
const { headers, cookies, body, redirect, status = 200 } = nextAuthResponse
const github = GithubProvider?.default || GithubProvider
const response = {
status,
headers: {},
export const options: NextAuthOptions = {
providers: [
github({
clientId: GITHUB_CLIENT_ID,
clientSecret: GITHUB_CLIENT_SECRET,
}),
],
}
const toSvelteKitResponse = async (
request: Request,
nextAuthResponse: NextAuthResponse<unknown>
): Promise<Response> => {
const { cookies, redirect } = nextAuthResponse
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
@@ -34,41 +58,45 @@ async function toSvelteKitResponse(
// no formData passed
}
if (formData?.json !== "true") {
response.status = 302
response.headers["Location"] = redirect
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 = 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,
options.secret = NEXTAUTH_SECRET
const req: RequestInternal = {
host: PUBLIC_NEXTAUTH_URL,
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 +107,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 +126,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) => Promise<unknown>
POST: (event) => Promise<unknown>
} => ({
get: (req) => SKNextAuthHandler(req, options),
post: (req) => SKNextAuthHandler(req, options),
GET: (event) => SKNextAuthHandler(event, options),
POST: (event) => SKNextAuthHandler(event, options),
})

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

@@ -9,6 +9,11 @@ const config = {
kit: {
adapter: adapter(),
// Override http methods in the Todo forms
methodOverride: {
allowed: ["PATCH", "DELETE"],
},
},
}

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

@@ -11,11 +11,11 @@ This is the Dgraph Adapter for [`next-auth`](https://next-auth.js.org).
1. Install the necessary packages
```bash npm2yarn
```bash npm2yarn2pnpm
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"
@@ -226,22 +226,22 @@ database you must customize next-auth `encode` and `decode` functions, as the de
further customize the jwt with roles if you want to implement [`RBAC logic`](https://dgraph.io/docs/graphql/authorization/directive/#role-based-access-control).
```js
import * as jwt from "jsonwebtoken";
import * as jwt from "jsonwebtoken"
export default NextAuth({
session: {
strategy: "jwt"
strategy: "jwt",
},
jwt: {
secret: process.env.SECRET,
encode: async ({ secret, token }) => {
return jwt.sign({...token, userId: token.id}, secret, {
return jwt.sign({ ...token, userId: token.id }, secret, {
algorithm: "HS256",
expiresIn: 30 * 24 * 60 * 60, // 30 days
});
})
},
decode: async ({ secret, token }) => {
return jwt.verify(token, secret, { algorithms: ["HS256"] });
}
return jwt.verify(token, secret, { algorithms: ["HS256"] })
},
},
})
```

View File

@@ -15,7 +15,7 @@ You can find the full schema in the table structure section below.
1. Install `next-auth` and `@next-auth/dynamodb-adapter`
```bash npm2yarn
```bash npm2yarn2pnpm
npm install next-auth @next-auth/dynamodb-adapter
```

View File

@@ -13,11 +13,11 @@ You can find the Fauna schema and seed information in the docs at [next-auth.js.
1. Install the necessary packages
```bash npm2yarn
```bash npm2yarn2pnpm
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

@@ -5,18 +5,14 @@ title: Firebase
# Firebase
:::warning
This adapter is still experimental and does not work with NextAuth.js 4 or newer. If you would like to help out upgrading it, please visit [this PR](https://github.com/nextauthjs/next-auth/pull/3873)
:::
This is the Firebase Adapter for [`next-auth`](https://next-auth.js.org). This package can only be used in conjunction with the primary `next-auth` package. It is not a standalone package.
This is the Firebase (Firestore) Adapter for [`next-auth`](https://next-auth.js.org). This package can only be used in conjunction with the primary `next-auth` package. It is not a standalone package.
## Getting Started
1. Install the necessary packages
```bash npm2yarn
npm install next-auth @next-auth/firebase-adapter@experimental
```bash npm2yarn2pnpm
npm install next-auth @next-auth/firebase-adapter
```
2. Add this adapter to your `pages/api/auth/[...nextauth].js` next-auth configuration object.
@@ -24,28 +20,31 @@ npm install next-auth @next-auth/firebase-adapter@experimental
```javascript title="pages/api/auth/[...nextauth].js"
import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google"
import { FirebaseAdapter } from "@next-auth/firebase-adapter"
import firebase from "firebase/app"
import "firebase/firestore"
const firestore = (
firebase.apps[0] ?? firebase.initializeApp(/* your config */)
).firestore()
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,
clientSecret: process.env.GOOGLE_SECRET,
}),
],
adapter: FirebaseAdapter(firestore),
...
})
adapter: FirestoreAdapter({
apiKey: process.env.FIREBASE_API_KEY,
appId: process.env.FIREBASE_APP_ID,
authDomain: process.env.FIREBASE_AUTH_DOMAIN,
databaseURL: process.env.FIREBASE_DATABASE_URL,
projectId: process.env.FIREBASE_PROJECT_ID,
storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
// Optional emulator config (see below for options)
emulator: {},
}),
// ...
});
```
## Options
@@ -69,6 +68,21 @@ const firebaseConfig = {
See [firebase.google.com/docs/web/setup](https://firebase.google.com/docs/web/setup) for more details.
You can optionally pass in emulator options to automatically connect to your local Firebase emulator.
```js
FirestoreAdapter({
// ...
// Passing in an enable object will enable the emulator
emulator: {
// Optional host, defaults to `localhost`
host: 'localhost',
// Optional port, defaults to `3001`
port: 3001,
},
}),
```
:::tip **From Firebase**
**Caution**: We do not recommend manually modifying an app's Firebase config file or object. If you initialize an app with invalid or missing values for any of these required "Firebase options", then your end users may experience serious issues.

View File

@@ -5,7 +5,7 @@ title: MikroORM
To use this Adapter, you need to install Mikro ORM, the driver that suits your database, and the separate `@next-auth/mikro-orm-adapter` package:
```bash npm2yarn
```bash npm2yarn2pnpm
npm install next-auth @next-auth/mikro-orm-adapter @mikro-orm/core @mikro-orm/[YOUR DRIVER]
```

View File

@@ -11,7 +11,7 @@ The MongoDB adapter does not handle connections automatically, so you will have
1. Install the necessary packages
```bash npm2yarn
```bash npm2yarn2pnpm
npm install next-auth @next-auth/mongodb-adapter mongodb
```
@@ -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

@@ -11,11 +11,11 @@ This is the Neo4j Adapter for [`next-auth`](https://next-auth.js.org). This pack
1. Install the necessary packages
```bash npm2yarn
```bash npm2yarn2pnpm
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

@@ -19,7 +19,7 @@ Depending on your architecture you can use PouchDB's http adapter to reach any d
1. Install `next-auth` and `@next-auth/pouchdb-adapter`
```bash npm2yarn
```bash npm2yarn2pnpm
npm install next-auth @next-auth/pouchdb-adapter
```

View File

@@ -7,20 +7,33 @@ title: Prisma
To use this Adapter, you need to install Prisma Client, Prisma CLI, and the separate `@next-auth/prisma-adapter` package:
```bash npm2yarn
```bash npm2yarn2pnpm
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

@@ -11,7 +11,7 @@ This is the Sequelize Adapter for [`next-auth`](https://next-auth.js.org).
1. Install the necessary packages
```bash npm2yarn
```bash npm2yarn2pnpm
npm install next-auth @next-auth/sequelize-adapter sequelize
```
@@ -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

@@ -5,21 +5,25 @@ title: TypeORM
# TypeORM
This Adapter is used to support SQL-flavored databases (like SQLite, MySQL, MSSQL, MariaDB, CockroachDB, etc.) through [TypeORM](https://typeorm.io), and mostly kept around for legacy reasons. (See the warning below.)
This Adapter is used to support SQL-flavored databases (like SQLite, MySQL, MSSQL, MariaDB, CockroachDB, etc.) through [TypeORM](https://typeorm.io).
:::note
If you previously used this Adapter with MongoDB, check out the [MongoDB Adapter](/adapters/mongodb) instead.
:::
:::warning
:::note
In the future, we might split up this adapter to support single flavors of SQL for easier maintenance and reduced bundle size.
:::
## Usage
:::warning
[`typeorm`](https://github.com/typeorm/typeorm) is still in active development and has not yet published a stable release. Because of this, you can expect breaking changes in minor versions. This adapter expects `typeorm@0.3.7` and is not validated against previous or future releases.
:::
To use this Adapter, you need to install the following packages:
```bash npm2yarn
```bash npm2yarn2pnpm
npm install next-auth @next-auth/typeorm-legacy-adapter typeorm
```
@@ -36,7 +40,7 @@ export default NextAuth({
})
```
`TypeORMLegacyAdapter` takes either a connection string, or a [`ConnectionOptions`](https://github.com/typeorm/typeorm/blob/master/docs/connection-options.md) object as its first parameter.
`TypeORMLegacyAdapter` takes either a connection string, or a [`DataSourceOptions`](https://github.com/typeorm/typeorm/blob/master/docs/data-source-options.md) object as its first parameter.
## Custom models
@@ -217,9 +221,9 @@ For example, you can add the naming convention option to the connection object i
import NextAuth from "next-auth"
import { TypeORMLegacyAdapter } from "@next-auth/typeorm-legacy-adapter"
import { SnakeNamingStrategy } from 'typeorm-naming-strategies'
import { ConnectionOptions } from "typeorm"
const connection: ConnectionOptions = {
export default NextAuth({
adapter: TypeORMLegacyAdapter({
type: "mysql",
host: "localhost",
port: 3306,
@@ -227,10 +231,7 @@ const connection: ConnectionOptions = {
password: "test",
database: "test",
namingStrategy: new SnakeNamingStrategy()
}
export default NextAuth({
adapter: TypeORMLegacyAdapter(connection),
}),
...
})
```

View File

@@ -7,7 +7,7 @@ title: Upstash Redis
To use this Adapter, you need to install `@upstash/redis` and `@next-auth/upstash-redis-adapter` package:
```bash npm2yarn
```bash npm2yarn2pnpm
npm install @upstash/redis @next-auth/upstash-redis-adapter
```
@@ -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

@@ -8,15 +8,15 @@ This feature is experimental and may be removed or changed in the future.
When calling from server-side i.e. in API routes or in `getServerSideProps`, we recommend using this function instead of `getSession` to retrieve the `session` object. This method is especially useful when you are using NextAuth.js with a database. This method can _drastically_ reduce response time when used over `getSession` server-side, due to avoiding an extra `fetch` to an API Route (this is generally [not recommended in Next.js](https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props#getserversideprops-or-api-routes)). In addition, `unstable_getServerSession` will correctly update the cookie expiry time and update the session content if `callbacks.jwt` or `callbacks.session` changed something.
Otherwise, if you only want to get the session token, see [`getToken`](tutorials/securing-pages-and-api-routes#using-gettoken).
Otherwise, if you only want to get the session token, see [`getToken`](/tutorials/securing-pages-and-api-routes#using-gettoken).
`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"
@@ -80,10 +80,11 @@ You can get the `withAuth` middleware function from `next-auth/middleware` eithe
### Prerequisites
You must set the [`NEXTAUTH_SECRET`](/configuration/options#nextauth_secret) environment variable when using this middleware. If you are using the [`secret` option](/configuration/options#secret) this value must match.
You must set the same secret in the middleware that you use in NextAuth. The easiest way is to set the [`NEXTAUTH_SECRET`](/configuration/options#nextauth_secret) environment variable. It will be picked up by both the [NextAuth config](/configuration/options#options), as well as the middleware config.
**We strongly recommend** replacing the `secret` value completely with this `NEXTAUTH_SECRET` environment variable. This environment variable will be picked up by both the [NextAuth config](/configuration/options#options), as well as the middleware config.
Alternatively, you can provide the secret using the [`secret`](#secret) option in the middleware config.
**We strongly recommend** replacing the `secret` value completely with this `NEXTAUTH_SECRET` environment variable.
### Basic usage
@@ -136,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',
}
```
@@ -149,6 +154,22 @@ See the documentation for the [pages option](/configuration/pages) for more info
---
### `secret`
- **Required**: _No_
#### Description
The same `secret` used in the [NextAuth.js config](/configuration/options#options).
#### Example (default value)
```js
secret: process.env.NEXTAUTH_SECRET
```
---
### Advanced usage
NextAuth.js Middleware is very flexible, there are multiple ways to use it.
@@ -160,13 +181,11 @@ If you do not define the options, NextAuth.js will use the default values for th
#### wrap middleware
```ts title="middleware.ts"
import type { NextRequest } from "next/server"
import type { JWT } from "next-auth/jwt"
import { withAuth } from "next-auth/middleware"
export default withAuth(
// `withAuth` can augment your Request with the user's token.
function middleware(req: NextRequest & { nextauth: { token: JWT | null } }) {
// `withAuth` augments your `Request` with the user's token.
function middleware(req) {
console.log(req.nextauth.token)
},
{

View File

@@ -13,19 +13,22 @@ 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.
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).
_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).
:::
:::note
Using [System Environment Variables](https://vercel.com/docs/concepts/projects/environment-variables#system-environment-variables) we automatically detect when you deploy to [Vercel](https://vercel.com) so you don't have to define this variable. Make sure **Automatically expose System Environment Variables** is checked in your Project Settings.
:::
### NEXTAUTH_SECRET
Used to encrypt the NextAuth.js JWT, and to hash [email verification tokens](/adapters/models#verification-token). This is the default value for the [`secret`](/configuration/options#secret) option. The `secret` option might be removed in the future in favor of this.
Used to encrypt the NextAuth.js JWT, and to hash [email verification tokens](/adapters/models#verification-token). This is the default value for the `secret` option in [NextAuth](/configuration/options#secret) and [Middleware](/configuration/nextjs#secret).
If you are using [Middleware](/configuration/nextjs#prerequisites) this environment variable must be set.
### NEXTAUTH_URL_INTERNAL
@@ -65,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.
@@ -111,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")
}
}
```
@@ -323,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.
@@ -366,11 +375,14 @@ Changes the color scheme theme of [pages](/configuration/pages) as well as allow
In addition, you can define a logo URL in `theme.logo` which will be rendered above the main card in the default signin/signout/error/verify-request pages, as well as a `theme.brandColor` which will affect the accent color of these pages.
The sign-in button's background color will match the `brandColor` and defaults to `"#346df1"`. The text color is `#fff` by default, but if your brand color gives a weak contrast, correct it with the `buttonText` color option.
```js
theme: {
colorScheme: "auto", // "auto" | "dark" | "light"
brandColor: "", // Hex color code
logo: "" // Absolute URL to image
logo: "", // Absolute URL to image
buttonText: "" // Hex color code
}
```
@@ -472,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
@@ -350,7 +350,7 @@ providers: [
## Built-in providers
NextAuth.js comes with a set of built-in providers. You can find them [here](https://github.com/nextauthjs/next-auth/tree/main/src/providers). Each built-in provider has its own documentation page:
NextAuth.js comes with a set of built-in providers. You can find them [here](https://github.com/nextauthjs/next-auth/tree/main/packages/next-auth/src/providers). Each built-in provider has its own documentation page:
<div className="provider-name-list">
{Object.entries(require("../../../providers.json"))

View File

@@ -11,6 +11,7 @@ Without these people, the project could not have become one of the most used aut
- [Balázs Orbán](https://github.com/balazsorban44) - **Lead Maintainer**
- [Nico Domino](https://github.com/ndom91) - Maintainer (Documentation, Core)
- [Lluis Agusti](https://github.com/lluia) - Maintainer (Documentation, Testing, TypeScript)
- [Thang Huu Vu](https://github.com/ThangHuuVu) - Maintainer (Core, TypeScript)
## Special thanks

View File

@@ -61,19 +61,26 @@ There should also be further details logged when this occurs, such as the error
### Signin / Callback
#### GET_AUTHORIZATION_URL_ERROR
This error can occur when we cannot get the OAuth v1 request token and generate the authorization URL.
Please double check your OAuth v1 provider settings, especially the OAuth token and OAuth token secret.
#### SIGNIN_OAUTH_ERROR
This error can occur in one of a few places, first during the redirect to the authorization URL of the provider. Next, in the signin flow while creating the PKCE code verifier. Finally, during the generation of the CSRF Token hash in the internal state during signin.
This error occurs during the redirection to the authorization URL of the OAuth provider. Possible causes:
Please check your OAuth provider settings and make sure your URLs and other options are correctly set on the provider side.
1. Cookie handling
Either PKCE code verifier or the generation of the CSRF token hash in the internal state failed.
#### CALLBACK_OAUTH_ERROR
If set, check your [`cookies` configuration](/configuration/options#cookies), and make sure the browser is not blocking/restricting cookies.
2. OAuth misconfiguration
Please check your OAuth provider and make sure your URLs and other options are correctly set.
If you are using an OAuth v1 provider, check your OAuth v1 provider settings, especially the OAuth token and OAuth token secret.
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.
@@ -129,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
@@ -149,13 +156,7 @@ This error occurs when there was an issue deleting the session from the database
---
### Other
#### SEND_VERIFICATION_EMAIL_ERROR
This error occurs when the Email Authentication Provider is unable to send an email.
Check your mail server configuration.
### Configuration
#### MISSING_NEXTAUTH_API_ROUTE_ERROR
@@ -167,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

@@ -63,17 +63,32 @@ _If you use a custom credentials provider user accounts will not be persisted in
<details>
<summary>
<h3 style={{display:"inline-block"}}>Can I use NextAuth.js with a website that does not use Next.js?</h3>
<h3 style={{display:"inline-block"}}>Can I use NextAuth.js with a framework different than Next.js?</h3>
</summary>
<p>
NextAuth.js is designed for use with Next.js and Serverless.
NextAuth.js was originally designed for use with Next.js and Serverless. However, today you could use the NextAuth.js core with any other framework. Checkout the examples for <a href="https://github.com/nextauthjs/next-auth/tree/main/apps/example-gatsby" target="_blank">Gatsby</a> and <a href="https://github.com/nextauthjs/next-auth/tree/main/apps/playground-sveltekit" target="_blank">SvelteKit</a>. If you would add another integration with other frameworks, feel free to work on it and send a pull request. Make sure to check if there's any on-going work before open a new issue.
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.
</p>
</details>
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))
<details>
<summary>
<h3 style={{display:"inline-block"}}>Can session generated by NextAuth.js be used by another website?</h3>
</summary>
<p>
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.
**Same domain**: you can create a website that handles sign-in with NextAuth.js and then access those sessions on a website that does not use NextAuth.js as long as the websites are on the same domain.
**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 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>.
**Different root domains**: 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>
@@ -221,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>
@@ -314,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

@@ -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
@@ -148,13 +148,9 @@ Because of how `_app` is written, it won't unnecessarily contact the `/api/auth/
More information can be found in the following [GitHub Issue](https://github.com/nextauthjs/next-auth/issues/1210).
### NextAuth.js + React-Query
### NextAuth.js + React Query
There is also an alternative client-side API library based upon [`react-query`](https://www.npmjs.com/package/react-query) available under [`nextauthjs/react-query`](https://github.com/nextauthjs/react-query).
If you use `react-query` in your project already, you can leverage it with NextAuth.js to handle the client-side session management for you as well. This replaces NextAuth.js's native `useSession` and `SessionProvider` from `next-auth/react`.
See repository [`README`](https://github.com/nextauthjs/react-query) for more details.
You can create your own session management solution using data fetching libraries like [React Query](https://tanstack.com/query/v4/docs/adapters/react-query) or [SWR](https://swr.vercel.app). You can use the [original implementation of `@next-auth/react-query`](https://github.com/nextauthjs/react-query) and look at the [`next-auth/react` source code](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/react/index.tsx) as a starting point.
---
@@ -427,13 +423,14 @@ This only works on pages where you provide the correct `pageProps`, however. Thi
```js title="pages/index.js"
import { unstable_getServerSession } from "next-auth/next"
import { authOptions } from './api/auth/[...nextauth]'
...
export async function getServerSideProps(ctx) {
export async function getServerSideProps({ req, res }) {
return {
props: {
session: await unstable_getServerSession(ctx)
session: await unstable_getServerSession(req, res, authOptions)
}
}
}
@@ -505,3 +502,29 @@ However, if it was set to `false`, it stops re-fetching the session and the comp
:::note
See [**the Next.js documentation**](https://nextjs.org/docs/advanced-features/custom-app) for more information on **\_app.js** in Next.js applications.
:::
### Custom base path
When your Next.js application uses a custom base path, set the `NEXTAUTH_URL` environment variable to the route to the API endpoint in full - as in the example below and as explained [here](/configuration/options#nextauth_url).
Also, make sure to pass the `basePath` page prop to the `<SessionProvider>` as in the example below so your custom base path is fully configured and used by NextAuth.js.
#### Example
In this example, the custom base path used is `/custom-route`.
```
NEXTAUTH_URL=https://example.com/custom-route/api/auth
```
```jsx title="pages/_app.js"
import { SessionProvider } from "next-auth/react"
export default function App({
Component,
pageProps: { session, ...pageProps },
}) {
return (
<SessionProvider session={session} basePath="/custom-route/api/auth">
<Component {...pageProps} />
</SessionProvider>
)
}
```

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,6 +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 "./auth/[...nextauth]"
export default async (req, res) => {
const session = await unstable_getServerSession(req, res, authOptions)
@@ -108,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

@@ -13,7 +13,7 @@ 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
```bash npm2yarn2pnpm
npm install next-auth
```
@@ -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

@@ -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

@@ -71,7 +71,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";
@@ -124,67 +124,74 @@ providers: [
The following code shows the complete source for the built-in `sendVerificationRequest()` method:
```js
import nodemailer from "nodemailer"
import { createTransport } from "nodemailer"
async function sendVerificationRequest({
identifier: email,
url,
provider: { server, from },
}) {
async function sendVerificationRequest(params) {
const { identifier, url, provider, theme } = params
const { host } = new URL(url)
const transport = nodemailer.createTransport(server)
await transport.sendMail({
to: email,
from,
// NOTE: You are not required to use `nodemailer`, use whatever you want.
const transport = createTransport(provider.server)
const result = await transport.sendMail({
to: identifier,
from: provider.from,
subject: `Sign in to ${host}`,
text: text({ url, host }),
html: html({ url, host, email }),
html: html({ url, host, theme }),
})
const failed = result.rejected.concat(result.pending).filter(Boolean)
if (failed.length) {
throw new Error(`Email(s) (${failed.join(", ")}) could not be sent`)
}
}
// Email HTML body
function html({ url, host, email }: Record<"url" | "host" | "email", string>) {
// Insert invisible space into domains and email address to prevent both the
// email address and the domain from being turned into a hyperlink by email
// clients like Outlook and Apple mail, as this is confusing because it seems
// like they are supposed to click on their email address to sign in.
const escapedEmail = `${email.replace(/\./g, "&#8203;.")}`
const escapedHost = `${host.replace(/\./g, "&#8203;.")}`
/**
* Email HTML body
* Insert invisible space into domains from being turned into a hyperlink by email
* clients like Outlook and Apple mail, as this is confusing because it seems
* like they are supposed to click on it to sign in.
*
* @note We don't add the email address to avoid needing to escape it, if you do, remember to sanitize it!
*/
function html(params: { url: string; host: string; theme: Theme }) {
const { url, host, theme } = params
// Some simple styling options
const backgroundColor = "#f9f9f9"
const textColor = "#444444"
const mainBackgroundColor = "#ffffff"
const buttonBackgroundColor = "#346df1"
const buttonBorderColor = "#346df1"
const buttonTextColor = "#ffffff"
const escapedHost = host.replace(/\./g, "&#8203;.")
const brandColor = theme.brandColor || "#346df1"
const color = {
background: "#f9f9f9",
text: "#444",
mainBackground: "#fff",
buttonBackground: brandColor,
buttonBorder: brandColor,
buttonText: theme.buttonText || "#fff",
}
return `
<body style="background: ${backgroundColor};">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<body style="background: ${color.background};">
<table width="100%" border="0" cellspacing="20" cellpadding="0"
style="background: ${color.mainBackground}; max-width: 600px; margin: auto; border-radius: 10px;">
<tr>
<td align="center" style="padding: 10px 0px 20px 0px; font-size: 22px; font-family: Helvetica, Arial, sans-serif; color: ${textColor};">
<strong>${escapedHost}</strong>
</td>
</tr>
</table>
<table width="100%" border="0" cellspacing="20" cellpadding="0" style="background: ${mainBackgroundColor}; max-width: 600px; margin: auto; border-radius: 10px;">
<tr>
<td align="center" style="padding: 10px 0px 0px 0px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; color: ${textColor};">
Sign in as <strong>${escapedEmail}</strong>
<td align="center"
style="padding: 10px 0px; font-size: 22px; font-family: Helvetica, Arial, sans-serif; color: ${color.text};">
Sign in to <strong>${escapedHost}</strong>
</td>
</tr>
<tr>
<td align="center" style="padding: 20px 0;">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td align="center" style="border-radius: 5px;" bgcolor="${buttonBackgroundColor}"><a href="${url}" target="_blank" style="font-size: 18px; font-family: Helvetica, Arial, sans-serif; color: ${buttonTextColor}; text-decoration: none; border-radius: 5px; padding: 10px 20px; border: 1px solid ${buttonBorderColor}; display: inline-block; font-weight: bold;">Sign in</a></td>
<td align="center" style="border-radius: 5px;" bgcolor="${color.buttonBackground}"><a href="${url}"
target="_blank"
style="font-size: 18px; font-family: Helvetica, Arial, sans-serif; color: ${color.buttonText}; text-decoration: none; border-radius: 5px; padding: 10px 20px; border: 1px solid ${color.buttonBorder}; display: inline-block; font-weight: bold;">Sign
in</a></td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="center" style="padding: 0px 0px 10px 0px; font-size: 16px; line-height: 22px; font-family: Helvetica, Arial, sans-serif; color: ${textColor};">
<td align="center"
style="padding: 0px 0px 10px 0px; font-size: 16px; line-height: 22px; font-family: Helvetica, Arial, sans-serif; color: ${color.text};">
If you did not request this email you can safely ignore it.
</td>
</tr>
@@ -193,8 +200,8 @@ function html({ url, host, email }: Record<"url" | "host" | "email", string>) {
`
}
// Email Text body (fallback for email clients that don't render HTML, e.g. feature phones)
function text({ url, host }: Record<"url" | "host", string>) {
/** Email Text body (fallback for email clients that don't render HTML, e.g. feature phones) */
function text({ url, host }: { url: string; host: string }) {
return `Sign in to ${host}\n${url}\n\n`
}
```
@@ -216,3 +223,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

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

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

@@ -5,7 +5,7 @@ title: Overview
Authentication Providers in **NextAuth.js** are services that can be used to sign in a user.
There's four ways a user can be signed in:
There are four ways a user can be signed in:
- [Using a built-in OAuth Provider](/configuration/providers/oauth) (e.g Github, Twitter, Google, etc...)
- [Using a custom OAuth Provider](/configuration/providers/oauth#using-a-custom-provider)

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,50 @@
---
id: wikimedia
title: Wikimedia
---
## Documentation
https://www.mediawiki.org/wiki/Extension:OAuth
This provider also supports all Wikimedia projects:
- Wikipedia
- Wikidata
- Wikibooks
- Wiktionary
- etc..
Please be aware that Wikimedia accounts do not have to have an associated email address. So you may want to add check if the user has an email address before allowing them to login.
## Configuration
1. Go to and accept the Consumer Registration doc: https://meta.wikimedia.org/wiki/Special:OAuthConsumerRegistration
2. Request a new OAuth 2.0 consumer to get the `clientId` and `clientSecret`: https://meta.wikimedia.org/wiki/Special:OAuthConsumerRegistration/propose/oauth2
2a. Add the following redirect URL into the console `http://<your-next-app-url>/api/auth/callback/wikimedia`
2b. Do not check the box next to `This consumer is only for [your username]`
2c. Unless you explicitly need a larger scope, feel free to select the radio button labelled `User identity verification only - no ability to read pages or act on the users behalf.`
After registration, you can initally test your application only with your own Wikimedia account. You may have to wait several days for the application to be approved for it to be used by everyone.
## Options
The **Wikimedia Provider** comes with a set of default options:
- [Wikimedia Provider options](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/providers/wikimedia.ts)
You can override any of the options to suit your own use case.
## Example
```js
import WikimediaProvider from "next-auth/providers/wikimedia";
...
providers: [
WikimediaProvider({
clientId: process.env.WIKIMEDIA_CLIENT_ID,
clientSecret: process.env.WIKIMEDIA_CLIENT_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

@@ -7,7 +7,7 @@ NextAuth.js provides the ability to setup a [custom Credential provider](/config
You will need an additional dependency, `ldapjs`, which you can install by running
```bash npm2yarn
```bash npm2yarn2pnpm
npm install ldapjs
```

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="/pages/_middleware.js"
```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.
@@ -61,7 +73,9 @@ You can protect server side rendered pages using the `unstable_getServerSession`
You need to add this to every server rendered page you want to protect. Be aware, `unstable_getServerSession` takes slightly different arguments than the method it is replacing, `getSession`.
```js title="pages/server-side-example.js"
import { useSession, unstable_getServerSession } from "next-auth/next"
import { unstable_getServerSession } from "next-auth/next"
import { authOptions } from "./api/auth/[...nextauth]"
import { useSession } from "next-auth/react"
export default function Page() {
const { data: session } = useSession()
@@ -120,6 +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 "./auth/[...nextauth]"
export default async (req, res) => {
const session = await unstable_getServerSession(req, res, authOptions)
@@ -142,10 +157,9 @@ If you are using JSON Web Tokens you can use the `getToken()` helper to access t
// This is an example of how to read a JSON Web Token from an API route
import { getToken } from "next-auth/jwt"
const secret = process.env.SECRET
export default async (req, res) => {
const token = await getToken({ req, secret })
// If you don't have NEXTAUTH_SECRET set, you will have to pass your secret as `secret` to `getToken`
const token = await getToken({ req })
if (token) {
// Signed in
console.log("JSON Web Token", JSON.stringify(token, null, 2))

View File

@@ -9,7 +9,7 @@ To test an implementation of NextAuth.js, we encourage you to use [Cypress](http
To get started, install the dependencies:
```bash npm2yarn
```bash npm2yarn2pnpm
npm install --save-dev cypress cypress-social-logins @testing-library/cypress
```

View File

@@ -37,6 +37,12 @@ Twitter OAuth 2.0 is currently in beta as certain changes might still be necessa
Some APIs are still experimental; they may be changed or removed in the future. Use at your own risk.
#### DEBUG_ENABLED
You have enabled the `debug` option. It is meant for development only, to help you catch issues in your authentication flow and you should consider removing this option when deploying to production. One way of only allowing debugging while not in production is to set `debug: process.env.NODE_ENV !== "production"`, so you can commit this without needing to change the value.
If you want to log debug messages during production anyway, we recommend setting the [`logger` option](/configuration/options#logger) with proper sanitization of potentially sensitive user information.
## Adapter
### ADAPTER_TYPEORM_UPDATING_ENTITIES

View File

@@ -155,9 +155,9 @@ module.exports = {
showLastUpdateAuthor: true,
showLastUpdateTime: true,
remarkPlugins: [
require("@sapphire/docusaurus-plugin-npm2yarn2pnpm").npm2yarn2pnpm,
require("remark-github"),
require("mdx-mermaid"),
[require("@docusaurus/remark-plugin-npm2yarn"), { sync: true }],
],
versions: {
current: {

View File

@@ -21,9 +21,9 @@
"dependencies": {
"@docusaurus/core": "^2.0.0-beta.21",
"@docusaurus/preset-classic": "^2.0.0-beta.21",
"@docusaurus/remark-plugin-npm2yarn": "^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",
"mdx-mermaid": "^1.2.2",
"mermaid": "^9.0.1",

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

@@ -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@canary
```
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"

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