@lobehub/chat 1.51.16 → 1.52.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +1 -0
- package/CHANGELOG.md +50 -0
- package/Dockerfile.database +2 -1
- package/changelog/v1.json +18 -0
- package/next.config.ts +1 -0
- package/package.json +1 -1
- package/src/app/[variants]/(main)/(mobile)/me/(home)/__tests__/UserBanner.test.tsx +3 -2
- package/src/app/[variants]/(main)/(mobile)/me/(home)/__tests__/useCategory.test.tsx +6 -6
- package/src/app/[variants]/(main)/(mobile)/me/(home)/features/UserBanner.tsx +3 -6
- package/src/app/[variants]/(main)/(mobile)/me/(home)/features/useCategory.tsx +2 -2
- package/src/app/[variants]/(main)/(mobile)/me/(home)/page.tsx +0 -2
- package/src/app/[variants]/(main)/(mobile)/me/profile/features/Category.tsx +2 -2
- package/src/app/[variants]/(main)/(mobile)/me/profile/page.tsx +0 -2
- package/src/app/[variants]/(main)/(mobile)/me/settings/page.tsx +0 -2
- package/src/app/[variants]/(main)/discover/search/page.tsx +0 -2
- package/src/app/[variants]/(main)/layout.tsx +0 -2
- package/src/app/[variants]/(main)/profile/(home)/Client.tsx +2 -2
- package/src/app/[variants]/(main)/profile/hooks/useCategory.tsx +2 -4
- package/src/app/[variants]/(main)/settings/_layout/Mobile/Header.tsx +1 -3
- package/src/app/[variants]/(main)/settings/layout.ts +0 -2
- package/src/app/[variants]/page.tsx +0 -1
- package/src/config/auth.ts +1 -2
- package/src/const/auth.ts +1 -2
- package/src/features/User/UserPanel/PanelContent.tsx +3 -7
- package/src/features/User/UserPanel/useMenu.tsx +2 -2
- package/src/features/User/__tests__/PanelContent.test.tsx +6 -7
- package/src/features/User/__tests__/useMenu.test.tsx +1 -1
- package/src/layout/GlobalProvider/StoreInitialization.tsx +5 -2
- package/src/layout/GlobalProvider/index.tsx +2 -2
- package/src/middleware.ts +7 -10
- package/src/server/routers/edge/config/index.test.ts +7 -7
- package/src/server/routers/edge/config/index.ts +7 -2
- package/src/services/__tests__/global.test.ts +6 -3
- package/src/services/chat.ts +2 -1
- package/src/services/global.ts +2 -2
- package/src/store/serverConfig/action.ts +36 -0
- package/src/store/serverConfig/index.ts +0 -1
- package/src/store/serverConfig/store.test.ts +1 -1
- package/src/store/serverConfig/store.ts +16 -9
- package/src/store/user/slices/auth/action.test.ts +4 -2
- package/src/store/user/slices/auth/action.ts +2 -4
- package/src/store/user/slices/auth/initialState.ts +0 -1
- package/src/store/user/slices/auth/selectors.ts +5 -7
- package/src/store/user/slices/common/action.ts +0 -1
- package/src/types/serverConfig.ts +6 -0
- package/src/libs/agent-runtime/togetherai/__snapshots__/index.test.ts.snap +0 -2190
package/.env.example
CHANGED
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,56 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.52.1](https://github.com/lobehub/lobe-chat/compare/v1.52.0...v1.52.1)
|
6
|
+
|
7
|
+
<sup>Released on **2025-02-08**</sup>
|
8
|
+
|
9
|
+
#### 🐛 Bug Fixes
|
10
|
+
|
11
|
+
- **misc**: Fix static relative issues.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### What's fixed
|
19
|
+
|
20
|
+
- **misc**: Fix static relative issues, closes [#5874](https://github.com/lobehub/lobe-chat/issues/5874) ([419977b](https://github.com/lobehub/lobe-chat/commit/419977b))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
30
|
+
## [Version 1.52.0](https://github.com/lobehub/lobe-chat/compare/v1.51.16...v1.52.0)
|
31
|
+
|
32
|
+
<sup>Released on **2025-02-08**</sup>
|
33
|
+
|
34
|
+
#### ✨ Features
|
35
|
+
|
36
|
+
- **misc**: Refactor the auth condition in Next Auth.
|
37
|
+
|
38
|
+
<br/>
|
39
|
+
|
40
|
+
<details>
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
42
|
+
|
43
|
+
#### What's improved
|
44
|
+
|
45
|
+
- **misc**: Refactor the auth condition in Next Auth, closes [#5866](https://github.com/lobehub/lobe-chat/issues/5866) ([e529108](https://github.com/lobehub/lobe-chat/commit/e529108))
|
46
|
+
|
47
|
+
</details>
|
48
|
+
|
49
|
+
<div align="right">
|
50
|
+
|
51
|
+
[](#readme-top)
|
52
|
+
|
53
|
+
</div>
|
54
|
+
|
5
55
|
### [Version 1.51.16](https://github.com/lobehub/lobe-chat/compare/v1.51.15...v1.51.16)
|
6
56
|
|
7
57
|
<sup>Released on **2025-02-07**</sup>
|
package/Dockerfile.database
CHANGED
@@ -38,6 +38,7 @@ FROM base AS builder
|
|
38
38
|
ARG USE_CN_MIRROR
|
39
39
|
ARG NEXT_PUBLIC_BASE_PATH
|
40
40
|
ARG NEXT_PUBLIC_SERVICE_MODE
|
41
|
+
ARG NEXT_PUBLIC_ENABLE_NEXT_AUTH
|
41
42
|
ARG NEXT_PUBLIC_SENTRY_DSN
|
42
43
|
ARG NEXT_PUBLIC_ANALYTICS_POSTHOG
|
43
44
|
ARG NEXT_PUBLIC_POSTHOG_HOST
|
@@ -49,7 +50,7 @@ ARG NEXT_PUBLIC_UMAMI_WEBSITE_ID
|
|
49
50
|
ENV NEXT_PUBLIC_BASE_PATH="${NEXT_PUBLIC_BASE_PATH}"
|
50
51
|
|
51
52
|
ENV NEXT_PUBLIC_SERVICE_MODE="${NEXT_PUBLIC_SERVICE_MODE:-server}" \
|
52
|
-
NEXT_PUBLIC_ENABLE_NEXT_AUTH="1" \
|
53
|
+
NEXT_PUBLIC_ENABLE_NEXT_AUTH="${NEXT_PUBLIC_ENABLE_NEXT_AUTH:-1}" \
|
53
54
|
APP_URL="http://app.com" \
|
54
55
|
DATABASE_DRIVER="node" \
|
55
56
|
DATABASE_URL="postgres://postgres:password@localhost:5432/postgres" \
|
package/changelog/v1.json
CHANGED
@@ -1,4 +1,22 @@
|
|
1
1
|
[
|
2
|
+
{
|
3
|
+
"children": {
|
4
|
+
"fixes": [
|
5
|
+
"Fix static relative issues."
|
6
|
+
]
|
7
|
+
},
|
8
|
+
"date": "2025-02-08",
|
9
|
+
"version": "1.52.1"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"children": {
|
13
|
+
"features": [
|
14
|
+
"Refactor the auth condition in Next Auth."
|
15
|
+
]
|
16
|
+
},
|
17
|
+
"date": "2025-02-08",
|
18
|
+
"version": "1.52.0"
|
19
|
+
},
|
2
20
|
{
|
3
21
|
"children": {},
|
4
22
|
"date": "2025-02-07",
|
package/next.config.ts
CHANGED
@@ -179,6 +179,7 @@ const nextConfig: NextConfig = {
|
|
179
179
|
],
|
180
180
|
// when external packages in dev mode with turbopack, this config will lead to bundle error
|
181
181
|
serverExternalPackages: isProd ? ['@electric-sql/pglite'] : undefined,
|
182
|
+
|
182
183
|
transpilePackages: ['pdfjs-dist', 'mermaid'],
|
183
184
|
|
184
185
|
webpack(config) {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.52.1",
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
5
5
|
"keywords": [
|
6
6
|
"framework",
|
@@ -49,8 +49,9 @@ afterEach(() => {
|
|
49
49
|
describe('UserBanner', () => {
|
50
50
|
it('should render UserInfo and DataStatistics when auth is disabled', () => {
|
51
51
|
act(() => {
|
52
|
-
useUserStore.setState({ isSignedIn: false
|
52
|
+
useUserStore.setState({ isSignedIn: false });
|
53
53
|
});
|
54
|
+
enableAuth = false;
|
54
55
|
|
55
56
|
render(<UserBanner />);
|
56
57
|
|
@@ -75,7 +76,7 @@ describe('UserBanner', () => {
|
|
75
76
|
|
76
77
|
it('should render UserLoginOrSignup when user is not logged in with auth enabled', () => {
|
77
78
|
act(() => {
|
78
|
-
useUserStore.setState({ isSignedIn: false
|
79
|
+
useUserStore.setState({ isSignedIn: false });
|
79
80
|
});
|
80
81
|
enableClerk = true;
|
81
82
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { act, renderHook } from '@testing-library/react';
|
2
2
|
import { describe, expect, it, vi } from 'vitest';
|
3
3
|
|
4
|
-
import { ServerConfigStoreProvider } from '@/store/serverConfig';
|
4
|
+
import { ServerConfigStoreProvider } from '@/store/serverConfig/Provider';
|
5
5
|
import { useUserStore } from '@/store/user';
|
6
6
|
|
7
7
|
import { useCategory } from '../features/useCategory';
|
@@ -45,12 +45,10 @@ afterEach(() => {
|
|
45
45
|
enableClerk = true;
|
46
46
|
});
|
47
47
|
|
48
|
-
// 目前对 enableAuth 的判定是在 useUserStore 中,所以需要 mock useUserStore
|
49
|
-
// 类型定义: enableAuth: () => boolean
|
50
48
|
describe('useCategory', () => {
|
51
49
|
it('should return correct items when the user is logged in with authentication', () => {
|
52
50
|
act(() => {
|
53
|
-
useUserStore.setState({ isSignedIn: true
|
51
|
+
useUserStore.setState({ isSignedIn: true });
|
54
52
|
});
|
55
53
|
enableAuth = true;
|
56
54
|
enableClerk = false;
|
@@ -70,8 +68,9 @@ describe('useCategory', () => {
|
|
70
68
|
|
71
69
|
it('should return correct items when the user is not logged in', () => {
|
72
70
|
act(() => {
|
73
|
-
useUserStore.setState({ isSignedIn: false
|
71
|
+
useUserStore.setState({ isSignedIn: false });
|
74
72
|
});
|
73
|
+
enableAuth = true;
|
75
74
|
|
76
75
|
const { result } = renderHook(() => useCategory(), { wrapper });
|
77
76
|
|
@@ -88,9 +87,10 @@ describe('useCategory', () => {
|
|
88
87
|
|
89
88
|
it('should handle settings for non-authenticated users', () => {
|
90
89
|
act(() => {
|
91
|
-
useUserStore.setState({ isSignedIn: false
|
90
|
+
useUserStore.setState({ isSignedIn: false });
|
92
91
|
});
|
93
92
|
enableClerk = false;
|
93
|
+
enableAuth = false;
|
94
94
|
|
95
95
|
const { result } = renderHook(() => useCategory(), { wrapper });
|
96
96
|
|
@@ -5,6 +5,7 @@ import { useRouter } from 'next/navigation';
|
|
5
5
|
import { memo } from 'react';
|
6
6
|
import { Flexbox } from 'react-layout-kit';
|
7
7
|
|
8
|
+
import { enableAuth, enableNextAuth } from '@/const/auth';
|
8
9
|
import { isDeprecatedEdition } from '@/const/version';
|
9
10
|
import DataStatistics from '@/features/User/DataStatistics';
|
10
11
|
import UserInfo from '@/features/User/UserInfo';
|
@@ -15,11 +16,7 @@ import { authSelectors } from '@/store/user/selectors';
|
|
15
16
|
const UserBanner = memo(() => {
|
16
17
|
const router = useRouter();
|
17
18
|
const isLoginWithAuth = useUserStore(authSelectors.isLoginWithAuth);
|
18
|
-
const [
|
19
|
-
authSelectors.enabledAuth(s),
|
20
|
-
s.openLogin,
|
21
|
-
authSelectors.enabledNextAuth(s),
|
22
|
-
]);
|
19
|
+
const [signIn] = useUserStore((s) => [s.openLogin]);
|
23
20
|
|
24
21
|
return (
|
25
22
|
<Flexbox gap={12} paddingBlock={8}>
|
@@ -38,7 +35,7 @@ const UserBanner = memo(() => {
|
|
38
35
|
<UserLoginOrSignup
|
39
36
|
onClick={() => {
|
40
37
|
// If use NextAuth, call openLogin method directly
|
41
|
-
if (
|
38
|
+
if (enableNextAuth) {
|
42
39
|
signIn();
|
43
40
|
return;
|
44
41
|
}
|
@@ -12,6 +12,7 @@ import { useRouter } from 'next/navigation';
|
|
12
12
|
import { useTranslation } from 'react-i18next';
|
13
13
|
|
14
14
|
import { CellProps } from '@/components/Cell';
|
15
|
+
import { enableAuth } from '@/const/auth';
|
15
16
|
import { LOBE_CHAT_CLOUD } from '@/const/branding';
|
16
17
|
import { DOCUMENTS, FEEDBACK, OFFICIAL_URL, UTM_SOURCE } from '@/const/url';
|
17
18
|
import { isServerMode } from '@/const/version';
|
@@ -27,10 +28,9 @@ export const useCategory = () => {
|
|
27
28
|
const { canInstall, install } = usePWAInstall();
|
28
29
|
const { t } = useTranslation(['common', 'setting', 'auth']);
|
29
30
|
const { showCloudPromotion, hideDocs } = useServerConfigStore(featureFlagsSelectors);
|
30
|
-
const [isLogin, isLoginWithAuth
|
31
|
+
const [isLogin, isLoginWithAuth] = useUserStore((s) => [
|
31
32
|
authSelectors.isLogin(s),
|
32
33
|
authSelectors.isLoginWithAuth(s),
|
33
|
-
authSelectors.enabledAuth(s),
|
34
34
|
]);
|
35
35
|
|
36
36
|
const profile: CellProps[] = [
|
@@ -6,15 +6,15 @@ import { memo } from 'react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
7
7
|
|
8
8
|
import Cell, { CellProps } from '@/components/Cell';
|
9
|
+
import { enableAuth } from '@/const/auth';
|
9
10
|
import { isDeprecatedEdition } from '@/const/version';
|
10
11
|
import { ProfileTabs } from '@/store/global/initialState';
|
11
12
|
import { useUserStore } from '@/store/user';
|
12
13
|
import { authSelectors } from '@/store/user/selectors';
|
13
14
|
|
14
15
|
const Category = memo(() => {
|
15
|
-
const [isLogin,
|
16
|
+
const [isLogin, isLoginWithClerk, signOut] = useUserStore((s) => [
|
16
17
|
authSelectors.isLogin(s),
|
17
|
-
authSelectors.enabledAuth(s),
|
18
18
|
authSelectors.isLoginWithClerk(s),
|
19
19
|
s.logout,
|
20
20
|
]);
|
@@ -4,6 +4,7 @@ import { Form, type ItemGroup } from '@lobehub/ui';
|
|
4
4
|
import { memo } from 'react';
|
5
5
|
import { useTranslation } from 'react-i18next';
|
6
6
|
|
7
|
+
import { enableAuth } from '@/const/auth';
|
7
8
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
8
9
|
import AvatarWithUpload from '@/features/AvatarWithUpload';
|
9
10
|
import UserAvatar from '@/features/User/UserAvatar';
|
@@ -14,8 +15,7 @@ type SettingItemGroup = ItemGroup;
|
|
14
15
|
|
15
16
|
const Client = memo<{ mobile?: boolean }>(() => {
|
16
17
|
const [isLoginWithNextAuth] = useUserStore((s) => [authSelectors.isLoginWithNextAuth(s)]);
|
17
|
-
const [
|
18
|
-
s.enableAuth(),
|
18
|
+
const [nickname, username, userProfile] = useUserStore((s) => [
|
19
19
|
userProfileSelectors.nickName(s),
|
20
20
|
userProfileSelectors.username(s),
|
21
21
|
userProfileSelectors.userProfile(s),
|
@@ -4,6 +4,7 @@ import Link from 'next/link';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
5
5
|
|
6
6
|
import type { MenuProps } from '@/components/Menu';
|
7
|
+
import { enableAuth } from '@/const/auth';
|
7
8
|
import { isDeprecatedEdition } from '@/const/version';
|
8
9
|
import { ProfileTabs } from '@/store/global/initialState';
|
9
10
|
import { useUserStore } from '@/store/user';
|
@@ -11,10 +12,7 @@ import { authSelectors } from '@/store/user/slices/auth/selectors';
|
|
11
12
|
|
12
13
|
export const useCategory = () => {
|
13
14
|
const { t } = useTranslation('auth');
|
14
|
-
const [
|
15
|
-
authSelectors.enabledAuth(s),
|
16
|
-
authSelectors.isLoginWithClerk(s),
|
17
|
-
]);
|
15
|
+
const [isLoginWithClerk] = useUserStore((s) => [authSelectors.isLoginWithClerk(s)]);
|
18
16
|
|
19
17
|
const cateItems: MenuProps['items'] = [
|
20
18
|
{
|
@@ -6,13 +6,12 @@ import { memo } from 'react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
7
7
|
import { Flexbox } from 'react-layout-kit';
|
8
8
|
|
9
|
+
import { enableAuth } from '@/const/auth';
|
9
10
|
import { useActiveSettingsKey } from '@/hooks/useActiveTabKey';
|
10
11
|
import { useQueryRoute } from '@/hooks/useQueryRoute';
|
11
12
|
import { useShowMobileWorkspace } from '@/hooks/useShowMobileWorkspace';
|
12
13
|
import { SettingsTabs } from '@/store/global/initialState';
|
13
14
|
import { useSessionStore } from '@/store/session';
|
14
|
-
import { useUserStore } from '@/store/user';
|
15
|
-
import { authSelectors } from '@/store/user/selectors';
|
16
15
|
import { mobileHeaderSticky } from '@/styles/mobileHeader';
|
17
16
|
|
18
17
|
const Header = memo(() => {
|
@@ -22,7 +21,6 @@ const Header = memo(() => {
|
|
22
21
|
const showMobileWorkspace = useShowMobileWorkspace();
|
23
22
|
const activeSettingsKey = useActiveSettingsKey();
|
24
23
|
const isSessionActive = useSessionStore((s) => !!s.activeId);
|
25
|
-
const enableAuth = useUserStore(authSelectors.enabledAuth);
|
26
24
|
|
27
25
|
const handleBackClick = () => {
|
28
26
|
if (isSessionActive && showMobileWorkspace) {
|
package/src/config/auth.ts
CHANGED
@@ -217,8 +217,7 @@ export const getAuthConfig = () => {
|
|
217
217
|
CLERK_WEBHOOK_SECRET: process.env.CLERK_WEBHOOK_SECRET,
|
218
218
|
|
219
219
|
// Next Auth
|
220
|
-
NEXT_PUBLIC_ENABLE_NEXT_AUTH:
|
221
|
-
!!process.env.NEXT_AUTH_SECRET || process.env.NEXT_PUBLIC_ENABLE_NEXT_AUTH === '1',
|
220
|
+
NEXT_PUBLIC_ENABLE_NEXT_AUTH: process.env.NEXT_PUBLIC_ENABLE_NEXT_AUTH === '1',
|
222
221
|
NEXT_AUTH_SSO_PROVIDERS: process.env.NEXT_AUTH_SSO_PROVIDERS,
|
223
222
|
NEXT_AUTH_SECRET: process.env.NEXT_AUTH_SECRET,
|
224
223
|
NEXT_AUTH_DEBUG: !!process.env.NEXT_AUTH_DEBUG,
|
package/src/const/auth.ts
CHANGED
@@ -2,8 +2,7 @@ import { authEnv } from '@/config/auth';
|
|
2
2
|
|
3
3
|
export const enableClerk = authEnv.NEXT_PUBLIC_ENABLE_CLERK_AUTH;
|
4
4
|
export const enableNextAuth = authEnv.NEXT_PUBLIC_ENABLE_NEXT_AUTH;
|
5
|
-
export const enableAuth =
|
6
|
-
authEnv.NEXT_PUBLIC_ENABLE_CLERK_AUTH || authEnv.NEXT_PUBLIC_ENABLE_NEXT_AUTH;
|
5
|
+
export const enableAuth = enableClerk || enableNextAuth || false;
|
7
6
|
|
8
7
|
export const LOBE_CHAT_AUTH_HEADER = 'X-lobe-chat-auth';
|
9
8
|
|
@@ -5,6 +5,7 @@ import { Flexbox } from 'react-layout-kit';
|
|
5
5
|
|
6
6
|
import BrandWatermark from '@/components/BrandWatermark';
|
7
7
|
import Menu from '@/components/Menu';
|
8
|
+
import { enableAuth, enableNextAuth } from '@/const/auth';
|
8
9
|
import { isDeprecatedEdition } from '@/const/version';
|
9
10
|
import { useUserStore } from '@/store/user';
|
10
11
|
import { authSelectors } from '@/store/user/selectors';
|
@@ -19,12 +20,7 @@ import { useMenu } from './useMenu';
|
|
19
20
|
const PanelContent = memo<{ closePopover: () => void }>(({ closePopover }) => {
|
20
21
|
const router = useRouter();
|
21
22
|
const isLoginWithAuth = useUserStore(authSelectors.isLoginWithAuth);
|
22
|
-
const [openSignIn, signOut
|
23
|
-
s.openLogin,
|
24
|
-
s.logout,
|
25
|
-
s.enableAuth(),
|
26
|
-
s.enabledNextAuth,
|
27
|
-
]);
|
23
|
+
const [openSignIn, signOut] = useUserStore((s) => [s.openLogin, s.logout]);
|
28
24
|
const { mainItems, logoutItems } = useMenu();
|
29
25
|
|
30
26
|
const handleSignIn = () => {
|
@@ -36,7 +32,7 @@ const PanelContent = memo<{ closePopover: () => void }>(({ closePopover }) => {
|
|
36
32
|
signOut();
|
37
33
|
closePopover();
|
38
34
|
// NextAuth doesn't need to redirect to login page
|
39
|
-
if (
|
35
|
+
if (enableNextAuth) return;
|
40
36
|
router.push('/login');
|
41
37
|
};
|
42
38
|
|
@@ -21,6 +21,7 @@ import { useTranslation } from 'react-i18next';
|
|
21
21
|
import { Flexbox } from 'react-layout-kit';
|
22
22
|
|
23
23
|
import type { MenuProps } from '@/components/Menu';
|
24
|
+
import { enableAuth } from '@/const/auth';
|
24
25
|
import { LOBE_CHAT_CLOUD } from '@/const/branding';
|
25
26
|
import {
|
26
27
|
DISCORD,
|
@@ -68,8 +69,7 @@ export const useMenu = () => {
|
|
68
69
|
const hasNewVersion = useNewVersion();
|
69
70
|
const { t } = useTranslation(['common', 'setting', 'auth']);
|
70
71
|
const { showCloudPromotion, hideDocs } = useServerConfigStore(featureFlagsSelectors);
|
71
|
-
const [
|
72
|
-
authSelectors.enabledAuth(s),
|
72
|
+
const [isLogin, isLoginWithAuth] = useUserStore((s) => [
|
73
73
|
authSelectors.isLogin(s),
|
74
74
|
authSelectors.isLoginWithAuth(s),
|
75
75
|
]);
|
@@ -68,13 +68,12 @@ vi.mock('@/const/version', () => ({
|
|
68
68
|
// 定义一个变量来存储 enableAuth 的值
|
69
69
|
let enableAuth = true;
|
70
70
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
});
|
71
|
+
// 模拟 @/const/auth 模块
|
72
|
+
vi.mock('@/const/auth', () => ({
|
73
|
+
get enableAuth() {
|
74
|
+
return enableAuth;
|
75
|
+
},
|
76
|
+
}));
|
78
77
|
|
79
78
|
describe('PanelContent', () => {
|
80
79
|
const closePopover = vi.fn();
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { act, renderHook } from '@testing-library/react';
|
2
2
|
import { describe, expect, it, vi } from 'vitest';
|
3
3
|
|
4
|
-
import { ServerConfigStoreProvider } from '@/store/serverConfig';
|
4
|
+
import { ServerConfigStoreProvider } from '@/store/serverConfig/Provider';
|
5
5
|
import { useUserStore } from '@/store/user';
|
6
6
|
|
7
7
|
import { useMenu } from '../UserPanel/useMenu';
|
@@ -5,6 +5,7 @@ import { memo } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
6
6
|
import { createStoreUpdater } from 'zustand-utils';
|
7
7
|
|
8
|
+
import { enableNextAuth } from '@/const/auth';
|
8
9
|
import { useIsMobile } from '@/hooks/useIsMobile';
|
9
10
|
import { useEnabledDataSync } from '@/hooks/useSyncData';
|
10
11
|
import { useAgentStore } from '@/store/agent';
|
@@ -37,10 +38,12 @@ const StoreInitialization = memo(() => {
|
|
37
38
|
// init the system preference
|
38
39
|
useInitSystemStatus();
|
39
40
|
|
41
|
+
// fetch server config
|
42
|
+
const useFetchServerConfig = useServerConfigStore((s) => s.useInitServerConfig);
|
43
|
+
useFetchServerConfig();
|
44
|
+
|
40
45
|
// Update NextAuth status
|
41
46
|
const useUserStoreUpdater = createStoreUpdater(useUserStore);
|
42
|
-
const enableNextAuth = useServerConfigStore(serverConfigSelectors.enabledOAuthSSO);
|
43
|
-
useUserStoreUpdater('enabledNextAuth', enableNextAuth);
|
44
47
|
const oAuthSSOProviders = useServerConfigStore(serverConfigSelectors.oAuthSSOProviders);
|
45
48
|
useUserStoreUpdater('oAuthSSOProviders', oAuthSSOProviders);
|
46
49
|
|
@@ -4,7 +4,7 @@ import { appEnv } from '@/config/app';
|
|
4
4
|
import { getServerFeatureFlagsValue } from '@/config/featureFlags';
|
5
5
|
import DevPanel from '@/features/DevPanel';
|
6
6
|
import { getServerGlobalConfig } from '@/server/globalConfig';
|
7
|
-
import { ServerConfigStoreProvider } from '@/store/serverConfig';
|
7
|
+
import { ServerConfigStoreProvider } from '@/store/serverConfig/Provider';
|
8
8
|
import { getAntdLocale } from '@/utils/locale';
|
9
9
|
|
10
10
|
import AntdV5MonkeyPatch from './AntdV5MonkeyPatch';
|
@@ -37,7 +37,7 @@ const GlobalLayout = async ({
|
|
37
37
|
|
38
38
|
// get default feature flags to use with ssr
|
39
39
|
const serverFeatureFlags = getServerFeatureFlagsValue();
|
40
|
-
const serverConfig = getServerGlobalConfig();
|
40
|
+
const serverConfig = await getServerGlobalConfig();
|
41
41
|
return (
|
42
42
|
<StyleRegistry>
|
43
43
|
<Locale antdLocale={antdLocale} defaultLang={userLocale}>
|
package/src/middleware.ts
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';
|
2
2
|
import { NextRequest, NextResponse } from 'next/server';
|
3
3
|
import { UAParser } from 'ua-parser-js';
|
4
|
-
import urlJoin from 'url-join';
|
5
4
|
|
6
5
|
import { authEnv } from '@/config/auth';
|
7
6
|
import { LOBE_THEME_APPEARANCE } from '@/const/theme';
|
@@ -84,23 +83,21 @@ const defaultMiddleware = (request: NextRequest) => {
|
|
84
83
|
if (['/api', '/trpc', '/webapi'].some((path) => url.pathname.startsWith(path)))
|
85
84
|
return NextResponse.next();
|
86
85
|
|
87
|
-
//
|
88
|
-
//
|
89
|
-
//
|
90
|
-
|
86
|
+
// refs: https://github.com/lobehub/lobe-chat/pull/5866
|
87
|
+
// new handle segment rewrite: /${route}${originalPathname}
|
88
|
+
// / -> /zh-CN__0__dark
|
89
|
+
// /discover -> /zh-CN__0__dark/discover
|
90
|
+
const nextPathname = `/${route}` + (url.pathname === '/' ? '' : url.pathname);
|
91
91
|
console.log(`[rewrite] ${url.pathname} -> ${nextPathname}`);
|
92
|
+
|
92
93
|
url.pathname = nextPathname;
|
93
94
|
|
94
|
-
return NextResponse.rewrite(url);
|
95
|
+
return NextResponse.rewrite(url, { status: 200 });
|
95
96
|
};
|
96
97
|
|
97
|
-
const publicRoute = ['/', '/discover'];
|
98
|
-
|
99
98
|
// Initialize an Edge compatible NextAuth middleware
|
100
99
|
const nextAuthMiddleware = NextAuthEdge.auth((req) => {
|
101
100
|
const response = defaultMiddleware(req);
|
102
|
-
// skip the '/' route
|
103
|
-
if (publicRoute.some((url) => req.nextUrl.pathname.startsWith(url))) return response;
|
104
101
|
|
105
102
|
// Just check if session exists
|
106
103
|
const session = req.auth;
|
@@ -37,7 +37,7 @@ describe('configRouter', () => {
|
|
37
37
|
const response = await router.getGlobalConfig();
|
38
38
|
|
39
39
|
// Assert
|
40
|
-
const result = response.languageModel?.openai;
|
40
|
+
const result = response.serverConfig.languageModel?.openai;
|
41
41
|
|
42
42
|
expect(result).toMatchSnapshot();
|
43
43
|
process.env.OPENAI_MODEL_LIST = '';
|
@@ -49,7 +49,7 @@ describe('configRouter', () => {
|
|
49
49
|
|
50
50
|
const response = await router.getGlobalConfig();
|
51
51
|
|
52
|
-
const result = response.languageModel?.openai?.serverModelCards;
|
52
|
+
const result = response.serverConfig.languageModel?.openai?.serverModelCards;
|
53
53
|
|
54
54
|
expect(result).toMatchSnapshot();
|
55
55
|
|
@@ -62,7 +62,7 @@ describe('configRouter', () => {
|
|
62
62
|
|
63
63
|
const response = await router.getGlobalConfig();
|
64
64
|
|
65
|
-
const result = response.languageModel?.openai?.serverModelCards;
|
65
|
+
const result = response.serverConfig.languageModel?.openai?.serverModelCards;
|
66
66
|
|
67
67
|
expect(result?.find((s) => s.id === 'gpt-4-0125-preview')?.displayName).toEqual(
|
68
68
|
'gpt-4-32k',
|
@@ -76,7 +76,7 @@ describe('configRouter', () => {
|
|
76
76
|
|
77
77
|
const response = await router.getGlobalConfig();
|
78
78
|
|
79
|
-
const result = response.languageModel?.openai?.serverModelCards;
|
79
|
+
const result = response.serverConfig.languageModel?.openai?.serverModelCards;
|
80
80
|
|
81
81
|
expect(result?.find((r) => r.id === 'gpt-4')).toBeUndefined();
|
82
82
|
|
@@ -88,7 +88,7 @@ describe('configRouter', () => {
|
|
88
88
|
|
89
89
|
const response = await router.getGlobalConfig();
|
90
90
|
|
91
|
-
const result = response.languageModel?.openai?.serverModelCards;
|
91
|
+
const result = response.serverConfig.languageModel?.openai?.serverModelCards;
|
92
92
|
|
93
93
|
const model = result?.find((o) => o.id === 'gpt-4-1106-preview');
|
94
94
|
|
@@ -102,7 +102,7 @@ describe('configRouter', () => {
|
|
102
102
|
|
103
103
|
const response = await router.getGlobalConfig();
|
104
104
|
|
105
|
-
const result = response.languageModel?.openai?.serverModelCards;
|
105
|
+
const result = response.serverConfig.languageModel?.openai?.serverModelCards;
|
106
106
|
|
107
107
|
expect(result).toContainEqual({
|
108
108
|
displayName: 'model1',
|
@@ -137,7 +137,7 @@ describe('configRouter', () => {
|
|
137
137
|
const response = await router.getGlobalConfig();
|
138
138
|
|
139
139
|
// Assert
|
140
|
-
const result = response.languageModel?.openrouter;
|
140
|
+
const result = response.serverConfig.languageModel?.openrouter;
|
141
141
|
|
142
142
|
expect(result).toMatchSnapshot();
|
143
143
|
|
@@ -1,12 +1,17 @@
|
|
1
|
+
import { getServerFeatureFlagsValue } from '@/config/featureFlags';
|
1
2
|
import { publicProcedure, router } from '@/libs/trpc';
|
2
3
|
import { getServerDefaultAgentConfig, getServerGlobalConfig } from '@/server/globalConfig';
|
4
|
+
import { GlobalRuntimeConfig } from '@/types/serverConfig';
|
3
5
|
|
4
6
|
export const configRouter = router({
|
5
7
|
getDefaultAgentConfig: publicProcedure.query(async () => {
|
6
8
|
return getServerDefaultAgentConfig();
|
7
9
|
}),
|
8
10
|
|
9
|
-
getGlobalConfig: publicProcedure.query(async () => {
|
10
|
-
|
11
|
+
getGlobalConfig: publicProcedure.query(async (): Promise<GlobalRuntimeConfig> => {
|
12
|
+
const serverConfig = await getServerGlobalConfig();
|
13
|
+
const serverFeatureFlags = getServerFeatureFlagsValue();
|
14
|
+
|
15
|
+
return { serverConfig, serverFeatureFlags };
|
11
16
|
}),
|
12
17
|
});
|