🐛 fix: fix feishu sso provider (#11970)

This commit is contained in:
Arvin Xu
2026-01-31 00:50:11 +08:00
committed by GitHub
parent 67c4bafd3f
commit ffd9fff091
16 changed files with 39 additions and 28 deletions

View File

@@ -37,7 +37,7 @@ Were building the worlds largest humanagent co-evolving network.
[![][share-mastodon-shield]][share-mastodon-link]
[![][share-linkedin-shield]][share-linkedin-link]
<sup>Agent teams that grow with you</sup>
<sup>Agent teammates that grow with you</sup>
[![][github-trending-shield]][github-trending-url]

View File

@@ -35,7 +35,7 @@ LobeHub 是一个工作与生活空间,用于发现、构建并与会随着您
[![][share-weibo-shield]][share-weibo-link]
[![][share-mastodon-shield]][share-mastodon-link]
<sup>Agent teams that grow with you</sup>
<sup>Agent teammates that grow with you</sup>
[![][github-trending-shield]][github-trending-url]
[![][github-hello-shield]][github-hello-url]

View File

@@ -192,7 +192,7 @@
"profile.usernameRule": "Username can only contain letters, numbers, or underscores",
"profile.usernameUpdateFailed": "Failed to update username, please try again later",
"signin.subtitle": "Sign up or log in to your {{appName}} account",
"signin.title": "Agent teams that grow with you",
"signin.title": "Agent teammates that grow with you",
"signout": "Log Out",
"signup": "Sign Up",
"stats.aiheatmaps": "Activity Index",

View File

@@ -8,6 +8,7 @@
"codes.DELETED_ACCOUNT_EMAIL": "This email has been associated with a deleted account and cannot be used for registration",
"codes.EMAIL_CAN_NOT_BE_UPDATED": "Email cannot be updated for this account",
"codes.EMAIL_NOT_ALLOWED": "Email not allowed for registration",
"codes.EMAIL_NOT_FOUND": "No email associated with this account. Please check if your account has an email bound.",
"codes.EMAIL_NOT_VERIFIED": "Please verify your email first",
"codes.FAILED_TO_CREATE_SESSION": "Failed to create session",
"codes.FAILED_TO_CREATE_USER": "Failed to create user",

View File

@@ -2,7 +2,7 @@
"changelog.description": "Stay updated on the new features and improvements of {{appName}}",
"changelog.title": "Changelog",
"chat.description": "{{appName}} is a work-and-lifestyle space to find, build, and collaborate with agent teams that grow with you.",
"chat.title": "{{appName}} · Agent teams that grow with you",
"chat.title": "{{appName}} · Agent teammates that grow with you",
"discover.assistants.description": "Content, Q&A, images, video, voice, workflows—browse and add Agents from the Community.",
"discover.assistants.title": "Agent Community",
"discover.description": "Explore Agents, Skills, Providers, models, and MCP Servers.",

View File

@@ -8,6 +8,7 @@
"codes.DELETED_ACCOUNT_EMAIL": "该邮箱已关联至已删除的账户,无法用于注册",
"codes.EMAIL_CAN_NOT_BE_UPDATED": "当前邮箱无法修改,如需更换,请联系支持",
"codes.EMAIL_NOT_ALLOWED": "该邮箱不允许用于注册",
"codes.EMAIL_NOT_FOUND": "登录账号未关联邮箱,请检查账号是否已绑定邮箱",
"codes.EMAIL_NOT_VERIFIED": "邮箱还未验证,请先查收验证邮件完成验证",
"codes.FAILED_TO_CREATE_SESSION": "会话创建遇到了问题。你可以先重试;如仍失败,请检查网络或稍后再试",
"codes.FAILED_TO_CREATE_USER": "创建用户遇到了问题。你可以稍后再试",

View File

@@ -2,7 +2,7 @@
import { SiDiscord } from '@icons-pack/react-simple-icons';
import { SOCIAL_URL } from '@lobechat/business-const';
import { Alert, Button, Flexbox, Icon } from '@lobehub/ui';
import { Button, Flexbox, Icon, Text } from '@lobehub/ui';
import { cssVar } from 'antd-style';
import { parseAsString, useQueryState } from 'nuqs';
import { memo } from 'react';
@@ -45,7 +45,9 @@ const AuthErrorPage = memo(() => {
subtitle={description}
title={t('title')}
>
<Alert title={error || 'UNKNOWN'} type={'error'} />
<Text style={{ fontFamily: cssVar.fontFamilyCode }} type={'secondary'}>
ErrorCode: {error || 'UNKNOWN'}
</Text>
</AuthCard>
);
});

View File

