@lobehub/chat 0.158.2 → 0.159.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 +4 -0
- package/CHANGELOG.md +58 -0
- package/Dockerfile +3 -0
- package/README.md +1 -0
- package/README.zh-CN.md +1 -0
- package/docs/self-hosting/advanced/authentication.mdx +9 -0
- package/docs/self-hosting/advanced/authentication.zh-CN.mdx +9 -0
- package/docs/self-hosting/environment-variables/model-provider.mdx +16 -7
- package/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx +16 -7
- package/docs/usage/features/multi-ai-providers.mdx +1 -0
- package/docs/usage/features/multi-ai-providers.zh-CN.mdx +1 -0
- package/locales/ar/error.json +2 -0
- package/locales/ar/modelProvider.json +12 -0
- package/locales/bg-BG/error.json +2 -0
- package/locales/bg-BG/modelProvider.json +12 -0
- package/locales/de-DE/error.json +2 -0
- package/locales/de-DE/modelProvider.json +12 -0
- package/locales/en-US/error.json +2 -0
- package/locales/en-US/modelProvider.json +12 -0
- package/locales/es-ES/error.json +2 -0
- package/locales/es-ES/modelProvider.json +12 -0
- package/locales/fr-FR/error.json +2 -0
- package/locales/fr-FR/modelProvider.json +12 -0
- package/locales/it-IT/error.json +2 -0
- package/locales/it-IT/modelProvider.json +12 -0
- package/locales/ja-JP/error.json +2 -0
- package/locales/ja-JP/modelProvider.json +12 -0
- package/locales/ko-KR/error.json +2 -0
- package/locales/ko-KR/modelProvider.json +12 -0
- package/locales/nl-NL/error.json +2 -0
- package/locales/nl-NL/modelProvider.json +12 -0
- package/locales/pl-PL/error.json +2 -0
- package/locales/pl-PL/modelProvider.json +12 -0
- package/locales/pt-BR/error.json +2 -0
- package/locales/pt-BR/modelProvider.json +12 -0
- package/locales/ru-RU/error.json +2 -0
- package/locales/ru-RU/modelProvider.json +12 -0
- package/locales/tr-TR/error.json +2 -0
- package/locales/tr-TR/modelProvider.json +12 -0
- package/locales/vi-VN/error.json +2 -0
- package/locales/vi-VN/modelProvider.json +12 -0
- package/locales/zh-CN/error.json +2 -0
- package/locales/zh-CN/modelProvider.json +12 -0
- package/locales/zh-TW/error.json +2 -0
- package/locales/zh-TW/modelProvider.json +12 -0
- package/package.json +2 -2
- package/src/app/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/Main.tsx +13 -15
- package/src/app/(main)/settings/common/features/Common.tsx +11 -8
- package/src/app/(main)/settings/common/index.tsx +1 -9
- package/src/app/(main)/settings/llm/DeepSeek/index.tsx +21 -0
- package/src/app/(main)/settings/llm/index.tsx +2 -0
- package/src/app/api/chat/agentRuntime.test.ts +17 -0
- package/src/app/api/chat/agentRuntime.ts +5 -0
- package/src/app/api/errorResponse.test.ts +6 -0
- package/src/app/api/errorResponse.ts +3 -0
- package/src/components/ModelIcon/index.tsx +2 -0
- package/src/components/ModelProviderIcon/index.tsx +5 -0
- package/src/components/ModelTag/ModelIcon.tsx +2 -0
- package/src/config/modelProviders/deepseek.ts +23 -0
- package/src/config/modelProviders/index.ts +4 -0
- package/src/config/server/provider.ts +10 -0
- package/src/const/settings/index.ts +6 -0
- package/src/features/Conversation/Error/APIKeyForm/ProviderAvatar.tsx +5 -0
- package/src/features/Conversation/Error/APIKeyForm/index.tsx +4 -0
- package/src/features/Conversation/Error/OAuthForm.tsx +6 -4
- package/src/features/Conversation/Error/index.tsx +1 -0
- package/src/features/User/__tests__/UserAvatar.test.tsx +8 -3
- package/src/features/User/__tests__/useMenu.test.tsx +3 -3
- package/src/libs/agent-runtime/AgentRuntime.ts +7 -0
- package/src/libs/agent-runtime/deepseek/index.test.ts +254 -0
- package/src/libs/agent-runtime/deepseek/index.ts +15 -0
- package/src/libs/agent-runtime/error.ts +3 -0
- package/src/libs/agent-runtime/index.ts +1 -0
- package/src/libs/agent-runtime/types/type.ts +1 -0
- package/src/libs/next-auth/index.ts +0 -7
- package/src/locales/default/error.ts +3 -0
- package/src/locales/default/modelProvider.ts +12 -0
- package/src/migrations/FromV3ToV4/types/v3.ts +0 -8
- package/src/server/globalConfig/index.ts +4 -0
- package/src/services/__tests__/chat.test.ts +16 -0
- package/src/services/chat.ts +3 -0
- package/src/store/serverConfig/selectors.ts +1 -0
- package/src/store/user/slices/auth/action.test.ts +61 -0
- package/src/store/user/slices/auth/action.ts +17 -15
- package/src/store/user/slices/auth/selectors.test.ts +18 -2
- package/src/store/user/slices/auth/selectors.ts +4 -4
- package/src/store/user/slices/settings/actions/llm.ts +2 -0
- package/src/types/next-auth.d.ts +23 -0
- package/src/types/serverConfig.ts +1 -0
- package/src/types/settings/modelProvider.ts +1 -0
- package/src/hooks/useOAuthSession.ts +0 -24
|
@@ -13,6 +13,7 @@ import { parseAgentConfig } from './parseDefaultAgent';
|
|
|
13
13
|
|
|
14
14
|
export const getServerGlobalConfig = () => {
|
|
15
15
|
const {
|
|
16
|
+
ACCESS_CODES,
|
|
16
17
|
ENABLE_LANGFUSE,
|
|
17
18
|
|
|
18
19
|
DEFAULT_AGENT_CONFIG,
|
|
@@ -23,6 +24,7 @@ export const getServerGlobalConfig = () => {
|
|
|
23
24
|
ENABLED_AWS_BEDROCK,
|
|
24
25
|
ENABLED_GOOGLE,
|
|
25
26
|
ENABLED_GROQ,
|
|
27
|
+
ENABLED_DEEPSEEK,
|
|
26
28
|
ENABLED_PERPLEXITY,
|
|
27
29
|
ENABLED_ANTHROPIC,
|
|
28
30
|
ENABLED_MINIMAX,
|
|
@@ -48,6 +50,7 @@ export const getServerGlobalConfig = () => {
|
|
|
48
50
|
config: parseAgentConfig(DEFAULT_AGENT_CONFIG),
|
|
49
51
|
},
|
|
50
52
|
|
|
53
|
+
enabledAccessCode: ACCESS_CODES?.length > 0,
|
|
51
54
|
enabledOAuthSSO: enableNextAuth,
|
|
52
55
|
languageModel: {
|
|
53
56
|
anthropic: {
|
|
@@ -63,6 +66,7 @@ export const getServerGlobalConfig = () => {
|
|
|
63
66
|
}),
|
|
64
67
|
},
|
|
65
68
|
bedrock: { enabled: ENABLED_AWS_BEDROCK },
|
|
69
|
+
deepseek: { enabled: ENABLED_DEEPSEEK },
|
|
66
70
|
google: { enabled: ENABLED_GOOGLE },
|
|
67
71
|
groq: { enabled: ENABLED_GROQ },
|
|
68
72
|
minimax: { enabled: ENABLED_MINIMAX },
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
LobeBedrockAI,
|
|
11
11
|
LobeGoogleAI,
|
|
12
12
|
LobeGroq,
|
|
13
|
+
LobeDeepSeekAI,
|
|
13
14
|
LobeMistralAI,
|
|
14
15
|
LobeMoonshotAI,
|
|
15
16
|
LobeOllamaAI,
|
|
@@ -873,6 +874,21 @@ describe('AgentRuntimeOnClient', () => {
|
|
|
873
874
|
expect(runtime['_runtime']).toBeInstanceOf(LobeGroq);
|
|
874
875
|
});
|
|
875
876
|
|
|
877
|
+
it('DeepSeek provider: with apiKey', async () => {
|
|
878
|
+
merge(initialSettingsState, {
|
|
879
|
+
settings: {
|
|
880
|
+
languageModel: {
|
|
881
|
+
deepseek: {
|
|
882
|
+
apiKey: 'user-deepseek-key',
|
|
883
|
+
},
|
|
884
|
+
},
|
|
885
|
+
},
|
|
886
|
+
} as UserSettingsState) as unknown as UserStore;
|
|
887
|
+
const runtime = await initializeWithClientStore(ModelProvider.DeepSeek, {});
|
|
888
|
+
expect(runtime).toBeInstanceOf(AgentRuntime);
|
|
889
|
+
expect(runtime['_runtime']).toBeInstanceOf(LobeDeepSeekAI);
|
|
890
|
+
});
|
|
891
|
+
|
|
876
892
|
/**
|
|
877
893
|
* Should not have a unknown provider in client, but has
|
|
878
894
|
* similar cases in server side
|
package/src/services/chat.ts
CHANGED
|
@@ -6,6 +6,7 @@ export const featureFlagsSelectors = (s: ServerConfigStore) =>
|
|
|
6
6
|
mapFeatureFlagsEnvToState(s.featureFlags);
|
|
7
7
|
|
|
8
8
|
export const serverConfigSelectors = {
|
|
9
|
+
enabledAccessCode: (s: ServerConfigStore) => !!s.serverConfig?.enabledAccessCode,
|
|
9
10
|
enabledOAuthSSO: (s: ServerConfigStore) => s.serverConfig.enabledOAuthSSO,
|
|
10
11
|
enabledTelemetryChat: (s: ServerConfigStore) => s.serverConfig.telemetry.langfuse || false,
|
|
11
12
|
isMobile: (s: ServerConfigStore) => s.isMobile || false,
|
|
@@ -43,6 +43,16 @@ afterEach(() => {
|
|
|
43
43
|
enableClerk = false;
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Mock nextauth 库相关方法
|
|
48
|
+
*/
|
|
49
|
+
vi.mock('next-auth/react', async () => {
|
|
50
|
+
return {
|
|
51
|
+
signIn: vi.fn(),
|
|
52
|
+
signOut: vi.fn(),
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
|
|
46
56
|
describe('createAuthSlice', () => {
|
|
47
57
|
describe('refreshUserConfig', () => {
|
|
48
58
|
it('should refresh user config', async () => {
|
|
@@ -162,6 +172,32 @@ describe('createAuthSlice', () => {
|
|
|
162
172
|
|
|
163
173
|
expect(clerkSignOutMock).not.toHaveBeenCalled();
|
|
164
174
|
});
|
|
175
|
+
|
|
176
|
+
it('should call next-auth signOut when NextAuth is enabled', async () => {
|
|
177
|
+
useUserStore.setState({ enabledNextAuth: () => true });
|
|
178
|
+
|
|
179
|
+
const { result } = renderHook(() => useUserStore());
|
|
180
|
+
|
|
181
|
+
await act(async () => {
|
|
182
|
+
await result.current.logout();
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const { signOut } = await import('next-auth/react');
|
|
186
|
+
|
|
187
|
+
expect(signOut).toHaveBeenCalled();
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('should not call next-auth signOut when NextAuth is disabled', async () => {
|
|
191
|
+
const { result } = renderHook(() => useUserStore());
|
|
192
|
+
|
|
193
|
+
await act(async () => {
|
|
194
|
+
await result.current.logout();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const { signOut } = await import('next-auth/react');
|
|
198
|
+
|
|
199
|
+
expect(signOut).not.toHaveBeenCalled();
|
|
200
|
+
});
|
|
165
201
|
});
|
|
166
202
|
|
|
167
203
|
describe('openLogin', () => {
|
|
@@ -190,6 +226,31 @@ describe('createAuthSlice', () => {
|
|
|
190
226
|
|
|
191
227
|
expect(clerkSignInMock).not.toHaveBeenCalled();
|
|
192
228
|
});
|
|
229
|
+
|
|
230
|
+
it('should call next-auth signIn when NextAuth is enabled', async () => {
|
|
231
|
+
useUserStore.setState({ enabledNextAuth: () => true });
|
|
232
|
+
|
|
233
|
+
const { result } = renderHook(() => useUserStore());
|
|
234
|
+
|
|
235
|
+
await act(async () => {
|
|
236
|
+
await result.current.openLogin();
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
const { signIn } = await import('next-auth/react');
|
|
240
|
+
|
|
241
|
+
expect(signIn).toHaveBeenCalled();
|
|
242
|
+
});
|
|
243
|
+
it('should not call next-auth signIn when NextAuth is disabled', async () => {
|
|
244
|
+
const { result } = renderHook(() => useUserStore());
|
|
245
|
+
|
|
246
|
+
await act(async () => {
|
|
247
|
+
await result.current.openLogin();
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
const { signIn } = await import('next-auth/react');
|
|
251
|
+
|
|
252
|
+
expect(signIn).not.toHaveBeenCalled();
|
|
253
|
+
});
|
|
193
254
|
});
|
|
194
255
|
|
|
195
256
|
describe('openUserProfile', () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import useSWR, { SWRResponse, mutate } from 'swr';
|
|
2
2
|
import { StateCreator } from 'zustand/vanilla';
|
|
3
3
|
|
|
4
|
-
import { enableClerk
|
|
4
|
+
import { enableClerk } from '@/const/auth';
|
|
5
5
|
import { UserConfig, userService } from '@/services/user';
|
|
6
6
|
import { switchLang } from '@/utils/client/switchLang';
|
|
7
7
|
import { setNamespace } from '@/utils/storeDebug';
|
|
@@ -13,8 +13,9 @@ const n = setNamespace('auth');
|
|
|
13
13
|
const USER_CONFIG_FETCH_KEY = 'fetchUserConfig';
|
|
14
14
|
|
|
15
15
|
export interface UserAuthAction {
|
|
16
|
+
enableAuth: () => boolean;
|
|
17
|
+
enabledNextAuth: () => boolean;
|
|
16
18
|
getUserConfig: () => void;
|
|
17
|
-
login: () => Promise<void>;
|
|
18
19
|
/**
|
|
19
20
|
* universal logout method
|
|
20
21
|
*/
|
|
@@ -24,8 +25,8 @@ export interface UserAuthAction {
|
|
|
24
25
|
*/
|
|
25
26
|
openLogin: () => Promise<void>;
|
|
26
27
|
openUserProfile: () => Promise<void>;
|
|
27
|
-
refreshUserConfig: () => Promise<void>;
|
|
28
28
|
|
|
29
|
+
refreshUserConfig: () => Promise<void>;
|
|
29
30
|
useFetchUserConfig: (initServer: boolean) => SWRResponse<UserConfig | undefined>;
|
|
30
31
|
}
|
|
31
32
|
|
|
@@ -35,13 +36,15 @@ export const createAuthSlice: StateCreator<
|
|
|
35
36
|
[],
|
|
36
37
|
UserAuthAction
|
|
37
38
|
> = (set, get) => ({
|
|
39
|
+
enableAuth: () => {
|
|
40
|
+
return enableClerk || get()?.enabledNextAuth();
|
|
41
|
+
},
|
|
42
|
+
enabledNextAuth: () => {
|
|
43
|
+
return !!get()?.serverConfig.enabledOAuthSSO;
|
|
44
|
+
},
|
|
38
45
|
getUserConfig: () => {
|
|
39
46
|
console.log(n('userconfig'));
|
|
40
47
|
},
|
|
41
|
-
login: async () => {
|
|
42
|
-
// TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法
|
|
43
|
-
console.log(n('login'));
|
|
44
|
-
},
|
|
45
48
|
logout: async () => {
|
|
46
49
|
if (enableClerk) {
|
|
47
50
|
get().clerkSignOut?.({ redirectUrl: location.toString() });
|
|
@@ -49,9 +52,10 @@ export const createAuthSlice: StateCreator<
|
|
|
49
52
|
return;
|
|
50
53
|
}
|
|
51
54
|
|
|
55
|
+
const enableNextAuth = get().enabledNextAuth();
|
|
52
56
|
if (enableNextAuth) {
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
const { signOut } = await import('next-auth/react');
|
|
58
|
+
signOut();
|
|
55
59
|
}
|
|
56
60
|
},
|
|
57
61
|
openLogin: async () => {
|
|
@@ -63,20 +67,19 @@ export const createAuthSlice: StateCreator<
|
|
|
63
67
|
return;
|
|
64
68
|
}
|
|
65
69
|
|
|
70
|
+
const enableNextAuth = get().enabledNextAuth();
|
|
66
71
|
if (enableNextAuth) {
|
|
67
|
-
|
|
72
|
+
const { signIn } = await import('next-auth/react');
|
|
73
|
+
signIn();
|
|
68
74
|
}
|
|
69
75
|
},
|
|
76
|
+
|
|
70
77
|
openUserProfile: async () => {
|
|
71
78
|
if (enableClerk) {
|
|
72
79
|
get().clerkOpenUserProfile?.();
|
|
73
80
|
|
|
74
81
|
return;
|
|
75
82
|
}
|
|
76
|
-
|
|
77
|
-
if (enableNextAuth) {
|
|
78
|
-
// TODO: 针对开启 next-auth 的场景,需要在这里调用打开 profile 页
|
|
79
|
-
}
|
|
80
83
|
},
|
|
81
84
|
refreshUserConfig: async () => {
|
|
82
85
|
await mutate([USER_CONFIG_FETCH_KEY, true]);
|
|
@@ -84,7 +87,6 @@ export const createAuthSlice: StateCreator<
|
|
|
84
87
|
// when get the user config ,refresh the model provider list to the latest
|
|
85
88
|
get().refreshModelProviderList();
|
|
86
89
|
},
|
|
87
|
-
|
|
88
90
|
useFetchUserConfig: (initServer) =>
|
|
89
91
|
useSWR<UserConfig | undefined>(
|
|
90
92
|
[USER_CONFIG_FETCH_KEY, initServer],
|
|
@@ -31,6 +31,7 @@ describe('userProfileSelectors', () => {
|
|
|
31
31
|
const store: UserStore = {
|
|
32
32
|
isSignedIn: false,
|
|
33
33
|
user: null,
|
|
34
|
+
enableAuth: () => false,
|
|
34
35
|
} as unknown as UserStore;
|
|
35
36
|
|
|
36
37
|
expect(userProfileSelectors.nickName(store)).toBe('userPanel.defaultNickname');
|
|
@@ -43,6 +44,7 @@ describe('userProfileSelectors', () => {
|
|
|
43
44
|
const store: UserStore = {
|
|
44
45
|
isSignedIn: true,
|
|
45
46
|
user: { fullName: 'John Doe' },
|
|
47
|
+
enableAuth: () => true,
|
|
46
48
|
} as UserStore;
|
|
47
49
|
|
|
48
50
|
expect(userProfileSelectors.nickName(store)).toBe('John Doe');
|
|
@@ -52,6 +54,7 @@ describe('userProfileSelectors', () => {
|
|
|
52
54
|
const store: UserStore = {
|
|
53
55
|
isSignedIn: true,
|
|
54
56
|
user: { username: 'johndoe' },
|
|
57
|
+
enableAuth: () => true,
|
|
55
58
|
} as UserStore;
|
|
56
59
|
|
|
57
60
|
expect(userProfileSelectors.nickName(store)).toBe('johndoe');
|
|
@@ -60,7 +63,11 @@ describe('userProfileSelectors', () => {
|
|
|
60
63
|
it('should return anonymous nickname when not signed in', () => {
|
|
61
64
|
enableAuth = true;
|
|
62
65
|
|
|
63
|
-
const store: UserStore = {
|
|
66
|
+
const store: UserStore = {
|
|
67
|
+
enableAuth: () => true,
|
|
68
|
+
isSignedIn: false,
|
|
69
|
+
user: null,
|
|
70
|
+
} as unknown as UserStore;
|
|
64
71
|
|
|
65
72
|
expect(userProfileSelectors.nickName(store)).toBe('userPanel.anonymousNickName');
|
|
66
73
|
expect(t).toHaveBeenCalledWith('userPanel.anonymousNickName', { ns: 'common' });
|
|
@@ -74,6 +81,7 @@ describe('userProfileSelectors', () => {
|
|
|
74
81
|
const store: UserStore = {
|
|
75
82
|
isSignedIn: false,
|
|
76
83
|
user: null,
|
|
84
|
+
enableAuth: () => false,
|
|
77
85
|
} as unknown as UserStore;
|
|
78
86
|
|
|
79
87
|
expect(userProfileSelectors.username(store)).toBe('LobeChat');
|
|
@@ -83,13 +91,18 @@ describe('userProfileSelectors', () => {
|
|
|
83
91
|
const store: UserStore = {
|
|
84
92
|
isSignedIn: true,
|
|
85
93
|
user: { username: 'johndoe' },
|
|
94
|
+
enableAuth: () => true,
|
|
86
95
|
} as UserStore;
|
|
87
96
|
|
|
88
97
|
expect(userProfileSelectors.username(store)).toBe('johndoe');
|
|
89
98
|
});
|
|
90
99
|
|
|
91
100
|
it('should return "anonymous" when not signed in', () => {
|
|
92
|
-
const store: UserStore = {
|
|
101
|
+
const store: UserStore = {
|
|
102
|
+
enableAuth: () => true,
|
|
103
|
+
isSignedIn: false,
|
|
104
|
+
user: null,
|
|
105
|
+
} as unknown as UserStore;
|
|
93
106
|
|
|
94
107
|
expect(userProfileSelectors.username(store)).toBe('anonymous');
|
|
95
108
|
});
|
|
@@ -103,6 +116,7 @@ describe('authSelectors', () => {
|
|
|
103
116
|
|
|
104
117
|
const store: UserStore = {
|
|
105
118
|
isSignedIn: false,
|
|
119
|
+
enableAuth: () => false,
|
|
106
120
|
} as UserStore;
|
|
107
121
|
|
|
108
122
|
expect(authSelectors.isLogin(store)).toBe(true);
|
|
@@ -111,6 +125,7 @@ describe('authSelectors', () => {
|
|
|
111
125
|
it('should return true when signed in', () => {
|
|
112
126
|
const store: UserStore = {
|
|
113
127
|
isSignedIn: true,
|
|
128
|
+
enableAuth: () => true,
|
|
114
129
|
} as UserStore;
|
|
115
130
|
|
|
116
131
|
expect(authSelectors.isLogin(store)).toBe(true);
|
|
@@ -119,6 +134,7 @@ describe('authSelectors', () => {
|
|
|
119
134
|
it('should return false when not signed in and auth is enabled', () => {
|
|
120
135
|
const store: UserStore = {
|
|
121
136
|
isSignedIn: false,
|
|
137
|
+
enableAuth: () => true,
|
|
122
138
|
} as UserStore;
|
|
123
139
|
|
|
124
140
|
expect(authSelectors.isLogin(store)).toBe(false);
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { t } from 'i18next';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { enableClerk } from '@/const/auth';
|
|
4
4
|
import { UserStore } from '@/store/user';
|
|
5
5
|
import { LobeUser } from '@/types/user';
|
|
6
6
|
|
|
7
7
|
const DEFAULT_USERNAME = 'LobeChat';
|
|
8
8
|
|
|
9
9
|
const nickName = (s: UserStore) => {
|
|
10
|
-
if (!enableAuth) return t('userPanel.defaultNickname', { ns: 'common' });
|
|
10
|
+
if (!s.enableAuth()) return t('userPanel.defaultNickname', { ns: 'common' });
|
|
11
11
|
|
|
12
12
|
if (s.isSignedIn) return s.user?.fullName || s.user?.username;
|
|
13
13
|
|
|
@@ -15,7 +15,7 @@ const nickName = (s: UserStore) => {
|
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
const username = (s: UserStore) => {
|
|
18
|
-
if (!enableAuth) return DEFAULT_USERNAME;
|
|
18
|
+
if (!s.enableAuth()) return DEFAULT_USERNAME;
|
|
19
19
|
|
|
20
20
|
if (s.isSignedIn) return s.user?.username;
|
|
21
21
|
|
|
@@ -35,7 +35,7 @@ export const userProfileSelectors = {
|
|
|
35
35
|
*/
|
|
36
36
|
const isLogin = (s: UserStore) => {
|
|
37
37
|
// 如果没有开启鉴权,说明不需要登录,默认是登录态
|
|
38
|
-
if (!enableAuth) return true;
|
|
38
|
+
if (!s.enableAuth()) return true;
|
|
39
39
|
|
|
40
40
|
return s.isSignedIn;
|
|
41
41
|
};
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
AnthropicProviderCard,
|
|
6
6
|
AzureProviderCard,
|
|
7
7
|
BedrockProviderCard,
|
|
8
|
+
DeepSeekProviderCard,
|
|
8
9
|
GoogleProviderCard,
|
|
9
10
|
GroqProviderCard,
|
|
10
11
|
MinimaxProviderCard,
|
|
@@ -109,6 +110,7 @@ export const llmSettingsSlice: StateCreator<
|
|
|
109
110
|
chatModels: mergeModels('togetherai', TogetherAIProviderCard.chatModels),
|
|
110
111
|
},
|
|
111
112
|
BedrockProviderCard,
|
|
113
|
+
DeepSeekProviderCard,
|
|
112
114
|
PerplexityProviderCard,
|
|
113
115
|
MinimaxProviderCard,
|
|
114
116
|
MistralProviderCard,
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type DefaultSession } from 'next-auth';
|
|
2
|
+
|
|
3
|
+
declare module 'next-auth' {
|
|
4
|
+
/**
|
|
5
|
+
* Returned by `useSession`, `auth`, contains information about the active session.
|
|
6
|
+
*/
|
|
7
|
+
interface Session {
|
|
8
|
+
user: {
|
|
9
|
+
firstName?: string;
|
|
10
|
+
} & DefaultSession['user'];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* More types can be extends here
|
|
14
|
+
* ref: https://authjs.dev/getting-started/typescript
|
|
15
|
+
*/
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare module '@auth/core/jwt' {
|
|
19
|
+
/** Returned by the `jwt` callback and `auth`, when using JWT sessions */
|
|
20
|
+
interface JWT {
|
|
21
|
+
userId: string;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -15,6 +15,7 @@ export interface ServerModelProviderConfig {
|
|
|
15
15
|
|
|
16
16
|
export interface GlobalServerConfig {
|
|
17
17
|
defaultAgent?: DeepPartial<GlobalDefaultAgent>;
|
|
18
|
+
enabledAccessCode?: boolean;
|
|
18
19
|
enabledOAuthSSO?: boolean;
|
|
19
20
|
languageModel?: Partial<Record<GlobalLLMProviderKey, ServerModelProviderConfig>>;
|
|
20
21
|
telemetry: {
|
|
@@ -44,6 +44,7 @@ export interface GlobalLLMConfig {
|
|
|
44
44
|
anthropic: GeneralModelProviderConfig;
|
|
45
45
|
azure: AzureOpenAIConfig;
|
|
46
46
|
bedrock: AWSBedrockConfig;
|
|
47
|
+
deepseek: GeneralModelProviderConfig;
|
|
47
48
|
google: GeneralModelProviderConfig;
|
|
48
49
|
groq: GeneralModelProviderConfig;
|
|
49
50
|
minimax: GeneralModelProviderConfig;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { User } from '@auth/core/types';
|
|
2
|
-
import { SessionContextValue, useSession } from 'next-auth/react';
|
|
3
|
-
import { useMemo } from 'react';
|
|
4
|
-
|
|
5
|
-
interface OAuthSession {
|
|
6
|
-
isOAuthLoggedIn: boolean;
|
|
7
|
-
user?: User | null;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const useOAuthSession = () => {
|
|
11
|
-
let authSession: SessionContextValue | null;
|
|
12
|
-
try {
|
|
13
|
-
// refs: https://github.com/lobehub/lobe-chat/pull/1286
|
|
14
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
15
|
-
authSession = useSession();
|
|
16
|
-
} catch {
|
|
17
|
-
authSession = null;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const { data: session, status } = authSession || {};
|
|
21
|
-
const isOAuthLoggedIn = (status === 'authenticated' && session && !!session.user) || false;
|
|
22
|
-
|
|
23
|
-
return useMemo<OAuthSession>(() => ({ isOAuthLoggedIn, user: session?.user }), [session, status]);
|
|
24
|
-
};
|