From dfeefc4f58ee24f1ee6cdbe22d5e720b2ba621b8 Mon Sep 17 00:00:00 2001 From: Taesu <166604494+bytaesu@users.noreply.github.com> Date: Mon, 9 Feb 2026 12:51:45 +0900 Subject: [PATCH] fix: standardize `name` field masking as an empty string (#7794) Co-authored-by: Cursor Agent Co-authored-by: Taesu --- packages/better-auth/src/api/routes/callback.ts | 2 +- .../better-auth/src/plugins/oauth-proxy/index.ts | 2 +- packages/better-auth/src/social.test.ts | 8 ++------ packages/core/src/social-providers/apple.ts | 6 +++--- packages/core/src/social-providers/cognito.ts | 11 ++++++----- packages/core/src/social-providers/github.ts | 2 +- packages/core/src/social-providers/gitlab.ts | 2 +- packages/core/src/social-providers/huggingface.ts | 2 +- packages/core/src/social-providers/kakao.ts | 2 +- packages/core/src/social-providers/line.ts | 2 +- packages/core/src/social-providers/naver.ts | 2 +- packages/core/src/social-providers/notion.ts | 2 +- packages/core/src/social-providers/paybin.ts | 6 +----- packages/core/src/social-providers/polar.ts | 2 +- packages/core/src/social-providers/tiktok.ts | 3 ++- packages/core/src/social-providers/vercel.ts | 2 +- packages/sso/src/routes/sso.ts | 12 +++++++----- 17 files changed, 32 insertions(+), 36 deletions(-) diff --git a/packages/better-auth/src/api/routes/callback.ts b/packages/better-auth/src/api/routes/callback.ts index 8e2086ea35..8066450255 100644 --- a/packages/better-auth/src/api/routes/callback.ts +++ b/packages/better-auth/src/api/routes/callback.ts @@ -256,7 +256,7 @@ export const callbackOAuth = createAuthEndpoint( ...userInfo, id: String(userInfo.id), email: userInfo.email, - name: userInfo.name || userInfo.email, + name: userInfo.name || "", }, account: accountData, callbackURL, diff --git a/packages/better-auth/src/plugins/oauth-proxy/index.ts b/packages/better-auth/src/plugins/oauth-proxy/index.ts index e5fc18bd7f..e1f5831f57 100644 --- a/packages/better-auth/src/plugins/oauth-proxy/index.ts +++ b/packages/better-auth/src/plugins/oauth-proxy/index.ts @@ -407,7 +407,7 @@ export const oAuthProxy = (opts?: O) => { userInfo: { id: String(userInfo.id), email: userInfo.email, - name: userInfo.name || userInfo.email, + name: userInfo.name || "", image: userInfo.image, emailVerified: userInfo.emailVerified, }, diff --git a/packages/better-auth/src/social.test.ts b/packages/better-auth/src/social.test.ts index a6391bf6e1..8e47f35265 100644 --- a/packages/better-auth/src/social.test.ts +++ b/packages/better-auth/src/social.test.ts @@ -1061,12 +1061,8 @@ describe("Apple Provider", async () => { // Name should NOT be the email address expect(session.data?.user.name).not.toBe("user@privaterelay.appleid.com"); - // Name should be undefined, null, or space when not provided - expect( - session.data?.user.name === undefined || - session.data?.user.name === null || - session.data?.user.name === " ", - ).toBe(true); + // Name should be empty string when not provided + expect(session.data?.user.name).toBe(""); }); it("should use firstName and lastName when provided in token.user", async () => { diff --git a/packages/core/src/social-providers/apple.ts b/packages/core/src/social-providers/apple.ts index cb02ad25aa..9067254628 100644 --- a/packages/core/src/social-providers/apple.ts +++ b/packages/core/src/social-providers/apple.ts @@ -158,15 +158,15 @@ export const apple = (options: AppleOptions) => { return null; } - // TODO: " " masking will be removed when the name field is made optional + // TODO: "" masking will be removed when the name field is made optional let name: string; if (token.user?.name) { const firstName = token.user.name.firstName || ""; const lastName = token.user.name.lastName || ""; const fullName = `${firstName} ${lastName}`.trim(); - name = fullName || " "; + name = fullName; } else { - name = profile.name || " "; + name = profile.name || ""; } const emailVerified = diff --git a/packages/core/src/social-providers/cognito.ts b/packages/core/src/social-providers/cognito.ts index 7a55054a7c..456be22fc7 100644 --- a/packages/core/src/social-providers/cognito.ts +++ b/packages/core/src/social-providers/cognito.ts @@ -178,10 +178,7 @@ export const cognito = (options: CognitoOptions) => { return null; } const name = - profile.name || - profile.given_name || - profile.username || - profile.email; + profile.name || profile.given_name || profile.username || ""; const enrichedProfile = { ...profile, name, @@ -220,7 +217,11 @@ export const cognito = (options: CognitoOptions) => { return { user: { id: userInfo.sub, - name: userInfo.name || userInfo.given_name || userInfo.username, + name: + userInfo.name || + userInfo.given_name || + userInfo.username || + "", email: userInfo.email, image: userInfo.picture, emailVerified: userInfo.email_verified, diff --git a/packages/core/src/social-providers/github.ts b/packages/core/src/social-providers/github.ts index 5e5b342e0a..c74d4a4ec0 100644 --- a/packages/core/src/social-providers/github.ts +++ b/packages/core/src/social-providers/github.ts @@ -170,7 +170,7 @@ export const github = (options: GithubOptions) => { return { user: { id: profile.id, - name: profile.name || profile.login, + name: profile.name || profile.login || "", email: profile.email, image: profile.avatar_url, emailVerified, diff --git a/packages/core/src/social-providers/gitlab.ts b/packages/core/src/social-providers/gitlab.ts index 8c694a836e..566b5ce979 100644 --- a/packages/core/src/social-providers/gitlab.ts +++ b/packages/core/src/social-providers/gitlab.ts @@ -141,7 +141,7 @@ export const gitlab = (options: GitlabOptions) => { return { user: { id: profile.id, - name: profile.name ?? profile.username, + name: profile.name ?? profile.username ?? "", email: profile.email, image: profile.avatar_url, emailVerified: profile.email_verified ?? false, diff --git a/packages/core/src/social-providers/huggingface.ts b/packages/core/src/social-providers/huggingface.ts index 774717a223..763f850ef9 100644 --- a/packages/core/src/social-providers/huggingface.ts +++ b/packages/core/src/social-providers/huggingface.ts @@ -104,7 +104,7 @@ export const huggingface = (options: HuggingFaceOptions) => { return { user: { id: profile.sub, - name: profile.name || profile.preferred_username, + name: profile.name || profile.preferred_username || "", email: profile.email, image: profile.picture, emailVerified: profile.email_verified ?? false, diff --git a/packages/core/src/social-providers/kakao.ts b/packages/core/src/social-providers/kakao.ts index f976ccb36d..2b441dc942 100644 --- a/packages/core/src/social-providers/kakao.ts +++ b/packages/core/src/social-providers/kakao.ts @@ -161,7 +161,7 @@ export const kakao = (options: KakaoOptions) => { const kakaoProfile = account.profile || {}; const user = { id: String(profile.id), - name: kakaoProfile.nickname || account.name || undefined, + name: kakaoProfile.nickname || account.name || "", email: account.email, image: kakaoProfile.profile_image_url || kakaoProfile.thumbnail_image_url, diff --git a/packages/core/src/social-providers/line.ts b/packages/core/src/social-providers/line.ts index e77c811644..6c9b154833 100644 --- a/packages/core/src/social-providers/line.ts +++ b/packages/core/src/social-providers/line.ts @@ -147,7 +147,7 @@ export const line = (options: LineOptions) => { const userMap = await options.mapProfileToUser?.(profile as any); // ID preference order const id = (profile as any).sub || (profile as any).userId; - const name = (profile as any).name || (profile as any).displayName; + const name = (profile as any).name || (profile as any).displayName || ""; const image = (profile as any).picture || (profile as any).pictureUrl || undefined; const email = (profile as any).email; diff --git a/packages/core/src/social-providers/naver.ts b/packages/core/src/social-providers/naver.ts index 0f192d7cc1..f9ebcbe5ca 100644 --- a/packages/core/src/social-providers/naver.ts +++ b/packages/core/src/social-providers/naver.ts @@ -96,7 +96,7 @@ export const naver = (options: NaverOptions) => { const res = profile.response || {}; const user = { id: res.id, - name: res.name || res.nickname, + name: res.name || res.nickname || "", email: res.email, image: res.profile_image, emailVerified: false, diff --git a/packages/core/src/social-providers/notion.ts b/packages/core/src/social-providers/notion.ts index d6f4ece80f..7db9c46fb6 100644 --- a/packages/core/src/social-providers/notion.ts +++ b/packages/core/src/social-providers/notion.ts @@ -94,7 +94,7 @@ export const notion = (options: NotionOptions) => { return { user: { id: userProfile.id, - name: userProfile.name || "Notion User", + name: userProfile.name || "", email: userProfile.person?.email || null, image: userProfile.avatar_url, emailVerified: false, diff --git a/packages/core/src/social-providers/paybin.ts b/packages/core/src/social-providers/paybin.ts index 4f357d4285..aca15616f6 100644 --- a/packages/core/src/social-providers/paybin.ts +++ b/packages/core/src/social-providers/paybin.ts @@ -104,11 +104,7 @@ export const paybin = (options: PaybinOptions) => { return { user: { id: user.sub, - name: - user.name || - user.preferred_username || - (user.email ? user.email.split("@")[0] : "User") || - "User", + name: user.name || user.preferred_username || "", email: user.email, image: user.picture, emailVerified: user.email_verified || false, diff --git a/packages/core/src/social-providers/polar.ts b/packages/core/src/social-providers/polar.ts index fe9734ab1a..ae855eda76 100644 --- a/packages/core/src/social-providers/polar.ts +++ b/packages/core/src/social-providers/polar.ts @@ -96,7 +96,7 @@ export const polar = (options: PolarOptions) => { return { user: { id: profile.id, - name: profile.public_name || profile.username, + name: profile.public_name || profile.username || "", email: profile.email, image: profile.avatar_url, emailVerified: profile.email_verified ?? false, diff --git a/packages/core/src/social-providers/tiktok.ts b/packages/core/src/social-providers/tiktok.ts index fd6d86fa6d..b4512d8ec2 100644 --- a/packages/core/src/social-providers/tiktok.ts +++ b/packages/core/src/social-providers/tiktok.ts @@ -197,7 +197,8 @@ export const tiktok = (options: TiktokOptions) => { user: { email: profile.data.user.email || profile.data.user.username, id: profile.data.user.open_id, - name: profile.data.user.display_name || profile.data.user.username, + name: + profile.data.user.display_name || profile.data.user.username || "", image: profile.data.user.avatar_large_url, emailVerified: false, }, diff --git a/packages/core/src/social-providers/vercel.ts b/packages/core/src/social-providers/vercel.ts index 9048fe7c1a..35c41180c6 100644 --- a/packages/core/src/social-providers/vercel.ts +++ b/packages/core/src/social-providers/vercel.ts @@ -73,7 +73,7 @@ export const vercel = (options: VercelOptions) => { return { user: { id: profile.sub, - name: profile.name ?? profile.preferred_username, + name: profile.name ?? profile.preferred_username ?? "", email: profile.email, image: profile.picture, emailVerified: profile.email_verified ?? false, diff --git a/packages/sso/src/routes/sso.ts b/packages/sso/src/routes/sso.ts index 691cadaae2..bd0d7e9167 100644 --- a/packages/sso/src/routes/sso.ts +++ b/packages/sso/src/routes/sso.ts @@ -1674,7 +1674,7 @@ export const callbackSSO = (options?: SSOOptions) => { const linked = await handleOAuthUserInfo(ctx, { userInfo: { email: userInfo.email, - name: userInfo.name || userInfo.email, + name: userInfo.name || "", id: userInfo.id, image: userInfo.image, emailVerified: options?.trustEmailVerified @@ -2216,7 +2216,8 @@ export const callbackSSOSAML = (options?: SSOOptions) => { .filter(Boolean) .join(" ") || attributes[mapping.name || "displayName"] || - extract.nameID, + extract.nameID || + "", emailVerified: options?.trustEmailVerified && mapping.emailVerified ? ((attributes[mapping.emailVerified] || false) as boolean) @@ -2253,7 +2254,7 @@ export const callbackSSOSAML = (options?: SSOOptions) => { const result = await handleOAuthUserInfo(ctx, { userInfo: { email: userInfo.email as string, - name: (userInfo.name || userInfo.email) as string, + name: (userInfo.name || "") as string, id: userInfo.id as string, emailVerified: Boolean(userInfo.emailVerified), }, @@ -2698,7 +2699,8 @@ export const acsEndpoint = (options?: SSOOptions) => { .filter(Boolean) .join(" ") || attributes[mapping.name || "displayName"] || - extract.nameID, + extract.nameID || + "", emailVerified: options?.trustEmailVerified && mapping.emailVerified ? ((attributes[mapping.emailVerified] || false) as boolean) @@ -2736,7 +2738,7 @@ export const acsEndpoint = (options?: SSOOptions) => { const result = await handleOAuthUserInfo(ctx, { userInfo: { email: userInfo.email as string, - name: (userInfo.name || userInfo.email) as string, + name: (userInfo.name || "") as string, id: userInfo.id as string, emailVerified: Boolean(userInfo.emailVerified), },