Adds a new way to import providers for modularity and better tree-shaking.
BREAKING CHANGE:
Providers now have to be imported one-by-one:
Example:
```diff
- import Provider from "next-auth/providers"
- Providers.Auth0({...})
+ import Auth0Provider from "next-auth/providers/auth0"
+ Auth0Provider({...})
```
> This touches on all OAuth providers, so there is a big potential for breaking by default. We have let new providers be added for contributors' specific needs, but from now on, we will require a more strict default on all new providers, so the basic behavior is predictable for everyone.
⚠ Unfortunately, we will not have the capacity to test each and every provider that has been added to the default providers, but we will do our best to test the most popular ones. (@ndom91 has worked on setting up the infrastructure for this). If you wish to make sure that the provider you are using will stay working, please reach out with your concerns and tell us how can you help us test that particular provider in the future. 🙏
That said, I will try my best to not break ANY of the currently built-in providers, or at least make the migration super easy. So hopefully, you won't have to change anything. It will most probably affect you if you defined a custom provider though.
We will monitor the default configuration much more closely, so the behavior will be more consistent across providers by default.
Closes#1846, Closes#1605, Closes#1607
BREAKING CHANGES:
Basecamp provider is removed. See the explanation [here](https://github.com/basecamp/api/blob/master/sections/authentication.md#on-authenticating-users-via-oauth)
**ALL** OAuth providers' `profile` callback is expected to only return these fields by default from now on: `id`, `name`, `email`, and `image` at most. Any of these missing values should be set to `null`.
The following new options are available:
1. `authorization` (replaces `authorizationUrl`, `authorizationParams`, `scope`)
2. `token` replaces (`accessTokenUrl`, `headers`, `params`)
3. `userinfo` (replaces `profileUrl`)
These three options map nicely to the OAuth spec's three endpoints for
1. initiating the login flow
2. retrieve OAuth tokens
3. retrieve user information
They all take the form of `EndpointHandler`:
```ts
type EndpointRequest<C, R> = (
context: C & {
/** `openid-client` Client */
client: Client
/** Provider is passed for convenience, ans also contains the `callbackUrl`. */
provider: OAuthConfig & {
signinUrl: string
callbackUrl: string
}
}
) => Awaitable<R>
/** Gives granular control of the request to the given endpoint */
type AdvancedEndpointHandler<P extends UrlParams, C, R> = {
/** Endpoint URL. Can contain parameters. Optionally, you can use `params`*/
url?: string
/** These will be prepended to the `url` */
params?: P
/**
* Control the corresponding OAuth endpoint request completely.
* Useful if your provider relies on some custom behavior
* or it diverges from the OAuth spec.
*
* - ⚠ **This is an advanced option.**
* You should **try to avoid using advanced options** unless you are very comfortable using them.
*/
request?: EndpointRequest<C, R>
}
/** Either an URL (containing all the parameters) or an object with more granular control. */
type EndpointHandler<P extends UrlParams, C = any, R = any> =
| string
| AdvancedEndpointHandler<P, C, R>
```
In case of `authorization`, the `EndpointHandler` can define the `params` as [`AuthorizationParameters`](51dc47d9ac/types/index.d.ts (L108-L143))
> Note: `authorization` does not implement `request` yet. We will have to see if there is demand for it.
From now on, instead of using the `...` spread operator when adding a new built-in provider, the user is expected to add `options` as a property at the end of the default config. This way, we can deep merge the user config with the default one. This is needed to let the user do something like this:
```js
MyProvider({
clientId: "",
clientSecret: "",
authorization: { params: {scope: ""} }
})
```
So even if the default config defines anything in `authorization`, only the user-defined parts will be overridden.
* chore(deps): add openid-client
* chore: merge in next
* refactor(provider): remove redundant requestUrl param
* feat(provider): make profile callback optional
* refactor: use openid-client for OAuth2/OIDC
* refactor: use openidClient in oauth signin handler
* refactor: use openidClient in oauth callback handler
* docs(warn): add async issuer/old config warnings
* chore(deps): remove jsonwebtoken
* chore: add issuer property for testing locally
* chore(dev): import providers one-by-one
* fix(oauth): handle when no user in body/query
* chore(deps): remove pkce-challenge
* chore(dev): change Auth0 protection
* refactor(oauth): simplify pkce/state
* refactor: split OAuth1 client, reduce openid client
will improve API in another PR
* chore: change comment, dev app
* chore: mention OIDC client config discovery
* fix: add new operator when creating OIDC client
* refactor: delete req.query.nextauth after use
* docs(ts): use `TokenSet` from `openid-client`
* chore: simplify/type signin route
* refactor: rename to client-legacy to indicate intnet of maintenance
* chore(deps): try setting `oauth` as optional peer dep
* chore(deps): add `oauth` back as regular dependency
* chore(deps): add @types/oauth as dev dependency
* chore: remove params kept for backwards compatibility
* chore: don't make breaking changes in this PR
* chore(core): use correct TS declarations
* refactor: move files/add more accurate types internally
* chore: remove TODO comment
* chore: catch all errors in authorization URL generation
* docs(readme): add opencollective details to readme
* docs(www): add sponsors to docs footer
* docs(readme): move support under ack
* docs(www): dropped docusaurus link in footer
* Update Fauna Adapter
- added one-liner to explain how to use the setup scripts inside of the Fauna dashboard
- updated the `verification_request_by_token` index name to match what is expected inside of the SDK which is `verification_request_by_token_and_identifier`
* Update Typo
Co-authored-by: Balázs Orbán <info@balazsorban.com>
Co-authored-by: Balázs Orbán <info@balazsorban.com>
Unified API for all of our user-facing methods.
NOTE: `events.error` has been removed. This method has never been called in the core, so it did actually nothing. If you want to log errors to a third-party, check out the [`logger`](https://next-auth.js.org/configuration/options#logger) option instead.
BREAKING CHANGE:
Two event signatures changed to use named params, `signOut` and `updateUser`:
```diff
// [...nextauth].js
...
events: {
- signOut(tokenOrSession),
+ signOut({ token, session }), // token if using JWT, session if DB persisted sessions.
- updateUser(user)
+ updateUser({ user })
}
```
Similar to #2342, this aims to unify the user-facing API and provide an easier way to extend in the future.
In addition, this PR also solves the problem when the `logger.error` method sometimes did not print results, because `Error` instances are not serializable and will be printed as empty objects `"{}"`.
After this PR, we make any `Error` instances serializable as described here: https://iaincollins.medium.com/error-handling-in-javascript-a6172ccdf9afCloses#1602
Achieved by adding a `client: true` flag when logs are coming from the frontend.
BREAKING CHANGE:
The main change is that instead of an unknown number of parameters, the log events have at most two, where the second parameter is usually an object. In the case of the `error` event, it can also be an `Error` instance (that is serializable by `JSON.stringify`). If it is an object, an `Error` instance will be available on `metadata.error`, and `message` will default to `metadata.error.message`. This is done so that an error event always provides some kind of a stack to see where the error happened
```diff
// [...nextauth.js]
import log from "some-logger-service"
...
logger: {
- error(code, ...message) {},
+ error(code, metadata) {},
- warn(code, ...message) {},
+ warn(code) {}
- debug(code, ...message) {}
+ debug(code, metadata) {}
}
```
This change aligns the API with `openid-client`'s `checks` https://github.com/panva/node-openid-client/blob/main/docs/README.md#clientcallbackredirecturi-parameters-checks-extras, a library which we intend to migrate to in the future. Aligning our API early, so people get used to it.
Also, objectively the name `protection` might not have been as clear as I first thought. `checks` better describe the intention.
BREAKING CHANGE:
The `state` option on OAuth providers is now deprecated. Use `checks: ["state"]` instead.
`protections` is renamed to `checks`, here is an example:
```diff
- protection: ["pkce"]
+ checks: ["pkece"]
```
Furthermore, string values are not supported anymore. This is to be able to handle fewer cases internally.
```diff
- checks: "state"
+ checks: ["state"]
```
A living session could be a requirement for specific pages (like dashboards). If it doesn’t exist, the user should be redirected to a page asking them to sign in again.
Sometimes, a user might log out by accident, or by deleting cookies on purpose. If that happens (e.g. on a separate tab), then `useSession({ required: true })` should detect the absence of a session cookie and always return a non-nullable Session object type.
When `required: true` is set, the default behavior will be to redirect the user to the sign-in page. This can be overridden by an `action()` callback:
```js
const session = useSession({
required: true,
action() {
// ....
}
})
if (session.status === "Loading") return "Loading or not authenticated..."
// session.data is always defined here.
```
Co-authored-by: Kristóf Poduszló <kripod@protonmail.com>
Co-authored-by: Lluis Agusti <hi@llu.lu>
BREAKING CHANGE:
The `useSession` hook now returns an object. Here is how to accommodate for this change:
```diff
- const [ session, loading ] = useSession()
+ const { data: session, status } = useSession()
+ const loading = status === "loading"
```
With the new `status` option, you can test states much more clearly.
* (docs) initial issue template forms as per #2271
* (typo) fix grammar and typo
* (forms) make the requested changes
* (chore) delete the old .md files
* (forms) fix type key