mirror of
https://github.com/better-auth/better-auth.git
synced 2026-10-18 11:32:15 -05:00
fix(auth): honor social disableSignUp for ID token sign-in (#11491)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"better-auth": patch
|
||||
---
|
||||
|
||||
Respect social provider `disableSignUp` when signing in with an ID token.
|
||||
@@ -342,6 +342,7 @@ export const signInSocial = <O extends BetterAuthOptions>() =>
|
||||
callbackURL: c.body.callbackURL,
|
||||
disableSignUp:
|
||||
(provider.disableImplicitSignUp && !c.body.requestSignUp) ||
|
||||
provider.options?.disableSignUp ||
|
||||
provider.disableSignUp,
|
||||
source: {
|
||||
method: "oauth",
|
||||
|
||||
@@ -696,6 +696,132 @@ describe("Disable implicit signup", async () => {
|
||||
});
|
||||
|
||||
describe("Disable signup", async () => {
|
||||
/**
|
||||
* @see https://github.com/better-auth/better-auth/issues/11480
|
||||
*/
|
||||
describe("ID-token sign-in", () => {
|
||||
const googleIdTokenOptions = (email: string) => {
|
||||
const profile: GoogleProfile = {
|
||||
aud: "test",
|
||||
azp: "test",
|
||||
email,
|
||||
email_verified: true,
|
||||
exp: 2_000_000_000,
|
||||
family_name: "User",
|
||||
given_name: "Google",
|
||||
iat: 1_900_000_000,
|
||||
iss: "https://accounts.google.com",
|
||||
name: "Google User",
|
||||
picture: "https://example.com/avatar.png",
|
||||
sub: "google-id-token-user",
|
||||
};
|
||||
return {
|
||||
clientId: "test",
|
||||
clientSecret: "test",
|
||||
verifyIdToken: async () => true,
|
||||
getUserInfo: async () => ({
|
||||
user: { email, name: profile.name, emailVerified: true },
|
||||
data: profile,
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
it.each([
|
||||
{ requestSignUp: undefined, scenario: "without requestSignUp" },
|
||||
{ requestSignUp: true, scenario: "with requestSignUp" },
|
||||
])("rejects ID-token sign-in for a new user $scenario", async ({
|
||||
requestSignUp,
|
||||
}) => {
|
||||
const email = "new-id-token-user@example.com";
|
||||
const { client, auth } = await getTestInstance(
|
||||
{
|
||||
socialProviders: {
|
||||
google: {
|
||||
...googleIdTokenOptions(email),
|
||||
disableSignUp: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{ disableTestUser: true },
|
||||
);
|
||||
|
||||
const response = await client.signIn.social({
|
||||
provider: "google",
|
||||
idToken: { token: "a.b.c" },
|
||||
requestSignUp,
|
||||
});
|
||||
|
||||
const user = await (await auth.$context).adapter.findOne({
|
||||
model: "user",
|
||||
where: [{ field: "email", value: email }],
|
||||
});
|
||||
expect(user).toBeNull();
|
||||
expect(response.error).toMatchObject({
|
||||
status: 401,
|
||||
code: "OAUTH_LINK_ERROR",
|
||||
message: "signup disabled",
|
||||
});
|
||||
});
|
||||
|
||||
it("allows an existing ID-token user to sign in when provider sign-up is disabled", async () => {
|
||||
const email = "existing-id-token-user@example.com";
|
||||
const { client, auth } = await getTestInstance(
|
||||
{ socialProviders: { google: googleIdTokenOptions(email) } },
|
||||
{ disableTestUser: true },
|
||||
);
|
||||
const signIn = () =>
|
||||
client.signIn.social({
|
||||
provider: "google",
|
||||
idToken: { token: "a.b.c" },
|
||||
});
|
||||
|
||||
const firstResponse = await signIn();
|
||||
expect(firstResponse.error).toBeNull();
|
||||
|
||||
const provider = (await auth.$context).socialProviders.find(
|
||||
(provider) => provider.id === "google",
|
||||
);
|
||||
expect(provider).toBeDefined();
|
||||
provider!.options!.disableSignUp = true;
|
||||
|
||||
const response = await signIn();
|
||||
expect(response.error).toBeNull();
|
||||
expect(response.data).toMatchObject({
|
||||
redirect: false,
|
||||
user: { email },
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps the top-level provider sign-up restriction for ID-token sign-in", async () => {
|
||||
const { client, auth } = await getTestInstance(
|
||||
{
|
||||
socialProviders: {
|
||||
google: {
|
||||
...googleIdTokenOptions("top-level-id-token-user@example.com"),
|
||||
disableSignUp: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{ disableTestUser: true },
|
||||
);
|
||||
const provider = (await auth.$context).socialProviders.find(
|
||||
(provider) => provider.id === "google",
|
||||
);
|
||||
expect(provider).toBeDefined();
|
||||
provider!.disableSignUp = true;
|
||||
|
||||
const response = await client.signIn.social({
|
||||
provider: "google",
|
||||
idToken: { token: "a.b.c" },
|
||||
});
|
||||
expect(response.error).toMatchObject({
|
||||
status: 401,
|
||||
code: "OAUTH_LINK_ERROR",
|
||||
message: "signup disabled",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("Should not create user when sign up is disabled", async () => {
|
||||
const headers = new Headers();
|
||||
const { client, cookieSetter } = await getTestInstance({
|
||||
|
||||
Reference in New Issue
Block a user