mirror of
https://github.com/better-auth/better-auth.git
synced 2026-06-04 13:26:23 -05:00
fix: enforce override user info on oauth signin (#2294)
This commit is contained in:
@@ -189,6 +189,7 @@ export const callbackOAuth = createAuthEndpoint(
|
||||
disableSignUp:
|
||||
(provider.disableImplicitSignUp && !requestSignUp) ||
|
||||
provider.options?.disableSignUp,
|
||||
overrideUserInfo: provider.options?.overrideUserInfoOnSignIn,
|
||||
});
|
||||
if (result.error) {
|
||||
c.context.logger.error(result.error.split(" ").join("_"));
|
||||
|
||||
@@ -105,9 +105,10 @@ export async function handleOAuthUserInfo(
|
||||
}
|
||||
}
|
||||
if (overrideUserInfo) {
|
||||
const { id: _, ...restUserInfo } = userInfo;
|
||||
// update user info from the provider if overrideUserInfo is true
|
||||
await c.context.internalAdapter.updateUser(dbUser.user.id, {
|
||||
...userInfo,
|
||||
...restUserInfo,
|
||||
email: userInfo.email.toLowerCase(),
|
||||
emailVerified:
|
||||
userInfo.email.toLocaleLowerCase() === dbUser.user.email
|
||||
|
||||
@@ -7,6 +7,8 @@ import { getOAuth2Tokens, refreshAccessToken } from "../oauth2";
|
||||
import { signJWT } from "../crypto/jwt";
|
||||
import { OAuth2Server } from "oauth2-mock-server";
|
||||
import { betterFetch } from "@better-fetch/fetch";
|
||||
import Database from "better-sqlite3";
|
||||
import { getMigrations } from "../db";
|
||||
|
||||
let server = new OAuth2Server();
|
||||
|
||||
@@ -16,7 +18,33 @@ vi.mock("../oauth2", async (importOriginal) => {
|
||||
...original,
|
||||
validateAuthorizationCode: vi
|
||||
.fn()
|
||||
.mockImplementation(async (...args: any) => {
|
||||
.mockImplementation(async (option: any) => {
|
||||
if (option.options.overrideUserInfoOnSignIn) {
|
||||
const data: GoogleProfile = {
|
||||
email: "user@email.com",
|
||||
email_verified: true,
|
||||
name: "Updated User",
|
||||
picture: "https://test.com/picture.png",
|
||||
exp: 1234567890,
|
||||
sub: "1234567890",
|
||||
iat: 1234567890,
|
||||
aud: "test",
|
||||
azp: "test",
|
||||
nbf: 1234567890,
|
||||
iss: "test",
|
||||
locale: "en",
|
||||
jti: "test",
|
||||
given_name: "Updated",
|
||||
family_name: "User",
|
||||
};
|
||||
const testIdToken = await signJWT(data, DEFAULT_SECRET);
|
||||
const tokens = getOAuth2Tokens({
|
||||
access_token: "test",
|
||||
refresh_token: "test",
|
||||
id_token: testIdToken,
|
||||
});
|
||||
return tokens;
|
||||
}
|
||||
const data: GoogleProfile = {
|
||||
email: "user@email.com",
|
||||
email_verified: true,
|
||||
@@ -549,3 +577,109 @@ describe("Disable signup", async () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("signin", async () => {
|
||||
const database = new Database(":memory:");
|
||||
|
||||
beforeAll(async () => {
|
||||
const migrations = await getMigrations({
|
||||
database,
|
||||
});
|
||||
await migrations.runMigrations();
|
||||
});
|
||||
it("should allow user info override during sign in", async () => {
|
||||
let state = "";
|
||||
const { client, cookieSetter } = await getTestInstance({
|
||||
database,
|
||||
socialProviders: {
|
||||
google: {
|
||||
clientId: "test",
|
||||
clientSecret: "test",
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
const signInRes = await client.signIn.social({
|
||||
provider: "google",
|
||||
callbackURL: "/callback",
|
||||
});
|
||||
expect(signInRes.data).toMatchObject({
|
||||
url: expect.stringContaining("google.com"),
|
||||
redirect: true,
|
||||
});
|
||||
state = new URL(signInRes.data!.url!).searchParams.get("state") || "";
|
||||
|
||||
const headers = new Headers();
|
||||
|
||||
await client.$fetch("/callback/google", {
|
||||
query: {
|
||||
state,
|
||||
code: "test",
|
||||
},
|
||||
method: "GET",
|
||||
onError: (c) => {
|
||||
cookieSetter(headers)(c as any);
|
||||
},
|
||||
});
|
||||
|
||||
const session = await client.getSession({
|
||||
fetchOptions: {
|
||||
headers,
|
||||
},
|
||||
});
|
||||
expect(session.data?.user).toMatchObject({
|
||||
name: "First Last",
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow user info override during sign in", async () => {
|
||||
let state = "";
|
||||
const { client, cookieSetter } = await getTestInstance(
|
||||
{
|
||||
database,
|
||||
socialProviders: {
|
||||
google: {
|
||||
clientId: "test",
|
||||
clientSecret: "test",
|
||||
enabled: true,
|
||||
overrideUserInfoOnSignIn: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
disableTestUser: true,
|
||||
},
|
||||
);
|
||||
const signInRes = await client.signIn.social({
|
||||
provider: "google",
|
||||
callbackURL: "/callback",
|
||||
});
|
||||
expect(signInRes.data).toMatchObject({
|
||||
url: expect.stringContaining("google.com"),
|
||||
redirect: true,
|
||||
});
|
||||
state = new URL(signInRes.data!.url!).searchParams.get("state") || "";
|
||||
|
||||
const headers = new Headers();
|
||||
|
||||
await client.$fetch("/callback/google", {
|
||||
query: {
|
||||
state,
|
||||
code: "test",
|
||||
},
|
||||
method: "GET",
|
||||
onError: (c) => {
|
||||
cookieSetter(headers)(c as any);
|
||||
},
|
||||
});
|
||||
|
||||
const session = await client.getSession({
|
||||
fetchOptions: {
|
||||
headers,
|
||||
},
|
||||
});
|
||||
expect(session.data?.user).toMatchObject({
|
||||
name: "Updated User",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user