libre-webui 0.2.4
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/LICENSE +201 -0
- package/README.md +204 -0
- package/backend/dist/db.d.ts +19 -0
- package/backend/dist/db.d.ts.map +1 -0
- package/backend/dist/db.js +355 -0
- package/backend/dist/db.js.map +1 -0
- package/backend/dist/env.d.ts +2 -0
- package/backend/dist/env.d.ts.map +1 -0
- package/backend/dist/env.js +22 -0
- package/backend/dist/env.js.map +1 -0
- package/backend/dist/index.d.ts +4 -0
- package/backend/dist/index.d.ts.map +1 -0
- package/backend/dist/index.js +751 -0
- package/backend/dist/index.js.map +1 -0
- package/backend/dist/middleware/auth.d.ts +18 -0
- package/backend/dist/middleware/auth.d.ts.map +1 -0
- package/backend/dist/middleware/auth.js +98 -0
- package/backend/dist/middleware/auth.js.map +1 -0
- package/backend/dist/middleware/index.d.ts +5 -0
- package/backend/dist/middleware/index.d.ts.map +1 -0
- package/backend/dist/middleware/index.js +62 -0
- package/backend/dist/middleware/index.js.map +1 -0
- package/backend/dist/models/personaModel.d.ts +37 -0
- package/backend/dist/models/personaModel.d.ts.map +1 -0
- package/backend/dist/models/personaModel.js +269 -0
- package/backend/dist/models/personaModel.js.map +1 -0
- package/backend/dist/models/userModel.d.ts +86 -0
- package/backend/dist/models/userModel.d.ts.map +1 -0
- package/backend/dist/models/userModel.js +212 -0
- package/backend/dist/models/userModel.js.map +1 -0
- package/backend/dist/routes/auth.d.ts +3 -0
- package/backend/dist/routes/auth.d.ts.map +1 -0
- package/backend/dist/routes/auth.js +389 -0
- package/backend/dist/routes/auth.js.map +1 -0
- package/backend/dist/routes/chat.d.ts +3 -0
- package/backend/dist/routes/chat.d.ts.map +1 -0
- package/backend/dist/routes/chat.js +767 -0
- package/backend/dist/routes/chat.js.map +1 -0
- package/backend/dist/routes/documents.d.ts +3 -0
- package/backend/dist/routes/documents.d.ts.map +1 -0
- package/backend/dist/routes/documents.js +244 -0
- package/backend/dist/routes/documents.js.map +1 -0
- package/backend/dist/routes/ollama.d.ts +3 -0
- package/backend/dist/routes/ollama.d.ts.map +1 -0
- package/backend/dist/routes/ollama.js +549 -0
- package/backend/dist/routes/ollama.js.map +1 -0
- package/backend/dist/routes/personas.d.ts +3 -0
- package/backend/dist/routes/personas.d.ts.map +1 -0
- package/backend/dist/routes/personas.js +505 -0
- package/backend/dist/routes/personas.js.map +1 -0
- package/backend/dist/routes/plugins.d.ts +3 -0
- package/backend/dist/routes/plugins.d.ts.map +1 -0
- package/backend/dist/routes/plugins.js +417 -0
- package/backend/dist/routes/plugins.js.map +1 -0
- package/backend/dist/routes/preferences.d.ts +3 -0
- package/backend/dist/routes/preferences.d.ts.map +1 -0
- package/backend/dist/routes/preferences.js +303 -0
- package/backend/dist/routes/preferences.js.map +1 -0
- package/backend/dist/routes/tts.d.ts +3 -0
- package/backend/dist/routes/tts.d.ts.map +1 -0
- package/backend/dist/routes/tts.js +304 -0
- package/backend/dist/routes/tts.js.map +1 -0
- package/backend/dist/routes/users.d.ts +3 -0
- package/backend/dist/routes/users.d.ts.map +1 -0
- package/backend/dist/routes/users.js +246 -0
- package/backend/dist/routes/users.js.map +1 -0
- package/backend/dist/services/authService.d.ts +51 -0
- package/backend/dist/services/authService.d.ts.map +1 -0
- package/backend/dist/services/authService.js +153 -0
- package/backend/dist/services/authService.js.map +1 -0
- package/backend/dist/services/chatService.d.ts +52 -0
- package/backend/dist/services/chatService.d.ts.map +1 -0
- package/backend/dist/services/chatService.js +645 -0
- package/backend/dist/services/chatService.js.map +1 -0
- package/backend/dist/services/documentService.d.ts +34 -0
- package/backend/dist/services/documentService.d.ts.map +1 -0
- package/backend/dist/services/documentService.js +428 -0
- package/backend/dist/services/documentService.js.map +1 -0
- package/backend/dist/services/encryptionService.d.ts +62 -0
- package/backend/dist/services/encryptionService.d.ts.map +1 -0
- package/backend/dist/services/encryptionService.js +284 -0
- package/backend/dist/services/encryptionService.js.map +1 -0
- package/backend/dist/services/memoryService.d.ts +140 -0
- package/backend/dist/services/memoryService.d.ts.map +1 -0
- package/backend/dist/services/memoryService.js +867 -0
- package/backend/dist/services/memoryService.js.map +1 -0
- package/backend/dist/services/mutationEngineService.d.ts +49 -0
- package/backend/dist/services/mutationEngineService.d.ts.map +1 -0
- package/backend/dist/services/mutationEngineService.js +432 -0
- package/backend/dist/services/mutationEngineService.js.map +1 -0
- package/backend/dist/services/ollamaService.d.ts +55 -0
- package/backend/dist/services/ollamaService.d.ts.map +1 -0
- package/backend/dist/services/ollamaService.js +450 -0
- package/backend/dist/services/ollamaService.js.map +1 -0
- package/backend/dist/services/personaService.d.ts +67 -0
- package/backend/dist/services/personaService.d.ts.map +1 -0
- package/backend/dist/services/personaService.js +373 -0
- package/backend/dist/services/personaService.js.map +1 -0
- package/backend/dist/services/pluginService.d.ts +42 -0
- package/backend/dist/services/pluginService.d.ts.map +1 -0
- package/backend/dist/services/pluginService.js +961 -0
- package/backend/dist/services/pluginService.js.map +1 -0
- package/backend/dist/services/preferencesService.d.ts +35 -0
- package/backend/dist/services/preferencesService.d.ts.map +1 -0
- package/backend/dist/services/preferencesService.js +255 -0
- package/backend/dist/services/preferencesService.js.map +1 -0
- package/backend/dist/services/simpleGitHubOAuth.d.ts +48 -0
- package/backend/dist/services/simpleGitHubOAuth.d.ts.map +1 -0
- package/backend/dist/services/simpleGitHubOAuth.js +203 -0
- package/backend/dist/services/simpleGitHubOAuth.js.map +1 -0
- package/backend/dist/services/simpleHuggingFaceOAuth.d.ts +43 -0
- package/backend/dist/services/simpleHuggingFaceOAuth.d.ts.map +1 -0
- package/backend/dist/services/simpleHuggingFaceOAuth.js +159 -0
- package/backend/dist/services/simpleHuggingFaceOAuth.js.map +1 -0
- package/backend/dist/services/userService.d.ts +1 -0
- package/backend/dist/services/userService.d.ts.map +1 -0
- package/backend/dist/services/userService.js +18 -0
- package/backend/dist/services/userService.js.map +1 -0
- package/backend/dist/storage.d.ts +55 -0
- package/backend/dist/storage.d.ts.map +1 -0
- package/backend/dist/storage.js +741 -0
- package/backend/dist/storage.js.map +1 -0
- package/backend/dist/test-encryption.d.ts +2 -0
- package/backend/dist/test-encryption.d.ts.map +1 -0
- package/backend/dist/test-encryption.js +64 -0
- package/backend/dist/test-encryption.js.map +1 -0
- package/backend/dist/types/index.d.ts +523 -0
- package/backend/dist/types/index.d.ts.map +1 -0
- package/backend/dist/types/index.js +31 -0
- package/backend/dist/types/index.js.map +1 -0
- package/backend/dist/utils/generationUtils.d.ts +10 -0
- package/backend/dist/utils/generationUtils.d.ts.map +1 -0
- package/backend/dist/utils/generationUtils.js +49 -0
- package/backend/dist/utils/generationUtils.js.map +1 -0
- package/backend/dist/utils/hash.d.ts +29 -0
- package/backend/dist/utils/hash.d.ts.map +1 -0
- package/backend/dist/utils/hash.js +73 -0
- package/backend/dist/utils/hash.js.map +1 -0
- package/backend/dist/utils/jwt.d.ts +37 -0
- package/backend/dist/utils/jwt.d.ts.map +1 -0
- package/backend/dist/utils/jwt.js +86 -0
- package/backend/dist/utils/jwt.js.map +1 -0
- package/bin/cli.js +150 -0
- package/electron/main.js +322 -0
- package/frontend/dist/_redirects +1 -0
- package/frontend/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/frontend/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/frontend/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/frontend/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/frontend/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/frontend/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/frontend/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/frontend/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/frontend/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/frontend/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/frontend/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/frontend/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/frontend/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/frontend/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/frontend/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/frontend/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/frontend/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/frontend/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/frontend/dist/assets/index-CRQkB7Wz.js +3 -0
- package/frontend/dist/css/index-B1OjddR-.css +1 -0
- package/frontend/dist/favicon-dark.png +0 -0
- package/frontend/dist/favicon-light.png +0 -0
- package/frontend/dist/index.html +23 -0
- package/frontend/dist/js/ArtifactContainer-c_oi7XMs.js +23 -0
- package/frontend/dist/js/ArtifactDemoPage-CdfwJVXu.js +98 -0
- package/frontend/dist/js/ChatPage-CyotkmS0.js +281 -0
- package/frontend/dist/js/ModelsPage-DNaziPHc.js +2 -0
- package/frontend/dist/js/PersonasPage-DcnbJf8Q.js +13 -0
- package/frontend/dist/js/UserManagementPage-DtTf92dS.js +1 -0
- package/frontend/dist/js/markdown-vendor-D-79K2xZ.js +22 -0
- package/frontend/dist/js/react-vendor-N--QU9DW.js +8 -0
- package/frontend/dist/js/router-vendor-B-t91v39.js +3 -0
- package/frontend/dist/js/ui-vendor-VxSCY_bv.js +177 -0
- package/frontend/dist/js/utils-vendor-DNzxLBGx.js +6 -0
- package/frontend/dist/logo-dark.png +0 -0
- package/frontend/dist/logo-light.png +0 -0
- package/frontend/dist/logo.svg +14 -0
- package/package.json +128 -0
- package/plugins/anthropic.json +25 -0
- package/plugins/elevenlabs.json +58 -0
- package/plugins/gemini.json +57 -0
- package/plugins/github.json +23 -0
- package/plugins/groq.json +25 -0
- package/plugins/mistral.json +73 -0
- package/plugins/openai-tts.json +38 -0
- package/plugins/openai.json +132 -0
- package/plugins/openrouter.json +353 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Libre WebUI
|
|
3
|
+
* Copyright (C) 2025 Kroonen AI, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at:
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import express from 'express';
|
|
18
|
+
import rateLimit from 'express-rate-limit';
|
|
19
|
+
import { userModel } from '../models/userModel.js';
|
|
20
|
+
import { authenticate, requireAdmin, } from '../middleware/auth.js';
|
|
21
|
+
const router = express.Router();
|
|
22
|
+
// Rate limiter for user management routes: 30 requests per 15 minutes
|
|
23
|
+
const userRateLimiter = rateLimit({
|
|
24
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
25
|
+
max: 30, // limit each IP to 30 requests per 15 minutes
|
|
26
|
+
message: {
|
|
27
|
+
success: false,
|
|
28
|
+
message: 'Too many user management requests, please try again later',
|
|
29
|
+
},
|
|
30
|
+
standardHeaders: true,
|
|
31
|
+
legacyHeaders: false,
|
|
32
|
+
});
|
|
33
|
+
/**
|
|
34
|
+
* Get all users (admin only)
|
|
35
|
+
*/
|
|
36
|
+
router.get('/', userRateLimiter, authenticate, requireAdmin, async (req, res) => {
|
|
37
|
+
try {
|
|
38
|
+
const users = userModel.getAllUsers();
|
|
39
|
+
res.json({
|
|
40
|
+
success: true,
|
|
41
|
+
data: users,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
console.error('Get users error:', error);
|
|
46
|
+
res.status(500).json({
|
|
47
|
+
success: false,
|
|
48
|
+
message: 'Internal server error',
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
/**
|
|
53
|
+
* Create a new user (admin only)
|
|
54
|
+
*/
|
|
55
|
+
router.post('/', userRateLimiter, authenticate, requireAdmin, async (req, res) => {
|
|
56
|
+
try {
|
|
57
|
+
const { username, email, password, role } = req.body;
|
|
58
|
+
// Validate required fields
|
|
59
|
+
if (!username || !email || !password || !role) {
|
|
60
|
+
res.status(400).json({
|
|
61
|
+
success: false,
|
|
62
|
+
message: 'Username, email, password, and role are required',
|
|
63
|
+
});
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// Validate role
|
|
67
|
+
if (role !== 'admin' && role !== 'user') {
|
|
68
|
+
res.status(400).json({
|
|
69
|
+
success: false,
|
|
70
|
+
message: 'Role must be either "admin" or "user"',
|
|
71
|
+
});
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// Check if username exists
|
|
75
|
+
if (userModel.usernameExists(username)) {
|
|
76
|
+
res.status(400).json({
|
|
77
|
+
success: false,
|
|
78
|
+
message: 'Username already exists',
|
|
79
|
+
});
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// Check if email exists
|
|
83
|
+
if (userModel.emailExists(email)) {
|
|
84
|
+
res.status(400).json({
|
|
85
|
+
success: false,
|
|
86
|
+
message: 'Email already exists',
|
|
87
|
+
});
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const { avatar } = req.body;
|
|
91
|
+
const user = await userModel.createUser({
|
|
92
|
+
username,
|
|
93
|
+
email,
|
|
94
|
+
password,
|
|
95
|
+
role,
|
|
96
|
+
avatar,
|
|
97
|
+
});
|
|
98
|
+
res.status(201).json({
|
|
99
|
+
success: true,
|
|
100
|
+
data: user,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.error('Create user error:', error);
|
|
105
|
+
res.status(500).json({
|
|
106
|
+
success: false,
|
|
107
|
+
message: 'Internal server error',
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
/**
|
|
112
|
+
* Update current user's profile (self-update, avatar only)
|
|
113
|
+
*/
|
|
114
|
+
router.patch('/me/avatar', userRateLimiter, authenticate, async (req, res) => {
|
|
115
|
+
try {
|
|
116
|
+
const userId = req.user?.userId;
|
|
117
|
+
if (!userId) {
|
|
118
|
+
res.status(401).json({
|
|
119
|
+
success: false,
|
|
120
|
+
message: 'Not authenticated',
|
|
121
|
+
});
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const { avatar } = req.body;
|
|
125
|
+
const user = await userModel.updateUser(userId, { avatar });
|
|
126
|
+
if (!user) {
|
|
127
|
+
res.status(404).json({
|
|
128
|
+
success: false,
|
|
129
|
+
message: 'User not found',
|
|
130
|
+
});
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
res.json({
|
|
134
|
+
success: true,
|
|
135
|
+
data: user,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
console.error('Update avatar error:', error);
|
|
140
|
+
res.status(500).json({
|
|
141
|
+
success: false,
|
|
142
|
+
message: 'Internal server error',
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
/**
|
|
147
|
+
* Update a user (admin only)
|
|
148
|
+
*/
|
|
149
|
+
router.patch('/:id', userRateLimiter, authenticate, requireAdmin, async (req, res) => {
|
|
150
|
+
try {
|
|
151
|
+
const { id } = req.params;
|
|
152
|
+
const { username, email, password, role, avatar } = req.body;
|
|
153
|
+
// Validate role if provided
|
|
154
|
+
if (role && role !== 'admin' && role !== 'user') {
|
|
155
|
+
res.status(400).json({
|
|
156
|
+
success: false,
|
|
157
|
+
message: 'Role must be either "admin" or "user"',
|
|
158
|
+
});
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
// Check if username exists (and is not the current user)
|
|
162
|
+
if (username && userModel.usernameExists(username)) {
|
|
163
|
+
const existingUser = userModel.getUserById(id);
|
|
164
|
+
if (!existingUser || existingUser.username !== username) {
|
|
165
|
+
res.status(400).json({
|
|
166
|
+
success: false,
|
|
167
|
+
message: 'Username already exists',
|
|
168
|
+
});
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Check if email exists (and is not the current user)
|
|
173
|
+
if (email && userModel.emailExists(email)) {
|
|
174
|
+
const existingUser = userModel.getUserById(id);
|
|
175
|
+
if (!existingUser || existingUser.email !== email) {
|
|
176
|
+
res.status(400).json({
|
|
177
|
+
success: false,
|
|
178
|
+
message: 'Email already exists',
|
|
179
|
+
});
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const user = await userModel.updateUser(id, {
|
|
184
|
+
username,
|
|
185
|
+
email,
|
|
186
|
+
password,
|
|
187
|
+
role,
|
|
188
|
+
avatar,
|
|
189
|
+
});
|
|
190
|
+
if (!user) {
|
|
191
|
+
res.status(404).json({
|
|
192
|
+
success: false,
|
|
193
|
+
message: 'User not found',
|
|
194
|
+
});
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
res.json({
|
|
198
|
+
success: true,
|
|
199
|
+
data: user,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
console.error('Update user error:', error);
|
|
204
|
+
res.status(500).json({
|
|
205
|
+
success: false,
|
|
206
|
+
message: 'Internal server error',
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
/**
|
|
211
|
+
* Delete a user (admin only)
|
|
212
|
+
*/
|
|
213
|
+
router.delete('/:id', userRateLimiter, authenticate, requireAdmin, async (req, res) => {
|
|
214
|
+
try {
|
|
215
|
+
const { id } = req.params;
|
|
216
|
+
// Prevent deleting yourself
|
|
217
|
+
if (req.user?.userId === id) {
|
|
218
|
+
res.status(400).json({
|
|
219
|
+
success: false,
|
|
220
|
+
message: 'You cannot delete your own account',
|
|
221
|
+
});
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const deleted = userModel.deleteUser(id);
|
|
225
|
+
if (!deleted) {
|
|
226
|
+
res.status(404).json({
|
|
227
|
+
success: false,
|
|
228
|
+
message: 'User not found',
|
|
229
|
+
});
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
res.json({
|
|
233
|
+
success: true,
|
|
234
|
+
message: 'User deleted successfully',
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
console.error('Delete user error:', error);
|
|
239
|
+
res.status(500).json({
|
|
240
|
+
success: false,
|
|
241
|
+
message: 'Internal server error',
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
export default router;
|
|
246
|
+
//# sourceMappingURL=users.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/routes/users.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { UserPublic } from '../models/userModel.js';
|
|
2
|
+
export declare const JWT_SECRET: string;
|
|
3
|
+
export interface AuthTokenPayload {
|
|
4
|
+
userId: string;
|
|
5
|
+
username: string;
|
|
6
|
+
role: 'admin' | 'user';
|
|
7
|
+
}
|
|
8
|
+
export interface SystemInfo {
|
|
9
|
+
requiresAuth: boolean;
|
|
10
|
+
singleUserMode: boolean;
|
|
11
|
+
hasUsers: boolean;
|
|
12
|
+
version?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class AuthService {
|
|
15
|
+
/**
|
|
16
|
+
* Generate JWT token for user
|
|
17
|
+
*/
|
|
18
|
+
generateToken(user: UserPublic): string;
|
|
19
|
+
/**
|
|
20
|
+
* Verify JWT token
|
|
21
|
+
*/
|
|
22
|
+
verifyToken(token: string): AuthTokenPayload | null;
|
|
23
|
+
/**
|
|
24
|
+
* Login user
|
|
25
|
+
*/
|
|
26
|
+
login(username: string, password: string): Promise<{
|
|
27
|
+
user: UserPublic;
|
|
28
|
+
token: string;
|
|
29
|
+
} | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Get system information
|
|
32
|
+
*/
|
|
33
|
+
getSystemInfo(): SystemInfo;
|
|
34
|
+
/**
|
|
35
|
+
* Get user from token
|
|
36
|
+
*/
|
|
37
|
+
getUserFromToken(token: string): Promise<UserPublic | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Get user by username
|
|
40
|
+
*/
|
|
41
|
+
getUserByUsername(username: string): Promise<UserPublic | null>;
|
|
42
|
+
/**
|
|
43
|
+
* Signup user
|
|
44
|
+
*/
|
|
45
|
+
signup(username: string, password: string, email?: string): Promise<{
|
|
46
|
+
user: UserPublic;
|
|
47
|
+
token: string;
|
|
48
|
+
} | null>;
|
|
49
|
+
}
|
|
50
|
+
export declare const authService: AuthService;
|
|
51
|
+
//# sourceMappingURL=authService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authService.d.ts","sourceRoot":"","sources":["../../src/services/authService.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAa,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAoB/D,eAAO,MAAM,UAAU,QAWjB,CAAC;AAEP,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,WAAW;IACtB;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM;IAUvC;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAUnD;;OAEG;IACG,KAAK,CACT,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAkBtD;;OAEG;IACH,aAAa,IAAI,UAAU;IAW3B;;OAEG;IACG,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAOjE;;OAEG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAerE;;OAEG;IACG,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAyBvD;AAED,eAAO,MAAM,WAAW,aAAoB,CAAC"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Libre WebUI
|
|
3
|
+
* Copyright (C) 2025 Kroonen AI, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at:
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import jwt from 'jsonwebtoken';
|
|
18
|
+
import { userModel } from '../models/userModel.js';
|
|
19
|
+
import { readFileSync } from 'fs';
|
|
20
|
+
import { fileURLToPath } from 'url';
|
|
21
|
+
import { dirname, join } from 'path';
|
|
22
|
+
import { randomBytes } from 'crypto';
|
|
23
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
24
|
+
const __dirname = dirname(__filename);
|
|
25
|
+
// Read version from package.json
|
|
26
|
+
let packageVersion = '0.1.0';
|
|
27
|
+
try {
|
|
28
|
+
const packageJsonPath = join(__dirname, '..', '..', 'package.json');
|
|
29
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
30
|
+
packageVersion = packageJson.version;
|
|
31
|
+
}
|
|
32
|
+
catch (_error) {
|
|
33
|
+
console.warn('Could not read version from package.json, using default');
|
|
34
|
+
}
|
|
35
|
+
// Generate or use JWT secret - never use hardcoded secrets in production
|
|
36
|
+
export const JWT_SECRET = process.env.JWT_SECRET ||
|
|
37
|
+
(() => {
|
|
38
|
+
const generatedSecret = randomBytes(64).toString('hex');
|
|
39
|
+
console.warn('⚠️ JWT_SECRET not provided - generated random secret for this session');
|
|
40
|
+
console.warn('🔒 For production, set JWT_SECRET environment variable to persist sessions across restarts');
|
|
41
|
+
return generatedSecret;
|
|
42
|
+
})();
|
|
43
|
+
export class AuthService {
|
|
44
|
+
/**
|
|
45
|
+
* Generate JWT token for user
|
|
46
|
+
*/
|
|
47
|
+
generateToken(user) {
|
|
48
|
+
const payload = {
|
|
49
|
+
userId: user.id,
|
|
50
|
+
username: user.username,
|
|
51
|
+
role: user.role,
|
|
52
|
+
};
|
|
53
|
+
return jwt.sign(payload, JWT_SECRET, { expiresIn: '24h' });
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Verify JWT token
|
|
57
|
+
*/
|
|
58
|
+
verifyToken(token) {
|
|
59
|
+
try {
|
|
60
|
+
const payload = jwt.verify(token, JWT_SECRET);
|
|
61
|
+
return payload;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error('Token verification failed:', error);
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Login user
|
|
70
|
+
*/
|
|
71
|
+
async login(username, password) {
|
|
72
|
+
const user = await userModel.verifyPassword(username, password);
|
|
73
|
+
if (!user)
|
|
74
|
+
return null;
|
|
75
|
+
const userPublic = {
|
|
76
|
+
id: user.id,
|
|
77
|
+
username: user.username,
|
|
78
|
+
email: user.email,
|
|
79
|
+
role: user.role,
|
|
80
|
+
avatar: user.avatar,
|
|
81
|
+
createdAt: new Date(user.created_at).toISOString(),
|
|
82
|
+
updatedAt: new Date(user.updated_at).toISOString(),
|
|
83
|
+
};
|
|
84
|
+
const token = this.generateToken(userPublic);
|
|
85
|
+
return { user: userPublic, token };
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get system information
|
|
89
|
+
*/
|
|
90
|
+
getSystemInfo() {
|
|
91
|
+
const userCount = userModel.getUserCount();
|
|
92
|
+
return {
|
|
93
|
+
requiresAuth: true, // For now, always require auth
|
|
94
|
+
singleUserMode: userCount === 1,
|
|
95
|
+
hasUsers: userCount > 0,
|
|
96
|
+
version: packageVersion,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get user from token
|
|
101
|
+
*/
|
|
102
|
+
async getUserFromToken(token) {
|
|
103
|
+
const payload = this.verifyToken(token);
|
|
104
|
+
if (!payload)
|
|
105
|
+
return null;
|
|
106
|
+
return userModel.getUserById(payload.userId);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get user by username
|
|
110
|
+
*/
|
|
111
|
+
async getUserByUsername(username) {
|
|
112
|
+
const user = userModel.getUserByUsername(username);
|
|
113
|
+
if (!user)
|
|
114
|
+
return null;
|
|
115
|
+
return {
|
|
116
|
+
id: user.id,
|
|
117
|
+
username: user.username,
|
|
118
|
+
email: user.email,
|
|
119
|
+
role: user.role,
|
|
120
|
+
avatar: user.avatar,
|
|
121
|
+
createdAt: new Date(user.created_at).toISOString(),
|
|
122
|
+
updatedAt: new Date(user.updated_at).toISOString(),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Signup user
|
|
127
|
+
*/
|
|
128
|
+
async signup(username, password, email) {
|
|
129
|
+
try {
|
|
130
|
+
const userCount = userModel.getUserCount();
|
|
131
|
+
// Only the very first real user (excluding the default system user) becomes admin
|
|
132
|
+
const isFirstRealUser = userCount === 0;
|
|
133
|
+
const userData = {
|
|
134
|
+
username,
|
|
135
|
+
password,
|
|
136
|
+
email: email || null, // Use null instead of empty string
|
|
137
|
+
// First real user becomes admin, subsequent users are regular users
|
|
138
|
+
role: isFirstRealUser ? 'admin' : 'user',
|
|
139
|
+
};
|
|
140
|
+
const user = await userModel.createUser(userData);
|
|
141
|
+
if (!user)
|
|
142
|
+
return null;
|
|
143
|
+
const token = this.generateToken(user);
|
|
144
|
+
return { user, token };
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
console.error('Signup error:', error);
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
export const authService = new AuthService();
|
|
153
|
+
//# sourceMappingURL=authService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authService.js","sourceRoot":"","sources":["../../src/services/authService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ChatSession, ChatMessage } from '../types/index.js';
|
|
2
|
+
declare class ChatService {
|
|
3
|
+
private sessions;
|
|
4
|
+
constructor();
|
|
5
|
+
private loadSessions;
|
|
6
|
+
private saveSessions;
|
|
7
|
+
createSession(model: string, title?: string, userId?: string, personaId?: string): Promise<ChatSession>;
|
|
8
|
+
getSession(sessionId: string, userId?: string): ChatSession | undefined;
|
|
9
|
+
getAllSessions(userId?: string): ChatSession[];
|
|
10
|
+
updateSession(sessionId: string, updates: Partial<ChatSession>, userId?: string): Promise<ChatSession | undefined>;
|
|
11
|
+
addMessage(sessionId: string, message: Omit<ChatMessage, 'id' | 'timestamp'> & {
|
|
12
|
+
id?: string;
|
|
13
|
+
}, userId?: string): ChatMessage | undefined;
|
|
14
|
+
updateMessage(sessionId: string, messageId: string, updates: Partial<ChatMessage>, userId?: string): ChatMessage | undefined;
|
|
15
|
+
deleteSession(sessionId: string, userId?: string): boolean;
|
|
16
|
+
clearAllSessions(userId?: string): void;
|
|
17
|
+
private generateTitle;
|
|
18
|
+
getMessagesForContext(sessionId: string, maxMessages?: number): ChatMessage[];
|
|
19
|
+
private updateSystemMessageForPersona;
|
|
20
|
+
private updateSystemMessageToDefault;
|
|
21
|
+
private replaceSystemMessage;
|
|
22
|
+
/**
|
|
23
|
+
* Process advanced persona interactions: memory storage, retrieval, and mutations
|
|
24
|
+
*/
|
|
25
|
+
private processAdvancedPersonaInteraction;
|
|
26
|
+
/**
|
|
27
|
+
* Update system message to include relevant memories
|
|
28
|
+
*/
|
|
29
|
+
private updateSystemMessageWithMemories;
|
|
30
|
+
/**
|
|
31
|
+
* Process advanced persona response - store AI responses as memories for future reference
|
|
32
|
+
*/
|
|
33
|
+
private processAdvancedPersonaResponse;
|
|
34
|
+
/**
|
|
35
|
+
* Create a new branch for a message (used for regeneration)
|
|
36
|
+
* This marks the original message as inactive and creates a new active variant
|
|
37
|
+
*/
|
|
38
|
+
createMessageBranch(sessionId: string, originalMessageId: string, newMessage: Omit<ChatMessage, 'id' | 'timestamp'> & {
|
|
39
|
+
id?: string;
|
|
40
|
+
}, userId?: string): ChatMessage | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Switch to a different branch of a message
|
|
43
|
+
*/
|
|
44
|
+
switchMessageBranch(sessionId: string, messageId: string, targetBranchIndex: number, userId?: string): ChatMessage | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Get all branches for a message
|
|
47
|
+
*/
|
|
48
|
+
getMessageBranches(sessionId: string, messageId: string, userId?: string): ChatMessage[];
|
|
49
|
+
}
|
|
50
|
+
declare const _default: ChatService;
|
|
51
|
+
export default _default;
|
|
52
|
+
//# sourceMappingURL=chatService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chatService.d.ts","sourceRoot":"","sources":["../../src/services/chatService.ts"],"names":[],"mappings":"AAiBA,OAAO,EACL,WAAW,EACX,WAAW,EAGZ,MAAM,mBAAmB,CAAC;AAQ3B,cAAM,WAAW;IACf,OAAO,CAAC,QAAQ,CAAuC;;IAMvD,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,YAAY;IAKd,aAAa,CACjB,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,GAAE,MAAkB,EAC1B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,CAAC;IAsGvB,UAAU,CACR,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,MAAkB,GACzB,WAAW,GAAG,SAAS;IAqC1B,cAAc,CAAC,MAAM,GAAE,MAAkB,GAAG,WAAW,EAAE;IAanD,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,EAC7B,MAAM,GAAE,MAAkB,GACzB,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IA6CnC,UAAU,CACR,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,EAChE,MAAM,GAAE,MAAkB,GACzB,WAAW,GAAG,SAAS;IA+G1B,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,EAC7B,MAAM,GAAE,MAAkB,GACzB,WAAW,GAAG,SAAS;IAmC1B,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,GAAE,MAAkB,GAAG,OAAO;IAYrE,gBAAgB,CAAC,MAAM,GAAE,MAAkB,GAAG,IAAI;IAelD,OAAO,CAAC,aAAa;IAYrB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,SAAK,GAAG,WAAW,EAAE;YAgC3D,6BAA6B;IA6C3C,OAAO,CAAC,4BAA4B;IAWpC,OAAO,CAAC,oBAAoB;IAgC5B;;OAEG;YACW,iCAAiC;IA4G/C;;OAEG;YACW,+BAA+B;IA8G7C;;OAEG;YACW,8BAA8B;IA2D5C;;;OAGG;IACH,mBAAmB,CACjB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,EACnE,MAAM,GAAE,MAAkB,GACzB,WAAW,GAAG,SAAS;IAgD1B;;OAEG;IACH,mBAAmB,CACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,MAAM,GAAE,MAAkB,GACzB,WAAW,GAAG,SAAS;IA6B1B;;OAEG;IACH,kBAAkB,CAChB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,MAAkB,GACzB,WAAW,EAAE;CAcjB;;AAED,wBAAiC"}
|