mirror of
https://github.com/lobehub/lobehub.git
synced 2026-03-27 13:29:15 +07:00
🐛 fix: fix feishu sso provider (#11970)
This commit is contained in:
@@ -37,7 +37,7 @@ We’re building the world’s largest human–agent 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]
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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": "创建用户遇到了问题。你可以稍后再试",
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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}>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
@@ -168,6 +168,7 @@ export function defineConfig() {
|
||||
// better auth
|
||||
'/signin',
|
||||
'/signup',
|
||||
'/auth-error',
|
||||
'/verify-email',
|
||||
'/reset-password',
|
||||
// oauth
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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'])],
|
||||
|
||||
Reference in New Issue
Block a user