mirror of
https://github.com/LukeHagar/better-auth.git
synced 2025-12-09 20:27:44 +00:00
refactor: account linking
This commit is contained in:
@@ -92,4 +92,10 @@ export const auth = betterAuth({
|
|||||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET || "",
|
clientSecret: process.env.GOOGLE_CLIENT_SECRET || "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
account: {
|
||||||
|
accountLinking: {
|
||||||
|
trustedProviders: ["google", "github"],
|
||||||
|
requireEmailVerified: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -77,19 +77,18 @@ The account table stores the authentication data of the user. The account table
|
|||||||
|
|
||||||
Account linking allows users to link multiple authentication methods to the same account. This is useful when users want to sign in using different methods.
|
Account linking allows users to link multiple authentication methods to the same account. This is useful when users want to sign in using different methods.
|
||||||
|
|
||||||
By default better auth doesn't allow account linking. To enable account linking, you must pass `enabled: true` in `account` options when initializing better auth.
|
By default better auth allows account linking for all providers. You can disable account linking by setting `accountLinking.enabled` to `false`.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const auth = new BetterAuth({
|
const auth = new BetterAuth({
|
||||||
account: {
|
account: {
|
||||||
accountLinking: {
|
accountLinking: {
|
||||||
enabled: true,
|
enabled: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also specify, the list of providers that should be trusted. Trusted providers are providers that can be linked to the account without verifying the user's email.
|
You can also specify, the list of providers that should be trusted. When a user signs in using a trusted provider, if the provider returns the `emailVerified` field in the user data, the account will be linked to the user.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const auth = new BetterAuth({
|
const auth = new BetterAuth({
|
||||||
@@ -100,21 +99,4 @@ const auth = new BetterAuth({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
```
|
|
||||||
|
|
||||||
By defualt the provider needs to returned `emailVerified` field in the user data to link the account. You can change this behavior by setting `requireEmailVerified` to `false`.
|
|
||||||
|
|
||||||
<Callout type="warn">
|
|
||||||
We strongly recommend you only link accounts that have verified emails to prevent account hijacking.
|
|
||||||
</Callout>
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const auth = new BetterAuth({
|
|
||||||
account: {
|
|
||||||
accountLinking: {
|
|
||||||
enabled: true,
|
|
||||||
requireEmailVerified: false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
```
|
```
|
||||||
@@ -97,21 +97,24 @@ export const callbackOAuth = createAuthEndpoint(
|
|||||||
c.context.options.account?.accountLinking?.trustedProviders;
|
c.context.options.account?.accountLinking?.trustedProviders;
|
||||||
const isTrustedProvider = trustedProviders
|
const isTrustedProvider = trustedProviders
|
||||||
? trustedProviders.includes(provider.id as "apple")
|
? trustedProviders.includes(provider.id as "apple")
|
||||||
: false;
|
: true;
|
||||||
if (!hasBeenLinked && (!user.emailVerified || !isTrustedProvider)) {
|
|
||||||
|
const shouldLink =
|
||||||
|
!hasBeenLinked && user.emailVerified && isTrustedProvider;
|
||||||
|
if (!shouldLink) {
|
||||||
let url: URL;
|
let url: URL;
|
||||||
try {
|
try {
|
||||||
url = new URL(currentURL || callbackURL);
|
url = new URL(currentURL || callbackURL);
|
||||||
url.searchParams.set("error", "user_already_exists");
|
url.searchParams.set("error", "account_not_linked");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw c.redirect(
|
throw c.redirect(
|
||||||
`${c.context.baseURL}/error?error=user_already_exists`,
|
`${c.context.baseURL}/error?error=account_not_linked`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
throw c.redirect(url.toString());
|
throw c.redirect(url.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasBeenLinked && user.emailVerified) {
|
if (shouldLink) {
|
||||||
try {
|
try {
|
||||||
await c.context.internalAdapter.linkAccount({
|
await c.context.internalAdapter.linkAccount({
|
||||||
providerId: provider.id,
|
providerId: provider.id,
|
||||||
|
|||||||
@@ -167,16 +167,9 @@ export interface BetterAuthOptions {
|
|||||||
*/
|
*/
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
/**
|
/**
|
||||||
* List of trusted providers. If the
|
* List of trusted providers
|
||||||
* provider is not in this list
|
|
||||||
* `emailVerified` field is ignored.
|
|
||||||
*/
|
*/
|
||||||
trustedProviders?: Array<OAuthProviderList[number] | "email-password">;
|
trustedProviders?: Array<OAuthProviderList[number] | "email-password">;
|
||||||
/**
|
|
||||||
* Require email verified field
|
|
||||||
* to be true to link the account
|
|
||||||
*/
|
|
||||||
requireEmailVerified?: boolean;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user