-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor: Providers create config instead of client #186
Conversation
This looks good so far! Let's make this easier. Let's move to configs and drop the current instances as arguments. This is a breaking change, but it is fine as this module is still in beta. We can just be sure to provide adequate documentation of the change. Also, please don't forget to run |
Thanks for the feedback. So you want to just ditch the existing providers (that return a client) and replace them with the config returning fns instead? |
Yep, that sounds good 👍🏾 |
@iuioiua ok, I've done the full refactor now, ready for review, have not tested in the wild yet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All oauth2_client interaction is abstracted away entirely in this file now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a template for new providers, it's not intended to ever be imported directly.
Should probably document this.
Documentation definitely need a good review |
Actually, I'd very much appreciate if this PR only took care of the objective, and nothing else. The changes in a PR should be single-purpose and this PR includes a heap of additional changes that haven't yet been discussed. I'm happy to discuss these suggestions in a new issue. |
The majority of the changes are to support passing config instead of client around. I'm happy to discuss, but I'm not sure what specifically falls outside. |
clientSecret: string; | ||
|
||
/** The custom domain of the authorization server, if supported by the provider. */ | ||
domain?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added this, as it's a common case, not juist for auth providers such as Okta & Auth0, but also for services that allow self deployment, eg. GitLab (although the gitlab provider doesn't currently support this, it probably should in the future).
* Default scopes to request, this should be the minimal read scopes for sign-in and | ||
* user identity (eg. id, email), it should also include scopes for OpenID Connect if the provider supports it. | ||
*/ | ||
scope: string[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I felt it made more sense to keep the config object flat, and move scope up, out of the 'defaults' prop, which is really an implementation detail within oauth2_client, and doesn't make a lot of sense in the config for this.
Also, I felt it would provide a better DX for a provider to supply a reasonable default scope so it's easier to get going with kv_oauth, ie. no need to go off hunting for scopes just for some basic user details.
This default scope is completely overridden if supplied by the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably one of the more major changes, introducing the config and some other types directly into kv_oauth. The main reasoning is to detach it from the hard oauth2_client dependency, and to provide a config more attuned to the needs of kv_oauth and its user over the needs of oauth2_client.
For example, bumping scope up, which felt out of place inside 'defaults' whilst refactoring, and ditching the additional request options, which felt very specific to oauth2_client and unnecessary for kv_oauth.
The config type is also broken down by source of config, so it's easier to compose the input and output types of the create config functions.
} from "./types.ts"; | ||
import { assert } from "https://deno.land/[email protected]/assert/assert.ts"; | ||
|
||
export function createOAuthConfig( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should probably jsdoc this!
But this adds consistency to the providers by combining the hardcoded config with the env vars and user supplied config in a consistent manner.
@@ -38,13 +39,6 @@ addEventListener("beforeunload", async () => { | |||
await kv.close(); | |||
}); | |||
|
|||
// OAuth 2.0 session | |||
export interface OAuthSession { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I move this into types, so that the internal oauth2_client.ts can reference it without depending on this core module from which it doesn't required anything else.
type OAuth2ClientConfig, | ||
OAuth2ResponseError, | ||
type Tokens, | ||
} from "https://deno.land/x/[email protected]/mod.ts"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed because nothing else requires this other than the _internal/oauth2_client.ts module
if (createOAuth2ClientFn === undefined) { | ||
throw new Error("Provider not found"); | ||
} | ||
function getOAuthConfig() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to rejig this a little so that the test case could set the necessary env vars.
*/ | ||
export interface OAuthProviderInfo { | ||
/** The name of the provider (single PascalCase name that matches the function name and uppercase env var prefix) */ | ||
name: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added this additional info for two purposes:
- The env var prefix is derived from this (uppercase).
- The user can support multiple providers in their app, and switch UI features or API calls based on this value without having to keep a separate var of the provider chosen, the demo actually demonstrates this nicely.
I think this PR should take care of replacing Anything outside of the
Additionally, we should export |
Fair points, I don't entirely agree with being so closely tied to the oauth2_client API, but we can work through this. I'd like to ask for consideration of one compromise: a |
Ok, let's see how that looks in a separate PR 👍🏾 |
I'm unsure if I was clear, but it'd be great if this PR could continue and only migrate arguments from |
What I mean is that it may be simpler to rebranch and cherry pick those parts, resulting in a new PR. I'm tied up on other things again atm, I'll see what I can squeeze in. |
Fair enough. I'll submit a PR tomorrow which handles the migration and ping you once done 🙂 |
Closing in favour of #207. Thank you, either way, Mark! |
This is an idealistic overhaul at replacing the OAuth2Client being passed around with a configuration, along with a few other refactors to plug leaky abstractions and future proof against potential changes or alternatives in oauth2_client API.
As mentioned in the discussions below it probably goes beyond the remit of the single issue it was meant to originally address, so I'm update this abstract to reflect that, raising new issues to cover the additional refactors and referencing them here. It's likely this PR will get closed with no further change and new PR's later raised, with that in mind I've also switched this back to a Draft.
Closes #174
Closes #193
Closes #195
Closes #196
Closes #197