forked from nextauthjs/next-auth
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: improve OAuth provider configuration (nextauthjs#2411)
> 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 nextauthjs#1846, Closes nextauthjs#1605, Closes nextauthjs#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`](https://github.com/panva/node-openid-client/blob/51dc47d9ac619b71cd1c983b0be750a12bbae008/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.
- Loading branch information
1 parent
f06e4d2
commit 7c65bda
Showing
65 changed files
with
742 additions
and
714 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Source: https://stackoverflow.com/a/34749873/5364135 | ||
|
||
/** | ||
* Simple object check. | ||
* @param item | ||
* @returns {boolean} | ||
*/ | ||
function isObject(item) { | ||
return item && typeof item === "object" && !Array.isArray(item) | ||
} | ||
|
||
/** | ||
* Deep merge two objects. | ||
* @param target | ||
* @param ...sources | ||
*/ | ||
export function merge(target, ...sources) { | ||
if (!sources.length) return target | ||
const source = sources.shift() | ||
|
||
if (isObject(target) && isObject(source)) { | ||
for (const key in source) { | ||
if (isObject(source[key])) { | ||
if (!target[key]) Object.assign(target, { [key]: {} }) | ||
merge(target[key], source[key]) | ||
} else { | ||
Object.assign(target, { [key]: source[key] }) | ||
} | ||
} | ||
} | ||
|
||
return merge(target, ...sources) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,19 @@ | ||
export default function FortyTwo(options) { | ||
return { | ||
id: '42-school', | ||
name: '42 School', | ||
type: 'oauth', | ||
version: '2.0', | ||
params: { grant_type: 'authorization_code' }, | ||
accessTokenUrl: 'https://api.intra.42.fr/oauth/token', | ||
authorizationUrl: | ||
'https://api.intra.42.fr/oauth/authorize?response_type=code', | ||
profileUrl: 'https://api.intra.42.fr/v2/me', | ||
profile: (profile) => ({ | ||
id: profile.id, | ||
email: profile.email, | ||
image: profile.image_url, | ||
name: profile.usual_full_name, | ||
}), | ||
...options, | ||
id: "42-school", | ||
name: "42 School", | ||
type: "oauth", | ||
authorization: "https://api.intra.42.fr/oauth/authorize", | ||
token: "https://api.intra.42.fr/oauth/token", | ||
userinfo: "https://api.intra.42.fr/v2/me", | ||
profile(profile) { | ||
return { | ||
id: profile.id, | ||
name: profile.usual_full_name, | ||
email: profile.email, | ||
image: profile.image_url, | ||
} | ||
}, | ||
options, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.