Compare commits

..

124 Commits

Author SHA1 Message Date
Balázs Orbán
46304838af chore(release): bump version 2022-06-10 12:48:25 +00:00
Balázs Orbán
76560aed5a chore: no git checks on publish 2022-06-10 14:39:43 +02:00
Balázs Orbán
25517b7315 fix: handle invalid callbackUrl 2022-06-10 13:52:00 +02:00
Tom Freudenberg
4daa63d5e1 feat(callback): return always status code 401 on error (#4601) 2022-06-09 18:43:50 +02:00
Chris Betz
81afeef194 feat(provider): Add United Effects provider (#4546)
* Adding United Effects as a provider
* Update packages/next-auth/src/providers/united-effects.ts
* returning name and image as null in profile response

Co-authored-by: Lluis Agusti <hi@llu.lu>
2022-06-04 00:03:23 +02:00
Or Linzer
008f29e6f8 docs(next): Update config comment (#4664)
* Update Custom JWT decode method
* Update docs/docs/configuration/nextjs.md

Co-authored-by: Lluis Agusti <hi@llu.lu>
2022-06-03 23:53:19 +02:00
Balázs Orbán
e4ee520b4a fix(ts): allow getToken in getServerSideProps (#4659) 2022-05-31 19:05:35 +02:00
Balázs Orbán
358b80d4ce feat(providers): make issuer configurable on Salesforce (#4658) 2022-05-31 19:02:35 +02:00
Balázs Orbán
0a7a916228 fix(ts): remove unused type (#4657) 2022-05-31 18:55:34 +02:00
Balázs Orbán
612c35e8c2 Revert "fix(ts): signIn infer provider type (#4623)" (#4655)
This reverts commit 46089eb5ae.
2022-05-31 18:44:54 +02:00
Thomas Knickman
9f6949816c chore(release): increase checkout depth (#4654)
Fetch two commits in CI so HEAD^1 is able to function correctly to determine diff between last commit and now.
2022-05-31 18:37:22 +02:00
Arthur Pedroti
46089eb5ae fix(ts): signIn infer provider type (#4623)
The "P" type it's not passed in any props, so the result type doesn't understand and return the false type always, Adding the "P" at provider type props.
2022-05-31 18:29:34 +02:00
42Atomys
7d8cc70faf feat(middleware): support custom cookieName (#4385)
* feat: Add the support of custom cookieName on the next-auth/middleware

* chore: Only accept used params based on NextAuthConfig

* docs: Remove duplicated docs

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-05-31 18:29:15 +02:00
Thanh Nhan
75602a3f04 fix(middleware): use relative URL for sign-in page callbackUrl (#4534)
* Use relative URL for middleware's signin callbackUrl

* Include params to callbackUrl if any

* For testing purpose, append params to existing link for test instead of create another one

* Update apps/dev/components/header.js

Co-authored-by: CODY Mai <nhan.mai@shiftasia.com>
Co-authored-by: Thang Vu <31528554+ThangHuuVu@users.noreply.github.com>
2022-05-31 18:14:24 +02:00
Shubham Jain
5b8a619cd0 docs: Remove trailing '/' from Authentik issuer example (#4646)
The Authentik provider already adds a `/` after the `issuer`, so this creates a double slash that causes a NextAuth `SIGNIN_OAUTH_ERROR` ("expected 200 OK, got: 301 Moved Permanently").
2022-05-31 18:13:32 +02:00
Alvin Li
16622f6428 feat(middleware): support custom jwt.decode (#4210)
* feat: custom jwt decode method for middleware

* Update docs/docs/configuration/options.md

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

Co-authored-by: Thang Vu <31528554+ThangHuuVu@users.noreply.github.com>
Co-authored-by: Nico Domino <yo@ndo.dev>
2022-05-31 17:45:37 +02:00
dependabot[bot]
e203801f30 chore(deps): bump next-auth in /apps/playground-sveltekit (#4615)
Bumps [next-auth](https://github.com/nextauthjs/next-auth) from 4.3.2 to 4.3.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.3.2...next-auth@v4.3.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-05-26 11:06:46 +02:00
Nico Domino
cfc0a55080 docs: add note to ensure pages actually exist (#4618)
* chore(docs): add note to ensure pages actually exist

* Update docs/docs/configuration/options.md

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

* Update docs/docs/configuration/pages.md

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

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-05-25 14:33:05 +02:00
mohammed hussam
dda4e0a7d8 docs: update blog link (#4591)
Authentication Patterns for Next.js is moved official next.js docs https://nextjs.org/docs/authentication#authentication-patterns
2022-05-20 19:48:52 +02:00
PalanikannanM
374f886e84 chore(tutorial): fixing the expires_in method of account object to expires_at (#4540)
Co-authored-by: Lluis Agusti <hi@llu.lu>
2022-05-19 22:28:07 +02:00
Ephraim Atta-Duncan
db188b872f docs: update screenshot (#4571) 2022-05-17 10:10:17 +02:00
Matías Aguilera
2838dd7e0f docs: fix font size for small devices (#4558)
Co-authored-by: Lluis Agusti <hi@llu.lu>
2022-05-14 23:55:03 +02:00
Imamuzzaki Abu Salam
08f6b31e41 missing "role" in the first sentence (#4560) 2022-05-14 09:36:01 +02:00
rgsthethird
602668f93c Small grammar fix (#4531)
'this environment variable must be set', instead of 'this environment variables must be set'.
2022-05-13 12:20:55 +02:00
Nico Domino
641d917175 chore: update test script and turborepo dependency (#4490)
Co-authored-by: Thang Vu <31528554+ThangHuuVu@users.noreply.github.com>
2022-05-07 13:35:46 +02:00
Nico Domino
70d59bb6e7 chore(docs): fix formatting / syntax (#4523) 2022-05-07 12:19:42 +02:00
Nico Domino
0c86d5a370 chore(docs): rm sandpack - unused (#4521) 2022-05-07 00:18:00 +02:00
Glenn Streetman
0ac8773c2b docs(tutorial): Adding role based login to database session strategy (#4449)
Co-authored-by: Lluis Agusti <hi@llu.lu>
Co-authored-by: ndom91 <yo@ndo.dev>
2022-05-07 00:13:42 +02:00
Nico Domino
714579e8d6 chore: update docs dependencies (#4522) 2022-05-07 00:01:02 +02:00
Negotiamini
8b6d2e3972 fix(types): typo (#4504) 2022-05-05 19:03:48 +02:00
Thang Vu
4f29d39521 chore: move to pnpm (#4420)
* feat: pnpm

* Update publish script

* gitignore the pnpm debug log

* Fix workspace

* Fix dev commands

* feat: pnpm

* Update publish script

* gitignore the pnpm debug log

* Fix workspace

* Fix dev commands

* chore: fix pnpm install in GitHub Action

* fix: update tsconfig path

* pnpm run -> pnpm

* chore: remove cache-node and add back setup-node

* fix: tsconfig dependencies

* chore: fix tsconfig path

* fix: adapter-test dependencies

* fix: setup-node for release-pr

* fix: import adapter-test

* chore: update workspace dependency for next-auth

* fix: test failure

* fix: add jest for adapters

* fix: jest again

* fix: mongo in prisma

* fix: `--no-git-checks` for `release-pr`

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-05-03 15:05:55 +02:00
Erica Pisani
042ed82ca0 docs: update Netlify section (#4489)
The build plugin now sets the NEXTAUTH_URL environment variable automatically
when it detects that 'next-auth' is installed in the project.
2022-05-02 00:36:56 +02:00
Jiří Hofman
a6901db11b docs: fix typo (#4488) 2022-04-29 12:25:59 +02:00
Lluis Agusti
0b953bd047 test(signout): fix skipped test (#4484) 2022-04-28 14:19:53 +02:00
Lluis Agusti
268c0636d7 chore(github): update PR template (#4482) 2022-04-28 13:28:35 +02:00
Balázs Orbán
c6903d3e85 chore. bump version 2022-04-28 12:18:48 +02:00
Balázs Orbán
a74d215745 Revert "fix: loosen env variable URL fallback (#4443)" (#4481)
This reverts commit d4fb7af6f5.
2022-04-28 11:50:29 +02:00
Kot
18174fae36 docs: Clarify code_challenge_method RFC requirement (#4464) 2022-04-28 11:45:31 +02:00
Balázs Orbán
d4fb7af6f5 fix: loosen env variable URL fallback (#4443)
Co-authored-by: Lluis Agusti <hi@llu.lu>
2022-04-28 11:42:40 +02:00
dependabot[bot]
bc15e2866e chore(deps): bump next-auth in /apps/playground-sveltekit (#4451)
Bumps [next-auth](https://github.com/nextauthjs/next-auth) from 4.2.1 to 4.3.2.
- [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/v4.2.1...next-auth@v4.3.2)

---
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-04-28 11:42:18 +02:00
Jonas Strassel
aee5ec2e4f docs: remove redudant and deprecated doc (#4475)
... as `session.jwt` has been replaced with `session.strategy: 'jwt'`
2022-04-28 11:42:06 +02:00
Balázs Orbán
f0ed23acf6 fix: allow react@18 as peer dependency 2022-04-28 11:35:14 +02:00
Lluis Agusti
fb4bbc3b08 fix(ts): handle NextRequest type (#4472)
* fix(jwt): handle NextRequest

* fix(cookie): Headers from fetch request

* Update packages/next-auth/src/jwt/index.ts

* fix: tests

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-04-28 11:22:49 +02:00
Smultar
4c832f855e Fixes 404 error, when visiting the options link (#4462)
The current link leads to nowhere.
2022-04-25 16:57:30 +02:00
Nico Domino
e3ace6e649 chore: add SIWE and signin example links (#4463)
* chore(docs): add link to SIWE example app / tutorial

* chore(docs): add link to example signin page and cleanup

* chore: update copy for SIWE credentials provider example
2022-04-24 14:18:03 +02:00
Jon Parton
8a75911567 fix(client): update 'signin' page error example (#4412)
Co-authored-by: Lluis Agusti <hi@llu.lu>
2022-04-22 18:24:33 +02:00
Lluis Agusti
8288ae5be8 fix(providers): profile types (#4202) 2022-04-22 13:15:24 +02:00
Jiyeol Lee
9f40cd1bd9 fix(client): add additional type (#4402)
* Add additional type
* do not cast to 'any' anymore
* add missing import
* import NextRequest from next/server

Co-authored-by: Lluis Agusti <hi@llu.lu>
2022-04-22 13:10:10 +02:00
Thang Vu
39b4d62336 docs: remove error event in config options (#4406) 2022-04-22 10:38:26 +02:00
Balázs Orbán
1faae313fa docs: update callbacks 2022-04-20 19:27:01 +02:00
Balázs Orbán
e71118b996 chore: bump versions 2022-04-20 19:07:54 +02:00
Balázs Orbán
afdb3c8d7c fix: more strict default callback url handling 2022-04-20 18:52:24 +02:00
Raúl Marín
fd755bc29e fix(signin): set email sign-in input to "email" & "required"(#4352)
* fix(core\pages\signin.tsx): set type of built-in email sign-in input to email for browse validation
* fix(core\pages\signin.tsx): add required attribute to built-in sign-in email input

Co-authored-by: Lluis Agusti <hi@llu.lu>
2022-04-15 19:12:01 +02:00
Yisu Kim
59daa0e43f fix(providers): add optional chaining to avoid nullish reference errors (#4365) 2022-04-14 16:35:54 +02:00
Simon Kirsten
58d06ed727 fix: Cleanup global __NEXTAUTH state after unmount (#4383) 2022-04-14 16:35:10 +02:00
Salah Eddine
82159d3e8f docs: remove auth from keycloack url (#4391)
in keycloak 17.0+ , There's a change in endpoints as per the official documentation (https://www.keycloak.org/docs-api/11.0/rest-api/index.html#_users_resource) .
so the new url well be https://my-keycloak-domain.com/realms/My_Realm
2022-04-14 16:28:21 +02:00
Balázs Orbán
abb9fed7aa chore: bump versions 2022-04-14 11:09:32 +02:00
Balázs Orbán
5471c0f675 chore: use --no-workspaces
See: https://github.com/npm/cli/issues/4605#issuecomment-1076900100
2022-04-14 11:03:27 +02:00
Balázs Orbán
b2da0b38d4 chore: add --verbose 2022-04-14 10:54:20 +02:00
Balázs Orbán
b3b8d4be46 chore: log npm config list 2022-04-13 18:05:21 +02:00
Balázs Orbán
182e118d9b chore: else 2022-04-13 15:19:18 +02:00
Balázs Orbán
7183b06939 chore: write .npmrc 2022-04-13 15:18:35 +02:00
Balázs Orbán
bd10e87bf4 chore: more visible log 2022-04-13 15:08:14 +02:00
Balázs Orbán
d07abfe517 chore: log 2022-04-13 15:00:44 +02:00
Balázs Orbán
c1110cdc98 chore: don't write .npmrc 2022-04-13 14:35:57 +02:00
Balázs Orbán
8ed038d891 chore: revert 2022-04-12 17:05:40 +02:00
Balázs Orbán
b25425795b chore: CI=1 2022-04-12 17:01:16 +02:00
Balázs Orbán
ad1650a817 chore: no brackets 2022-04-12 16:52:09 +02:00
Balázs Orbán
a4a487a22a chore: NPM_TOKEN_PKG 2022-04-12 16:46:26 +02:00
Balázs Orbán
b30de36126 chore: remove cat 2022-04-12 16:36:38 +02:00
Balázs Orbán
41e4e515ad chore: cat .npmrc 2022-04-12 16:35:12 +02:00
Balázs Orbán
cde1f82e3c chore: revert 2022-04-12 16:26:55 +02:00
Balázs Orbán
c39782007b chore: pkg vs org? 2022-04-12 16:22:33 +02:00
Balázs Orbán
984a089c15 chore: ignore .npmrc 2022-04-12 16:10:04 +02:00
Balázs Orbán
26f8b8c1f1 chore: remove npm whoami 2022-04-12 16:09:27 +02:00
Balázs Orbán
afc9b43c53 chore: npm whoami 2022-04-12 16:03:02 +02:00
Balázs Orbán
cdbd9ac2e6 chore: manually upgrade dep version 2022-04-12 15:39:55 +02:00
Balázs Orbán
3d8cc316f1 chore: debug release script 2022-04-12 15:32:50 +02:00
Balázs Orbán
3b8c568f79 chore: trigger deploy 2022-04-12 15:22:57 +02:00
Balázs Orbán
16668d307d docs: revert 2022-04-12 14:17:00 +02:00
Balázs Orbán
6e15bdcb2d fix: update default callbacks.redirect 2022-04-12 14:14:35 +02:00
Yisu Kim
7a4bf038b1 Update callbacks.md (#4361)
missing async keyword
2022-04-09 22:23:26 +02:00
Francis Gulotta
11ad64f617 docs: add google oauth URI examples (#4347)
* docs: add google oauth URI examples

* Update docs/docs/providers/google.md

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

Co-authored-by: Lluis Agusti <hi@llu.lu>
2022-04-09 09:45:55 +02:00
Francis Gulotta
0a278b9297 docs: callbacks can now be relative (#4346)
* docs: callbacks can now be relative

since v4 anyway

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

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

Co-authored-by: Lluis Agusti <hi@llu.lu>
2022-04-09 09:45:19 +02:00
Francis Gulotta
8c8070f30b docs(client): fix type in signIn examples (#4308) 2022-04-07 12:58:06 +02:00
Christopher Reece
6442d089c1 docs(adapters): update providerAccount to account (#4329) 2022-04-07 12:45:41 +02:00
Francis Gulotta
63398d4c3f docs: Update JWT docs to reflect JWE changes in v4 (#4313)
* docs: Update JWT docs to reflect JWE changes in v4

This PR https://github.com/nextauthjs/next-auth/pull/3039 changed the defaults for JWT tokens to be encrypted by default (JWE). We have conflicting documentation across the docs site and readme.

Additionatlly this PR https://github.com/nextauthjs/next-auth/pull/3783 made providing a secret required in production via NEXTAUTH_SECRET or an option.

* Missed a reference

* Update docs/docs/faq.md

Co-authored-by: Nico Domino <yo@ndo.dev>

* Update docs/docs/faq.md

Co-authored-by: Nico Domino <yo@ndo.dev>

Co-authored-by: Nico Domino <yo@ndo.dev>
2022-04-05 12:48:06 +02:00
Oliver Terbu
0d54170e83 feat: added siwe tutorial (#4276)
Co-authored-by: Oliver Terbu <oliver@awoie.local>
2022-04-04 22:52:55 +02:00
Francis Gulotta
174f0d6aec chore(docs): fix Custom Client Session Handling example (#4310)
* docs: fix Custom Client Session Handling example

It made reference to a useEffect call that was no longer needed.

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

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

Co-authored-by: Lluis Agusti <hi@llu.lu>
2022-04-04 22:11:59 +02:00
Francis Gulotta
f91b9dc03d docs: Add some more context to the adapters page (#4303)
Link the models to the adapters page to provide some context about what is passed into each function.

Co-authored-by: Nico Domino <yo@ndo.dev>
2022-04-02 12:48:19 +02:00
Sriram Jothiswaran
8763e4aeb9 chore(docs): update prisma mongodb connector required modifications (#4304)
* Update for Mongodb prisma connector 

In reference to https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#model-field-scalar-types, for scalar type String the native MongoDB type attribute is @db.String.

* Update prisma.md
2022-04-02 12:48:06 +02:00
Danny Luedke
e936c51575 Fix API directory (#4283)
Update the API directory from `pages/api/[...nextauth].ts` to `pages/api/auth/[...nextauth].ts`  so it matches the typescript example.
2022-03-29 22:44:24 +02:00
dependabot[bot]
8d7ba75bca chore(deps): bump minimist in /apps/playground-sveltekit (#4261)
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-28 11:18:36 +02:00
dependabot[bot]
67038b4022 chore(deps): bump node-forge from 1.2.1 to 1.3.0 (#4262)
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.2.1 to 1.3.0.
- [Release notes](https://github.com/digitalbazaar/forge/releases)
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/v1.2.1...v1.3.0)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-type: indirect
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-28 11:18:24 +02:00
dependabot[bot]
5b7ce98a87 chore(deps): bump minimist from 1.2.5 to 1.2.6 (#4263)
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-28 11:18:07 +02:00
Chandler GREFF
1c468f057d docs: fix return type in jwt decode example (#4273) 2022-03-28 11:17:52 +02:00
Nico Domino
ef22c5b835 chore(docs): add carbon ads to docs sidebar (#4250)
* chore(docs): add carbon ads to docs page

* fix: add carbon-wrap element

* fix: script in docusaurus config object

* fix: add _carbonads_js id

* fix: add script directly to sidebar

* fix: carbon ads style

* chore: bump ad container down a bit
2022-03-25 19:24:05 +01:00
Grégory D'Angelo
a912739b24 chore(docs): add full stack course (Next.js/NextAuth.js/Supabase/Prisma) (#4086)
* Add free course ""

* Adjust new entry formatting to comply with all the other resources in the page

Co-authored-by: Nico Domino <yo@ndo.dev>
2022-03-23 19:50:26 +01:00
Nico Domino
ae318788c3 chore(docs): fix broken tutorial links (#4241) 2022-03-23 19:32:24 +01:00
1000101
affa459fcc fix(docs): v3->v4 migration (#4039)
Co-authored-by: Nico Domino <yo@ndo.dev>
2022-03-23 19:18:23 +01:00
Nico Domino
b88a31ef1a chore(docs): add tutorial for avoiding corporate email scanning HEAD reqs (#3900)
* chore(docs): add tutorial for avoiding corporate email scanning HEAD requests breaking email invitations

* fix: move to internal guides section
2022-03-22 23:29:05 +01:00
Nico Domino
bc82d6555a chore(docs): add corporate proxy tutorial (#3931)
* chore(docs): add corporate proxy tutorial

* fix(docs): add details about provider proxy adjustments

* fix: add to internal guides section
2022-03-22 23:27:14 +01:00
Thang Vu
11954567c2 docs: fix markdown link in jwt options (#4197)
Co-authored-by: Nico Domino <yo@ndo.dev>
2022-03-22 22:55:21 +01:00
Thang Vu
6e28ccf84f chore(adapters): Add next-autth as devDependencies for adapters (#4226)
* Upgrade turborepo, add next-auth as dev deps

* Fix TS error

* Update adapters.json

* ignore linting
2022-03-21 21:26:37 +01:00
Deepak Prabhakara
f542b400ba updated port number (5000 is blocked by MacOS AirPlay) (#4221) 2022-03-19 09:30:21 +01:00
Piyush Priyadarshi
d1b76bc302 docs: remove unused negation operator (#4217) 2022-03-18 22:28:43 +01:00
Andreas Thomas
3f396be5d9 feat(deps): upgrade minimal peer dependency @upstash/redis@v1 (#4213)
BREAKING CHANGE

From now on, you will need a minimum version of `@upstash/redis@v1` installed if you want to use this adapter.

You can upgrade by running `npm i @upstash/redis@latest` or `yarn add @upstash/redis@latest`
2022-03-18 22:27:45 +01:00
Balázs Orbán
bf4916dd70 chore: manually bump versions 2022-03-17 19:24:08 +01:00
Balázs Orbán
5100784d72 chore: update tsconfig 2022-03-17 19:03:26 +01:00
Balázs Orbán
3853e16268 chore: downgrade turbo 2022-03-17 18:57:46 +01:00
Balázs Orbán
4c0cc9e614 chore: manually bump package versions
since the last automatic release failed to do so
2022-03-17 18:38:20 +01:00
Balázs Orbán
d0112aae61 chore: upgrade lock file 2022-03-17 16:49:37 +01:00
Balázs Orbán
e373ff2473 chore: exclude firebase 2022-03-17 15:03:39 +01:00
Balázs Orbán
6d6d0a8679 Merge branch 'main' of github.com:nextauthjs/next-auth 2022-03-17 13:51:39 +01:00
Balázs Orbán
8152752cc8 chore: exclude firebase from testing 2022-03-17 13:51:31 +01:00
Andreas Thomas
966381ac9b docs: pin @upstash/redis version to 0.2.1 (#4201)
Until we migrate to v1 there might be people installing the latest
version of @upstash/redis and then encountering errors.
With this they will at least get a warning.

This is obsolete and should be updated once
https://github.com/nextauthjs/next-auth/issues/4183 is resolved.

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-03-17 13:44:21 +01:00
Wayne Shih
8199c96b76 fix: update font-family stack (#4192) 2022-03-17 13:43:08 +01:00
Balázs Orbán
6a06b8e054 chore: ignore building firebase adapter 2022-03-17 13:41:58 +01:00
Thang Vu
68bab17914 fix: set module to commonjs for adapters (#4205)
* fix: set module to commonjs for adapters

* Update tsconfig.json

* Update tsconfig.json

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-03-17 13:36:25 +01:00
Nico Domino
47b4765941 docs: 1st party guides section (#4167)
* chore: simplify example-gatsby readme header

* chore(docs): move 1st party guides to own section
2022-03-16 00:01:29 +01:00
Simon Kirsten
6d45ad4840 fix: encode callbackUrl for custom sign-in page (#4174) 2022-03-15 23:57:52 +01:00
Alexandru Călin
e5e49aca1c docs(adapters): add dynamoDB cf ProjectionType (#4182) 2022-03-15 23:54:50 +01:00
Lluis Agusti
ea944ebb86 docs(oauth): use Mermaid for the diagram (#4147) 2022-03-15 23:54:19 +01:00
Balázs Orbán
ca8af7fcd5 chore: push tags before GitHub release 2022-03-15 23:13:08 +01:00
162 changed files with 28468 additions and 20839 deletions

View File

@@ -1,48 +1,28 @@
<!--
Thanks for your interest in the project. Bugs filed and PRs submitted are appreciated!
Please make sure that you are familiar with and follow the Code of Conduct for
this project (found in the CODE_OF_CONDUCT.md file).
Also, please make sure you're familiar with and follow the instructions in the
contributing guidelines (found in the CONTRIBUTING.md file).
If you're new to contributing to open source projects, you might find this free
video course helpful: https://kcd.im/pull-request
Please fill out the information below to expedite the review and (hopefully)
merge of your pull request!
-->
<!-- What changes are being made? (What feature/bug is being fixed here?) -->
## ☕️ Reasoning
## 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 🧢
<!-- Feel free cross items ( like this `~[] item~` ) if they're irrelevant to your changes.
To check an item, place an `x` in the box like so: `- [x] Documentation`. -->
## 🧢 Checklist
- [ ] Documentation
- [ ] Tests
- [ ] Ready to be merged
<!-- In your opinion, is this ready to be merged as soon as it's reviewed? -->
## 🎫 Affected issues
## Affected issues 🎟
<!--
Please [scout and link issues](https://github.com/nextauthjs/next-auth/issues) that might be solved by this PR.
If you write `"Fixes"` or `"Closes"` before the issue link like so:
Fixes: INSERT_ISSUE_LINK_HERE
```
Fixes #359
```
## 📌 Resources
the connected issue will be automatically closed once the PR is merged and hence help with maintenance of the library 😊
-->
- [Contributing guidelines](./CONTRIBUTING.md)
- [Code of conduct](./CODE_OF_CONDUCT.md)
- [Contributing to Open Source](https://kcd.im/pull-request)

View File

@@ -16,26 +16,23 @@ jobs:
steps:
- name: Init
uses: actions/checkout@v2
with:
fetch-depth: 2
- name: Install pnpm
uses: pnpm/action-setup@v2.2.1
with:
version: 6.32.8
- name: Setup Node
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: 16
cache: "yarn"
- name: Cache Node Modules
id: cache-node
uses: actions/cache@v2
with:
path: "**/node_modules"
key: cache-node_modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-${{ github.run_id }}
restore-keys: |
cache-node_modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-${{ github.run_id }}
cache-node_modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-
cache: "pnpm"
- name: Install dependencies
run: yarn --prefer-offline --frozen-lockfile
run: pnpm install
- name: Build
run: yarn build
run: pnpm build
- name: Run tests
run: yarn test
run: pnpm test
env:
UPSTASH_REDIS_URL: ${{ secrets.UPSTASH_REDIS_URL }}
UPSTASH_REDIS_KEY: ${{ secrets.UPSTASH_REDIS_KEY }}
@@ -55,30 +52,25 @@ jobs:
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Install pnpm
uses: pnpm/action-setup@v2.2.1
with:
version: 6.32.8
- name: Setup Node
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: 16
cache: "yarn"
- name: Cache Node Modules
id: cache-node
uses: actions/cache@v2
with:
path: "**/node_modules"
key: cache-node_modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-${{ github.run_id }}
restore-keys: |
cache-node_modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-${{ github.run_id }}
cache-node_modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-
cache: "pnpm"
- name: Install dependencies
run: yarn --prefer-offline --frozen-lockfile
run: pnpm install
- name: Publish to npm and GitHub
run: |
git config --global user.email "balazsorban44@users.noreply.github.com"
git config --global user.name "Balázs Orbán"
yarn release
pnpm release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN_PKG: ${{ secrets.NPM_TOKEN }}
NPM_TOKEN_PKG: ${{ secrets.NPM_TOKEN_PKG }}
NPM_TOKEN_ORG: ${{ secrets.NPM_TOKEN_ORG }}
release-pr:
name: Publish PR
@@ -89,22 +81,17 @@ jobs:
steps:
- name: Init
uses: actions/checkout@v2
- name: Install pnpm
uses: pnpm/action-setup@v2.2.1
with:
version: 6.32.8
- name: Setup Node
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: 16
cache: "yarn"
- name: Cache Node Modules
id: cache-node
uses: actions/cache@v2
with:
path: "**/node_modules"
key: cache-node_modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-${{ github.run_id }}
restore-keys: |
cache-node_modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-${{ github.run_id }}
cache-node_modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-
cache: "pnpm"
- name: Install dependencies
run: yarn --prefer-offline --frozen-lockfile
run: pnpm install
- name: Determine version
uses: ./.github/version-pr
id: determine-version
@@ -114,7 +101,7 @@ jobs:
run: |
cd packages/next-auth
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc
npm publish --access public --tag experimental
pnpm publish --no-git-checks --access public --tag experimental
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Comment version on PR

2
.gitignore vendored
View File

@@ -1,5 +1,6 @@
# Misc
.DS_Store
.npmrc
.env
.env.local
@@ -11,6 +12,7 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
firebase-debug.log
.pnpm-debug.log
# Dependencies

View File

@@ -6,19 +6,20 @@
"scripts": {
"clean": "rm -rf .next",
"copy:css": "cpx \"../../packages/next-auth/css/**/*\" src/css --watch",
"watch:css": "cd ../../packages/next-auth && npm run watch:css",
"dev": "npm-run-all --parallel dev:next watch:css copy:css",
"dev:next": "npx next dev",
"build": "npx next build",
"watch:css": "cd ../../packages/next-auth && pnpm watch:css",
"dev": "concurrently \"pnpm dev:next\" \"pnpm watch:css\" \"pnpm copy:css\"",
"dev:next": "next dev",
"build": "next build",
"start": "next start",
"email": "npx fake-smtp-server",
"start:email": "npm run email"
"email": "fake-smtp-server",
"start:email": "pnpm email"
},
"license": "ISC",
"dependencies": {
"@next-auth/fauna-adapter": "^1.0.1",
"@next-auth/prisma-adapter": "^1.0.1",
"@prisma/client": "^3.10.0",
"cpx": "^1.5.0",
"fake-smtp-server": "^0.8.0",
"faunadb": "^4.4.1",
"next": "^12.1.0",
@@ -29,6 +30,7 @@
"devDependencies": {
"@types/react": "^17.0.37",
"@types/react-dom": "^17.0.11",
"concurrently": "^7.1.0",
"prisma": "^3.10.0"
}
}
}

View File

@@ -1,5 +1,7 @@
body {
font-family: -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
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";
padding: 0 1rem 1rem 1rem;
max-width: 680px;
margin: 0 auto;

View File

@@ -1,7 +1,7 @@
body {
font-family: -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans,
sans-serif, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
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";
padding: 0 1rem 1rem 1rem;
max-width: 680px;
margin: 0 auto;

View File

@@ -30,7 +30,7 @@
"type": "module",
"dependencies": {
"cookie": "0.4.1",
"next-auth": "^4.2.1"
"next-auth": "^4.3.3"
},
"prettier": {
"semi": false,

View File

@@ -36,9 +36,9 @@
<style>
:global(body) {
font-family: -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans,
sans-serif, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
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";
padding: 0 1rem 1rem 1rem;
max-width: 680px;
margin: 0 auto;

View File

@@ -1201,9 +1201,9 @@ minimatch@^3.0.4:
brace-expansion "^1.1.7"
minimist@^1.2.0, minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
version "1.2.6"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
mkdirp@^0.5.1:
version "0.5.5"
@@ -1232,10 +1232,10 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
next-auth@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.2.1.tgz#042e4858d9f67b4f702d3a55bae0d2f04db3cac3"
integrity sha512-XDtt7nqevkNf4EJ2zKAKkI+MFsURf11kx11vPwxrBYA1MHeqWwaWbGOUOI2ekNTvfAg4nTEJJUH3LV2cLrH3Tg==
next-auth@^4.3.3:
version "4.3.3"
resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.3.3.tgz#5ff892e73648a0f33c2af0e9d7cafda729f63ae7"
integrity sha512-bUs+oOOPT18Pq/+4v9q4PA/DGoVoAX6jwY7RTfE/akFXwlny+y/mNS6lPSUwpqcHjljqBaq34PQA3+01SdOOPw==
dependencies:
"@babel/runtime" "^7.16.3"
"@panva/hkdf" "^1.0.1"

View File

@@ -119,6 +119,8 @@ NextAuthTable:
KeyType: RANGE
GlobalSecondaryIndexes:
- IndexName: GSI1
Projection:
ProjectionType: ALL
KeySchema:
- AttributeName: GSI1PK
KeyType: HASH

View File

@@ -133,12 +133,22 @@ npx prisma migrate dev
### MongoDB
Prisma supports MongoDB, and so does NextAuth.js. Following the instructions of the [Prisma documentation](https://www.prisma.io/docs/concepts/database-connectors/mongodb) on the MongoDB connector, the only thing you have to change is making sure that the `id` fields are mapped correctly:
Prisma supports MongoDB, and so does NextAuth.js. Following the instructions of the [Prisma documentation](https://www.prisma.io/docs/concepts/database-connectors/mongodb) on the MongoDB connector, things you have to change are:
1. Make sure that the id fields are mapped correctly
```prisma
id String @id @default(auto()) @map("_id") @db.ObjectId
```
2. The Native database type attribute to `@db.String` from `@db.Text`.
```prisma
refresh_token String? @db.String
access_token String? @db.String
id_token String? @db.String
```
Everything else should be the same.
## Naming Conventions

View File

@@ -87,10 +87,11 @@ The default redirect callback looks like this:
```js title="pages/api/auth/[...nextauth].js"
...
callbacks: {
redirect({ url, baseUrl }) {
if (url.startsWith(baseUrl)) return url
async redirect({ url, baseUrl }) {
// Allows relative callback URLs
else if (url.startsWith("/")) return new URL(url, baseUrl).toString()
if (url.startsWith("/")) return `${baseUrl}${url}`
// Allows callback URLs on the same origin
else if (new URL(url).origin === baseUrl) return url
return baseUrl
}
}
@@ -104,7 +105,7 @@ The redirect callback may be invoked more than once in the same flow.
## JWT callback
This callback is called whenever a JSON Web Token is created (i.e. at sign
in) or updated (i.e whenever a session is accessed in the client). The returned value will be [signed and optionally encrypted](/configuration/options#jwt), and it is stored in a cookie.
in) or updated (i.e whenever a session is accessed in the client). The returned value will be [encrypted](/configuration/options#jwt), and it is stored in a cookie.
Requests to `/api/auth/signin`, `/api/auth/session` and calls to `getSession()`, `useSession()` will invoke this function, but only if you are using a [JWT session](/configuration/options#session). This method is not invoked when you persist sessions in a database.

View File

@@ -52,7 +52,7 @@ Sent when an account in a given provider is linked to a user in our user databas
The message object will contain:
- `user`: The user object from your adapter.
- `providerAccount`: The object returned from the provider.
- `account`: The object returned from the provider.
### session

View File

@@ -16,16 +16,53 @@ You must set the [`NEXTAUTH_SECRET`](/configuration/options#nextauth_secret) env
**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.
---
### Basic usage
```js
import withAuth from "next-auth/middleware"
// or
import { withAuth } from "next-auth/middleware"
```
---
### Custom JWT decode method
If you have custom jwt decode method set in `[...nextauth].ts`, you must also pass the same `decode` method to `withAuth` in order to read the custom-signed JWT correctly. You may want to extract the encode/decode logic to a separate function for consistency.
`[...nextauth].ts`
```ts
import jwt from "jsonwebtoken";
export default NextAuth({
providers: [...],
secret: /* Please use `process.env.NEXTAUTH_SECRET` */,
jwt: {
encode: async ({ secret, token }) => {
return jwt.sign(token as any, secret);
},
decode: async ({ secret, token }) => {
return jwt.verify(token as string, secret) as any;
},
},
})
```
Any `_middleware.ts`
```ts
import withAuth from "next-auth/middleware"
import jwt from "jsonwebtoken";
export default withAuth({
jwt: {
decode: async ({ secret, token }) => {
return jwt.verify(token, secret) as any;
},
},
callbacks: {
authorized: ({ token }) => !!token,
},
})
```
---
### `callbacks`
- **Required:** No

View File

@@ -25,7 +25,7 @@ Using [System Environment Variables](https://vercel.com/docs/concepts/projects/e
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.
If you are using [Middleware](/configuration/nextjs#prerequisites) this environment variables must be set.
If you are using [Middleware](/configuration/nextjs#prerequisites) this environment variable must be set.
### NEXTAUTH_URL_INTERNAL
@@ -97,7 +97,7 @@ Default values for this option are shown below:
```js
session: {
// Choose how you want to save the user session.
// The default is `"jwt"`, an encrypted JWT (JWE) in the session cookie.
// The default is `"jwt"`, an encrypted JWT (JWE) stored in the session cookie.
// If you use an `adapter` however, we default it to `"database"` instead.
// You can still force a JWT session by explicitly defining `"jwt"`.
// When using `"database"`, the session cookie will only contain a `sessionToken` value,
@@ -123,7 +123,7 @@ session: {
#### Description
JSON Web Tokens can be used for session tokens if enabled with `session: { strategy: "jwt" }` option. JSON Web Tokens are enabled by default if you have not specified an adapter. JSON Web Tokens are encrypted (JWE) by default. We recommend you keep this behaviour. See the [Override JWT `encode` and `decode` methods] advanced option.(#override-jwt-encode-and-decode-methods)
JSON Web Tokens can be used for session tokens if enabled with `session: { strategy: "jwt" }` option. JSON Web Tokens are enabled by default if you have not specified an adapter. JSON Web Tokens are encrypted (JWE) by default. We recommend you keep this behaviour. See the [Override JWT `encode` and `decode` methods](#override-jwt-encode-and-decode-methods) advanced option.
#### JSON Web Token Options
@@ -226,6 +226,10 @@ pages: {
}
```
:::note
When using this configuration, ensure that these pages actually exist. For example `error: '/auth/error'` refers to a page file at `pages/auth/error.js`.
:::
See the documentation for the [pages option](/configuration/pages) for more information.
---
@@ -285,7 +289,6 @@ events: {
async updateUser(message) { /* user updated - e.g. their email was verified */ },
async linkAccount(message) { /* account (e.g. Twitter) linked to a user */ },
async session(message) { /* session is active */ },
async error(message) { /* error in authentication flow */ }
}
```
@@ -482,6 +485,8 @@ Using a custom cookie policy may introduce security flaws into your application
NextAuth.js uses encrypted JSON Web Tokens ([JWE](https://datatracker.ietf.org/doc/html/rfc7516)) by default. Unless you have a good reason, we recommend keeping this behaviour. Although you can override this using the `encode` and `decode` methods. Both methods must be defined at the same time.
**IMPORTANT: If you use middleware to protect routes, make sure the same method is also set in the [`_middleware.ts` options](/configuration/nextjs#custom-jwt-decode-method)**
```js
jwt: {
async encode(params: {
@@ -495,7 +500,7 @@ jwt: {
async decode(params: {
token: string
secret: string
}: Promise<JWT | null>) {
}): Promise<JWT | null> {
// return a `JWT` object, or `null` if decoding failed
return {}
},

View File

@@ -21,6 +21,10 @@ To add a custom login page, you can use the `pages` option:
...
```
:::note
When using this configuration, ensure that these pages actually exist. For example `error: '/auth/error'` refers to a page file at `pages/auth/error.js`.
:::
## Error codes
We purposefully restrict the returned error codes for increased security.
@@ -51,7 +55,7 @@ The following errors are passed as error query parameters to the default or over
- **SessionRequired**: The content of this page requires you to be signed in at all times. See [useSession](/getting-started/client#require-session) for configuration.
- **Default**: Catch all, will apply, if none of the above matched
Example: `/auth/error?error=Default`
Example: `/auth/signin?error=Default`
## Theming
@@ -90,24 +94,16 @@ export default function SignIn({ providers }) {
)
}
// This is the recommended way for Next.js 9.3 or newer
export async function getServerSideProps(context) {
const providers = await getProviders()
return {
props: { providers },
}
}
/*
// If older than Next.js 9.3
SignIn.getInitialProps = async () => {
return {
providers: await getProviders()
}
}
*/
```
There is another, more fully styled example signin page available [here](https://github.com/ndom91/next-auth-example-sign-in-page).
### Email Sign in
If you create a custom sign in form for email sign in, you will need to submit both fields for the **email** address and **csrfToken** from **/api/auth/csrf** in a POST request to **/api/auth/signin/email**.
@@ -128,22 +124,12 @@ export default function SignIn({ csrfToken }) {
)
}
// This is the recommended way for Next.js 9.3 or newer
export async function getServerSideProps(context) {
const csrfToken = await getCsrfToken(context)
return {
props: { csrfToken },
}
}
/*
// If older than Next.js 9.3
SignIn.getInitialProps = async (context) => {
return {
csrfToken: await getCsrfToken(context)
}
}
*/
```
You can also use the `signIn()` function which will handle obtaining the CSRF token for you:
@@ -176,7 +162,6 @@ export default function SignIn({ csrfToken }) {
)
}
// This is the recommended way for Next.js 9.3 or newer
export async function getServerSideProps(context) {
return {
props: {
@@ -184,15 +169,6 @@ export async function getServerSideProps(context) {
},
}
}
/*
// If older than Next.js 9.3
SignIn.getInitialProps = async (context) => {
return {
csrfToken: await getCsrfToken(context)
}
}
*/
```
You can also use the `signIn()` function which will handle obtaining the CSRF token for you:

View File

@@ -21,8 +21,33 @@ Without going into too much detail, the OAuth flow generally has 6 parts:
5. The application requests the resource from the resource server (API) and presents the access token for authentication
6. If the access token is valid, the resource server (API) serves the resource to the application
<img src="https://i2.wp.com/blogs.innovationm.com/wp-content/uploads/2019/07/blog-open1.png" alt="OAuth Flow Diagram" /><br />
<small>Source: https://dzone.com/articles/open-id-connect-authentication-with-oauth20-author</small>
```mermaid
sequenceDiagram
participant Browser
participant App Server
participant Auth Server (Github)
Note left of Browser: User clicks on "Sign in"
Browser->>App Server: GET<br/>"api/auth/signin"
App Server->>App Server: Computes the available<br/>sign in providers<br/>from the "providers" option
App Server->>Browser: Redirects to Sign in page
Note left of Browser: Sign in options<br/>are shown the user<br/>(Github, Twitter, etc...)
Note left of Browser: User clicks on<br/>"Sign in with Github"
Browser->>App Server: POST<br/>"api/auth/signin/github"
App Server->>App Server: Computes sign in<br/>options for Github<br/>(scopes, callback URL, etc...)
App Server->>Auth Server (Github): GET<br/>"github.com/login/oauth/authorize"
Note left of Auth Server (Github): Sign in options<br> are supplied as<br/>query params<br/>(clientId, <br/>scope, etc...)
Auth Server (Github)->>Browser: Shows sign in page<br/>in Github.com<br/>to the user
Note left of Browser: User inserts their<br/>credentials in Github
Browser->>Auth Server (Github): Github validates the inserted credentials
Auth Server (Github)->>Auth Server (Github): Generates one time access code<br/>and calls callback<br>URL defined in<br/>App settings
Auth Server (Github)->>App Server: GET<br/>"api/auth/github/callback?code=123"
App Server->>App Server: Grabs code<br/>to exchange it for<br/>access token
App Server->>Auth Server (Github): POST<br/>"github.com/login/oauth/access_token"<br/>{code: 123}
Auth Server (Github)->>Auth Server (Github): Verifies code is<br/>valid and generates<br/>access token
Auth Server (Github)->>App Server: { access_token: 16C7x... }
App Server->>App Server: Generates session token<br/>and stores session
App Server->>Browser: You're now logged in!
```
For more details, check out Aaron Parecki's blog post [OAuth2 Simplified](https://aaronparecki.com/oauth-2-simplified/) or Postman's blog post [OAuth 2.0: Implicit Flow is Dead, Try PKCE Instead](https://blog.postman.com/pkce-oauth-how-to/).

View File

@@ -85,6 +85,8 @@ Preview deployments at Vercel are often available via multiple URLs. For example
Netlify is very similar to Vercel in that you can deploy a Next.js project without almost any extra work.
In order to setup NextAuth.js correctly here, you will want to make sure you add your `NEXTAUTH_SECRET` and `NEXTAUTH_URL` environment variables in the project settings. Netlify also exposes some [system environment variables](https://docs.netlify.com/configure-builds/environment-variables/) from which you can check which `NODE_ENV` you are currently in and much more.
In order to setup NextAuth.js correctly here, you will want to make sure you add your `NEXTAUTH_SECRET` environment variable in the project settings. If you are using the [Essential Next.js Build Plugin](https://github.com/netlify/netlify-plugin-nextjs) within your project, you **do not** need to set the `NEXTAUTH_URL` environment variable as it is set automatically as part of the build process.
Netlify also exposes some [system environment variables](https://docs.netlify.com/configure-builds/environment-variables/) from which you can check which `NODE_ENV` you are currently in and much more.
After this, just make sure you either have your OAuth provider setup correctly with `clientId` / `clientSecret`'s and callback URLs.

View File

@@ -99,7 +99,7 @@ This is required to store the verification token. Please see the [email provider
The Credentials Provider can only be used if JSON Web Tokens are used for sessions.
JSON Web Tokens are used for Sessions by default if you have not specified a database. However, if you are using a database, then Database Sessions are enabled by default and you need to [explicitly enable JWT Sessions](https://next-auth.js.org/configuration/options#session) to use the Credentials Provider.
JSON Web Tokens are used for Sessions by default if you have not specified a database. However, if you are using a database, then Database Sessions are enabled by default and you need to [explicitly enable JWT Sessions](/configuration/options#session) to use the Credentials Provider.
If you are using a Credentials Provider, NextAuth.js will not persist users or sessions in a database - user accounts used with the Credentials Provider must be created and managed outside of NextAuth.js.
@@ -111,9 +111,17 @@ This error occurs when there was no `authorize()` handler defined on the credent
#### PKCE_ERROR
The provider you tried to use failed when setting [PKCE or Proof Key for Code Exchange](https://tools.ietf.org/html/rfc7636#section-4.2).
The provider you tried to use failed when setting [PKCE or Proof Key for Code Exchange](https://tools.ietf.org/html/rfc7636#section-4).
The `code_verifier` is saved in a cookie called (by default) `__Secure-next-auth.pkce.code_verifier` which expires after 15 minutes.
Check if `cookies.pkceCodeVerifier` is configured correctly. The default `code_challenge_method` is `"S256"`. This is currently not configurable to `"plain"`, as it is not recommended, and in most cases, it is only supported for backward compatibility.
Check if `cookies.pkceCodeVerifier` is configured correctly.
The default `code_challenge_method` is `"S256"`. This is currently not configurable to `"plain"`, [as per RFC7636](https://datatracker.ietf.org/doc/html/rfc7636#section-4.2):
> If the client is capable of using "S256", it MUST use "S256", as
S256" is Mandatory To Implement (MTI) on the server.
#### INVALID_CALLBACK_URL_ERROR
The `callbackUrl` provided was either invalid or not defined. See [specifying a `callbackUrl`](/getting-started/client#specifying-a-callbackurl) for more information.
---
@@ -121,7 +129,7 @@ Check if `cookies.pkceCodeVerifier` is configured correctly. The default `code_c
#### JWT_SESSION_ERROR
https://next-auth.js.org/errors#jwt_session_error JWKKeySupport: the key does not support HS512 verify algorithm
JWKKeySupport: 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
@@ -157,7 +165,7 @@ Make sure the file is there and the filename is written correctly.
#### NO_SECRET
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](https://next-auth.js.org/configuration/options#secret)
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

View File

@@ -270,7 +270,7 @@ Ultimately if your request is not accepted or is not actively in development, yo
</summary>
<p>
NextAuth.js by default uses JSON Web Tokens for saving the user's session. However, if you use a [database adapter](/adapters/overview), the database will be used to persist the user's session. You can force the usage of JWT when using a database [through the configuration options](/configuration/options#session).
NextAuth.js by default uses JSON Web Tokens for saving the user's session. However, if you use a [database adapter](/adapters/overview), the database will be used to persist the user's session. You can force the usage of JWT when using a database [through the configuration options](/configuration/options#session). Since v4 all our JWT tokens are now encrypted by default with A256GCM.
</p>
</details>
@@ -285,11 +285,9 @@ JSON Web Tokens can be used for session tokens, but are also used for lots of ot
- Advantages of using a JWT as a session token include that they do not require a database to store sessions, this can be faster and cheaper to run and easier to scale.
- JSON Web Tokens in NextAuth.js are secured using cryptographic signing (JWS) by default and it is easy for services and API endpoints to verify tokens without having to contact a database to verify them.
- JSON Web Tokens in NextAuth.js are secured using cryptographic encryption (JWE) to store the included information directly in a JWT session token. You may then use the token to pass information between services and APIs on the same domain without having to contact a database to verify the included information.
- You can enable encryption (JWE) to store include information directly in a JWT session token that you wish to keep secret and use the token to pass information between services / APIs on the same domain.
- You can use JWT to securely store information you do not mind the client knowing even without encryption, as the JWT is stored in a server-readable-only-token so data in the JWT is not accessible to third party JavaScript running on your site.
- You can use JWT to securely store information you do not mind the client knowing even without encryption, as the JWT is stored in a server-readable-only cookie so data in the JWT is not accessible to third party JavaScript running on your site.
</p>
</details>
@@ -308,7 +306,7 @@ JSON Web Tokens can be used for session tokens, but are also used for lots of ot
- As with database session tokens, JSON Web Tokens are limited in the amount of data you can store in them. There is typically a limit of around 4096 bytes per cookie, though the exact limit varies between browsers, proxies and hosting services. If you want to support most browsers, then do not exceed 4096 bytes per cookie. If you want to save more data, you will need to persist your sessions in a database (Source: [browsercookielimits.iain.guru](http://browsercookielimits.iain.guru/))
The more data you try to store in a token and the more other cookies you set, the closer you will come to this limit. If you wish to store more than ~4 KB of data you're probably at the point where you need to store a unique ID in the token and persist the data elsewhere (e.g. in a server-side key/value store).
The more data you try to store in a token and the more other cookies you set, the closer you will come to this limit. Since v4 we have implemented cookie chunking so that cookies over the 4kb limit get split and reassembled upon parsing. However since this data needs to be transmitted on every request, if you wish to store more than ~4 KB of data you're probably at the point where you want to store a unique ID in the token and persist the data elsewhere (e.g. in a server-side key/value store).
- Data stored in an encrypted JSON Web Token (JWE) may be compromised at some point.
@@ -316,9 +314,8 @@ 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.
- 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 using JSON Web Token you should at least specify a secret and ideally configure public/private keys.
</p>
</details>

View File

@@ -123,20 +123,18 @@ export default function App({
}
function Auth({ children }) {
const { data: session, status } = useSession({ required: true })
const isUser = !!session?.user
// if `{ required: true }` is supplied, `status` can only be "loading" or "authenticated"
const { status } = useSession({ required: true })
if (isUser) {
return children
if (status === 'loading') {
return <div>Loading...</div>
}
// Session is being fetched, or no user.
// If no user, useEffect() will redirect.
return <div>Loading...</div>
return children
}
```
It can be easily be extended/modified to support something like an options object for role based authentication on pages. An example:
It can be easily extended/modified to support something like an options object for role based authentication on pages. An example:
```jsx title="pages/admin.jsx"
AdminDashboard.auth = {
@@ -312,11 +310,11 @@ You can specify a different `callbackUrl` by specifying it as the second argumen
e.g.
- `signIn(null, { callbackUrl: 'http://localhost:3000/foo' })`
- `signIn('google', { callbackUrl: 'http://localhost:3000/foo' })`
- `signIn(undefined, { callbackUrl: '/foo' })`
- `signIn('google', { callbackUrl: 'http://localhost:3000/bar' })`
- `signIn('email', { email, callbackUrl: 'http://localhost:3000/foo' })`
The URL must be considered valid by the [redirect callback handler](/configuration/callbacks#redirect-callback). By default it requires the URL to be an absolute URL at the same host name, or else it will redirect to the homepage. You can define your own [redirect callback](/configuration/callbacks#redirect-callback) to allow other URLs, including supporting relative URLs.
The URL must be considered valid by the [redirect callback handler](/configuration/callbacks#redirect-callback). By default it requires the URL to be an absolute URL at the same host name, or a relative url starting with a slash. If it does not match it will redirect to the homepage. You can define your own [redirect callback](/configuration/callbacks#redirect-callback) to allow other URLs.
### Using the `redirect: false` option
@@ -400,7 +398,7 @@ As with the `signIn()` function, you can specify a `callbackUrl` parameter by pa
e.g. `signOut({ callbackUrl: 'http://localhost:3000/foo' })`
The URL must be considered valid by the [redirect callback handler](/configuration/callbacks#redirect-callback). By default this means it must be an absolute URL at the same host name (or else it will default to the homepage); you can define your own custom [redirect callback](/configuration/callbacks#redirect-callback) to allow other URLs, including supporting relative URLs.
The URL must be considered valid by the [redirect callback handler](/configuration/callbacks#redirect-callback). By default, it requires the URL to be an absolute URL at the same host name, or you can also supply a relative URL starting with a slash. If it does not match it will redirect to the homepage. You can define your own [redirect callback](/configuration/callbacks#redirect-callback) to allow other URLs.
### Using the `redirect: false` option

View File

@@ -15,7 +15,7 @@ The easiest way to get started is to clone the [example app](https://github.com/
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.
```javascript title="pages/api/auth/[...nextauth].js"
```javascript title="pages/api/auth/[...nextauth].js" showLineNumbers
import NextAuth from "next-auth"
import GithubProvider from "next-auth/providers/github"
@@ -42,8 +42,7 @@ All requests to `/api/auth/*` (`signIn`, `callback`, `signOut`, etc.) will autom
To be able to use `useSession` first you'll need to expose the session context, [`<SessionProvider />`](/getting-started/client#sessionprovider), at the top level of your application:
```javascript
// pages/_app.js
```jsx title="pages/_app.jsx" showLineNumbers
import { SessionProvider } from "next-auth/react"
export default function App({
@@ -68,7 +67,7 @@ Check out the [client documentation](/getting-started/client) to see how you can
The [`useSession()`](/getting-started/client#usesession) React Hook in the NextAuth.js client is the easiest way to check if someone is signed in.
```javascript
```jsx title="components/login-btn.jsx" showLineNumbers
import { useSession, signIn, signOut } from "next-auth/react"
export default function Component() {
@@ -96,7 +95,7 @@ You can use the `useSession` hook from anywhere in your application (e.g. in a h
To protect an API Route, you can use the [`getSession()`](/getting-started/client#getsession) method in the NextAuth.js client.
```javascript
```javascript title="pages/api/restricted.js" showLineNumbers
import { getSession } from "next-auth/react"
export default async (req, res) => {
@@ -123,18 +122,20 @@ NextAuth.js allows you to hook into various parts of the authentication flow via
For example, to pass a value from the sign-in to the frontend, client-side, you can use a combination of the [`session`](/configuration/callbacks#session-callback) and [`jwt`](/configuration/callbacks#jwt-callback) callback like so:
```javascript
```javascript title="pages/api/auth/[...nextauth].js"
...
callbacks: {
async jwt({ token, account }) {
// Persist the OAuth access_token to the token right after signin
if (account) {
// highlight-next-line
token.accessToken = account.access_token
}
return token
},
async session({ session, token, user }) {
// Send properties to the client, like an access_token from a provider.
// highlight-next-line
session.accessToken = token.accessToken
return session
}
@@ -144,10 +145,11 @@ callbacks: {
Now whenever you call `getSession` or `useSession`, the data object which is returned will include the `accessToken` value.
```js
```jsx title="components/accessToken.jsx" showLineNumbers
import { useSession, signIn, signOut } from "next-auth/react"
export default function Component() {
// highlight-next-line
const { data } = useSession()
const { accessToken } = data
@@ -158,7 +160,7 @@ export default function Component() {
## Configuring callback URL (OAuth only)
If you are using an OAuth provider either through one of our [built-in providers](/configuration/providers/oauth)
or through a [custom provider](/configuration/providers/oauth#using-a-custom-provider), you'll need to configure
or through a [custom provider](/configuration/providers/oauth#using-a-custom-provider), you'll need to configure
a callback URL in your provider's settings. Each provider has a "Configuration" section that should give you pointers on how to do that.
Follow [these steps](/configuration/providers/oauth#how-to) to learn how to integrate with an OAuth provider.

View File

@@ -38,8 +38,7 @@ _Note: Email sign-in requires a database to be configured to store single-use ve
- Designed to be secure by default and encourage best practices for safeguarding user data
- Uses Cross-Site Request Forgery Tokens on POST routes (sign in, sign out)
- Default cookie policy aims for the most restrictive policy appropriate for each cookie
- When JSON Web Tokens are enabled, they are signed by default (JWS) with HS512
- Use JWT encryption (JWE) by setting the option `encryption: true` (defaults to A256GCM)
- When JSON Web Tokens are enabled, they are encrypted by default (JWE) with A256GCM
- Auto-generates symmetric signing and encryption keys for developer convenience
- Features tab/window syncing and keepalive messages to support short-lived sessions
- Attempts to implement the latest guidance published by [Open Web Application Security Project](https://owasp.org/)

View File

@@ -47,7 +47,7 @@ This will work in code editors with a strong TypeScript integration like VSCode
Let's look at `Session`:
```ts title="pages/api/[...nextauth].ts"
```ts title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"
export default NextAuth({

View File

@@ -331,7 +331,7 @@ The way we save data with adapters have slightly changed. With the new Adapter A
- `user_id`/`userId` consistently named `userId`.
- `compound_id`/`compoundId` is removed from Account.
- `access_token`/`accessToken` is removed from Session.
- `email_verified`/`emailVerified` on User is consistently named `email_verified`.
- `email_verified`/`emailVerified` on User is consistently named `emailVerified`.
- `provider_id`/`providerId` renamed to `provider` on Account
- `provider_type`/`providerType` renamed to `type` on Account
- `provider_account_id`/`providerAccountId` on Account is consistently named `providerAccountId`
@@ -419,8 +419,8 @@ They are designed to be run directly against the database itself. So instead of
/* ACCOUNT */
ALTER TABLE accounts
CHANGE "access_token_expires" "expires_at" int
CHANGE "user_id" "userId" varchar(191)
ADD CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users(id)
CHANGE "user_id" "userId" varchar(255)
ADD CONSTRAINT fk_user_id FOREIGN KEY (userId) REFERENCES users(id)
RENAME COLUMN "provider_id" "provider"
RENAME COLUMN "provider_account_id" "providerAccountId"
DROP COLUMN "provider_type"
@@ -429,14 +429,14 @@ DROP COLUMN "compound_id"
DROP COLUMN "created_at"
DROP COLUMN "updated_at"
ADD COLUMN "token_type" varchar(191) NULL
ADD COLUMN "scope" varchar(191) NULL
ADD COLUMN "id_token" varchar(191) NULL
ADD COLUMN "session_state" varchar(191) NULL
ADD COLUMN "token_type" varchar(255) NULL
ADD COLUMN "scope" varchar(255) NULL
ADD COLUMN "id_token" varchar(255) NULL
ADD COLUMN "session_state" varchar(255) NULL
/* Note: These are only needed if you're going to be using the old Twitter OAuth 1.0 provider. */
ADD COLUMN "oauth_token_secret" varchar(191) NULL
ADD COLUMN "oauth_token" varchar(191) NULL
ADD COLUMN "oauth_token_secret" varchar(255) NULL
ADD COLUMN "oauth_token" varchar(255) NULL
/* USER */
ALTER TABLE users
@@ -448,15 +448,16 @@ DROP COLUMN "updated_at"
/* SESSION */
ALTER TABLE sessions
RENAME COLUMN "session_token" "sessionToken"
CHANGE "user_id" "userId" varchar(191)
ADD CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users(id)
CHANGE "user_id" "userId" varchar(255)
ADD CONSTRAINT fk_user_id FOREIGN KEY (userId) REFERENCES users(id)
DROP COLUMN "access_token"
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
DROP COLUMN "created_at"
DROP COLUMN "updated_at"
/* VERIFICATION REQUESTS */
ALTER TABLE verification_requests
ALTER TABLE verification_requests RENAME verification_tokens
ALTER TABLE verification_tokens
DROP COLUMN id
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
DROP COLUMN "created_at"
@@ -467,50 +468,84 @@ DROP COLUMN "updated_at"
```sql
/* ACCOUNT */
ALTER TABLE accounts RENAME COLUMN "user_id" TO "userId";
ALTER TABLE accounts RENAME COLUMN "provider_id" TO "provider";
ALTER TABLE accounts RENAME COLUMN "provider_account_id" TO "providerAccountId";
ALTER TABLE accounts RENAME COLUMN "access_token_expires" TO "expires_at";
ALTER TABLE accounts RENAME COLUMN "provider_type" TO "type";
/* Do conversion of TIMESTAMPTZ to BIGINT */
ALTER TABLE accounts ALTER COLUMN "expires_at" TYPE TEXT USING CAST(extract(epoch FROM "expires_at") AS BIGINT)*1000;
/* Keep id as SERIAL with autoincrement when using ORM. Using new v4 uuid format won't work because of incompatibility */
/* ALTER TABLE accounts ALTER COLUMN "id" TYPE TEXT; */
/* ALTER TABLE accounts ALTER COLUMN "userId" TYPE TEXT; */
ALTER TABLE accounts ALTER COLUMN "type" TYPE TEXT;
ALTER TABLE accounts ALTER COLUMN "provider" TYPE TEXT;
ALTER TABLE accounts ALTER COLUMN "providerAccountId" TYPE TEXT;
ALTER TABLE accounts ADD CONSTRAINT fk_user_id FOREIGN KEY ("userId") REFERENCES users(id);
ALTER TABLE accounts
CHANGE "access_token_expires" "expires_at" int
CHANGE "user_id" "userId" text
ADD CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users(id)
RENAME COLUMN "provider_id" "provider"
RENAME COLUMN "provider_account_id" "providerAccountId"
DROP COLUMN "provider_type"
DROP COLUMN "compound_id"
DROP COLUMN IF EXISTS "compound_id";
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
DROP COLUMN "created_at"
DROP COLUMN "updated_at"
ADD COLUMN "token_type" text NULL
ADD COLUMN "scope" text NULL
ADD COLUMN "id_token" text NULL
ADD COLUMN "session_state" text NULL
ALTER TABLE accounts
DROP COLUMN IF EXISTS "created_at",
DROP COLUMN IF EXISTS "updated_at";
ALTER TABLE accounts
ADD COLUMN IF NOT EXISTS "token_type" TEXT NULL,
ADD COLUMN IF NOT EXISTS "scope" TEXT NULL,
ADD COLUMN IF NOT EXISTS "id_token" TEXT NULL,
ADD COLUMN IF NOT EXISTS "session_state" TEXT NULL;
/* Note: These are only needed if you're going to be using the old Twitter OAuth 1.0 provider. */
ADD COLUMN "oauth_token_secret" text NULL
ADD COLUMN "oauth_token" text NULL
/* ALTER TABLE accounts
ADD COLUMN IF NOT EXISTS "oauth_token_secret" TEXT NULL,
ADD COLUMN IF NOT EXISTS "oauth_token" TEXT NULL; */
/* USER */
ALTER TABLE users
RENAME COLUMN "email_verified" "emailVerified"
ALTER TABLE users RENAME COLUMN "email_verified" TO "emailVerified";
/* Keep id as SERIAL with autoincrement when using ORM. Using new v4 uuid format won't work because of incompatibility */
/* ALTER TABLE users ALTER COLUMN "id" TYPE TEXT; */
ALTER TABLE users ALTER COLUMN "name" TYPE TEXT;
ALTER TABLE users ALTER COLUMN "email" TYPE TEXT;
ALTER TABLE users ALTER COLUMN "image" TYPE TEXT;
/* Do conversion of TIMESTAMPTZ to BIGINT and then TEXT */
ALTER TABLE users ALTER COLUMN "emailVerified" TYPE TEXT USING CAST(CAST(extract(epoch FROM "emailVerified") AS BIGINT)*1000 AS TEXT);
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
DROP COLUMN "created_at"
DROP COLUMN "updated_at"
ALTER TABLE users
DROP COLUMN IF EXISTS "created_at",
DROP COLUMN IF EXISTS "updated_at";
/* SESSION */
ALTER TABLE sessions
RENAME COLUMN "session_token" "sessionToken"
CHANGE "user_id" "userId" text
ADD CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users(id)
DROP COLUMN "access_token"
ALTER TABLE sessions RENAME COLUMN "session_token" TO "sessionToken";
ALTER TABLE sessions RENAME COLUMN "user_id" TO "userId";
/* Keep id as SERIAL with autoincrement when using ORM. Using new v4 uuid format won't work because of incompatibility */
/* ALTER TABLE sessions ALTER COLUMN "id" TYPE TEXT; */
/* ALTER TABLE sessions ALTER COLUMN "userId" TYPE TEXT; */
ALTER TABLE sessions ALTER COLUMN "sessionToken" TYPE TEXT;
ALTER TABLE sessions ADD CONSTRAINT fk_user_id FOREIGN KEY ("userId") REFERENCES users(id);
/* Do conversion of TIMESTAMPTZ to BIGINT and then TEXT */
ALTER TABLE sessions ALTER COLUMN "expires" TYPE TEXT USING CAST(CAST(extract(epoch FROM "expires") AS BIGINT)*1000 AS TEXT);
ALTER TABLE sessions DROP COLUMN IF EXISTS "access_token";
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
DROP COLUMN "created_at"
DROP COLUMN "updated_at"
ALTER TABLE sessions
DROP COLUMN IF EXISTS "created_at",
DROP COLUMN IF EXISTS "updated_at";
/* VERIFICATION REQUESTS */
ALTER TABLE verification_requests
DROP COLUMN id
ALTER TABLE verification_requests RENAME TO verification_tokens;
/* Keep id as ORM needs it */
/* ALTER TABLE verification_tokens DROP COLUMN IF EXISTS id; */
ALTER TABLE verification_tokens ALTER COLUMN "identifier" TYPE TEXT;
ALTER TABLE verification_tokens ALTER COLUMN "token" TYPE TEXT;
/* Do conversion of TIMESTAMPTZ to BIGINT and then TEXT */
ALTER TABLE verification_tokens ALTER COLUMN "expires" TYPE TEXT USING CAST(CAST(extract(epoch FROM "expires") AS BIGINT)*1000 AS TEXT);
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
DROP COLUMN "created_at"
DROP COLUMN "updated_at"
ALTER TABLE verification_tokens
DROP COLUMN IF EXISTS "created_at",
DROP COLUMN IF EXISTS "updated_at";
```
#### MongoDB

View File

@@ -0,0 +1,12 @@
---
id: basics
title: Basics
---
### [Securing pages and API routes](/tutorials/securing-pages-and-api-routes)
- How to restrict access to pages and API routes.
### [Usage with class components](/tutorials/usage-with-class-components)
- How to use `useSession()` hook with class components.

View File

@@ -0,0 +1,34 @@
---
id: fullstack
title: Fullstack
---
### [Refresh Token Rotation](/tutorials/refresh-token-rotation)
- How to implement refresh token rotation.
### [LDAP Authentication](/tutorials/ldap-auth-example)
- How to use the Credentials Provider to authenticate against an LDAP database. This approach can be used to authenticate existing user accounts against any backend.
### [Adding HTTP(S) Proxy Support](/tutorials/corporate-proxy)
- Add support for HTTP/HTTPS Proxy support to `openid-client` in order to use NextAuth.js behind a corporate proxy or other locked down network.
### [Using the Email Provider behind Corporate Email Scanning Services](/tutorials/avoid-corporate-link-checking-email-provider)
- An internal tutorial on modifying the catch-all API Route to gracefully handle `HEAD` requests.
## Database
### [Custom models with TypeORM](/adapters/typeorm#custom-models)
- How to use models with custom properties using the TypeORM adapter.
### [Creating a database adapter](/tutorials/creating-a-database-adapter)
- How to create a custom adapter, to use any database to fetch and store user / account data.
### [Adding role based login to database session strategy](/tutorials/role-based-login-strategy)
- Implement a role based login system by adding a custom session callback.

17
docs/docs/guides/index.md Normal file
View File

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

View File

@@ -0,0 +1,8 @@
---
id: testing
title: Testing
---
### [Testing with Cypress](/tutorials/testing-with-cypress)
- How to write tests using Cypress.

View File

@@ -31,5 +31,5 @@ providers: [
```
:::note
`issuer` should include the slug  e.g. `https://my-authentik-domain.com/application/o/My_Slug/`
`issuer` should include the slug without a trailing slash  e.g., `https://my-authentik-domain.com/application/o/My_Slug`
:::

View File

@@ -30,7 +30,7 @@ import BoxyHQSAMLProvider from "next-auth/providers/boxyhq-saml"
...
providers: [
BoxyHQSAMLProvider({
issuer: "http://localhost:5000",
issuer: "http://localhost:5225",
clientId: "dummy", // The dummy here is necessary since we'll pass tenant and product custom attributes in the client code
clientSecret: "dummy", // The dummy here is necessary since we'll pass tenant and product custom attributes in the client code
})

View File

@@ -23,7 +23,7 @@ The **Credentials Provider** comes with a set of default options:
You can override any of the options to suit your own use case.
## Example
## Example - Username / Password
The Credentials provider is specified like other providers, except that you need to define a handler for `authorize()` that accepts credentials submitted via HTTP POST as input and returns either:
@@ -73,9 +73,19 @@ providers: [
See the [callbacks documentation](/configuration/callbacks) for more information on how to interact with the token.
## Example - Web3 / Signin With Ethereum
The credentials provider can also be used to integrate with a service like [Sign-in With Ethereum](https://login.xyz).
For more information, check out the links below:
- [Tutorial](https://docs.login.xyz/integrations/nextauth.js)
- [Example App Repo](https://github.com/spruceid/siwe-next-auth-example).
- [Example App Demo](https://siwe-next-auth-example2.vercel.app/).
## Multiple providers
### Example code
### Example
You can specify more than one credentials provider by specifying a unique `id` for each one.

View File

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

View File

@@ -11,6 +11,11 @@ https://developers.google.com/identity/protocols/oauth2
https://console.developers.google.com/apis/credentials
The "Authorized 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/google`
- For development: `http://localhost:3000/api/auth/callback/google`
## Options
The **Google Provider** comes with a set of default options:

View File

@@ -37,5 +37,5 @@ providers: [
```
:::note
`issuer` should include the realm  e.g. `https://my-keycloak-domain.com/auth/realms/My_Realm`
`issuer` should include the realm  e.g. `https://my-keycloak-domain.com/realms/My_Realm`
:::

View File

@@ -41,9 +41,9 @@ providers: [
You must enable the _"Request email address from users"_ option in your app permissions if you want to obtain the users email address.
:::
![twitter](https://user-images.githubusercontent.com/7902980/83944068-1640ca80-a801-11ea-959c-0e744e2144f7.PNG)
![twitter](https://user-images.githubusercontent.com/55143799/168702338-a95912a7-b689-4680-aa2c-6306fe3c2ec7.jpeg)
## OAuth 2
## OAuth 2.0
Twitter supports OAuth 2, which is currently opt-in. To enable it, simply add `version: "2.0"` to your Provider configuration:
@@ -56,3 +56,7 @@ TwitterProvider({
```
Keep in mind that although this change is easy, it changes how and with which of [Twitter APIs](https://developer.twitter.com/en/docs/api-reference-index) you can interact with. Read the official [Twitter OAuth 2 documentation](https://developer.twitter.com/en/docs/authentication/oauth-2-0) for more details.
:::note
Email is currently not supported by Twitter OAuth 2.0.
:::

View File

@@ -0,0 +1,43 @@
---
id: united-effects
title: United Effects
---
## Documentation
https://docs.unitedeffects.com/integrations/nextauthjs
## Configuration
https://core.unitedeffects.com
## Options
The **United Effects Provider** comes with a set of default options:
- [United Effects Provider options](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/providers/united-effects.ts)
You can override any of the options to suit your own use case.
## Example
```js
import UnitedEffectsProvider from "next-auth/providers/united-effects";
...
providers: [
UnitedEffectsProvider({
clientId: process.env.UNITED_EFFECTS_CLIENT_ID,
clientSecret: process.env.UNITED_EFFECTS_CLIENT_SECRET,
issuer: process.env.UNITED_EFFECTS_ISSUER
})
]
...
```
:::note
`issuer` should be the fully qualified URL including your Auth Group ID  e.g. `https://auth.unitedeffects.com/YQpbQV5dbW-224dCovz-3`
:::
:::warning
The United Effects API does not return the user name or image by design, so this provider will return null for both. United Effects prioritizes user personal information security above all and has built a secured profile access request system separate from the provider API.
:::

View File

@@ -94,20 +94,10 @@ export default function SignIn({ providers }) {
)
}
// This is the recommended way for Next.js 9.3 or newer
export async function getServerSideProps(context) {
const providers = await getProviders()
return {
props: { providers },
}
}
/*
// If older than Next.js 9.3
SignIn.getInitialProps = async () => {
return {
providers: await getProviders()
}
}
*/
```

View File

@@ -1,3 +0,0 @@
import { CustomSandpack } from "../src/components/Sandpack"
<CustomSandpack />

View File

@@ -13,7 +13,7 @@ title: Tutorials and Explainers
- This is an introductory video to NextAuth.js for beginners. In this video, it is explained how to set up authentication in a few easy steps and add different configurations to make it more robust and secure.
#### [Authentication patterns for Next.js](https://leerob.io/blog/nextjs-authentication) <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>
#### [Authentication patterns for Next.js](https://nextjs.org/docs/authentication) <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>
- Next.js supports multiple patterns for authentication, each designed for different use cases. This guide will allow you to choose your adventure based on your constraints. By Lee Robinson.
@@ -21,14 +21,6 @@ title: Tutorials and Explainers
- This tutorial walks one through adding NextAuth.js to an existing project. Including setting up the OAuth client id and secret, adding the API routes for authentication, protecting pages and API routes behind that authentication, etc.
#### [Securing pages and API routes](tutorials/securing-pages-and-api-routes)
- How to restrict access to pages and API routes.
#### [Usage with class components](tutorials/usage-with-class-components)
- How to use `useSession()` hook with class components.
#### [Adding social authentication support to a Next.js app](https://getstarted.sh/bulletproof-next/add-social-authentication) <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>
- A tutorial by Arunoda Susirpiala. Checkout [GetStarted](https://getstarted.sh/) for more examples.
@@ -49,8 +41,26 @@ title: Tutorials and Explainers
- A video tutorial by Xiaoru Li from Prisma.
#### [How to authenticate Next.js Apps with Sign-In With Ethereum (SIWE) & NextAuth.js](https://docs.login.xyz/integrations/nextauth.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>
- Learn how to use Sign-In With Ethereum to authenticate your users with their existing Ethereum wallets - identifiers they personally control.
- Example application: [spruceid/siwe-next-auth-example](https://github.com/spruceid/siwe-next-auth-example)
## Fullstack
#### [Build a FullStack App with Next.js, NextAuth.js, Supabase & Prisma](https://themodern.dev/courses/build-a-fullstack-app-with-nextjs-supabase-and-prisma-322389284337222224) <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>
In this [free course](https://themodern.dev/courses/build-a-fullstack-app-with-nextjs-supabase-and-prisma-322389284337222224), you'll learn how to build a full-stack app using the following technologies:
- **Next.js** - The React framework for building the UI of the app and the REST API
- **NextAuth.js** - For implementing passwordless and OAuth authentication
- **Supabase** - For persisting the app data into a PostgreSQL database and storing media files
- **Prisma** - For making it easy to read and write data from our app from and to the database
The app that we'll work on in this course is called **_SupaVacation_**. It is an online marketplace for vacation rentals where users can browse through all the properties for rent, bookmark their favorite ones, and even rent their own properties.
> Here's [a live demo](https://supa-vacation.vercel.app/) of the app's final version. It is what your app should look likes after completing this course. Feel free to play with it to get an overview of all the features you'll be working on.
#### [Magic Link Authentication in Next.js with NextAuth and Fauna](https://alterclass.io/tutorials/magic-link-authentication-in-nextjs-with-nextauth-and-fauna) <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>
Learn how to implement passwordless/magic link authentication with database storage in your Next.js projects using NextAuth and Fauna DB.
@@ -75,22 +85,8 @@ This tutorial covers:
- This example shows how to implement a full-stack app in TypeScript with Next.js using Prisma Client as a backend. It also demonstrates how to implement authentication using NextAuth.js. By Nikolas Burk at Prisma.
## Testing
#### [Testing with Cypress](tutorials/testing-with-cypress)
- How to write tests using Cypress.
## Advanced
#### [Refresh Token Rotation](tutorials/refresh-token-rotation)
- How to implement refresh token rotation.
#### [LDAP Authentication](tutorials/ldap-auth-example)
- How to use the Credentials Provider to authenticate against an LDAP database. This approach can be used to authenticate existing user accounts against any backend.
#### [Add auth support to a Next.js app with a custom backend](https://arunoda.me/blog/add-auth-support-to-a-next-js-app-with-a-custom-backend) <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>
- A tutorial by Arunoda Susirpiala.
@@ -109,14 +105,6 @@ This tutorial covers:
## Database
#### [Custom models with TypeORM](adapters/typeorm#custom-models)
- How to use models with custom properties using the TypeORM adapter.
#### [Creating a database adapter](tutorials/creating-a-database-adapter)
- How to create a custom adapter, to use any database to fetch and store user / account data.
#### [Using NextAuth.js with Prisma and PlanetScale serverless databases](https://github.com/planetscale/nextjs-planetscale-starter)
#### [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

@@ -0,0 +1,40 @@
---
id: avoid-corporate-link-checking-email-provider
title: Allow Email Signups Behind Corporate Link Checker
---
If you use Office 365 or Outlook, or potentially other Email systems, you may notice your Email invitation Links not working.
This is because the invitation Email your User is receiving is being scanned by the Email provider. In the specific case of Outlook and their "SafeLink" feature, they send a HEAD request to each link in the Email. This request will trigger the NextAuth.js catch-all API Route with the users invitation token, in effect using it up.
Therefore, when the user wants to use it themselves, and clicks on the invitation link they will be greeted with an error message that the invitation is invalid.
## Workarounds
### Disable "SafeLink"
The first potential workaround is to simply disable this "SafeLink" feature for your organisation. Microsoft has more details on this [here](https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/safe-links?view=o365-worldwide#do-not-rewrite-the-following-urls-lists-in-safe-links-policies). Obviously this won't be an option for everyone as this is usually a part of corporate IT policy.
### Update NextAuth.js for 'HEAD' requests
The second option is to modify your `[...nextauth].js` catch-all API route a bit to gracefully handle these initial `HEAD` requests from the email service, without accidentally using up the invitation link.
This can be done by simply returning a `200` response on `HEAD` requests at the very top of the API route, before any other logic is executed.
For example
```jsx title="/pages/api/auth/[...nextauth].js"
import type { NextApiRequest, NextApiResponse } from "next"
import NextAuth from "next-auth"
export default async function auth(req: NextApiRequest, res: NextApiResponse) {
if(req.method === "HEAD") {
return res.status(200)
}
...
}
```
This should allow you to successfully use NextAuth.js's Email provider behind strict corporate IT settings.

View File

@@ -0,0 +1,83 @@
--
id: corporate-proxy
title: Add support for HTTP Proxy
--
Using NextAuth.js behind a corporate proxy is not supported out of the box. This is due to the fact that the underlying library we use, [`openid-client`](https://npm.im/openid-client), uses the built-in Node.js `http` / `https` libraries, which do not support proxys by default. (See: [`http` docs](https://nodejs.org/dist/latest-v16.x/docs/api/http.html), [`https` docs](https://nodejs.org/dist/latest-v16.x/docs/api/https.html)).
Therefore, we'll need to an additional proxy agent to the http client, such as `https-proxy-agent`. `openid-client` allows the user to set an `agent` for requests ([Source](https://github.com/panva/node-openid-client/blob/main/docs/README.md#customizing-individual-http-requests).
Thanks to [raphaelpc](https://github.com/raphaelpc) for the below diff, which when applied to `v4.2.1`, adds this agent support to the `client.js` file.
```diff
diff --git a/node_modules/next-auth/core/lib/oauth/client.js b/node_modules/next-auth/core/lib/oauth/client.js
index 77161bd..1082fba 100644
--- a/node_modules/next-auth/core/lib/oauth/client.js
+++ b/node_modules/next-auth/core/lib/oauth/client.js
@@ -7,11 +7,19 @@ exports.openidClient = openidClient;
var _openidClient = require("openid-client");
+var HttpsProxyAgent = require("https-proxy-agent");
+
async function openidClient(options) {
const provider = options.provider;
- if (provider.httpOptions) _openidClient.custom.setHttpOptionsDefaults(provider.httpOptions);
- let issuer;
+ let httpOptions = {};
+ if (provider.httpOptions) httpOptions = { ...provider.httpOptions };
+ if (process.env.http_proxy) {
+ let agent = new HttpsProxyAgent(process.env.http_proxy);
+ httpOptions.agent = agent;
+ }
+ _openidClient.custom.setHttpOptionsDefaults(httpOptions);
+ let issuer;
if (provider.wellKnown) {
issuer = await _openidClient.Issuer.discover(provider.wellKnown);
} else {
```
> For more details, see [this issue](https://github.com/nextauthjs/next-auth/issues/2509#issuecomment-1035410802)
After applying this patch, we can add the the proxy connecting string via the `http_proxy` environment variable.
### Provider
If you're having trouble with your provider when using the `https-proxy-agent`, you may be using a provider which requires an extra request to, for example, fetch the users profile picture. In cases like these, you'll have to add the proxy workaround to your provider config as well. Below is an example of how to do that with the `AzureAD` provider.
```diff
diff --git a/node_modules/next-auth/providers/azure-ad.js b/node_modules/next-auth/providers/azure-ad.js
index 73d96d3..536cd81 100644
--- a/node_modules/next-auth/providers/azure-ad.js
+++ b/node_modules/next-auth/providers/azure-ad.js
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
});
exports.default = AzureAD;
+const HttpsProxyAgent = require('https-proxy-agent');
+
function AzureAD(options) {
var _options$tenantId, _options$profilePhoto;
@@ -22,11 +24,15 @@ function AzureAD(options) {
},
async profile(profile, tokens) {
- const profilePicture = await fetch(`https://graph.microsoft.com/v1.0/me/photos/${profilePhotoSize}x${profilePhotoSize}/$value`, {
+ let fetchOptions = {
headers: {
- Authorization: `Bearer ${tokens.access_token}`
- }
- });
+ Authorization: `Bearer ${tokens.access_token}`,
+ },
+ };
+ if (process.env.http_proxy) {
+ fetchOptions.agent = new HttpsProxyAgent(process.env.http_proxy);
+ }
+ const profilePicture = await fetch(`https://graph.microsoft.com/v1.0/me/photos/${profilePhotoSize}x${profilePhotoSize}/$value`, fetchOptions);
if (profilePicture.ok) {
const pictureBuffer = await profilePicture.arrayBuffer();
```

View File

@@ -7,6 +7,8 @@ Using a custom adapter you can connect to any database back-end or even several
## How to create an adapter
For more information about the data these methods need to manage see [models](/adapters/models).
_See the code below for practical example._
### Example code

View File

@@ -61,7 +61,7 @@ async function refreshAccessToken(token) {
return {
...token,
accessToken: refreshedTokens.access_token,
accessTokenExpires: Date.now() + refreshedTokens.expires_in * 1000,
accessTokenExpires: Date.now() + refreshedTokens.expires_at * 1000,
refreshToken: refreshedTokens.refresh_token ?? token.refreshToken, // Fall back to old refresh token
}
} catch (error) {
@@ -88,7 +88,7 @@ export default NextAuth({
if (account && user) {
return {
accessToken: account.access_token,
accessTokenExpires: Date.now() + account.expires_in * 1000,
accessTokenExpires: Date.now() + account.expires_at * 1000,
refreshToken: account.refresh_token,
user,
}

View File

@@ -0,0 +1,60 @@
To add role based authentication to your application, you must do three things.
1. Update your database schema
2. Add the `role` to the session object
3. Check for `role` in your pages/components
First modify the `user` table and add a `role` column with the type of `String?`.
Below is an example Prisma schema file.
```javascript title="/prisma/schema.prisma"
model User {
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime?
image String?
role String? // New Column
accounts Account[]
sessions Session[]
}
```
Next, implement a custom session callback in the `[...nextauth].js` file, as shown below.
```javascript title="/pages/api/auth/[...nextauth].js"
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;
},
```
Going forward, when using the `getSession` hook, check that `session.user.role` matches the required role. The example below assumes the role `'admin'` is required.
```javascript title="/pages/admin.js"
import { getSession } from "next-auth/react"
export default function Page() {
const session = await getSession({ req })
if (session && session.user.role === "admin") {
return (
<div>
<h1>Admin</h1>
<p>Welcome to the Admin Portal!</p>
</div>
)
} else {
return (
<div>
<h1>You are not authorized to view this page!</h1>
</div>
)
}
}
```
Then it is up to you how you manage your roles, either through direct database access or building your own role update API.

View File

@@ -9,6 +9,13 @@ module.exports = {
themeConfig: {
prism: {
theme: require("prism-react-renderer/themes/vsDark"),
magicComments: [
{
className: "theme-code-block-highlighted-line",
line: "highlight-next-line",
block: { start: "highlight-start", end: "highlight-end" },
},
],
},
algolia: {
appId: "OUEDA16KPG",

View File

@@ -6,7 +6,7 @@
"url": "git://github.com/nextauthjs/docs.git"
},
"scripts": {
"start": "npm run generate-providers && docusaurus start --port 8000",
"start": "npm run generate-providers && docusaurus start --no-open --port 8000",
"dev": "npm run start",
"build": "npm run generate-providers && docusaurus build",
"docusaurus": "docusaurus",
@@ -18,26 +18,32 @@
"lint:fix": "prettier --write .",
"generate-providers": "node ./scripts/generate-providers.js"
},
"dependencies": {
"@codesandbox/sandpack-react": "^0.13.12",
"@docusaurus/core": "^2.0.0-beta.17",
"@docusaurus/preset-classic": "^2.0.0-beta.17",
"@docusaurus/remark-plugin-npm2yarn": "^2.0.0-beta.17",
"dependencies": {
"@docusaurus/core": "^2.0.0-beta.20",
"@docusaurus/preset-classic": "^2.0.0-beta.20",
"@docusaurus/remark-plugin-npm2yarn": "^2.0.0-beta.20",
"@docusaurus/theme-common": "2.0.0-beta.20",
"@mdx-js/react": "1.6.22",
"classnames": "^2.3.1",
"lodash.times": "^4.3.2",
"mdx-mermaid": "^1.2.1",
"mermaid": "^8.13.10",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"mdx-mermaid": "^1.2.2",
"mermaid": "^9.0.1",
"prism-react-renderer": "1.3.1",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-marquee-slider": "^1.1.5",
"remark-github": "^10.1.0",
"styled-components": "^5.3.3"
"styled-components": "5.3.3"
},
"devDependencies": {
"prettier": "^2.5.0"
"@docusaurus/module-type-aliases": "2.0.0-beta.20",
"prettier": "^2.6.2"
},
"browserslist": {
"production": [">0.2%", "not dead", "not op_mini all"],
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",

View File

@@ -40,10 +40,9 @@ module.exports = {
{
type: "category",
label: "Providers",
link: { type: "doc", id: "providers/overview" },
collapsed: true,
items: [
"providers/overview",
// TODO: Overview included twice due to autogeneration
{
type: "autogenerated",
dirName: "providers",
@@ -53,9 +52,9 @@ module.exports = {
{
type: "category",
label: "Adapters",
link: { type: "doc", id: "adapters/overview" },
collapsed: true,
items: [
"adapters/overview",
"adapters/models",
"adapters/prisma",
"adapters/fauna",
@@ -74,5 +73,18 @@ module.exports = {
"warnings",
"errors",
"deployment",
{
type: "category",
label: "Guides",
link: { type: "doc", id: "guides/guides" },
collapsed: true,
items: ["guides/basics", "guides/fullstack", "guides/testing"],
},
{
type: "html",
value:
'<script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?serve=CEAI6K3N&placement=next-authjsorg" id="_carbonads_js"></script>',
defaultStyle: true,
},
],
}

View File

@@ -1,7 +1,6 @@
import React from "react"
import Marquee, { Motion, randomIntFromInterval } from "react-marquee-slider"
import * as S from "./ProviderMarqueeStyle"
import times from "lodash.times"
import styles from "./ProviderMarqueeStyle.module.css"
const icons = [
"/img/providers/apple-black.svg",
@@ -20,7 +19,7 @@ const icons = [
"/img/providers/twitter.svg",
]
const ProviderMarquee = React.memo(({ size }) => {
const ProviderMarquee = React.memo(() => {
let scale = 0.4
if (typeof window !== "undefined") {
@@ -39,8 +38,8 @@ const ProviderMarquee = React.memo(({ size }) => {
}
return (
<S.FullWidth>
<S.Height height={500}>
<div className={styles.fullWidth}>
<div className={styles.height}>
<Marquee
key="1"
velocity={5}
@@ -48,24 +47,33 @@ const ProviderMarquee = React.memo(({ size }) => {
minScale={0.5}
resetAfterTries={200}
>
{times(icons.length, Number).map((id) => (
{icons.map((icon) => (
<Motion
key={`marquee-example-company-${id}`}
key={`marquee-example-company-${icon}`}
initDeg={randomIntFromInterval(0, 360)}
direction={Math.random() > 0.5 ? "clockwise" : "counterclockwise"}
velocity={10}
radius={scale * 70}
>
<S.Company scale={scale}>
<S.Circle scale={scale}>
<S.Logo src={icons[id]} alt="" />
</S.Circle>
</S.Company>
<div
className={styles.company}
style={{ height: `${scale * 75}px`, width: `${scale * 75}px` }}
>
<div
className={styles.circle}
style={{
height: `${scale * 150}px`,
width: `${scale * 150}px`,
}}
>
<img className={styles.logo} src={icon} alt="" />
</div>
</div>
</Motion>
))}
</Marquee>
</S.Height>
</S.FullWidth>
</div>
</div>
)
})

View File

@@ -1,11 +1,7 @@
import styled from "styled-components"
export const Circle = styled.div`
.circle {
position: absolute;
object-position: center center;
will-change: transform, opacity;
width: ${(props) => props.scale * 150}px;
height: ${(props) => props.scale * 150}px;
top: -50%;
left: -50%;
border-radius: 50%;
@@ -13,33 +9,31 @@ export const Circle = styled.div`
justify-content: center;
align-items: center;
margin-top: 1rem;
`
}
export const Logo = styled.img`
.logo {
display: block;
width: 65%;
height: 65%;
filter: grayscale(100%);
opacity: 0.1;
`
}
export const FullWidth = styled.div`
.fullWidth {
width: 100vw;
position: relative;
left: 50%;
right: 50%;
margin-left: -50vw;
margin-right: -50vw;
`
}
export const Height = styled.div`
.height {
position: relative;
width: 100%;
height: ${(props) => (props.height ? props.height + "px" : "auto")};
`
height: 500px;
}
export const Company = styled.div`
.company {
position: relative;
width: ${(props) => props.scale * 75}px;
height: ${(props) => props.scale * 75}px;
`
}

View File

@@ -1,16 +0,0 @@
import React from "react"
import {
SandpackProvider,
SandpackLayout,
SandpackCodeEditor,
SandpackPreview,
} from "@codesandbox/sandpack-react"
export const CustomSandpack = () => (
<SandpackProvider template="react">
<SandpackLayout>
<SandpackCodeEditor />
<SandpackPreview />
</SandpackLayout>
</SandpackProvider>
)

View File

@@ -7,11 +7,6 @@
/* @TODO Move as many styles for the homepage as possible into styles.module.css */
/**
* Sandpack integration
*/
@import "@codesandbox/sandpack-react/dist/index.css";
/* You can override the default Infima variables here. */
:root {
--ifm-color-link: #289ef9;
@@ -26,9 +21,10 @@
--ifm-color-info: #1eb1fc;
--ifm-color-success: #1eb1fc;
--ifm-color-warning: #c94b4b;
--ifm-font-family-base: -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell,
Noto Sans, sans-serif, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial,
sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
--ifm-font-family-base: 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";
--ifm-background-color: #fff;
--ifm-footer-background-color: #f9f9f9;
--ifm-hero-background-color: #f5f5f5;
@@ -61,12 +57,6 @@ html[data-theme="dark"] svg[id^="mermaid-svg"] text[id*="-attr"] {
@import "navbar.css";
@import "search.css";
@media screen and (max-width: 360px) {
html {
font-size: 0.8rem;
}
}
a {
font-weight: 600;
}
@@ -194,3 +184,92 @@ html[data-theme="dark"] hr {
.inline {
display: inline-block;
}
/* CarbonAds */
#carbonads * {
margin: initial;
padding: initial;
}
#carbonads {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial,
sans-serif;
}
#carbonads {
display: flex;
max-width: 330px;
background-color: hsl(0, 0%, 98%);
box-shadow: 0 1px 4px 1px hsla(0, 0%, 0%, 0.1);
z-index: 100;
margin-top: 30px;
}
#carbonads a {
color: inherit;
text-decoration: none;
}
#carbonads a:hover {
color: inherit;
}
#carbonads span {
position: relative;
display: block;
overflow: hidden;
}
#carbonads .carbon-wrap {
display: flex;
}
#carbonads .carbon-img {
display: block;
margin: 0;
line-height: 1;
}
#carbonads .carbon-img img {
display: block;
}
#carbonads .carbon-text {
font-size: 11px;
padding: 8px;
margin-bottom: 16px;
line-height: 1.5;
text-align: left;
}
#carbonads .carbon-poweredby {
display: block;
padding: 6px 8px;
background: #f1f1f2;
text-align: center;
text-transform: uppercase;
letter-spacing: 0.5px;
font-weight: 600;
font-size: 8px;
line-height: 1;
border-top-left-radius: 3px;
position: absolute;
bottom: 0;
right: 0;
}
html[data-theme="dark"] #carbonads .carbon-text {
color: #ddd;
}
html[data-theme="dark"] #carbonads > span {
background: #1a1a1a;
box-shadow: 0 0 1px hsl(0deg 0% 0% / 9%), 0 0 2px hsl(0deg 0% 0% / 9%),
0 0 4px hsl(0deg 0% 0% / 9%), 0 0 8px hsl(0deg 0% 0% / 9%);
}
html[data-theme="dark"] #carbonads .carbon-poweredby {
color: #aaa;
background: #1e2021;
}

View File

@@ -2,30 +2,24 @@
"name": "root",
"version": "0.0.0",
"private": true,
"workspaces": {
"packages": [
"packages/*",
"apps/dev",
"docs"
]
},
"repository": "https://github.com/nextauthjs/next-auth.git",
"scripts": {
"build:app": "turbo run build --scope=next-auth-app --include-dependencies",
"build": "turbo run build --scope=next-auth --scope=@next-auth/* --no-deps",
"lint": "turbo run lint --scope=!next-auth-docs",
"build:app": "turbo run build --filter=next-auth-app --include-dependencies",
"build": "turbo run build --filter=next-auth --filter=@next-auth/* --no-deps",
"lint": "turbo run lint --filter=!next-auth-docs",
"lint:fix": "turbo run lint -- --fix",
"test": "turbo run test --concurrency=1 --scope=!@next-auth/pouchdb-adapter --scope=!next-auth-*",
"test": "turbo run test --concurrency=1 --filter=!@next-auth/pouchdb-adapter --filter=!next-auth-* --filter=[HEAD^1]",
"setup": "turbo run setup",
"dev": "yarn dev:app",
"dev:app": "turbo run dev --parallel --no-deps --no-cache --scope=next-auth-app",
"dev:docs": "turbo run dev --parallel --no-deps --no-cache --scope=next-auth-docs",
"dev": "pnpm dev:app",
"dev:app": "turbo run dev --parallel --no-deps --no-cache --filter=next-auth-app",
"dev:docs": "turbo run dev --parallel --no-deps --no-cache --filter=next-auth-docs",
"version:pr": "node ./config/version-pr",
"release": "ts-node scripts/release"
},
"devDependencies": {
"@actions/core": "^1.6.0",
"@commitlint/parse": "16.0.0",
"@types/node": "^17.0.25",
"@types/semver": "7.3.9",
"@typescript-eslint/eslint-plugin": "^5.10.2",
"@typescript-eslint/parser": "^4.33.0",
@@ -43,11 +37,12 @@
"semver": "7.3.5",
"stream-to-array": "2.3.0",
"ts-node": "10.5.0",
"turbo": "^1.1.4",
"turbo": "^1.2.5",
"typescript": "^4.5.2"
},
"engines": {
"node": "^12.19.0 || ^14.15.0 || ^16.13.0"
"node": "^12.19.0 || ^14.15.0 || ^16.13.0",
"pnpm": ">=6.32.3"
},
"prettier": {
"semi": false,
@@ -102,7 +97,7 @@
"**/tests",
"**/__tests__"
],
"packageManager": "yarn@1.22.17",
"packageManager": "pnpm@6.32.8",
"funding": [
{
"type": "github",

View File

@@ -1,6 +1,6 @@
{
"name": "@next-auth/dgraph-adapter",
"version": "1.0.2",
"version": "1.0.3",
"description": "Dgraph adapter for next-auth.",
"homepage": "https://next-auth.js.org",
"repository": "https://github.com/nextauthjs/adapters",
@@ -31,13 +31,16 @@
},
"peerDependencies": {
"jsonwebtoken": "^8.5.1",
"next-auth": "^4.0.1"
"next-auth": "workspace:*"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:^0.0.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"@types/jest": "^26.0.24",
"@types/jsonwebtoken": "^8.5.5",
"@types/node-fetch": "^2.5.11",
"jest": "^27.0.6",
"jest": "^27.4.3",
"next-auth": "workspace:*",
"ts-jest": "^27.0.3"
},
"dependencies": {
@@ -45,6 +48,6 @@
"node-fetch": "^2.6.1"
},
"jest": {
"preset": "adapter-test/jest"
"preset": "@next-auth/adapter-test/jest"
}
}

View File

@@ -1,7 +1,7 @@
import { DgraphAdapter, format } from "../src"
import { client as dgraphClient } from "../src/client"
import * as fragments from "../src/graphql/fragments"
import { runBasicTests } from "adapter-test"
import { runBasicTests } from "@next-auth/adapter-test"
import fs from "fs"
import path from "path"

View File

@@ -1,5 +1,5 @@
{
"extends": "tsconfig/base.json",
"extends": "@next-auth/tsconfig/adapters.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"

View File

@@ -3,7 +3,7 @@
* https://jestjs.io/docs/en/configuration.html
*/
module.exports = {
...require("adapter-test/jest/jest-preset"),
...require("@next-auth/adapter-test/jest/jest-preset"),
// // Indicates whether the coverage information should be collected while executing the test
// collectCoverage: true,
// // Indicates which provider should be used to instrument code for coverage

View File

@@ -1,7 +1,7 @@
{
"name": "@next-auth/dynamodb-adapter",
"repository": "https://github.com/nextauthjs/adapters",
"version": "1.0.2",
"version": "1.0.3",
"description": "AWS DynamoDB adapter for next-auth.",
"keywords": [
"next-auth",
@@ -21,7 +21,7 @@
"scripts": {
"test:default": "jest",
"test:custom": "CUSTOM_MODEL=1 jest",
"test": "yarn test:default && yarn test:custom",
"test": "pnpm test:default && pnpm test:custom",
"build": "tsc"
},
"files": [
@@ -32,11 +32,15 @@
"license": "ISC",
"peerDependencies": {
"@aws-sdk/lib-dynamodb": "^3.36.1",
"next-auth": "^4.0.1"
"next-auth": "workspace:*"
},
"devDependencies": {
"@aws-sdk/client-dynamodb": "^3.36.1",
"@aws-sdk/lib-dynamodb": "^3.36.1",
"@shelf/jest-dynamodb": "^2.1.0"
"@next-auth/adapter-test": "workspace:^0.0.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"@shelf/jest-dynamodb": "^2.1.0",
"jest": "^27.4.3",
"next-auth": "workspace:*"
}
}

View File

@@ -1,7 +1,7 @@
import { DynamoDB } from "@aws-sdk/client-dynamodb"
import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb"
import { DynamoDBAdapter } from "../src"
import { runBasicTests } from "adapter-test"
import { runBasicTests } from "@next-auth/adapter-test"
import { format } from "../src/"
const config = {
endpoint: "http://127.0.0.1:8000",

View File

@@ -1,5 +1,5 @@
{
"extends": "tsconfig/base.json",
"extends": "@next-auth/tsconfig/adapters.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"

View File

@@ -1,13 +1,16 @@
{
"name": "@next-auth/fauna-adapter",
"version": "1.0.2",
"version": "1.0.3",
"description": "Fauna Adapter for NextAuth",
"homepage": "https://next-auth.js.org",
"repository": "https://github.com/nextauthjs/adapters",
"bugs": {
"url": "https://github.com/nextauthjs/next-auth/issues"
},
"files": ["dist", "README.md"],
"files": [
"dist",
"README.md"
],
"author": "Bhanu Teja P",
"contributors": [
{
@@ -21,7 +24,12 @@
],
"main": "dist/index.js",
"license": "ISC",
"keywords": ["next-auth", "next.js", "fauna", "faunadb"],
"keywords": [
"next-auth",
"next.js",
"fauna",
"faunadb"
],
"private": false,
"publishConfig": {
"access": "public"
@@ -33,13 +41,17 @@
},
"peerDependencies": {
"faunadb": "^4.3.0",
"next-auth": "^4.0.1"
"next-auth": "workspace:*"
},
"devDependencies": {
"@fauna-labs/fauna-schema-migrate": "^2.1.3",
"faunadb": "^4.3.0"
"@next-auth/adapter-test": "workspace:^0.0.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"faunadb": "^4.3.0",
"jest": "^27.4.3",
"next-auth": "workspace:*"
},
"jest": {
"preset": "adapter-test/jest"
"preset": "@next-auth/adapter-test/jest"
}
}

View File

@@ -1,5 +1,5 @@
import { collections, FaunaAdapter, format, indexes, query } from "../src"
import { runBasicTests } from "adapter-test"
import { runBasicTests } from "@next-auth/adapter-test"
import { Client as FaunaClient, Get, Match, Ref } from "faunadb"
const client = new FaunaClient({

View File

@@ -1,5 +1,5 @@
{
"extends": "tsconfig/base.json",
"extends": "@next-auth/tsconfig/adapters.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"

View File

@@ -1 +1 @@
module.exports = require("../adapter-test/jest.config")
module.exports = require("@next-auth/adapter-test/jest.config")

View File

@@ -28,15 +28,19 @@
"access": "public"
},
"scripts": {
"build": "tsc",
"build:wip": "tsc",
"test:wip": "FIRESTORE_EMULATOR_HOST=localhost:8080 firebase emulators:exec --only firestore --project next-auth-test jest"
},
"peerDependencies": {
"firebase": "^8.6.2",
"next-auth": "latest"
"next-auth": "workspace:*"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:^0.0.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"firebase": "^8.6.2",
"firebase-tools": "^9.11.0"
"firebase-tools": "^9.11.0",
"jest": "^27.4.3",
"next-auth": "workspace:*"
}
}

View File

@@ -1,4 +1,4 @@
import { runBasicTests } from "adapter-test"
import { runBasicTests } from "@next-auth/adapter-test"
import { FirebaseAdapter } from "../src"
import { docSnapshotToObject, querySnapshotToObject } from "../src/utils"

View File

@@ -1,5 +1,5 @@
{
"extends": "tsconfig/base.json",
"extends": "@next-auth/tsconfig/base.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"

View File

@@ -1,6 +1,6 @@
{
"name": "@next-auth/mikro-orm-adapter",
"version": "1.0.1",
"version": "2.0.1",
"description": "MikroORM adapter for next-auth.",
"homepage": "https://next-auth.js.org",
"repository": "https://github.com/nextauthjs/adapters",
@@ -33,13 +33,17 @@
],
"peerDependencies": {
"@mikro-orm/core": "^5.0.2",
"next-auth": "^4.0.1"
"next-auth": "workspace:*"
},
"devDependencies": {
"@mikro-orm/core": "^5.0.2",
"@mikro-orm/sqlite": "^5.0.2"
"@mikro-orm/sqlite": "^5.0.2",
"@next-auth/adapter-test": "workspace:^0.0.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"jest": "^27.4.3",
"next-auth": "workspace:*"
},
"jest": {
"preset": "adapter-test/jest"
"preset": "@next-auth/adapter-test/jest"
}
}

View File

@@ -2,7 +2,7 @@ import type { Options } from "@mikro-orm/core"
import type { SqliteDriver } from "@mikro-orm/sqlite"
import { MikroORM, wrap } from "@mikro-orm/core"
import { runBasicTests } from "adapter-test"
import { runBasicTests } from "@next-auth/adapter-test"
import { MikroOrmAdapter, defaultEntities } from "../src"
import { User, VeryImportantEntity } from "./testEntities"

View File

@@ -7,7 +7,7 @@ import {
Property,
Unique,
} from "@mikro-orm/core"
import { randomUUID } from "adapter-test"
import { randomUUID } from "@next-auth/adapter-test"
import type { defaultEntities } from "../src"
import { Account, Session } from "../src/entities"

View File

@@ -1,5 +1,5 @@
{
"extends": "tsconfig/base.json",
"extends": "@next-auth/tsconfig/adapters.json",
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,

View File

@@ -1,6 +1,6 @@
{
"name": "@next-auth/mongodb-adapter",
"version": "1.0.1",
"version": "1.0.3",
"description": "mongoDB adapter for next-auth.",
"homepage": "https://next-auth.js.org",
"repository": "https://github.com/nextauthjs/adapters",
@@ -10,7 +10,13 @@
"author": "Balázs Orbán <info@balazsorban.com>",
"main": "dist/index.js",
"license": "ISC",
"keywords": ["next-auth", "next.js", "oauth", "mongodb", "adapter"],
"keywords": [
"next-auth",
"next.js",
"oauth",
"mongodb",
"adapter"
],
"private": false,
"publishConfig": {
"access": "public"
@@ -20,15 +26,22 @@
"test:watch": "./tests/test.sh -w",
"build": "tsc"
},
"files": ["README.md", "dist"],
"files": [
"README.md",
"dist"
],
"peerDependencies": {
"mongodb": "^4.1.1",
"next-auth": "^4.0.1"
"next-auth": "workspace:*"
},
"devDependencies": {
"mongodb": "^4.4.0"
"@next-auth/adapter-test": "workspace:^0.0.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"jest": "^27.4.3",
"mongodb": "^4.4.0",
"next-auth": "workspace:*"
},
"jest": {
"preset": "adapter-test/jest"
"preset": "@next-auth/adapter-test/jest"
}
}

View File

@@ -1,4 +1,4 @@
import { runBasicTests } from "adapter-test"
import { runBasicTests } from "@next-auth/adapter-test"
import { defaultCollections, format, MongoDBAdapter, _id } from "../src"
import { MongoClient } from "mongodb"
const name = "custom-test"

View File

@@ -1,4 +1,4 @@
import { runBasicTests } from "adapter-test"
import { runBasicTests } from "@next-auth/adapter-test"
import { defaultCollections, format, MongoDBAdapter, _id } from "../src"
import { MongoClient } from "mongodb"

View File

@@ -1,5 +1,5 @@
{
"extends": "tsconfig/base.json",
"extends": "@next-auth/tsconfig/adapters.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"

View File

@@ -1,6 +1,6 @@
{
"name": "@next-auth/neo4j-adapter",
"version": "1.0.2",
"version": "1.0.3",
"description": "neo4j adapter for next-auth.",
"homepage": "https://next-auth.js.org",
"repository": "https://github.com/nextauthjs/adapters",
@@ -34,16 +34,20 @@
],
"peerDependencies": {
"neo4j-driver": "^4.0.0",
"next-auth": "^4.0.1"
"next-auth": "workspace:*"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:^0.0.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"@types/uuid": "^8.3.3",
"neo4j-driver": "^4.4.0"
"jest": "^27.4.3",
"neo4j-driver": "^4.4.0",
"next-auth": "workspace:*"
},
"dependencies": {
"uuid": "^8.3.2"
},
"jest": {
"preset": "adapter-test/jest"
"preset": "@next-auth/adapter-test/jest"
}
}

View File

@@ -1,5 +1,5 @@
import * as neo4j from "neo4j-driver"
import { runBasicTests } from "adapter-test"
import { runBasicTests } from "@next-auth/adapter-test"
import statements from "./resources/statements"
import { Neo4jAdapter, format } from "../src"

View File

@@ -1,5 +1,5 @@
{
"extends": "tsconfig/base.json",
"extends": "@next-auth/tsconfig/adapters.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"

View File

@@ -10,7 +10,12 @@
"author": "jpbourgeon <jeanphilippe.bourgeon@gmail.com> (https://github.com/jpbourgeon)",
"main": "dist/index.js",
"license": "ISC",
"keywords": ["next-auth", "next.js", "oauth", "pouchdb"],
"keywords": [
"next-auth",
"next.js",
"oauth",
"pouchdb"
],
"private": false,
"publishConfig": {
"access": "public"
@@ -20,9 +25,12 @@
"tdd": "jest --watch",
"test:wip": "jest"
},
"files": ["README.md", "dist"],
"files": [
"README.md",
"dist"
],
"peerDependencies": {
"next-auth": "^3.23.3",
"next-auth": "workspace:*",
"pouchdb": "^7.2.2",
"pouchdb-find": "^7.2.2"
},
@@ -31,12 +39,16 @@
"ulid": "^2.3.0"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:^0.0.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"@types/pouchdb": "^6.4.0",
"jest": "^27.4.3",
"next-auth": "workspace:*",
"pouchdb": "^7.2.2",
"pouchdb-adapter-memory": "^7.2.2",
"pouchdb-find": "^7.2.2"
},
"jest": {
"preset": "adapter-test/jest"
"preset": "@next-auth/adapter-test/jest"
}
}

View File

@@ -6,7 +6,7 @@ import find from "pouchdb-find"
import { ulid } from "ulid"
import Providers from "next-auth/providers"
import { PouchDBAdapter } from "../src"
import { runBasicTests } from "adapter-test"
import { runBasicTests } from "@next-auth/adapter-test"
// pouchdb setup
PouchDB.plugin(memoryAdapter).plugin(find)

View File

@@ -1,5 +1,5 @@
{
"extends": "tsconfig/base.json",
"extends": "@next-auth/tsconfig/base.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist",

View File

@@ -1,6 +1,6 @@
{
"name": "@next-auth/prisma-adapter",
"version": "1.0.1",
"version": "1.0.3",
"description": "Prisma adapter for next-auth.",
"homepage": "https://next-auth.js.org",
"repository": "https://github.com/nextauthjs/adapters",
@@ -10,7 +10,12 @@
"author": "William Luke",
"main": "dist/index.js",
"license": "ISC",
"keywords": ["next-auth", "next.js", "oauth", "prisma"],
"keywords": [
"next-auth",
"next.js",
"oauth",
"prisma"
],
"private": false,
"publishConfig": {
"access": "public"
@@ -19,23 +24,31 @@
"clean": "rm -rf ./prisma/migrations && rm ./prisma/dev.db*",
"init:default": "prisma migrate dev --name init --skip-seed",
"init:custom": "prisma migrate dev --name init-custom --schema ./prisma/custom.prisma",
"test:default": "yarn init:default && jest",
"test:custom": "yarn init:custom && CUSTOM_MODEL=1 jest",
"test:default": "pnpm init:default && jest",
"test:custom": "pnpm init:custom && CUSTOM_MODEL=1 jest",
"test:mongodb": "./tests/mongodb.test.sh",
"test": "yarn test:default && yarn test:custom && yarn test:mongodb",
"test": "pnpm test:default && pnpm test:custom && pnpm test:mongodb",
"build": "prisma generate && tsc",
"studio": "prisma studio"
},
"files": ["README.md", "dist"],
"files": [
"README.md",
"dist"
],
"peerDependencies": {
"@prisma/client": ">=2.26.0 || >=3",
"next-auth": "^4.0.1"
"next-auth": "workspace:*"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:^0.0.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"@prisma/client": "^3.10.0",
"jest": "^27.4.3",
"mongodb": "^4.4.0",
"next-auth": "workspace:*",
"prisma": "^3.10.0"
},
"jest": {
"preset": "adapter-test/jest"
"preset": "@next-auth/adapter-test/jest"
}
}

View File

@@ -1,4 +1,4 @@
import { randomUUID, runBasicTests } from "adapter-test"
import { randomUUID, runBasicTests } from "@next-auth/adapter-test"
import { PrismaClient } from "@prisma/client"
import { PrismaAdapter } from "../src"
const prisma = new PrismaClient()

View File

@@ -16,7 +16,7 @@ done
# Start db
docker run -d --rm -p 27017:27017 --name ${CONTAINER_NAME} "prismagraphql/mongo-single-replica:4.4.3-bionic"
yarn prisma generate --schema ./prisma/mongodb.prisma
pnpm prisma generate --schema ./prisma/mongodb.prisma
if $JEST_WATCH; then
# Run jest in watch mode

View File

@@ -1,5 +1,5 @@
{
"extends": "tsconfig/base.json",
"extends": "@next-auth/tsconfig/adapters.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"

View File

@@ -1,6 +1,6 @@
{
"name": "@next-auth/sequelize-adapter",
"version": "1.0.1",
"version": "1.0.3",
"description": "Sequelize adapter for next-auth.",
"homepage": "https://next-auth.js.org",
"repository": "https://github.com/nextauthjs/adapters",
@@ -29,13 +29,17 @@
"dist"
],
"peerDependencies": {
"next-auth": "^4.0.1",
"next-auth": "workspace:*",
"sequelize": "^6.6.5"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:^0.0.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"jest": "^27.4.3",
"next-auth": "workspace:*",
"sequelize": "^6.6.5"
},
"jest": {
"preset": "adapter-test/jest"
"preset": "@next-auth/adapter-test/jest"
}
}
}

View File

@@ -1,4 +1,4 @@
import type { Account as ApadterAccount } from "next-auth"
import type { Account as AdapterAccount } from "next-auth"
import type {
Adapter,
AdapterUser,
@@ -12,8 +12,8 @@ export { defaultModels as models }
// @see https://sequelize.org/master/manual/typescript.html
interface AccountInstance
extends Model<ApadterAccount, Partial<ApadterAccount>>,
ApadterAccount {}
extends Model<AdapterAccount, Partial<AdapterAccount>>,
AdapterAccount {}
interface UserInstance
extends Model<AdapterUser, Partial<AdapterUser>>,
AdapterUser {}

View File

@@ -1,5 +1,5 @@
import { Sequelize, DataTypes } from "sequelize"
import { runBasicTests } from "adapter-test"
import { runBasicTests } from "@next-auth/adapter-test"
import SequelizeAdapter, { models } from "../src"
const sequelize = new Sequelize({

View File

@@ -1,5 +1,5 @@
{
"extends": "tsconfig/base.json",
"extends": "@next-auth/tsconfig/adapters.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"

View File

@@ -1,5 +1,5 @@
{
"name": "adapter-test",
"name": "@next-auth/adapter-test",
"version": "0.0.0",
"repository": "https://github.com/nextauthjs/next-auth.git",
"contributors": [
@@ -19,6 +19,7 @@
"@types/nodemailer": "^6.4.4",
"@typescript-eslint/eslint-plugin": "^4.24.0",
"@typescript-eslint/parser": "^4.24.0",
"babel-jest": "^27.4.2",
"eslint": "^7.27.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard-with-typescript": "^20.0.0",
@@ -26,7 +27,7 @@
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"jest": "^27.0.3",
"next-auth": "latest",
"next-auth": "workspace:*",
"prettier": "^2.3.0",
"ts-jest": "^27.0.3",
"typescript": "^4.2.4"

View File

@@ -1,6 +1,6 @@
{
"name": "@next-auth/typeorm-legacy-adapter",
"version": "1.0.1",
"version": "1.0.3",
"description": "TypeORM (legacy) adapter for next-auth.",
"homepage": "https://next-auth.js.org",
"repository": "https://github.com/nextauthjs/adapters",
@@ -32,13 +32,17 @@
"init:db": "tests/init.sh",
"test:containers": "tests/test.sh",
"test": "tests/test.sh",
"mysql": "yarn init:db && tests/mysql/test.sh",
"postgres": "yarn init:db && tests/postgresql/test.sh",
"mysql": "pnpm init:db && tests/mysql/test.sh",
"postgres": "pnpm init:db && tests/postgresql/test.sh",
"sqlite": "tests/sqlite/test.sh"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:^0.0.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"jest": "^27.4.3",
"mssql": "^7.2.1",
"mysql": "^2.18.1",
"next-auth": "workspace:*",
"pg": "^8.7.1",
"sqlite3": "^5.0.2",
"typeorm": "^0.2.37",
@@ -47,7 +51,7 @@
"peerDependencies": {
"mssql": "^6.2.1 || 7",
"mysql": "^2.18.1",
"next-auth": "^4.0.1",
"next-auth": "workspace:*",
"pg": "^8.2.1",
"sqlite3": "^5.0.2",
"typeorm": "^0.2.31"
@@ -67,6 +71,6 @@
}
},
"jest": {
"preset": "adapter-test/jest"
"preset": "@next-auth/adapter-test/jest"
}
}

View File

@@ -1,5 +1,5 @@
import { ConnectionManager, ConnectionOptions } from "typeorm"
import { TestOptions } from "adapter-test"
import { TestOptions } from "@next-auth/adapter-test"
import * as defaultEntities from "../src/entities"
import { parseConnectionConfig } from "../src/utils"

View File

@@ -1,5 +1,5 @@
{
"extends": "tsconfig/base.json",
"extends": "@next-auth/tsconfig/adapters.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist",

View File

@@ -29,9 +29,12 @@ npm install next-auth @next-auth/upstash-redis-adapter @upstash/redis
```js
import NextAuth from "next-auth"
import { UpstashRedisAdapter } from "@next-auth/upstash-adapter"
import upstashRedisClient from "@upstash/redis"
import { Redis } from "@upstash/redis"
const redis = upstashRedisClient("UPSTASH_REDIS_REST_URL", "UPSTASH_REDIS_REST_TOKEN")
const redis = new Redis({
url:"UPSTASH_REDIS_REST_URL",
token:"UPSTASH_REDIS_REST_TOKEN",
})
// For more information on each option (and a full list of options) go to
// https://next-auth.js.org/configuration/options

View File

@@ -1,6 +1,6 @@
{
"name": "@next-auth/upstash-redis-adapter",
"version": "1.1.0",
"version": "3.0.0",
"description": "Upstash adapter for next-auth. It uses Upstash's connectionless (HTTP based) Redis client.",
"homepage": "https://next-auth.js.org",
"repository": "https://github.com/nextauthjs/adapters",
@@ -30,17 +30,21 @@
"dist"
],
"peerDependencies": {
"@upstash/redis": "^0.2.1",
"next-auth": "^4.0.1"
"@upstash/redis": "^1.0.1",
"next-auth": "workspace:*"
},
"devDependencies": {
"@upstash/redis": "^0.2.1",
"dotenv": "^10.0.0"
"@next-auth/adapter-test": "workspace:^0.0.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"@upstash/redis": "^1.0.1",
"dotenv": "^10.0.0",
"jest": "^27.4.3",
"next-auth": "workspace:*"
},
"dependencies": {
"uuid": "^8.3.2"
},
"jest": {
"preset": "adapter-test/jest"
"preset": "@next-auth/adapter-test/jest"
}
}

View File

@@ -1,6 +1,11 @@
import type { Account as AdapterAccount } from "next-auth"
import type { Adapter, AdapterUser, AdapterSession } from "next-auth/adapters"
import type { Upstash } from "@upstash/redis/src/types"
import type {
Adapter,
AdapterUser,
AdapterSession,
VerificationToken,
} from "next-auth/adapters"
import type { Redis } from "@upstash/redis"
import { v4 as uuid } from "uuid"
@@ -32,14 +37,15 @@ function isDate(value: any) {
return value && isoDateRE.test(value) && !isNaN(Date.parse(value))
}
export function reviveFromJson(json: string) {
return JSON.parse(json, (_, value) =>
isDate(value) ? new Date(value) : value
)
export function hydrateDates(json: object) {
return Object.entries(json).reduce((acc, [key, val]) => {
acc[key] = isDate(val) ? new Date(val as string) : val
return acc
}, {} as any)
}
export function UpstashRedisAdapter(
client: Upstash,
client: Redis,
options: UpstashRedisAdapterOptions = {}
): Adapter {
const mergedOptions = {
@@ -70,12 +76,15 @@ export function UpstashRedisAdapter(
}
const getAccount = async (id: string) => {
const response = await client.get(accountKeyPrefix + id)
if (!response.data) return null
return reviveFromJson(response.data)
const account = await client.get<AdapterAccount>(accountKeyPrefix + id)
if (!account) return null
return hydrateDates(account)
}
const setSession = async (id: string, session: AdapterSession) => {
const setSession = async (
id: string,
session: AdapterSession
): Promise<AdapterSession> => {
const sessionKey = sessionKeyPrefix + id
await setObjectAsJson(sessionKey, session)
await client.set(sessionByUserIdKeyPrefix + session.userId, sessionKey)
@@ -83,21 +92,24 @@ export function UpstashRedisAdapter(
}
const getSession = async (id: string) => {
const response = await client.get(sessionKeyPrefix + id)
if (!response.data) return null
return reviveFromJson(response.data)
const session = await client.get<AdapterSession>(sessionKeyPrefix + id)
if (!session) return null
return hydrateDates(session)
}
const setUser = async (id: string, user: AdapterUser) => {
const setUser = async (
id: string,
user: AdapterUser
): Promise<AdapterUser> => {
await setObjectAsJson(userKeyPrefix + id, user)
await client.set(`${emailKeyPrefix}${user.email as string}`, id)
return user
}
const getUser = async (id: string) => {
const response = await client.get(userKeyPrefix + id)
if (!response.data) return null
return reviveFromJson(response.data)
const user = await client.get<AdapterUser>(userKeyPrefix + id)
if (!user) return null
return hydrateDates(user)
}
return {
@@ -110,9 +122,11 @@ export function UpstashRedisAdapter(
},
getUser,
async getUserByEmail(email) {
const emailResponse = await client.get(emailKeyPrefix + email)
if (!emailResponse.data) return null
return await getUser(emailResponse.data)
const userId = await client.get<string>(emailKeyPrefix + email)
if (!userId) {
return null
}
return await getUser(userId)
},
async getUserByAccount(account) {
const dbAccount = await getAccount(
@@ -124,7 +138,7 @@ export function UpstashRedisAdapter(
async updateUser(updates) {
const userId = updates.id as string
const user = await getUser(userId)
return await setUser(userId, { ...user, ...updates })
return await setUser(userId, { ...(user as AdapterUser), ...updates })
},
async linkAccount(account) {
const id = `${account.provider}:${account.providerAccountId}`
@@ -158,10 +172,13 @@ export function UpstashRedisAdapter(
},
async useVerificationToken(verificationToken) {
const tokenKey = verificationTokenKeyPrefix + verificationToken.identifier
const tokenResponse = await client.get(tokenKey)
if (!tokenResponse.data) return null
const token = await client.get<VerificationToken>(tokenKey)
if (!token) return null
await client.del(tokenKey)
return reviveFromJson(tokenResponse.data)
return hydrateDates(token)
// return reviveFromJson(token)
},
async unlinkAccount(account) {
const id = `${account.provider}:${account.providerAccountId}`
@@ -177,17 +194,15 @@ export function UpstashRedisAdapter(
const user = await getUser(userId)
if (!user) return
const accountByUserKey = accountByUserIdPrefix + userId
const accountRequest = await client.get(accountByUserKey)
const accountKey = accountRequest.data
const accountKey = await client.get<string>(accountByUserKey)
const sessionByUserIdKey = sessionByUserIdKeyPrefix + userId
const sessionRequest = await client.get(sessionByUserIdKey)
const sessionKey = sessionRequest.data
const sessionKey = await client.get<string>(sessionByUserIdKey)
await client.del(
userKeyPrefix + userId,
`${emailKeyPrefix}${user.email as string}`,
accountKey,
accountKey as string,
accountByUserKey,
sessionKey,
sessionKey as string,
sessionByUserIdKey
)
},

View File

@@ -1,6 +1,6 @@
import upstashRedisClient from "@upstash/redis"
import { runBasicTests } from "adapter-test"
import { reviveFromJson, UpstashRedisAdapter } from "../src"
import { Redis } from "@upstash/redis"
import { runBasicTests } from "@next-auth/adapter-test"
import { hydrateDates, UpstashRedisAdapter } from "../src"
import "dotenv/config"
if (!process.env.UPSTASH_REDIS_URL || !process.env.UPSTASH_REDIS_KEY) {
@@ -8,35 +8,39 @@ if (!process.env.UPSTASH_REDIS_URL || !process.env.UPSTASH_REDIS_KEY) {
expect(true).toBe(true)
})
} else {
const client = upstashRedisClient(
process.env.UPSTASH_REDIS_URL,
process.env.UPSTASH_REDIS_KEY
)
const client = new Redis({
url: process.env.UPSTASH_REDIS_URL,
token: process.env.UPSTASH_REDIS_KEY,
})
runBasicTests({
adapter: UpstashRedisAdapter(client, { baseKeyPrefix: "testApp:" }),
db: {
async user(id: string) {
const { data } = await client.get(`testApp:user:${id}`)
return reviveFromJson(data)
const data = await client.get<object>(`testApp:user:${id}`)
if (!data) return null
return hydrateDates(data)
},
async account({ provider, providerAccountId }) {
const { data } = await client.get(
const data = await client.get<object>(
`testApp:user:account:${provider}:${providerAccountId}`
)
return reviveFromJson(data)
if (!data) return null
return hydrateDates(data)
},
async session(sessionToken) {
const { data } = await client.get(
const data = await client.get<object>(
`testApp:user:session:${sessionToken}`
)
return reviveFromJson(data)
if (!data) return null
return hydrateDates(data)
},
async verificationToken(where) {
const { data } = await client.get(
const data = await client.get<object>(
`testApp:user:token:${where.identifier}`
)
return reviveFromJson(data)
if (!data) return null
return hydrateDates(data)
},
},
})

View File

@@ -1,5 +1,5 @@
{
"extends": "tsconfig/base.json",
"extends": "@next-auth/tsconfig/adapters.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"

View File

@@ -77,8 +77,7 @@ NextAuth.js can be used with or without a database.
- Designed to be secure by default and encourage best practices for safeguarding user data
- Uses Cross-Site Request Forgery (CSRF) Tokens on POST routes (sign in, sign out)
- Default cookie policy aims for the most restrictive policy appropriate for each cookie
- When JSON Web Tokens are enabled, they are signed by default (JWS) with HS512
- Use JWT encryption (JWE) by setting the option `encryption: true` (defaults to A256GCM)
- When JSON Web Tokens are enabled, they are encrypted by default (JWE) with A256GCM
- Auto-generates symmetric signing and encryption keys for developer convenience
- Features tab/window syncing and session polling to support short lived sessions
- Attempts to implement the latest guidance published by [Open Web Application Security Project](https://owasp.org)

View File

@@ -1,6 +1,6 @@
{
"name": "next-auth",
"version": "4.2.1",
"version": "4.4.0",
"description": "Authentication for Next.js",
"homepage": "https://next-auth.js.org",
"repository": "https://github.com/nextauthjs/next-auth.git",
@@ -36,15 +36,15 @@
"./providers/*": "./providers/*.js"
},
"scripts": {
"build": "yarn clean && yarn run build:js && yarn run build:css",
"build": "pnpm clean && pnpm build:js && pnpm build:css",
"clean": "rm -rf client css lib providers core jwt react next index.d.ts index.js adapters.d.ts middleware.d.ts middleware.js",
"build:js": "yarn run clean && yarn run generate-providers && tsc && babel --config-file ./config/babel.config.js src --out-dir . --extensions \".tsx,.ts,.js,.jsx\"",
"build:js": "pnpm clean && pnpm generate-providers && tsc && babel --config-file ./config/babel.config.js src --out-dir . --extensions \".tsx,.ts,.js,.jsx\"",
"build:css": "postcss --config config/postcss.config.js src/**/*.css --base src --dir . && node config/wrap-css.js",
"watch:css": "postcss --config config/postcss.config.js --watch src/**/*.css --base src --dir .",
"test": "jest --config ./config/jest.config.js",
"prepublishOnly": "yarn run build",
"prepublishOnly": "pnpm build",
"generate-providers": "node ./config/generate-providers.js",
"setup": "yarn run generate-providers",
"setup": "pnpm generate-providers",
"lint": "eslint src config"
},
"files": [
@@ -76,8 +76,8 @@
},
"peerDependencies": {
"nodemailer": "^6.6.5",
"react": "^17.0.2 || ^18.0.0-0",
"react-dom": "^17.0.2 || ^18.0.0-0"
"react": "^17.0.2 || ^18",
"react-dom": "^17.0.2 || ^18"
},
"peerDependenciesMeta": {
"nodemailer": {
@@ -92,6 +92,7 @@
"@babel/preset-env": "^7.16.4",
"@babel/preset-react": "^7.16.0",
"@babel/preset-typescript": "^7.16.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"@testing-library/dom": "^8.11.3",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
@@ -106,13 +107,12 @@
"babel-jest": "^27.4.2",
"babel-plugin-jsx-pragmatic": "^1.0.2",
"babel-preset-preact": "^2.0.0",
"cpx": "^1.5.0",
"cssnano": "^5.0.12",
"jest": "^27.4.3",
"jest-watch-typeahead": "^1.0.0",
"msw": "^0.36.3",
"next": "12.1.0",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.12",
"postcss-cli": "^9.0.2",
"postcss-nested": "^5.0.6",
"react": "^17.0.2",
@@ -132,4 +132,4 @@
"**/tests",
"**/__tests__"
]
}
}

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