Compare commits

...

124 Commits

Author SHA1 Message Date
Balázs Orbán
562bcf216c feat(ts): preliminary TypeScript support (#1223)
* chore: replace standard with ts-standard

* feat(ts): add some initial types

* feat(ts): import and use types

* chore: allow global fetch through package.json

* chore: upgrade lint scripts to use ts-standard

* chore: run linter on dev app

* chore(ts): satisfy dev Next.js server for TS

* fix: add eslint as dev dependency

* fix(lint): ignore next-env.d.ts from linting

* feat(ts): improve cookies options types

* fix: run linter with fix
2021-02-01 11:23:04 +01:00
Balázs Orbán
690f81ec60 feat(provider): option to disable client-side redirects (credentials) (#1219)
* chore: add credentials provider to dev app

* feat: add redirect option to signIn, signOut

* feat: set correct status codes for credentials errors

* chore: add credentials page to dev app

* fix: support any provider name for credentials
2021-02-01 11:04:24 +01:00
Balázs Orbán
909acab3f7 Merge branch 'main' into canary [skip release] 2021-02-01 11:03:03 +01:00
Cody Ogden
da01aa693a docs: Update Providers.Credential Example Block [skip release] (#1225)
Closing curly bracket where it should have been a square bracket.
2021-01-31 22:27:42 +01:00
Balázs Orbán
8a1798f9b5 fix: make OAuth 1 work after refactoring (#1218)
* chore: add twitter provider to dev app

* feat: bind client instance to overriden methods

* fix: don't add extra params to getOAuthRequestToken

* chore: add twitter to env example, add secret gen instructions
2021-01-30 22:48:39 +01:00
Balázs Orbán
f106a9ed99 docs: remove announcement bar [skip release] 2021-01-30 12:32:02 +01:00
Balázs Orbán
a2e68cd13e docs: more emphasis on req methods [skip release] 2021-01-30 12:29:20 +01:00
Balázs Orbán
4a8da4416a fix: leave accessTokenExpires as null
Forwarding expires_in as is to accessTokenExpires has shown to cause issues with Prisma, and maybe with other flows as well. Setting it back to `null` for now. We still forward `expires_in`, so users can use it if they want to.

Fixes #1216
2021-01-30 11:51:21 +01:00
Vova
7dc147a893 feat(provider): Add Medium (#1213) 2021-01-29 23:51:04 +01:00
Balázs Orbán
4ab2ccae9c feat: send all params to logger function (#1214) 2021-01-29 23:45:29 +01:00
Balázs Orbán
10c4d9dbf0 refactor: provide raw idToken through account object (#1211)
* refactor: provide raw idToken through account object

* docs: clear up accessToken naming

* refactor: provide raw token response to account

* chore: fix grammar in comments
2021-01-29 23:27:32 +01:00
Samson Zhang
048c1f22a8 docs: Fix grammar in "Feature Requests" section of FAQs [skip release] (#1212) 2021-01-29 22:31:30 +01:00
Balázs Orbán
63c9d83dbe Merge branch 'main' into canary 2021-01-29 18:24:27 +01:00
Balázs Orbán
4f481eef0b fix: forward second argument to fetch body in signIn
fixes #1206
2021-01-28 11:27:36 +01:00
Aishah
5dca70e667 docs(adapter): add adapter repo to documentation [skip release] (#1173)
* docs(adapter): add adapter repo to documentation

* docs(adapter): elaborate on custom repo
2021-01-28 01:55:15 +01:00
Carmelo Scandaliato
6c5db3c2a0 docs(provider): fix typos in providers code snippets [skip release] (#1204) 2021-01-27 21:48:15 +01:00
Dillon Mulroy
d2cd02ae78 fix: Add a null check to the window 'storage' event listener (#1198)
* Add a null check to the window 'storage' event listener

While testing in Cypress it's possible to receive a null value on Storage Events when 'clear' is called and will cause errors as seen in #1125.

* Update index.js

typo

* Update src/client/index.js

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

* formatting

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2021-01-27 21:45:24 +01:00
Balázs Orbán
ba35ada2bb fix: send /authorize params through url 2021-01-25 22:29:48 +01:00
Balázs Orbán
f4d9e54071 feat(provider): re-add state, expand protection provider options (#1184)
* refactor: move OAuthCallbackError to errors file

* refactor: improve pkce handling

* feat(provider): re-introduce state to provider options

* docs(provider): mention protection options "state" and "none"

* docs(provider): document state property deprecation

* fix: only add code_verifier param if protection is pkce

* docs: explain state deprecation better

* chore: unify string
2021-01-22 21:50:09 +01:00
Balázs Orbán
393bd4ae71 chore(provider): remove Mixer (#1178)
"Thank you to our amazing community and Partners.
As of July 22, the Mixer service has closed."
2021-01-21 23:10:41 +01:00
Balázs Orbán
e9fd979561 docs: fix typo in callbacks.md [skip release] 2021-01-21 23:03:03 +01:00
Balázs Orbán
1aeca00d67 docs: clear things up around using access_token [skip release]
#1078
2021-01-21 22:59:07 +01:00
Balázs Orbán
cf2f89997e fix: fix lint issues 2021-01-21 22:19:56 +01:00
Balázs Orbán
af36bd545d fix: use startsWith for protocol matching in parseUrl
closes #842
2021-01-21 22:17:58 +01:00
Luke Lau
b61bfc2add fix(provider): use authed_user on slack instead of spotify (#1174) 2021-01-21 21:32:32 +01:00
Balázs Orbán
47a5c9d830 docs(provider): add Salesforce provider 2021-01-21 13:13:45 +01:00
Mohamed El Mahallawy
6c84325cc8 feat(provider): add Salesforce provider (#1027) 2021-01-21 13:11:41 +01:00
Balázs Orbán
d56fa6ad02 fix: correct logger import 2021-01-20 17:46:07 +01:00
Balázs Orbán
536f0ad108 feat: add PKCE support (#941)
* chore(deps): upgrade dependencies

* chore(deps): add pkce-challenge

* feat(pkce): initial implementation of PCKE support

* chore: remove URLSearchParams

* chore(deps): upgrade lockfile

* refactor: store code_verifier in a cookie

* refactor: add pkce handlers

* docs: add PKCE documentation

* chore: remove unused param

* chore: revert unnecessary code change

* fix: correct variable names
2021-01-20 15:06:08 +01:00
Balázs Orbán
4f93e6ab15 docs: update info about TypeScript [skip release] 2021-01-20 00:45:01 +01:00
Zhao Lei
47bcd1e98b feat(provider): add option to generate email verification token (#541)
* Add option to generate email verification token

* chore: remove unused import

* refactor: define default generateVerificationToken in-place

* refactor: define default generateVerificationToken in-place

Co-authored-by: Nico Domino <yo@ndo.dev>
Co-authored-by: Balázs Orbán <info@balazsorban.com>
2021-01-20 00:22:34 +01:00
Henrik Wenz
b3c76177d7 fix(adapter): fix ISO Datetime type error in Prisma updateSession (#640)
Co-authored-by: Nico Domino <yo@ndo.dev>
Co-authored-by: Balázs Orbán <info@balazsorban.com>
2021-01-19 23:48:54 +01:00
Balázs Orbán
0987f72acb feat: forward signIn auth params to /authorize (#1149)
* refactor: authorisation -> authorization

* feat: forward authorizationParams from signIn function

* refactor: take auth params as third argument

* docs: document signIn authorizationParams
2021-01-19 00:23:02 +01:00
Balázs Orbán
de9538dde8 chore(adapters): remove fauna (#1148) 2021-01-18 22:58:47 +01:00
Radhika
3bec8ea483 docs: remove v1 documentation (#1142) 2021-01-18 19:28:48 +01:00
Yuri Gor
d02c41568c chore(deps): upgrade typeorm to v0.2.30 (#1145) 2021-01-18 19:27:09 +01:00
t.kuriyama
d5206874df feat: add native hkdf (#1124)
* feat: add native hkdf

* feat: import only needed to do hkdf

* feat: tweak digest and arguments
2021-01-17 22:23:39 +01:00
Balázs Orbán
2f88880ee3 chore: fix lint issues [skip release] 2021-01-14 01:32:53 +01:00
suraj10k
b1f6901c52 chore: Comply to Vercel Open Source sponsorship [skip release] (#1087)
* added banner

* Changed banner image allignment

* changed location of banner again

* added to acknowledgement

* added to acknowledgement 1

* changed image size

* k

* l

* s

* s

* .

* added link to the banner in readme.md

* fixed image redirect

* fixed image allignment

* made changes in readme and index.js

* Changed the source of the banner image

* added banner to the footer of the site
2021-01-13 19:28:56 +01:00
Balázs Orbán
1a1a1f9721 chore: define providers in single file for docs [skip release] 2021-01-12 20:55:48 +01:00
Aymeric
ecbaa14e30 feat(provider): finish Reddit provider and add documentation (#1094)
* Create reddit.md

* uncommented profile callback

* Update reddit.md

* fix lint issues

* added reddit provider

* added reddit provider

* Add Reddit Provider

For some reason a bunch of providers got deleted in the last commit

* Add Reddit Provider

* Add Reddit Provider
2021-01-12 20:39:50 +01:00
Balázs Orbán
0c40529535 style: make p system theme aware [skip release] 2021-01-12 19:01:21 +01:00
Balázs Orbán
72b6050076 fix: export getSession [skip release]
somehow the default export does not work in the dev app
2021-01-12 17:04:37 +01:00
Balázs Orbán
47621b56b2 refactor: show signin page in dev app [skip release] 2021-01-12 17:03:13 +01:00
Balázs Orbán
54a28b5f1b refactor: be explicit about path in jsonconfig [skip release] 2021-01-12 17:02:52 +01:00
Ben
ad791ea45c feat(provider): add LINE provider (#1091) 2021-01-12 13:30:08 +01:00
Balázs Orbán
1838e43b27 feat(pages): add dark theme support (#1088)
* feat(pages): add dark theme support

* docs: document theme option

* chore: remove ts-check from dev app

* style(pages): fix some text colors in dark mode
2021-01-11 21:56:48 +01:00
Balázs Orbán
354d6c35c3 docs: update some urls in the docs [skip release] 2021-01-11 20:45:53 +01:00
Balázs Orbán
2e4832caf8 chore: update caiuse-lite db 2021-01-11 20:06:42 +01:00
Balázs Orbán
f05644dafa docs: improve FAQ docs [skip release] 2021-01-11 20:06:31 +01:00
Balázs Orbán
e7e8e0f393 docs: clarify .env usage in CONTRIBUTING.md [skip release] (#1085) 2021-01-11 12:57:12 +01:00
Alex B
416d92c33f feat: replace blur/focus event to visibility API for getSession (#1081) 2021-01-10 23:26:33 +01:00
Balázs Orbán
e504044489 fix: pass csrfToken to signin renderer 2021-01-10 21:03:00 +01:00
Balázs Orbán
173df76c0f feat: improve package development experience (#1064)
* chore(deps): add next and react to dev dependencies

* chore: move build configs to avoid crash with next dev

* chore: add next js dev app

* chore: remove .txt extension from LICENSE file

* chore: update CONTRIBUTING.md

* chore: watch css under development

* style(lint): run linter on index.css

* chore: fix some imports for dev server

* refactor: simplify client code

* chore: mention VSCode extension for linting

* docs: reword CONTRIBUTING.md

* chore: ignore linting pages and components
2021-01-10 20:20:21 +01:00
Balázs Orbán
44ffd55fe2 refactor: code base improvements 3 (#1072)
* refactor: extend res.{end,send,json}, redirect

* refactor: chain res methods, remove unnecessary ones

* refactor: simplify oauth callback signature

* refactor: code simplifications

* refactor: re-export everything from routes in one

* refactor: split up main index.js to multiple files

* refactor: simplify passing of provider(s) around

* refactor: extend req with callbackUrl inline

* refactor: simplify page rendering

* refactor: move error page redirects to main file, simplify renderer

* refactor: inline req.options definition

* refactor: simplify error fallbacks

* refactor: remove else branches and unnecessary try..catch

* refactor: add docs, and simplify jwt functions

* refactor: prefer errors object over switch..case in signin page

* feat: log all params sent to logger instead of only first

* refactor: fewer lines input validation

* refactor: remove even more unnecessary else branches
2021-01-10 20:15:25 +01:00
Evgeniy Boreyko
fb8ec8a469 feat(provider): add vk.com provider (#1060)
* feat(provider): add vk.com provider

* refactor(provider): reduce vk.com provider api
2021-01-09 22:25:05 +01:00
Balázs Orbán
65504d6917 fix: remove async from NextAuth default handler
This function should not return a Promise
2021-01-06 08:45:54 +01:00
Balázs Orbán
3fcdd22656 feat(provider): reduce user facing API (#1023)
Co-authored-by: Balazs Orban <balazs@nhi.no>
2021-01-05 16:34:26 +01:00
Balázs Orbán
7a1d712096 fix: use authorizationUrl correctly 2021-01-04 22:53:02 +01:00
Balázs Orbán
f7ff4c9219 fix: trigger release 2021-01-04 22:20:15 +01:00
Balázs Orbán
20f40d027a refactor: code base improvements 2 (#1045) 2021-01-04 22:16:42 +01:00
Balázs Orbán
b5384e7403 docs: misc improvements [skip release] (#1043) 2021-01-04 20:30:41 +01:00
Balázs Orbán
b5c4e91f17 chore: run tests on canary [skip release] 2021-01-03 23:18:46 +01:00
Balázs Orbán
f1f144951a docs: add powered by vercel logo [skip release] 2021-01-03 13:40:48 +01:00
Balázs Orbán
0380edfae9 fix: don't chain on res.end on non-chainable res methods (#1031) 2021-01-02 21:45:20 +01:00
Balázs Orbán
4d89b27784 fix: miscellaneous bugfixes (#1030)
* fix: use named params to fix order

* fix: avoid recursive redirects

* fix: revert to use parsed baseUrl

* fix: avoid recursive res.end calls

* fix: use named params in renderPage

* fix: promisify lib/oauth/callback result
2021-01-02 21:28:54 +01:00
Balázs Orbán
e17acb6762 chore: rename labeler.yaml to labeler.yml [skip release] 2021-01-02 17:57:33 +01:00
Balázs Orbán
91e26ca475 chore: add auto labeling to PRs [skip release] (#1025)
* chore: add auto labeling to PRs [skip release]

* chore: allow any file type for test label to be added
2021-01-01 23:05:13 +01:00
Balázs Orbán
c8e76b4b5d feat: forward id_token to jwt and signIn callbacks (#1024) 2021-01-01 21:49:27 +01:00
Didi Keke
a8362ec380 feat(provider): Add Mail.ru OAuth Service Provider and Callback snippet (#522)
* Update callback.js

- Fix Mail.ru bug (missing request parameter: access_token)

Note: setGetAccessTokenProfileUrl should be added to Mail.ru provider to enable support.

* Add Mail.ru OAuth Service Provider

* Update callbacks.md

- Fix broken callbacks snippet.

* Update callback.js

- Bug fix https://github.com/nextauthjs/next-auth/pull/522#issuecomment-669851914
- Minor refactoring.

* Fix: Code linting.

* Update callback.js

Improve approach for building of URL based review recommendation.

* Feat: Reduce API surface expansion

Make use of provider.id === "mailru" as suggested in review discussion in place of setGetAccessTokenProfileUrl.

* Fix: Code linting
2021-01-01 19:05:21 +01:00
Balázs Orbán
f2ad69358f refactor: code base improvements (#959)
* chore: fix casing of OAuth

* refacotr: simplify default callbacks lib file

* refactor: use native URL instead of string concats

* refactor: move redirect to res.redirect, done to res.end

* refactor: move options to req

* refactor: improve IntelliSense, name all functions

* fix(lint): fix lint errors

* refactor: remove jwt-decode dependency

* refactor: refactor some callbacks to Promises

* revert: "refactor: use native URL instead of string concats"

Refs: 690c55b04089e4f3157424c816d43ee4cecb77a0

* chore: misc changes

Co-authored-by: Balazs Orban <balazs@nhi.no>
2021-01-01 14:53:06 +01:00
Balázs Orbán
ca06976422 docs: fix typos in CONTRIBUTING.md [skip release] 2021-01-01 13:43:19 +01:00
Balázs Orbán
7fa4275340 docs: update contributing information [skip release] (#1011)
* docs: update CONTRIBUTING.md

* docs:  use db instead of database for more space

* docs: update CONTRIBUTING.md

* docs: update PR template

* docs: add note about skipping a release
2021-01-01 13:37:46 +01:00
Melanie Seltzer
c684336b32 docs: small update to sign in/out examples (#1016)
* Update examples in client.md

* Update more examples

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2021-01-01 13:11:49 +01:00
Balázs Orbán
82d16e6ac4 feat: allow to return string in signIn callback (#1019) 2020-12-31 21:55:30 +01:00
Balázs Orbán
bf7efbc252 docs: Remove unnecessary promises (#915) 2020-12-31 12:16:03 +01:00
Florian Michaut
b9862b86b5 feat(db): make Fauna DB collections & indexes configurable (#968)
* Add collections & indexes overrides for Fauna DB

* Fix the name of the verification token index

Co-authored-by: Florian Michaut <florian@coding-days.com>
2020-12-31 10:26:26 +01:00
Ben West
9b579b5fcb Change image to text from varchar (#777)
Co-authored-by: Nico Domino <yo@ndo.dev>
2020-12-31 06:25:10 +01:00
Yuma Matsune
abcf845ebf fix(adapter): use findOne for typeorm (#1014) 2020-12-30 21:08:09 +01:00
Balázs Orbán
ee398d1acd fix: treat user.id as optional param (#1010) 2020-12-30 14:23:59 +01:00
Balázs Orbán
c31cbbcd30 chore(release): trigger release on docs type 2020-12-29 23:02:07 +01:00
Balázs Orbán
1728f50952 chore(release): delete old workflow 2020-12-29 22:51:00 +01:00
Junior Vidotti
2eb17cba1a docs(database): add mssql indexes in docs, fix typos (#925)
* added mssql indexes in docs, fixed typo

* docs: fix typo in www/docs/schemas/mssql.md

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2020-12-29 22:49:38 +01:00
Balazs Orban
15196ee3d1 chore(release): change semantic-release/git to semantic-release/github 2020-12-29 22:42:32 +01:00
Balázs Orbán
aa4439e182 feat: add semantic-release (#920) 2020-12-29 22:00:08 +01:00
Nico Domino
66ec439b4d Update README.md 2020-12-26 01:56:20 +01:00
Nico Domino
a49068643c Update README.md 2020-12-25 20:21:09 +01:00
Paul Kenneth Kent
1a315fe5ac feat: add strava provider (#986)
* Add Strava as a provider

* Add documentation for Strava provider

* Fix lint errors

Co-authored-by: Paul Kenneth Kent <paul@ventureharbour.com>
2020-12-23 19:02:36 +01:00
Nico Domino
652ac7de35 Update README.md
Updated the readme to include the projects logo, fixed some typos, and added license info and contributor image.
2020-12-22 00:34:31 +01:00
Balázs Orbán
28ce71d99e chore: hide comments from pull request template 2020-12-17 18:25:17 +01:00
pkabore
28e2afbd3a docs: Correcting a typo. "available" Line 70 (#965)
* chore: use stale label, instead of wontfix

* chore: add link to issue explaining stalebot

* chore: fix typo in stalebot comment

* chore: run build GitHub Action on canary also

* chore: run build GitHub Actions on canary as well

* chore: add reproduction section to questions

* feat(provider): Add Azure Active Directory B2C (#809)

* add provider: Microsoft

* documentation

* support no tenant setup

* fix code style

* chore: rename Microsoft provider to AzureADB2C

* chore: alphabetical order in providers/index

* Revert "feat(provider): Add Azure Active Directory B2C (#809)" (#919)

This reverts commit 6e6a24a7af.

* chore: add myself to the contributors list 🙈

* Correcting a typo. "available" Line 70

Co-authored-by: Balázs Orbán <info@balazsorban.com>
Co-authored-by: Vladimir Evdokimov <evdokimov.vladimir@gmail.com>
2020-12-17 18:23:58 +01:00
pkabore
eb828d42f8 docs: We have twice the word "side" (#964)
* chore: use stale label, instead of wontfix

* chore: add link to issue explaining stalebot

* chore: fix typo in stalebot comment

* chore: run build GitHub Action on canary also

* chore: run build GitHub Actions on canary as well

* chore: add reproduction section to questions

* feat(provider): Add Azure Active Directory B2C (#809)

* add provider: Microsoft

* documentation

* support no tenant setup

* fix code style

* chore: rename Microsoft provider to AzureADB2C

* chore: alphabetical order in providers/index

* Revert "feat(provider): Add Azure Active Directory B2C (#809)" (#919)

This reverts commit 6e6a24a7af.

* chore: add myself to the contributors list 🙈

* We have twice the word "side"

Co-authored-by: Balázs Orbán <info@balazsorban.com>
Co-authored-by: Vladimir Evdokimov <evdokimov.vladimir@gmail.com>
2020-12-17 18:21:31 +01:00
imgregduh
d03504c6ef docs: fix typo Adapater -> Adapter (#960)
Co-authored-by: Balázs Orbán <info@balazsorban.com>
Co-authored-by: Vladimir Evdokimov <evdokimov.vladimir@gmail.com>
2020-12-16 09:18:53 +01:00
dependabot[bot]
8827950f12 chore(deps): Bump ini from 1.3.5 to 1.3.8 in /www (#953)
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-13 02:33:08 +01:00
Jakub Naskręski
4f89d74d78 feat: Display error if no [...nextauth].js found (#678)
* Display error if no [...nextauth].js found

fixes #647

* Log the error and describe it inside errors.md

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2020-12-13 02:28:09 +01:00
Haldun Anil
be159b1b18 docs: fix incorrect references in cypress docs (#932)
* chore: use stale label, instead of wontfix

* chore: add link to issue explaining stalebot

* chore: fix typo in stalebot comment

* chore: run build GitHub Action on canary also

* chore: run build GitHub Actions on canary as well

* chore: add reproduction section to questions

* feat(provider): Add Azure Active Directory B2C (#809)

* add provider: Microsoft

* documentation

* support no tenant setup

* fix code style

* chore: rename Microsoft provider to AzureADB2C

* chore: alphabetical order in providers/index

* Revert "feat(provider): Add Azure Active Directory B2C (#809)" (#919)

This reverts commit 6e6a24a7af.

* chore: add myself to the contributors list 🙈

* docs: fix incorrect references in cypress docs

* chore: add additional docs clarification

Co-authored-by: Balázs Orbán <info@balazsorban.com>
Co-authored-by: Vladimir Evdokimov <evdokimov.vladimir@gmail.com>
2020-12-09 17:07:12 +01:00
Luke Lau
19f2664a78 feat: Store user ID in sub claim of default JWT (#784)
This allows us to check if the user is signed in when using JWTs

Part of #625
2020-12-08 18:53:47 +01:00
Balázs Orbán
bd86e7c7c7 chore: reword PR template 2020-12-08 00:23:40 +01:00
Balázs Orbán
7ce37c71d7 chore: create PULL_REQUEST_TEMPLATE.md 2020-12-08 00:12:44 +01:00
Balázs Orbán
3c3a4d2c4f chore: add note about conveting questions to discussions 2020-12-07 17:09:53 +01:00
Balázs Orbán
5fcf80ce81 chore: disallow issues without template 2020-12-07 17:08:51 +01:00
dependabot[bot]
7a4534a6b1 chore(dep): Bump highlight.js from 9.18.1 to 9.18.5 (#880)
Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 9.18.1 to 9.18.5.
- [Release notes](https://github.com/highlightjs/highlight.js/releases)
- [Changelog](https://github.com/highlightjs/highlight.js/blob/9.18.5/CHANGES.md)
- [Commits](https://github.com/highlightjs/highlight.js/compare/9.18.1...9.18.5)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Balázs Orbán <info@balazsorban.com>
Co-authored-by: Nico Domino <yo@ndo.dev>
2020-12-07 10:48:01 +01:00
Kristóf Poduszló
ddaa830e10 refactor(db): update Prisma calls to support 2.12+ (#881)
Co-authored-by: Balázs Orbán <info@balazsorban.com>
Co-authored-by: Nico Domino <yo@ndo.dev>
2020-12-07 00:44:22 +01:00
Cathy Chen
9dbd372f08 update(provider): Update Slack provider to use V2 OAuth endpoints (#895)
* Update Slack to v2 authorize urls, option for additional authorize params
* acessTokenGetter + documentation
2020-12-07 00:31:32 +01:00
Vladimir Evdokimov
dde908b54a feat(provider): Add Azure Active Directory B2C (#921)
* add provider: Microsoft

* documentation

* support no tenant setup

* fix code style

* chore: rename Microsoft provider to AzureADB2C

* chore: alphabetical order in providers/index

* doc: add provider to FAQ
2020-12-06 22:57:54 +01:00
Joe Bell
831c59dd5c feat: add foursquare (#584) 2020-12-06 20:56:00 +01:00
RobertCraigie
3abb0c8223 feat(provider): Add Bungie (#589)
* Add Bungie provider

* Use absolute URL for images

* Correct image URL and use consistent formatting

Co-authored-by: Nico Domino <yo@ndo.dev>
2020-12-06 20:34:25 +01:00
dependabot[bot]
8c56e13577 Bump next from 9.5.3 to 9.5.4 in /test/docker/app (#759)
Bumps [next](https://github.com/vercel/next.js) from 9.5.3 to 9.5.4.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v9.5.3...v9.5.4)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Nico Domino <yo@ndo.dev>
2020-12-06 20:31:09 +01:00
Joost Jansky
12d7856640 feat(provider): add netlify (#555)
Co-authored-by: styxlab <cws@DE01WP777.scdom.net>
Co-authored-by: Balázs Orbán <info@balazsorban.com>
2020-12-06 20:25:14 +01:00
Joseph Vaughan
4635113133 add(db): Add support for Fauna DB (#708)
* Add support for Fauna DB

* Add integration tests

Co-authored-by: Nico Domino <yo@ndo.dev>
2020-12-06 20:19:14 +01:00
Fabrizio Ruggeri
1aea187d5e Include callbackUrl in newUser page (#790)
* Include callbackUrl in newUser page

* Update src/server/routes/callback.js

Co-authored-by: Iain Collins <me@iaincollins.com>

* Update src/server/routes/callback.js

Co-authored-by: Iain Collins <me@iaincollins.com>

Co-authored-by: Iain Collins <me@iaincollins.com>
Co-authored-by: Nico Domino <yo@ndo.dev>
2020-12-06 19:50:41 +01:00
Nico Domino
47b8788249 WIP: Update Docusaurus + Site dependencies (#802)
* update: deps

* fix: broken link

* fix: search upgrade change
2020-12-06 19:47:33 +01:00
Aymeric
06a160aa0c Fix for Reddit Authentication (#866)
* Fixed Reddit Authentication

* updated fix for build test

* updated buffer to avoid deprecation message

* Updated for passing tests
2020-12-06 19:30:16 +01:00
Manish Chiniwalar
93f4dc0622 docs: Update default ports for support Databases (#839)
https://next-auth.js.org/configuration/databases
2020-12-06 19:17:47 +01:00
Balázs Orbán
6088a05204 Merge main into canary (#917)
* chore: use stale label, instead of wontfix

* chore: add link to issue explaining stalebot

* chore: fix typo in stalebot comment

* chore: run build GitHub Action on canary also

* chore: run build GitHub Actions on canary as well

* chore: add reproduction section to questions
2020-12-06 10:24:28 +01:00
Balázs Orbán
d242d72106 fix(provider): handle no profile image for Spotify (#914)
* chore(deps): upgrade "standard"

* style(lint): run lint fix

* fix(provider): optional chain Spotify provider profile img
2020-12-05 18:55:12 +01:00
Alan Ray
766874dbd8 fix: update Okta routes (#763)
the current routing for the Okta provider does not follow the standard
set by Okta, and as such doesn't allow for custom subdomains. this
update amends the routes to allow for customer subdomains, and also
aligns next-auth with Okta's documentation.
2020-12-05 11:33:13 +01:00
Daggy1234
0b7343702f fix: ensure Images are produced for discord (#734) 2020-12-05 11:28:16 +01:00
Josh Padnick
0327b9049a fix: update nodemailer version in response to CVE. (#860)
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7769 reports a high-severity issue with the current version of nodemailer. This should be merged and released right away if possible.
2020-12-05 11:26:04 +01:00
Pauldic
2ee460de00 docs: fix typo in callbacks.md (#815)
This is a simple typographical error changed accesed to accessed
2020-12-05 11:24:04 +01:00
Joshua K. Martinez
c8de34d003 docs: fix discord example code (#850) 2020-12-05 11:23:07 +01:00
James Perkins
d15572074f docs: update for Now to Vercel (#847)
Vercel archived their now packages a while back, so you can use vercel env pull to pull in the .env
2020-12-05 11:20:48 +01:00
Luke Lau
7b6fd818a5 feat: allow react 17 as a peer dependency (#819)
Co-authored-by: Balázs Orbán <info@balazsorban.com>
2020-12-05 11:18:36 +01:00
Balázs Orbán
e031591468 feat: simplify NextAuth instantiation (#911) 2020-12-05 11:11:08 +01:00
32 changed files with 1038 additions and 354 deletions

View File

@@ -5,11 +5,14 @@ export default function AccessDenied () {
<>
<h1>Access Denied</h1>
<p>
<a href="/api/auth/signin"
onClick={(e) => {
e.preventDefault()
signIn()
}}>You must be signed in to view this page</a>
<a
href='/api/auth/signin'
onClick={(e) => {
e.preventDefault()
signIn()
}}
>You must be signed in to view this page
</a>
</p>
</>
)

View File

@@ -1,6 +1,5 @@
import Link from 'next/link'
import { signIn, signOut, useSession } from 'next-auth/client'
import * as client from 'next-auth/client'
import styles from './header.module.css'
// The approach used in this component shows how to built a sign in and sign out
@@ -26,7 +25,7 @@ export default function Header () {
You are not signed in
</span>
<a
href="/api/auth/signin"
href='/api/auth/signin'
className={styles.buttonPrimary}
onClick={(e) => {
e.preventDefault()
@@ -51,7 +50,7 @@ export default function Header () {
<strong>{session.user.email || session.user.name}</strong>
</span>
<a
href="/api/auth/signout"
href='/api/auth/signout'
className={styles.button}
onClick={(e) => {
e.preventDefault()
@@ -96,6 +95,11 @@ export default function Header () {
<a>API</a>
</Link>
</li>
<li className={styles.navItem}>
<Link href='/credentials'>
<a>Credentials</a>
</Link>
</li>
</ul>
</nav>
</header>

View File

@@ -1,12 +0,0 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"next-auth": ["./src/server"],
"next-auth/adapters": ["./src/adapters"],
"next-auth/client": ["./src/client"],
"next-auth/jwt": ["./src/lib/jwt"],
"next-auth/providers": ["./src/providers"]
}
}
}

2
next-env.d.ts vendored Normal file
View File

@@ -0,0 +1,2 @@
/// <reference types="next" />
/// <reference types="next/types/global" />

806
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -29,8 +29,8 @@
"prepublishOnly": "npm run build",
"publish:beta": "npm publish --tag beta",
"publish:canary": "npm publish --tag canary",
"lint": "standard",
"lint:fix": "standard --fix"
"lint": "ts-standard",
"lint:fix": "ts-standard --fix"
},
"files": [
"dist",
@@ -74,11 +74,13 @@
"@semantic-release/github": "^7.2.0",
"@semantic-release/npm": "7.0.8",
"@semantic-release/release-notes-generator": "^9.0.1",
"@types/react": "^17.0.0",
"autoprefixer": "^9.7.6",
"babel-preset-preact": "^2.0.0",
"conventional-changelog-conventionalcommits": "4.4.0",
"cssnano": "^4.1.10",
"dotenv": "^8.2.0",
"eslint": "^7.19.0",
"mocha": "^8.1.3",
"mongodb": "^3.5.9",
"mssql": "^6.2.1",
@@ -92,13 +94,17 @@
"puppeteer-extra-plugin-stealth": "^2.6.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"standard": "^16.0.3"
"ts-standard": "^10.0.0",
"typescript": "^4.1.3"
},
"standard": {
"ts-standard": {
"project": "./tsconfig.json",
"ignore": [
"test/",
"pages/",
"components/"
"next-env.d.ts"
],
"globals": [
"fetch"
]
}
}

View File

@@ -8,10 +8,10 @@ export default function Page () {
<p><em>You must be signed in to see responses.</em></p>
<h2>Session</h2>
<p>/api/examples/session</p>
<iframe src="/api/examples/session"/>
<iframe src='/api/examples/session' />
<h2>JSON Web Token</h2>
<p>/api/examples/jwt</p>
<iframe src="/api/examples/jwt"/>
<iframe src='/api/examples/jwt' />
</Layout>
)
}
}

View File

@@ -1,92 +1,43 @@
import NextAuth from "next-auth"
import Providers from "next-auth/providers"
import NextAuth from 'next-auth'
import Providers from 'next-auth/providers'
export default NextAuth({
// https://next-auth.js.org/configuration/providers
providers: [
Providers.GitHub({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
clientSecret: process.env.GITHUB_SECRET
}),
Providers.Auth0({
clientId: process.env.AUTH0_ID,
clientSecret: process.env.AUTH0_SECRET,
domain: process.env.AUTH0_DOMAIN,
protection: "pkce"
protection: 'pkce'
}),
Providers.Twitter({
clientId: process.env.TWITTER_ID,
clientSecret: process.env.TWITTER_SECRET,
clientSecret: process.env.TWITTER_SECRET
}),
Providers.Credentials({
name: 'Credentials',
credentials: {
password: { label: 'Password', type: 'password' }
},
async authorize (credentials) {
if (credentials.password === 'password') {
return {
id: 1,
name: 'Fill Murray',
email: 'bill@fillmurray.com',
image: 'https://www.fillmurray.com/64/64'
}
}
return null
}
})
],
// Database optional. MySQL, Maria DB, Postgres and MongoDB are supported.
// https://next-auth.js.org/configuration/databases
//
// Notes:
// * You must to install an appropriate node_module for your database
// * The Email provider requires a database (OAuth providers do not)
// The secret should be set to a reasonably long random string.
// It is used to sign cookies and to sign and encrypt JSON Web Tokens, unless
// a separate secret is defined explicitly for encrypting the JWT.
session: {
// Use JSON Web Tokens for session instead of database sessions.
// This option can be used with or without a database for users/accounts.
// Note: `jwt` is automatically set to `true` if no database is specified.
jwt: true,
// Seconds - How long until an idle session expires and is no longer valid.
// maxAge: 30 * 24 * 60 * 60, // 30 days
// Seconds - Throttle how frequently to write to database to extend a session.
// Use it to limit write operations. Set to 0 to always update the database.
// Note: This option is ignored if using JSON Web Tokens
// updateAge: 24 * 60 * 60, // 24 hours
},
// JSON Web tokens are only used for sessions if the `jwt: true` session
// option is set - or by default if no database is specified.
// https://next-auth.js.org/configuration/options#jwt
jwt: {
encryption: true,
secret: process.env.SECRET,
// A secret to use for key generation (you should set this explicitly)
// secret: 'INp8IvdIyeMcoGAgFGoA61DdBglwwSqnXJZkgz8PSnw',
// Set to true to use encryption (default: false)
// encryption: true,
// You can define your own encode/decode functions for signing and encryption
// if you want to override the default behaviour.
// encode: async ({ secret, token, maxAge }) => {},
// decode: async ({ secret, token, maxAge }) => {},
secret: process.env.SECRET
},
// You can define custom pages to override the built-in pages.
// The routes shown here are the default URLs that will be used when a custom
// pages is not specified for that route.
// https://next-auth.js.org/configuration/pages
pages: {
// signIn: '/api/auth/signin', // Displays signin buttons
// signOut: '/api/auth/signout', // Displays form with sign out button
// error: '/api/auth/error', // Error code passed in query string as ?error=
// verifyRequest: '/api/auth/verify-request', // Used for check email page
// newUser: null // If set, new users will be directed here on first sign in
},
// Callbacks are asynchronous functions you can use to control what happens
// when an action is performed.
// https://next-auth.js.org/configuration/callbacks
callbacks: {
// signIn: async (user, account, profile) => { return Promise.resolve(true) },
// redirect: async (url, baseUrl) => { return Promise.resolve(baseUrl) },
// session: async (session, user) => { return Promise.resolve(session) },
// jwt: async (token, user, account, profile, isNewUser) => { return Promise.resolve(token) }
},
// Events are useful for logging
// https://next-auth.js.org/configuration/events
events: {},
// Enable debug messages in the console if you are having problems
debug: false,
debug: false
})

View File

@@ -1,5 +1,5 @@
// This is an example of how to read a JSON Web Token from an API route
import jwt from "next-auth/jwt"
import jwt from 'next-auth/jwt'
const secret = process.env.SECRET

View File

@@ -9,4 +9,4 @@ export default async (req, res) => {
} else {
res.send({ error: 'You must be sign in to view the protected content on this page.' })
}
}
}

View File

@@ -4,4 +4,4 @@ import { getSession } from 'next-auth/client'
export default async (req, res) => {
const session = await getSession({ req })
res.send(JSON.stringify(session, null, 2))
}
}

View File

@@ -19,4 +19,4 @@ export default function Page () {
</p>
</Layout>
)
}
}

60
pages/credentials.js Normal file
View File

@@ -0,0 +1,60 @@
import * as React from 'react'
import { signIn, signOut, useSession } from 'next-auth/client'
import Layout from 'components/layout'
export default function Page () {
const [response, setResponse] = React.useState(null)
const handleLogin = (options) => async () => {
if (options.redirect) {
return signIn('credentials', options)
}
const response = await signIn('credentials', options)
setResponse(response)
if (response.ok) {
window.alert('Manually refreshing to update session, if login was successful')
window.location.reload()
}
}
const handleLogout = (options) => async () => {
if (options.redirect) {
return signOut(options)
}
const response = await signOut(options)
setResponse(response)
if (response.ok) {
window.alert('Manually refreshing to update session, if logout was successful')
window.location.reload()
}
}
const [session] = useSession()
if (session) {
return (
<Layout>
<h1>Test different flows for Credentials logout</h1>
<span className='spacing'>Default:</span>
<button onClick={handleLogout({ redirect: true })}>Logout</button><br />
<span className='spacing'>No redirect:</span>
<button onClick={handleLogout({ redirect: false })}>Logout</button><br />
<p>Response:</p>
<pre style={{ background: '#eee', padding: 16 }}>{JSON.stringify(response, null, 2)}</pre>
</Layout>
)
}
return (
<Layout>
<h1>Test different flows for Credentials login</h1>
<span className='spacing'>Default:</span>
<button onClick={handleLogin({ redirect: true, password: 'password' })}>Login</button><br />
<span className='spacing'>No redirect:</span>
<button onClick={handleLogin({ redirect: false, password: 'password' })}>Login</button><br />
<span className='spacing'>No redirect, wrong password:</span>
<button onClick={handleLogin({ redirect: false, password: '' })}>Login</button>
<p>Response:</p>
<pre style={{ background: '#eee', padding: 16 }}>{JSON.stringify(response, null, 2)}</pre>
</Layout>
)
}

View File

@@ -4,7 +4,7 @@ export default function Page () {
return (
<Layout>
<p>
This is an example site to demonstrate how to use <a href={`https://next-auth.js.org`}>NextAuth.js</a> for authentication.
This is an example site to demonstrate how to use <a href='https://next-auth.js.org'>NextAuth.js</a> for authentication.
</p>
<h2>Terms of Service</h2>
<p>
@@ -27,4 +27,4 @@ export default function Page () {
</p>
</Layout>
)
}
}

View File

@@ -5,7 +5,7 @@ import AccessDenied from '../components/access-denied'
export default function Page ({ content, session }) {
// If no session exists, display access denied message
if (!session) { return <Layout><AccessDenied/></Layout> }
if (!session) { return <Layout><AccessDenied /></Layout> }
// If session exists, display content
return (
@@ -16,7 +16,7 @@ export default function Page ({ content, session }) {
)
}
export async function getServerSideProps(context) {
export async function getServerSideProps (context) {
const session = await getSession(context)
let content = null

View File

@@ -4,24 +4,24 @@ import Layout from '../components/layout'
import AccessDenied from '../components/access-denied'
export default function Page () {
const [ session, loading ] = useSession()
const [ content , setContent ] = useState()
const [session, loading] = useSession()
const [content, setContent] = useState()
// Fetch content from protected route
useEffect(()=>{
useEffect(() => {
const fetchData = async () => {
const res = await fetch('/api/examples/protected')
const json = await res.json()
if (json.content) { setContent(json.content) }
}
fetchData()
},[session])
}, [session])
// When rendering client side don't display anything until loading is complete
if (typeof window !== 'undefined' && loading) return null
// If no session exists, display access denied message
if (!session) { return <Layout><AccessDenied/></Layout> }
if (!session) { return <Layout><AccessDenied /></Layout> }
// If session exists, display content
return (
@@ -30,4 +30,4 @@ export default function Page () {
<p><strong>{content}</strong></p>
</Layout>
)
}
}

View File

@@ -1,4 +1,4 @@
import { useSession, getSession } from 'next-auth/client'
import { getSession } from 'next-auth/client'
import Layout from '../components/layout'
export default function Page () {
@@ -6,7 +6,6 @@ export default function Page () {
// populated on render without needing to go through a loading stage.
// This is possible because of the shared context configured in `_app.js` that
// is used by `useSession()`.
const [ session, loading ] = useSession()
return (
<Layout>
@@ -29,7 +28,7 @@ export default function Page () {
}
// Export the `session` prop to use sessions with Server Side Rendering
export async function getServerSideProps(context) {
export async function getServerSideProps (context) {
return {
props: {
session: await getSession(context)

View File

@@ -10,7 +10,6 @@
//
// We use HTTP POST requests with CSRF Tokens to protect against CSRF attacks.
/* global fetch:false */
import { useState, useEffect, useContext, createContext, createElement } from 'react'
import logger from '../lib/logger'
import parseUrl from '../lib/parse-url'
@@ -233,62 +232,101 @@ const _useSessionHook = (session) => {
return [data, loading]
}
// Client side method
export const signIn = async (provider, args = {}, authorizationParams = {}) => {
/**
* Client-side method to initiate a signin flow
* or send the user to the signin page listing all possible providers.
* (Automatically adds the CSRF token to the request)
* @see https://next-auth.js.org/getting-started/client#signin
* @param {string} [provider]
* @param {SignInOptions} [options]
* @param {object} [authorizationParams]
* @return {Promise<SignInResponse | undefined>}
* @typedef {{callbackUrl?: string; redirect?: boolean}} SignInOptions
* @typedef {{error: string | null; status: number; ok: boolean}} SignInResponse
*/
export async function signIn (provider, options = {}, authorizationParams = {}) {
const {
callbackUrl = window.location,
redirect = true
} = options
const baseUrl = _apiBaseUrl()
const callbackUrl = args?.callbackUrl ?? window.location
const providers = await getProviders()
// Redirect to sign in page if no valid provider specified
if (!(provider in providers)) {
// If Provider not recognized, redirect to sign in page
window.location = `${baseUrl}/signin?callbackUrl=${encodeURIComponent(callbackUrl)}`
} else {
const signInUrl = (providers[provider].type === 'credentials')
? `${baseUrl}/callback/${provider}`
: `${baseUrl}/signin/${provider}`
return
}
const isCredentials = providers[provider].type === 'credentials'
const signInUrl = isCredentials
? `${baseUrl}/callback/${provider}`
: `${baseUrl}/signin/${provider}`
// If is any other provider type, POST to provider URL with CSRF Token,
// callback URL and any other parameters supplied.
const fetchOptions = {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: _encodedForm({
...args,
csrfToken: await getCsrfToken(),
callbackUrl: callbackUrl,
json: true
})
}
const _signInUrl = `${signInUrl}?${_encodedForm(authorizationParams)}`
const res = await fetch(_signInUrl, fetchOptions)
const data = await res.json()
// If is any other provider type, POST to provider URL with CSRF Token,
// callback URL and any other parameters supplied.
const fetchOptions = {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
...options,
csrfToken: await getCsrfToken(),
callbackUrl,
json: true
})
}
const _signInUrl = `${signInUrl}?${new URLSearchParams(authorizationParams)}`
const res = await fetch(_signInUrl, fetchOptions)
const data = await res.json()
if (redirect || !isCredentials) {
window.location = data.url ?? callbackUrl
return
}
const error = new URL(data.url).searchParams.get('error')
return {
error,
status: res.status,
ok: res.ok
}
}
// Client side method
export const signOut = async (args = {}) => {
const callbackUrl = args.callbackUrl ?? window.location
/**
* Signs the user out, by removing the session cookie.
* (Automatically adds the CSRF token to the request)
* @param {SignOutOptions} [options]
* @returns {Promise<{url?: string} | undefined>}
* @typedef {{callbackUrl?: string; redirect?: boolean;}} SignOutOptions
*/
export async function signOut (options = {}) {
const {
callbackUrl = window.location,
redirect = true
} = options
const baseUrl = _apiBaseUrl()
const fetchOptions = {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: _encodedForm({
body: new URLSearchParams({
csrfToken: await getCsrfToken(),
callbackUrl: callbackUrl,
callbackUrl,
json: true
})
}
const res = await fetch(`${baseUrl}/signout`, fetchOptions)
const data = await res.json()
_sendMessage({ event: 'session', data: { trigger: 'signout' } })
window.location = data.url ?? callbackUrl
if (redirect) {
window.location = data.url ?? callbackUrl
return
}
return data
}
// Provider to wrap the app in to make session data available globally
@@ -321,12 +359,6 @@ const _apiBaseUrl = () => {
}
}
const _encodedForm = (formData) => {
return Object.keys(formData).map((key) => {
return encodeURIComponent(key) + '=' + encodeURIComponent(formData[key])
}).join('&')
}
const _sendMessage = (message) => {
if (typeof localStorage !== 'undefined') {
const timestamp = Math.floor(new Date().getTime() / 1000)

91
src/server/index.d.ts vendored Normal file
View File

@@ -0,0 +1,91 @@
import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
import { CallbacksOptions } from './lib/callbacks'
import { CookiesOptions } from './lib/cookie'
import { EventsOptions } from './lib/events'
export interface Provider {
id: string
name: string
type: string
version: string
params: Record<string, unknown>
scope: string
accessTokenUrl: string
authorizationUrl: string
profileUrl?: string
grant_type?: string
profile?: (profile: any) => Promise<any>
}
/** @docs https://next-auth.js.org/configuration/options */
export interface NextAuthOptions {
/** @docs https://next-auth.js.org/configuration/options#theme */
theme?: 'auto' | 'dark' | 'light'
/** @docs https://next-auth.js.org/configuration/options#providers */
providers: Provider[]
/** @docs https://next-auth.js.org/configuration/options#database */
database?: any
/** @docs https://next-auth.js.org/configuration/options#secret */
secret?: any
/** @docs https://next-auth.js.org/configuration/options#session */
session?: any
/** @docs https://next-auth.js.org/configuration/options#jwt */
jwt?: any
/** @docs https://next-auth.js.org/configuration/options#pages */
pages?: {
signIn?: string
signOut?: string
/** Error code passed in query string as ?error= */
error?: string
verifyRequest?: string
/** If set, new users will be directed here on first sign in */
newUser?: string
}
/**
* Callbacks are asynchronous functions you can use to control what happens when an action is performed.
* Callbacks are extremely powerful, especially in scenarios involving JSON Web Tokens as
* they allow you to implement access controls without a database and
* to integrate with external databases or APIs.
* @docs https://next-auth.js.org/configuration/options#callbacks
*/
callbacks?: CallbacksOptions
/** @docs https://next-auth.js.org/configuration/options#events */
events?: EventsOptions
/** @docs https://next-auth.js.org/configuration/options#adapter */
adapter?: any
/** @docs https://next-auth.js.org/configuration/options#debug */
debug?: boolean
/** @docs https://next-auth.js.org/configuration/options#usesecurecookies */
useSecureCookies?: boolean
/** @docs https://next-auth.js.org/configuration/options#cookies */
cookies?: CookiesOptions
}
/** Options that are the same both in internal and user provided options. */
export type NextAuthSharedOptions = 'pages' | 'jwt' | 'events' | 'callbacks' | 'cookies' | 'secret' | 'adapter' | 'theme' | 'debug'
export interface NextAuthInternalOptions extends Pick<NextAuthOptions, NextAuthSharedOptions> {
pkce?: {
code_verifier?: string
/**
* Could be `"plain"`, but not recommended.
* We ignore it for now.
* @spec https://tools.ietf.org/html/rfc7636#section-4.2.
*/
code_challenge_method?: 'S256'
}
provider?: Provider
baseUrl?: string
basePath?: string
action?: string
csrfToken?: string
}
export interface NextAuthRequest extends NextApiRequest {
options: NextAuthInternalOptions
}
export interface NextAuthResponse extends NextApiResponse {}
export declare function NextAuthHandler (req: NextAuthRequest, res: NextAuthResponse, options: NextAuthOptions): ReturnType<NextApiHandler>
export declare function NextAuthHandler (options: NextAuthOptions): ReturnType<NextApiHandler>

View File

@@ -21,6 +21,11 @@ if (!process.env.NEXTAUTH_URL) {
logger.warn('NEXTAUTH_URL', 'NEXTAUTH_URL environment variable not set')
}
/**
* @param {import("next").NextApiRequest} req
* @param {import("next").NextApiResponse} res
* @param {import(".").NextAuthOptions} userOptions
*/
async function NextAuthHandler (req, res, userOptions) {
// If debug enabled, set ENV VAR so that logger logs debug messages
if (userOptions.debug) {

7
src/server/lib/callbacks.d.ts vendored Normal file
View File

@@ -0,0 +1,7 @@
export interface CallbacksOptions {
signIn?: (user: any, account: any, profile: any) => Promise<never | string>
jwt?: (token: any, user: any, account: any, profile: any, isNewUser?: boolean) => Promise<any>
session?: (session: any, userOrToken: any) => Promise<any>
redirect?: (url: string, baseUrl: string) => Promise<string>
}

16
src/server/lib/cookie.d.ts vendored Normal file
View File

@@ -0,0 +1,16 @@
export interface CookieOption {
name: string
options: {
httpOnly: boolean
sameSite: string
path?: string
secure: boolean
}
}
export interface CookiesOptions {
sessionToken: CookieOption
callbackUrl: CookieOption
csrfToken: CookieOption
pkceCodeVerifier: CookieOption
}

View File

@@ -110,6 +110,7 @@ function _serialize (name, val, options) {
* For more on prefixes see https://googlechrome.github.io/samples/cookie-prefixes/
*
* @TODO Review cookie settings (names, options)
* @return {import("./cookie").CookiesOptions}
*/
export function defaultCookies (useSecureCookies) {
const cookiePrefix = useSecureCookies ? '__Secure-' : ''

12
src/server/lib/events.d.ts vendored Normal file
View File

@@ -0,0 +1,12 @@
export type EventType=
| 'signIn'
| 'signOut'
| 'createUser'
| 'updateUser'
| 'linkAccount'
| 'session'
| 'error'
export type EventCallback = (message: any) => Promise<void>
export type EventsOptions = Partial<Record<EventType, EventCallback>>

View File

@@ -3,6 +3,7 @@ import oAuthClient from './client'
import logger from '../../../lib/logger'
import { OAuthCallbackError } from '../../../lib/errors'
/** @param {import("../..").NextAuthRequest} req */
export default async function oAuthCallback (req) {
const { provider, pkce } = req.options
const client = oAuthClient(provider)
@@ -89,7 +90,7 @@ export default async function oAuthCallback (req) {
* refresh_token?: string
* id_token?: string
* }
* provider: object
* provider: import("../..").Provider
* user?: object
* }} profileParams
*/

View File

@@ -7,6 +7,7 @@ import { sign as jwtSign } from 'jsonwebtoken'
* @TODO Refactor to remove dependancy on 'oauth' package
* It is already quite monkey patched, we don't use all the features and and it
* would be easier to maintain if all the code was native to next-auth.
* @param {import("../..").Provider} provider
*/
export default function oAuthClient (provider) {
if (provider.version?.startsWith('2.')) {
@@ -86,6 +87,9 @@ export default function oAuthClient (provider) {
/**
* Ported from https://github.com/ciaranj/node-oauth/blob/a7f8a1e21c362eb4ed2039431fb9ac2ae749f26a/lib/oauth2.js
* @param {string} code
* @param {import("../..").Provider} provider
* @param {string | undefined} codeVerifier
*/
async function getOAuth2AccessToken (code, provider, codeVerifier) {
const url = provider.accessTokenUrl
@@ -184,6 +188,9 @@ async function getOAuth2AccessToken (code, provider, codeVerifier) {
*
* 18/08/2020 @robertcraigie added results parameter to pass data to an optional request preparer.
* e.g. see providers/bungie
* @param {import("../..").Provider} provider
* @param {string} accessToken
* @param {any} results
*/
async function getOAuth2 (provider, accessToken, results) {
let url = provider.profileUrl

View File

@@ -8,7 +8,11 @@ const PKCE_LENGTH = 64
const PKCE_CODE_CHALLENGE_METHOD = 'S256' // can be 'plain', not recommended https://tools.ietf.org/html/rfc7636#section-4.2
const PKCE_MAX_AGE = 60 * 15 // 15 minutes in seconds
/** Adds `code_verifier` to `req.options.pkce`, and removes the corresponding cookie */
/**
* Adds `code_verifier` to `req.options.pkce`, and removes the corresponding cookie
* @param {import("../..").NextAuthRequest} req
* @param {import("../..").NextAuthResponse} res
*/
export async function handleCallback (req, res) {
const { cookies, provider, baseUrl, basePath } = req.options
try {
@@ -38,7 +42,11 @@ export async function handleCallback (req, res) {
}
}
/** Adds `code_challenge` and `code_challenge_method` to `req.options.pkce`. */
/**
* Adds `code_challenge` and `code_challenge_method` to `req.options.pkce`.
* @param {import("../..").NextAuthRequest} req
* @param {import("../..").NextAuthResponse} res
*/
export async function handleSignin (req, res) {
const { cookies, provider, baseUrl, basePath } = req.options
try {

View File

@@ -6,6 +6,8 @@ import { OAuthCallbackError } from '../../../lib/errors'
* For OAuth 2.0 flows, if the provider supports state,
* check if state matches the one sent on signin
* (a hash of the NextAuth.js CSRF token).
* @param {import("../..").NextAuthRequest} req
* @param {import("../..").NextAuthResponse} res
*/
export async function handleCallback (req, res) {
const { csrfToken, provider, baseUrl, basePath } = req.options
@@ -31,7 +33,11 @@ export async function handleCallback (req, res) {
}
}
/** Adds CSRF token to the authorizationParams. */
/**
* Adds CSRF token to the authorizationParams.
* @param {import("../..").NextAuthRequest} req
* @param {import("../..").NextAuthResponse} res
*/
export async function handleSignin (req, res) {
const { provider, baseUrl, basePath, csrfToken } = req.options
try {

View File

@@ -1,6 +1,7 @@
import oAuthClient from '../oauth/client'
import logger from '../../../lib/logger'
/** @param {import("../..").NextAuthRequest} req */
export default async function getAuthorizationUrl (req) {
const { provider } = req.options

View File

@@ -4,7 +4,11 @@ import * as cookie from '../lib/cookie'
import logger from '../../lib/logger'
import dispatchEvent from '../lib/dispatch-event'
/** Handle callbacks from login services */
/**
* Handle callbacks from login services
* @param {import("..").NextAuthRequest} req
* @param {import("..").NextAuthResponse} res
*/
export default async function callback (req, res) {
const {
provider,
@@ -217,12 +221,12 @@ export default async function callback (req, res) {
} else if (provider.type === 'credentials' && req.method === 'POST') {
if (!useJwtSession) {
logger.error('CALLBACK_CREDENTIALS_JWT_ERROR', 'Signin in with credentials is only supported if JSON Web Tokens are enabled')
return res.redirect(`${baseUrl}${basePath}/error?error=Configuration`)
return res.status(500).redirect(`${baseUrl}${basePath}/error?error=Configuration`)
}
if (!provider.authorize) {
logger.error('CALLBACK_CREDENTIALS_HANDLER_ERROR', 'Must define an authorize() handler to use credentials authentication provider')
return res.redirect(`${baseUrl}${basePath}/error?error=Configuration`)
return res.status(500).redirect(`${baseUrl}${basePath}/error?error=Configuration`)
}
const credentials = req.body
@@ -231,7 +235,7 @@ export default async function callback (req, res) {
try {
userObjectReturnedFromAuthorizeHandler = await provider.authorize(credentials)
if (!userObjectReturnedFromAuthorizeHandler) {
return res.redirect(`${baseUrl}${basePath}/error?error=CredentialsSignin&provider=${encodeURIComponent(provider.id)}`)
return res.status(401).redirect(`${baseUrl}${basePath}/error?error=CredentialsSignin&provider=${encodeURIComponent(provider.id)}`)
}
} catch (error) {
if (error instanceof Error) {
@@ -246,7 +250,7 @@ export default async function callback (req, res) {
try {
const signInCallbackResponse = await callbacks.signIn(user, account, credentials)
if (signInCallbackResponse === false) {
return res.redirect(`${baseUrl}${basePath}/error?error=AccessDenied`)
return res.status(403).redirect(`${baseUrl}${basePath}/error?error=AccessDenied`)
}
} catch (error) {
if (error instanceof Error) {

View File

@@ -2,6 +2,8 @@
* Return a JSON object with a list of all OAuth providers currently configured
* and their signin and callback URLs. This makes it possible to automatically
* generate buttons for all providers when rendering client side.
* @param {import("..").NextAuthRequest} req
* @param {import("..").NextAuthResponse} res
*/
export default function providers (req, res) {
const { providers } = req.options

48
tsconfig.json Normal file
View File

@@ -0,0 +1,48 @@
{
"compilerOptions": {
"strictNullChecks": true,
"baseUrl": ".",
"paths": {
"next-auth": [
"./src/server"
],
"next-auth/adapters": [
"./src/adapters"
],
"next-auth/client": [
"./src/client"
],
"next-auth/jwt": [
"./src/lib/jwt"
],
"next-auth/providers": [
"./src/providers"
]
},
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
],
"exclude": [
"node_modules"
]
}