@lobehub/chat 1.80.2 → 1.80.3
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/CHANGELOG.md +25 -0
- package/changelog/v1.json +9 -0
- package/next.config.ts +5 -1
- package/package.json +1 -1
- package/src/database/models/user.ts +13 -1
- package/src/layout/AuthProvider/NextAuth/UserUpdater.tsx +18 -11
- package/src/libs/oidc-provider/adapter.ts +5 -6
- package/src/libs/oidc-provider/provider.ts +1 -0
- package/src/server/routers/lambda/user.ts +9 -2
- package/src/services/user/client.ts +5 -2
- package/src/store/user/slices/common/action.ts +9 -2
- package/src/types/user/index.ts +6 -1
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,31 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.80.3](https://github.com/lobehub/lobe-chat/compare/v1.80.2...v1.80.3)
|
6
|
+
|
7
|
+
<sup>Released on **2025-04-16**</sup>
|
8
|
+
|
9
|
+
#### ♻ Code Refactoring
|
10
|
+
|
11
|
+
- **misc**: Refactor to get user info from api.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### Code refactoring
|
19
|
+
|
20
|
+
- **misc**: Refactor to get user info from api, closes [#7444](https://github.com/lobehub/lobe-chat/issues/7444) ([4c1fb4a](https://github.com/lobehub/lobe-chat/commit/4c1fb4a))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
5
30
|
### [Version 1.80.2](https://github.com/lobehub/lobe-chat/compare/v1.80.1...v1.80.2)
|
6
31
|
|
7
32
|
<sup>Released on **2025-04-16**</sup>
|
package/changelog/v1.json
CHANGED
package/next.config.ts
CHANGED
@@ -33,8 +33,12 @@ const nextConfig: NextConfig = {
|
|
33
33
|
'@lobehub/ui',
|
34
34
|
'gpt-tokenizer',
|
35
35
|
],
|
36
|
+
// oidc provider depend on constructor.name
|
37
|
+
// but swc minification will remove the name
|
38
|
+
// so we need to disable it
|
39
|
+
// refs: https://github.com/lobehub/lobe-chat/pull/7430
|
40
|
+
serverMinification: false,
|
36
41
|
webVitalsAttribution: ['CLS', 'LCP'],
|
37
|
-
webpackMemoryOptimizations: true,
|
38
42
|
},
|
39
43
|
async headers() {
|
40
44
|
return [
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.80.
|
3
|
+
"version": "1.80.3",
|
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",
|
@@ -62,10 +62,15 @@ export class UserModel {
|
|
62
62
|
getUserState = async (decryptor: DecryptUserKeyVaults) => {
|
63
63
|
const result = await this.db
|
64
64
|
.select({
|
65
|
+
avatar: users.avatar,
|
66
|
+
email: users.email,
|
67
|
+
firstName: users.firstName,
|
68
|
+
fullName: users.fullName,
|
65
69
|
isOnboarded: users.isOnboarded,
|
70
|
+
lastName: users.lastName,
|
66
71
|
preference: users.preference,
|
67
|
-
|
68
72
|
settingsDefaultAgent: userSettings.defaultAgent,
|
73
|
+
|
69
74
|
settingsGeneral: userSettings.general,
|
70
75
|
settingsHotkey: userSettings.hotkey,
|
71
76
|
settingsKeyVaults: userSettings.keyVaults,
|
@@ -73,6 +78,7 @@ export class UserModel {
|
|
73
78
|
settingsSystemAgent: userSettings.systemAgent,
|
74
79
|
settingsTTS: userSettings.tts,
|
75
80
|
settingsTool: userSettings.tool,
|
81
|
+
username: users.username,
|
76
82
|
})
|
77
83
|
.from(users)
|
78
84
|
.where(eq(users.id, this.userId))
|
@@ -105,10 +111,16 @@ export class UserModel {
|
|
105
111
|
};
|
106
112
|
|
107
113
|
return {
|
114
|
+
avatar: state.avatar || undefined,
|
115
|
+
email: state.email || undefined,
|
116
|
+
firstName: state.firstName || undefined,
|
117
|
+
fullName: state.fullName || undefined,
|
108
118
|
isOnboarded: state.isOnboarded,
|
119
|
+
lastName: state.lastName || undefined,
|
109
120
|
preference: state.preference as UserPreference,
|
110
121
|
settings,
|
111
122
|
userId: this.userId,
|
123
|
+
username: state.username || undefined,
|
112
124
|
};
|
113
125
|
};
|
114
126
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
'use client';
|
2
2
|
|
3
3
|
import { useSession } from 'next-auth/react';
|
4
|
-
import { memo } from 'react';
|
4
|
+
import { memo, useEffect } from 'react';
|
5
5
|
import { createStoreUpdater } from 'zustand-utils';
|
6
6
|
|
7
7
|
import { useUserStore } from '@/store/user';
|
@@ -17,20 +17,27 @@ const UserUpdater = memo(() => {
|
|
17
17
|
const nextUser = session?.user;
|
18
18
|
const useStoreUpdater = createStoreUpdater(useUserStore);
|
19
19
|
|
20
|
-
const lobeUser = {
|
21
|
-
avatar: nextUser?.image,
|
22
|
-
email: nextUser?.email,
|
23
|
-
fullName: nextUser?.name,
|
24
|
-
id: nextUser?.id,
|
25
|
-
} as LobeUser;
|
26
|
-
|
27
20
|
useStoreUpdater('isLoaded', isLoaded);
|
28
|
-
useStoreUpdater('user', lobeUser);
|
29
21
|
useStoreUpdater('isSignedIn', isSignedIn);
|
30
|
-
|
31
22
|
useStoreUpdater('nextSession', session);
|
32
|
-
useStoreUpdater('nextUser', nextUser);
|
33
23
|
|
24
|
+
// 使用 useEffect 处理需要保持同步的用户数据
|
25
|
+
useEffect(() => {
|
26
|
+
if (nextUser) {
|
27
|
+
const userAvatar = useUserStore.getState().user?.avatar;
|
28
|
+
|
29
|
+
const lobeUser = {
|
30
|
+
// 头像使用设置的,而不是从 next-auth 中获取
|
31
|
+
avatar: userAvatar || '',
|
32
|
+
email: nextUser.email,
|
33
|
+
fullName: nextUser.name,
|
34
|
+
id: nextUser.id,
|
35
|
+
} as LobeUser;
|
36
|
+
|
37
|
+
// 更新用户相关数据
|
38
|
+
useUserStore.setState({ nextUser: nextUser, user: lobeUser });
|
39
|
+
}
|
40
|
+
}, [nextUser]);
|
34
41
|
return null;
|
35
42
|
});
|
36
43
|
|
@@ -22,9 +22,10 @@ class OIDCAdapter {
|
|
22
22
|
private name: string;
|
23
23
|
|
24
24
|
constructor(name: string, db: LobeChatDatabase) {
|
25
|
+
log('[%s] Constructor called with name: %s', name, name);
|
26
|
+
|
25
27
|
this.name = name;
|
26
28
|
this.db = db;
|
27
|
-
log('Creating adapter for model: %s', name);
|
28
29
|
}
|
29
30
|
|
30
31
|
/**
|
@@ -530,12 +531,10 @@ class OIDCAdapter {
|
|
530
531
|
/**
|
531
532
|
* 创建适配器工厂
|
532
533
|
*/
|
533
|
-
static createAdapterFactory(db: LobeChatDatabase) {
|
534
|
+
static createAdapterFactory = (db: LobeChatDatabase) => {
|
534
535
|
log('Creating adapter factory with database instance');
|
535
|
-
return
|
536
|
-
|
537
|
-
};
|
538
|
-
}
|
536
|
+
return (name: string) => new OIDCAdapter(name, db);
|
537
|
+
};
|
539
538
|
}
|
540
539
|
|
541
540
|
export { OIDCAdapter as DrizzleAdapter };
|
@@ -272,6 +272,7 @@ export const createOIDCProvider = async (db: LobeChatDatabase): Promise<Provider
|
|
272
272
|
const baseUrl = urlJoin(appEnv.APP_URL!, '/oidc');
|
273
273
|
|
274
274
|
const provider = new Provider(baseUrl, configuration);
|
275
|
+
provider.proxy = true;
|
275
276
|
|
276
277
|
provider.on('server_error', (ctx, err) => {
|
277
278
|
logProvider('OIDC Provider Server Error: %O', err); // Use logProvider
|
@@ -85,17 +85,24 @@ export const userRouter = router({
|
|
85
85
|
const hasExtraSession = await sessionModel.hasMoreThanN(1);
|
86
86
|
|
87
87
|
return {
|
88
|
+
avatar: state.avatar,
|
88
89
|
canEnablePWAGuide: hasMoreThan4Messages,
|
89
90
|
canEnableTrace: hasMoreThan4Messages,
|
91
|
+
email: state.email,
|
92
|
+
firstName: state.firstName,
|
93
|
+
|
94
|
+
fullName: state.fullName,
|
95
|
+
|
90
96
|
// 有消息,或者创建过助手,则认为有 conversation
|
91
97
|
hasConversation: hasAnyMessages || hasExtraSession,
|
92
|
-
|
93
98
|
// always return true for community version
|
94
99
|
isOnboard: state.isOnboarded || true,
|
100
|
+
lastName: state.lastName,
|
95
101
|
preference: state.preference as UserPreference,
|
96
102
|
settings: state.settings,
|
97
103
|
userId: ctx.userId,
|
98
|
-
|
104
|
+
username: state.username,
|
105
|
+
} satisfies UserInitializationState;
|
99
106
|
}),
|
100
107
|
|
101
108
|
makeUserOnboarded: userProcedure.mutation(async ({ ctx }) => {
|
@@ -39,18 +39,21 @@ export class ClientService extends BaseClientService implements IUserService {
|
|
39
39
|
encryptKeyVaultsStr ? JSON.parse(encryptKeyVaultsStr) : {},
|
40
40
|
);
|
41
41
|
|
42
|
-
const user = await UserModel.findById(clientDB as any, this.userId);
|
43
42
|
const messageCount = await this.messageModel.count();
|
44
43
|
const sessionCount = await this.sessionModel.count();
|
45
44
|
|
46
45
|
return {
|
47
46
|
...state,
|
48
|
-
avatar:
|
47
|
+
avatar: state.avatar ?? '',
|
49
48
|
canEnablePWAGuide: messageCount >= 4,
|
50
49
|
canEnableTrace: messageCount >= 4,
|
50
|
+
firstName: state.firstName,
|
51
|
+
fullName: state.fullName,
|
51
52
|
hasConversation: messageCount > 0 || sessionCount > 0,
|
52
53
|
isOnboard: true,
|
54
|
+
lastName: state.lastName,
|
53
55
|
preference: await this.preferenceStorage.getFromLocalStorage(),
|
56
|
+
username: state.username,
|
54
57
|
};
|
55
58
|
};
|
56
59
|
|
@@ -7,7 +7,7 @@ import { useOnlyFetchOnceSWR } from '@/libs/swr';
|
|
7
7
|
import { userService } from '@/services/user';
|
8
8
|
import type { UserStore } from '@/store/user';
|
9
9
|
import type { GlobalServerConfig } from '@/types/serverConfig';
|
10
|
-
import { UserInitializationState } from '@/types/user';
|
10
|
+
import { LobeUser, UserInitializationState } from '@/types/user';
|
11
11
|
import type { UserSettings } from '@/types/user/settings';
|
12
12
|
import { merge } from '@/utils/merge';
|
13
13
|
import { setNamespace } from '@/utils/storeDebug';
|
@@ -91,7 +91,14 @@ export const createCommonSlice: StateCreator<
|
|
91
91
|
// if there is avatar or userId (from client DB), update it into user
|
92
92
|
const user =
|
93
93
|
data.avatar || data.userId
|
94
|
-
? merge(get().user, {
|
94
|
+
? merge(get().user, {
|
95
|
+
avatar: data.avatar,
|
96
|
+
firstName: data.firstName,
|
97
|
+
fullName: data.fullName,
|
98
|
+
id: data.userId,
|
99
|
+
latestName: data.lastName,
|
100
|
+
username: data.username,
|
101
|
+
} as LobeUser)
|
95
102
|
: get().user;
|
96
103
|
|
97
104
|
set(
|
package/src/types/user/index.ts
CHANGED
@@ -48,14 +48,19 @@ export interface UserInitializationState {
|
|
48
48
|
avatar?: string;
|
49
49
|
canEnablePWAGuide?: boolean;
|
50
50
|
canEnableTrace?: boolean;
|
51
|
+
email?: string;
|
52
|
+
firstName?: string;
|
53
|
+
fullName?: string;
|
51
54
|
hasConversation?: boolean;
|
52
55
|
isOnboard?: boolean;
|
56
|
+
lastName?: string;
|
53
57
|
preference: UserPreference;
|
54
58
|
settings: DeepPartial<UserSettings>;
|
55
59
|
userId?: string;
|
60
|
+
username?: string;
|
56
61
|
}
|
57
62
|
|
58
63
|
export const NextAuthAccountSchame = z.object({
|
59
64
|
provider: z.string(),
|
60
65
|
providerAccountId: z.string(),
|
61
|
-
});
|
66
|
+
});
|