@@ -101,7 +101,7 @@ export const SignInEmailStep = ({
<AuthCard
footer={footer}
subtitle={t('signin.subtitle', { appName: BRANDING_NAME })}
title={'Agent teams that grow with you'}
title={'Agent teammates that grow with you'}
>
{!serverConfigInit && (
<Flexbox gap={12}>

View File

@@ -55,7 +55,7 @@ export const SignInPasswordStep = ({
</>
}
subtitle={t('betterAuth.signin.passwordStep.subtitle')}
title={'Agent teams that grow with you'}
title={'Agent teammates that grow with you'}
>
<Text fontSize={20}>{email}</Text>
<Form

View File

@@ -69,7 +69,7 @@ const provider: GenericProviderDefinition<{
authorizationUrlParams: {
app_id: clientId,
response_type: 'code',
scope: '',
scope: 'contact:user.base:readonly contact:user.email:readonly',
},
clientId,
clientSecret,
@@ -79,8 +79,8 @@ const provider: GenericProviderDefinition<{
getToken: async ({ code, redirectURI }) => {
const tokenResponse = await fetch(FEISHU_TOKEN_URL, {
body: JSON.stringify({
app_id: clientId,
app_secret: clientSecret,
client_id: clientId,
client_secret: clientSecret,
code,
grant_type: 'authorization_code',
redirect_uri: redirectURI,
@@ -124,16 +124,12 @@ const provider: GenericProviderDefinition<{
},
});
if (!response.ok) {
return null;
}
if (!response.ok) return null;
const payload = (await response.json()) as unknown;
const profileResponse = payload as FeishuUserInfoResponse;
if (profileResponse.code && profileResponse.code !== 0) {
return null;
}
if (profileResponse.code && profileResponse.code !== 0) return null;
const profile: FeishuUserProfile | undefined =
profileResponse.data ?? (isFeishuProfile(payload) ? payload : undefined);
@@ -143,11 +139,16 @@ const provider: GenericProviderDefinition<{
const unionId = profile.union_id ?? profile.open_id;
if (!unionId) return null;
const syntheticEmail =
profile.email ?? profile.enterprise_email ?? `${unionId}@feishu.lobehub`;
// Always use union_id to construct email for consistency
// This avoids issues when:
// 1. Admin hasn't enabled "Allow OpenAPI to access email field" in Feishu admin console
// 2. User hasn't bound an email in Feishu
// 3. User's email changes later (which would cause account mismatch)
const email = profile.email || profile.enterprise_email || `${unionId}@feishu.sso`;
return {
email: syntheticEmail,
...profile,
email,
emailVerified: false,
id: unionId,
image:
@@ -156,13 +157,13 @@ const provider: GenericProviderDefinition<{
profile.avatar_middle ??
profile.avatar_big,
name: profile.name ?? profile.en_name ?? unionId,
...profile,
};
},
pkce: false,
providerId: 'feishu',
responseMode: 'query',
scopes: [],
scopes: ['contact:user.base:readonly', 'contact:user.email:readonly'],
tokenUrl: FEISHU_TOKEN_URL,
};
},

View File

@@ -43,7 +43,7 @@ const provider: GenericProviderDefinition<{
* and returns openid/unionid alongside tokens, so we exchange the code
* manually instead of proxying through a custom API route.
*/
getToken: async ({ code }) => {
getToken: async ({ code }) => {
const tokenUrl = new URL(WECHAT_TOKEN_URL);
tokenUrl.searchParams.set('appid', clientId);
tokenUrl.searchParams.set('secret', clientSecret);
@@ -74,10 +74,11 @@ const provider: GenericProviderDefinition<{
tokenType: data.token_type ?? 'Bearer',
};
},
/**
* Use openid/unionid returned in the token response; no custom scope encoding needed.
*/
getUserInfo: async (tokens) => {
getUserInfo: async (tokens) => {
const accessToken = tokens.accessToken;
const openId = (tokens as { raw?: WeChatTokenResponse }).raw?.openid;
const unionId = (tokens as { raw?: WeChatTokenResponse }).raw?.unionid;
@@ -114,7 +115,7 @@ const provider: GenericProviderDefinition<{
...profile,
};
},
pkce: false,
providerId: 'wechat',
@@ -122,6 +123,8 @@ const provider: GenericProviderDefinition<{
responseMode: 'query',
scopes: ['snsapi_login'],
tokenUrl: WECHAT_TOKEN_URL,
};
},

View File

@@ -168,6 +168,7 @@ export function defineConfig() {
// better auth
'/signin',
'/signup',
'/auth-error',
'/verify-email',
'/reset-password',
// oauth

View File

@@ -201,7 +201,7 @@ export default {
'profile.usernameRule': 'Username can only contain letters, numbers, or underscores',
'profile.usernameUpdateFailed': 'Failed to update username, please try again later',
'signin.subtitle': 'Sign up or log in to your {{appName}} account',
'signin.title': 'Agent teams that grow with you',
'signin.title': 'Agent teammates that grow with you',
'signout': 'Log Out',
'signup': 'Sign Up',
'stats.aiheatmaps': 'Activity Index',

View File

@@ -10,6 +10,8 @@ export default {
'This email has been associated with a deleted account and cannot be used for registration',
'codes.EMAIL_CAN_NOT_BE_UPDATED': 'Email cannot be updated for this account',
'codes.EMAIL_NOT_ALLOWED': 'Email not allowed for registration',
'codes.EMAIL_NOT_FOUND':
'No email associated with this account. Please check if your account has an email bound.',
'codes.EMAIL_NOT_VERIFIED': 'Please verify your email first',
'codes.FAILED_TO_CREATE_SESSION': 'Failed to create session',
'codes.FAILED_TO_CREATE_USER': 'Failed to create user',

View File

@@ -3,7 +3,7 @@ export default {
'changelog.title': 'Changelog',
'chat.description':
'{{appName}} is a work-and-lifestyle space to find, build, and collaborate with agent teams that grow with you.',
'chat.title': '{{appName}} · Agent teams that grow with you',
'chat.title': '{{appName}} · Agent teammates that grow with you',
'discover.assistants.description':
'Content, Q&A, images, video, voice, workflows—browse and add Agents from the Community.',
'discover.assistants.title': 'Agent Community',

View File

@@ -94,7 +94,7 @@ export class Ld {
'email': BRANDING_EMAIL.support,
},
'description':
'Agent teams that grow with you\n' +
'Agent teammates that grow with you\n' +
'LobeHub is a work-and-lifestyle space to find, build, and collaborate with agent teams that grow with you.',
'email': BRANDING_EMAIL.business,
'founders': [this.getAuthors(['arvinxx']), this.getAuthors(['canisminor'])],