Skip to content
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

Passing options from a parent plugin loses the type inference for the ouath2 object #2

Open
alexkahndev opened this issue Aug 26, 2024 · 0 comments

Comments

@alexkahndev
Copy link
Contributor

alexkahndev commented Aug 26, 2024

I am trying to write a library around the plugin to add routes and functionality for a full auth flow with all of the providers. The issue arises from the fact that the user needs to be able to pass the options from the parent plugin to the oauth2 plugin. The type inference that is gained by having the oauth2 object with its specific providers is lost when it is passed as a parameter. The code for the auth wrapper functions as intended however it causes type errors and the type inference of knowing what providers are available is lost. When making a regular auth plugin using a predefined provider like Google works as intended, the issue is you would have to make 48 of those and then keep them updated. The point of my auth library would be to allow any provider listed by the user and give them the routes and functionality for auth.

I created a sample repository to show the problem I'm describing https://github.com/alexkahndev/oauth2-type-example it has two files of note the auth-plugin and google-plugin.

The google-plugin is the individual specified provider and has type safety. In this scenario both Google and GitHub were listed as providers to the oauth2, so it knew what was available for authorize()

oauth2({
	Google: [
	        process.env.GOOGLE_CLIENT_ID,
	        process.env.GOOGLE_CLIENT_SECRET,
	        process.env.GOOGLE_REDIRECT_URI
        ],
        GitHub: ["client_id", "client_secret", "redirect_uri"]
})
const token = await oauth2.authorize("Google");

(property) authorize: <"Google">(provider: "Google") => Promise<OAuth2Tokens>
const token = await oauth2.authorize();

(property) authorize: <"GitHub" | "Google">(provider: "GitHub" | "Google", ...options: never) => Promise<OAuth2Tokens>

The auth-plugin is where the options are taken as a parameter by the parent and passed to oauth2 plugin. This passing of the options object losses the type safety and inference.

export const authPlugin = <Options extends ElysiaOauth2Options>(
	options: Options
) => {
return new Elysia().use(oauth2(options)
}

Authorize still works but it loses inference

const token = await oauth2.authorize("Google");

property) authorize: <"Google">(provider: "Google") => Promise<OAuth2Tokens>
const token = await oauth2.authorize();

property) authorize: <keyof Options>(provider: keyof Options, ...options: GetProviderAuthorizeOptions<keyof Options>) => Promise<Awaited<ReturnType<InstanceType<typeof import("/home/alexkahn/webdev/oauth2-type-example/node_modules/arctic/dist/index")[keyof Options]>["validateAuthorizationCode"]>>>

Refresh and revoke work functionally but produce a type error

const tokens = await oauth2.refresh(
	"Google",
	userRefreshToken.value
);

Argument of type 'string' is not assignable to parameter of type 'Extract<keyof Options, { [K in keyof RefreshableProvidersMap<keyof Options>]: RefreshableProvidersMap<keyof Options>[K] extends never ? never : K; }[keyof Options]>'.ts(2345)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant