How to link Generic OAuth to existing user

I have a question about Generic OAuth account linking. Say I have a user [email protected]. I set up a Generic OAuth plugin to authenticate to Nylas, which in turn sends the user through an OAuth authentication with their Google account. But say the user's Google account email is [email protected]. Currently when user completes the Nylas authentication, better-auth is creating a new user [email protected], then creating a Nylas account record linked to that new user. But I want the Nylas account record to be linked to the currently-logged-in user [email protected] and not create a new user when the emails are different. I tried this in my auth.ts config but it didn't help:
account: {
accountLinking: {
allowDifferentEmails: true,
},
},
account: {
accountLinking: {
allowDifferentEmails: true,
},
},
1 Reply
Phil
PhilOP2d ago
Here is my Generic OAuth config if it helps:
providerId: "nylas",
clientId: process.env.NEXT_PUBLIC_NYLAS_CLIENT_ID!,
clientSecret: process.env.NEXT_PUBLIC_NYLAS_CLIENT_SECRET!,
authorizationUrl: `https://${process.env.NEXT_PUBLIC_NYLAS_API_URI}/v3/connect/auth`,
tokenUrl: `https://${process.env.NEXT_PUBLIC_NYLAS_API_URI}/v3/connect/token`,
userInfoUrl: `https://${process.env.NEXT_PUBLIC_NYLAS_API_URI}/v3/grants/me`,
scopes: ['https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/gmail.modify', 'https://www.googleapis.com/auth/calendar', 'https://www.googleapis.com/auth/gmail.labels', 'https://www.googleapis.com/auth/contacts'],
getUserInfo: async ({ accessToken }) => {
const response = await fetch(
`https://${process.env.NEXT_PUBLIC_NYLAS_API_URI}/v3/grants/me`,
{ headers: { Authorization: `Bearer ${accessToken}` } }
);
const userData = await response.json();
return {
id: userData.data.id,
provider: userData.data.provider,
email: userData.data.email,
emailVerified: true,
name: userData.data.name,
};
},
providerId: "nylas",
clientId: process.env.NEXT_PUBLIC_NYLAS_CLIENT_ID!,
clientSecret: process.env.NEXT_PUBLIC_NYLAS_CLIENT_SECRET!,
authorizationUrl: `https://${process.env.NEXT_PUBLIC_NYLAS_API_URI}/v3/connect/auth`,
tokenUrl: `https://${process.env.NEXT_PUBLIC_NYLAS_API_URI}/v3/connect/token`,
userInfoUrl: `https://${process.env.NEXT_PUBLIC_NYLAS_API_URI}/v3/grants/me`,
scopes: ['https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/gmail.modify', 'https://www.googleapis.com/auth/calendar', 'https://www.googleapis.com/auth/gmail.labels', 'https://www.googleapis.com/auth/contacts'],
getUserInfo: async ({ accessToken }) => {
const response = await fetch(
`https://${process.env.NEXT_PUBLIC_NYLAS_API_URI}/v3/grants/me`,
{ headers: { Authorization: `Bearer ${accessToken}` } }
);
const userData = await response.json();
return {
id: userData.data.id,
provider: userData.data.provider,
email: userData.data.email,
emailVerified: true,
name: userData.data.name,
};
},
Ah, I figured it out: it requires a combination of setting allowDifferentEmails: true and using genericAuthClient.oauth2.link instead of genericAuthClient.signIn.oauth2.

Did you find this page helpful?