@lobehub/chat 0.162.24 → 0.163.0
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/.github/workflows/release.yml +21 -2
- package/.github/workflows/sync.yml +1 -1
- package/.github/workflows/test.yml +35 -4
- package/CHANGELOG.md +50 -0
- package/LICENSE +38 -21
- package/README.md +8 -8
- package/README.zh-CN.md +8 -8
- package/codecov.yml +11 -0
- package/docs/self-hosting/platform/zeabur.mdx +1 -1
- package/docs/self-hosting/platform/zeabur.zh-CN.mdx +1 -1
- package/drizzle.config.ts +29 -0
- package/next.config.mjs +3 -0
- package/package.json +25 -5
- package/scripts/migrateServerDB/index.ts +30 -0
- package/src/app/(main)/(mobile)/me/(home)/features/useCategory.tsx +2 -1
- package/src/app/(main)/chat/@session/features/SessionListContent/List/Item/Actions.tsx +95 -88
- package/src/app/(main)/chat/settings/features/HeaderContent.tsx +37 -31
- package/src/app/(main)/settings/llm/components/ProviderConfig/index.tsx +11 -1
- package/src/app/api/middleware/auth/index.ts +1 -1
- package/src/app/api/webhooks/clerk/__tests__/fixtures/createUser.json +73 -0
- package/src/app/api/webhooks/clerk/route.ts +159 -0
- package/src/app/api/webhooks/clerk/validateRequest.ts +22 -0
- package/src/app/trpc/edge/[trpc]/route.ts +1 -1
- package/src/app/trpc/lambda/[trpc]/route.ts +26 -0
- package/src/config/auth.ts +2 -0
- package/src/config/db.ts +13 -1
- package/src/database/server/core/db.ts +44 -0
- package/src/database/server/core/dbForTest.ts +45 -0
- package/src/database/server/index.ts +1 -0
- package/src/database/server/migrations/0000_init.sql +439 -0
- package/src/database/server/migrations/0001_add_client_id.sql +9 -0
- package/src/database/server/migrations/0002_amusing_puma.sql +9 -0
- package/src/database/server/migrations/meta/0000_snapshot.json +1583 -0
- package/src/database/server/migrations/meta/0001_snapshot.json +1636 -0
- package/src/database/server/migrations/meta/0002_snapshot.json +1630 -0
- package/src/database/server/migrations/meta/_journal.json +27 -0
- package/src/database/server/models/__tests__/file.test.ts +140 -0
- package/src/database/server/models/__tests__/message.test.ts +847 -0
- package/src/database/server/models/__tests__/plugin.test.ts +172 -0
- package/src/database/server/models/__tests__/session.test.ts +595 -0
- package/src/database/server/models/__tests__/topic.test.ts +623 -0
- package/src/database/server/models/__tests__/user.test.ts +173 -0
- package/src/database/server/models/_template.ts +44 -0
- package/src/database/server/models/file.ts +51 -0
- package/src/database/server/models/message.ts +378 -0
- package/src/database/server/models/plugin.ts +63 -0
- package/src/database/server/models/session.ts +290 -0
- package/src/database/server/models/sessionGroup.ts +69 -0
- package/src/database/server/models/topic.ts +265 -0
- package/src/database/server/models/user.ts +138 -0
- package/src/database/server/modules/DataImporter/__tests__/fixtures/messages.json +1101 -0
- package/src/database/server/modules/DataImporter/__tests__/index.test.ts +954 -0
- package/src/database/server/modules/DataImporter/index.ts +333 -0
- package/src/database/server/schemas/_id.ts +15 -0
- package/src/database/server/schemas/lobechat.ts +601 -0
- package/src/database/server/utils/idGenerator.test.ts +39 -0
- package/src/database/server/utils/idGenerator.ts +26 -0
- package/src/features/AgentSetting/AgentModal/index.tsx +6 -7
- package/src/features/User/UserPanel/useMenu.tsx +43 -37
- package/src/libs/trpc/client.ts +52 -3
- package/src/server/files/s3.ts +21 -1
- package/src/server/keyVaultsEncrypt/index.test.ts +62 -0
- package/src/server/keyVaultsEncrypt/index.ts +93 -0
- package/src/server/mock.ts +1 -1
- package/src/server/routers/{index.ts → edge/index.ts} +3 -3
- package/src/server/routers/lambda/file.ts +49 -0
- package/src/server/routers/lambda/importer.ts +54 -0
- package/src/server/routers/lambda/index.ts +28 -0
- package/src/server/routers/lambda/message.ts +165 -0
- package/src/server/routers/lambda/plugin.ts +100 -0
- package/src/server/routers/lambda/session.ts +194 -0
- package/src/server/routers/lambda/sessionGroup.ts +77 -0
- package/src/server/routers/lambda/topic.ts +134 -0
- package/src/server/routers/lambda/user.ts +57 -0
- package/src/services/file/index.ts +4 -7
- package/src/services/file/server.ts +45 -0
- package/src/services/import/index.ts +4 -1
- package/src/services/import/server.ts +115 -0
- package/src/services/message/index.ts +4 -8
- package/src/services/message/server.ts +93 -0
- package/src/services/plugin/index.ts +4 -9
- package/src/services/plugin/server.ts +46 -0
- package/src/services/session/index.ts +4 -8
- package/src/services/session/server.ts +148 -0
- package/src/services/topic/index.ts +4 -9
- package/src/services/topic/server.ts +68 -0
- package/src/services/user/index.ts +4 -9
- package/src/services/user/server.ts +28 -0
- package/src/store/user/slices/modelList/selectors/keyVaults.test.ts +201 -0
- package/src/store/user/slices/modelList/selectors/keyVaults.ts +15 -3
- package/src/store/user/slices/modelList/selectors/modelConfig.test.ts +29 -1
- package/src/store/user/slices/modelList/selectors/modelConfig.ts +21 -1
- package/src/types/user/settings/keyVaults.ts +1 -1
- package/tests/setup-db.ts +7 -0
- package/vitest.config.ts +2 -1
- package/vitest.server.config.ts +23 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { TRPCError } from '@trpc/server';
|
|
2
|
+
import { eq } from 'drizzle-orm';
|
|
3
|
+
import { DeepPartial } from 'utility-types';
|
|
4
|
+
|
|
5
|
+
import { serverDB } from '@/database/server';
|
|
6
|
+
import { KeyVaultsGateKeeper } from '@/server/keyVaultsEncrypt';
|
|
7
|
+
import { UserPreference } from '@/types/user';
|
|
8
|
+
import { UserSettings } from '@/types/user/settings';
|
|
9
|
+
import { merge } from '@/utils/merge';
|
|
10
|
+
|
|
11
|
+
import { NewUser, UserItem, userSettings, users } from '../schemas/lobechat';
|
|
12
|
+
import { SessionModel } from './session';
|
|
13
|
+
|
|
14
|
+
export class UserModel {
|
|
15
|
+
createUser = async (params: NewUser) => {
|
|
16
|
+
const [user] = await serverDB
|
|
17
|
+
.insert(users)
|
|
18
|
+
.values({ ...params })
|
|
19
|
+
.returning();
|
|
20
|
+
|
|
21
|
+
// Create an inbox session for the user
|
|
22
|
+
const model = new SessionModel(user.id);
|
|
23
|
+
|
|
24
|
+
await model.createInbox();
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
deleteUser = async (id: string) => {
|
|
28
|
+
return serverDB.delete(users).where(eq(users.id, id));
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
findById = async (id: string) => {
|
|
32
|
+
return serverDB.query.users.findFirst({ where: eq(users.id, id) });
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
getUserState = async (id: string) => {
|
|
36
|
+
const result = await serverDB
|
|
37
|
+
.select({
|
|
38
|
+
isOnboarded: users.isOnboarded,
|
|
39
|
+
preference: users.preference,
|
|
40
|
+
|
|
41
|
+
settingsDefaultAgent: userSettings.defaultAgent,
|
|
42
|
+
settingsGeneral: userSettings.general,
|
|
43
|
+
settingsKeyVaults: userSettings.keyVaults,
|
|
44
|
+
settingsLanguageModel: userSettings.languageModel,
|
|
45
|
+
settingsSystemAgent: userSettings.systemAgent,
|
|
46
|
+
settingsTTS: userSettings.tts,
|
|
47
|
+
settingsTool: userSettings.tool,
|
|
48
|
+
})
|
|
49
|
+
.from(users)
|
|
50
|
+
.where(eq(users.id, id))
|
|
51
|
+
.leftJoin(userSettings, eq(users.id, userSettings.id));
|
|
52
|
+
|
|
53
|
+
if (!result || !result[0]) {
|
|
54
|
+
throw new TRPCError({ code: 'UNAUTHORIZED', message: 'user not found' });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const state = result[0];
|
|
58
|
+
|
|
59
|
+
// Decrypt keyVaults
|
|
60
|
+
let decryptKeyVaults = {};
|
|
61
|
+
if (state.settingsKeyVaults) {
|
|
62
|
+
const gateKeeper = await KeyVaultsGateKeeper.initWithEnvKey();
|
|
63
|
+
const { wasAuthentic, plaintext } = await gateKeeper.decrypt(state.settingsKeyVaults);
|
|
64
|
+
|
|
65
|
+
if (wasAuthentic) {
|
|
66
|
+
try {
|
|
67
|
+
decryptKeyVaults = JSON.parse(plaintext);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
console.error(`Failed to parse keyVaults ,userId: ${id}. Error:`, e);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const settings: DeepPartial<UserSettings> = {
|
|
75
|
+
defaultAgent: state.settingsDefaultAgent || {},
|
|
76
|
+
general: state.settingsGeneral || {},
|
|
77
|
+
keyVaults: decryptKeyVaults,
|
|
78
|
+
languageModel: state.settingsLanguageModel || {},
|
|
79
|
+
systemAgent: state.settingsSystemAgent || {},
|
|
80
|
+
tool: state.settingsTool || {},
|
|
81
|
+
tts: state.settingsTTS || {},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
isOnboarded: state.isOnboarded,
|
|
86
|
+
preference: state.preference as UserPreference,
|
|
87
|
+
settings,
|
|
88
|
+
userId: id,
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
async updateUser(id: string, value: Partial<UserItem>) {
|
|
93
|
+
return serverDB
|
|
94
|
+
.update(users)
|
|
95
|
+
.set({ ...value, updatedAt: new Date() })
|
|
96
|
+
.where(eq(users.id, id));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async deleteSetting(id: string) {
|
|
100
|
+
return serverDB.delete(userSettings).where(eq(userSettings.id, id));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async updateSetting(id: string, value: Partial<UserSettings>) {
|
|
104
|
+
const { keyVaults, ...res } = value;
|
|
105
|
+
|
|
106
|
+
// Encrypt keyVaults
|
|
107
|
+
let encryptedKeyVaults: string | null = null;
|
|
108
|
+
|
|
109
|
+
if (keyVaults) {
|
|
110
|
+
// TODO: better to add a validation
|
|
111
|
+
const data = JSON.stringify(keyVaults);
|
|
112
|
+
const gateKeeper = await KeyVaultsGateKeeper.initWithEnvKey();
|
|
113
|
+
|
|
114
|
+
encryptedKeyVaults = await gateKeeper.encrypt(data);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const newValue = { ...res, keyVaults: encryptedKeyVaults };
|
|
118
|
+
|
|
119
|
+
// update or create user settings
|
|
120
|
+
const settings = await serverDB.query.userSettings.findFirst({ where: eq(users.id, id) });
|
|
121
|
+
if (!settings) {
|
|
122
|
+
await serverDB.insert(userSettings).values({ id, ...newValue });
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return serverDB.update(userSettings).set(newValue).where(eq(userSettings.id, id));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async updatePreference(id: string, value: Partial<UserPreference>) {
|
|
130
|
+
const user = await serverDB.query.users.findFirst({ where: eq(users.id, id) });
|
|
131
|
+
if (!user) return;
|
|
132
|
+
|
|
133
|
+
return serverDB
|
|
134
|
+
.update(users)
|
|
135
|
+
.set({ preference: merge(user.preference, value) })
|
|
136
|
+
.where(eq(users.id, id));
|
|
137
|
+
}
|
|
138
|
+
}
|