[GH-ISSUE #851] Ability to link Generic OAuth provider to account #8467

Closed
opened 2026-04-13 03:32:37 -05:00 by GiteaMirror · 3 comments
Owner

Originally created by @mandrillxx on GitHub (Dec 11, 2024).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/851

Is your feature request related to a problem? Please describe.
I'd like the ability to link a generic oauth provider to an already existing account.

Describe the solution you'd like
Using the generic oauth plugin, i'd like the ability to do:

genericOAuth({
      config: [
        {
          providerId: "roblox",
          clientId: env.ROBLOX_CLIENT_ID,
          clientSecret:
            env.ROBLOX_CLIENT_SECRET,
          discoveryUrl:
            "https://apis.roblox.com/oauth/.well-known/openid-configuration",
        },
      ],
    }),

to then do after, when the user already has an account (they'll already be signed in at this point, and I just want the ability to link the roblox account to their account)

await authClient.linkSocial({
	provider: "roblox",
	callbackURL: "/dashboard?redirect=true",
});

Describe alternatives you've considered
I've tried adding it to the trusted providers

account: {
    accountLinking: {
      enabled: true,
      trustedProviders: ["roblox"],
    },
  },

however this still produces a type error when trying to pass "roblox" as a provider param to linkSocial, and a 400 error on the server.

maybe an officially supported roblox social provider too?

Originally created by @mandrillxx on GitHub (Dec 11, 2024). Original GitHub issue: https://github.com/better-auth/better-auth/issues/851 **Is your feature request related to a problem? Please describe.** I'd like the ability to link a generic oauth provider to an already existing account. **Describe the solution you'd like** Using the generic oauth plugin, i'd like the ability to do: ```ts genericOAuth({ config: [ { providerId: "roblox", clientId: env.ROBLOX_CLIENT_ID, clientSecret: env.ROBLOX_CLIENT_SECRET, discoveryUrl: "https://apis.roblox.com/oauth/.well-known/openid-configuration", }, ], }), ``` to then do after, when the user already has an account (they'll already be signed in at this point, and I just want the ability to link the roblox account to their account) ```ts await authClient.linkSocial({ provider: "roblox", callbackURL: "/dashboard?redirect=true", }); ``` **Describe alternatives you've considered** I've tried adding it to the trusted providers ```ts account: { accountLinking: { enabled: true, trustedProviders: ["roblox"], }, }, ``` however this still produces a type error when trying to pass "roblox" as a provider param to linkSocial, and a 400 error on the server. maybe an officially supported roblox social provider too?
GiteaMirror added the enhancementlocked labels 2026-04-13 03:32:38 -05:00
Author
Owner

@D3visionNL commented on GitHub (Dec 25, 2024):

Same, just found this issue in the Discord and figured I'd give it a bump here too. I want to use BA specifically for the ability to link social accounts so it would be great to have custom Oauth support for the social linking feature.

<!-- gh-comment-id:2561935347 --> @D3visionNL commented on GitHub (Dec 25, 2024): Same, just found this issue in the Discord and figured I'd give it a bump here too. I want to use BA specifically for the ability to link social accounts so it would be great to have custom Oauth support for the social linking feature.
Author
Owner

@D3visionNL commented on GitHub (Dec 27, 2024):

For whoever ends up working on this. Please take into account that certain OAuth providers, like Roblox, do not return an email address. I created a fork to experiment with Roblox integration and ran into this issue. Because BA is hard-coded to expect an email address this threw some errors and because of length checking and/or trimming submitting an empty string does not work either.

All in all this means that for Roblox, or other providers that do not return email addresses to work, there should probably be a way to make the link process ignore the email address existence check as well as the code that checks if the returned email is the same as the email that the user is registered under.

I solved it by doing this, however I am sure that there is a nicer way to do this that would also more easily allow for other providers to be specified.

src/api/routes/callback.ts, line 104

if (!userInfo.email && provider.id !== "roblox") {
	c.context.logger.error(
		"Provider did not return email. This could be due to misconfiguration in the provider settings.",
	);
	return redirectOnError("email_not_found");
}

if (!callbackURL) {
	c.context.logger.error("No callback URL found");
	throw c.redirect(
		`${c.context.baseURL}/error?error=please_restart_the_process`,
	);
}
if (link) {
	if (link.email !== userInfo?.email?.toLowerCase() && provider.id !== "roblox") {
		return redirectOnError("email_doesn't_match");
	}
......
<!-- gh-comment-id:2564065600 --> @D3visionNL commented on GitHub (Dec 27, 2024): For whoever ends up working on this. Please take into account that certain OAuth providers, like Roblox, do not return an email address. I created a fork to experiment with Roblox integration and ran into this issue. Because BA is hard-coded to expect an email address this threw some errors and because of length checking and/or trimming submitting an empty string does not work either. All in all this means that for Roblox, or other providers that do not return email addresses to work, there should probably be a way to make the link process ignore the email address existence check as well as the code that checks if the returned email is the same as the email that the user is registered under. I solved it by doing this, however I am sure that there is a nicer way to do this that would also more easily allow for other providers to be specified. src/api/routes/callback.ts, line 104 ``` if (!userInfo.email && provider.id !== "roblox") { c.context.logger.error( "Provider did not return email. This could be due to misconfiguration in the provider settings.", ); return redirectOnError("email_not_found"); } if (!callbackURL) { c.context.logger.error("No callback URL found"); throw c.redirect( `${c.context.baseURL}/error?error=please_restart_the_process`, ); } if (link) { if (link.email !== userInfo?.email?.toLowerCase() && provider.id !== "roblox") { return redirectOnError("email_doesn't_match"); } ...... ```
Author
Owner

@D3visionNL commented on GitHub (Dec 27, 2024):

Also @mandrillxx my fork has the Roblox provider built-in and is currently on version 1.1.4.

You can install it using npm install 'https://gitpkg.vercel.app/D3visionNL/better-auth/packages/better-auth?main' (or whichever package manager you prefer)
I had to use gitpkg cause else you get the main package which is kinda useless.

Config is:

roblox:{
    clientId: <your clientid>, 
    clientSecret: <your clientsecret>,
}

Please do keep in mind that I am fully intending for this to be temporary so don't expect me to keep it up to date.

For anyone who looks at this, yes I know you're not supposed to push the dist into the actual repo but this is the only easy way for me to have the option to pull in changes from the official repo😂

And lastly, as I explained in my response above, I am not making a PR with my "implementation" due to the email address issue needing a more proper fix than mine.

<!-- gh-comment-id:2564068066 --> @D3visionNL commented on GitHub (Dec 27, 2024): Also @mandrillxx my fork has the Roblox provider built-in and is currently on version 1.1.4. You can install it using `npm install 'https://gitpkg.vercel.app/D3visionNL/better-auth/packages/better-auth?main'` (or whichever package manager you prefer) I had to use gitpkg cause else you get the main package which is kinda useless. Config is: ``` roblox:{ clientId: <your clientid>, clientSecret: <your clientsecret>, } ``` Please do keep in mind that I am fully intending for this to be temporary so don't expect me to keep it up to date. For anyone who looks at this, yes I know you're not supposed to push the dist into the actual repo but this is the only easy way for me to have the option to pull in changes from the official repo😂 And lastly, as I explained in my response above, I am not making a PR with my "implementation" due to the email address issue needing a more proper fix than mine.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#8467