feat(安全): 添加后台登录密码配置功能
实现后台管理密码的设置和更新功能,包括: - 在前端添加密码输入框和显示/隐藏切换按钮 - 在后端添加密码验证和存储逻辑 - 密码修改后需要重新登录生效
This commit is contained in:
parent
c2bc2f1c07
commit
7c976bdf0a
3 changed files with 70 additions and 0 deletions
|
|
@ -478,6 +478,46 @@ export async function handleUIApiRequests(method, pathParam, req, res, currentCo
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update admin password
|
||||||
|
if (method === 'POST' && pathParam === '/api/admin-password') {
|
||||||
|
try {
|
||||||
|
const body = await getRequestBody(req);
|
||||||
|
const { password } = body;
|
||||||
|
|
||||||
|
if (!password || password.trim() === '') {
|
||||||
|
res.writeHead(400, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify({
|
||||||
|
error: {
|
||||||
|
message: '密码不能为空'
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入密码到 pwd 文件
|
||||||
|
const pwdFilePath = path.join(process.cwd(), 'pwd');
|
||||||
|
await fs.writeFile(pwdFilePath, password.trim(), 'utf8');
|
||||||
|
|
||||||
|
console.log('[UI API] Admin password updated successfully');
|
||||||
|
|
||||||
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
message: '后台登录密码已更新'
|
||||||
|
}));
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[UI API] Failed to update admin password:', error);
|
||||||
|
res.writeHead(500, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify({
|
||||||
|
error: {
|
||||||
|
message: '更新密码失败: ' + error.message
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get configuration
|
// Get configuration
|
||||||
if (method === 'GET' && pathParam === '/api/config') {
|
if (method === 'GET' && pathParam === '/api/config') {
|
||||||
let systemPrompt = '';
|
let systemPrompt = '';
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,9 @@ async function saveConfiguration() {
|
||||||
systemPrompt: document.getElementById('systemPrompt')?.value || '',
|
systemPrompt: document.getElementById('systemPrompt')?.value || '',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 获取后台登录密码(如果有输入)
|
||||||
|
const adminPassword = document.getElementById('adminPassword')?.value || '';
|
||||||
|
|
||||||
// 根据不同提供商保存不同的配置
|
// 根据不同提供商保存不同的配置
|
||||||
const provider = document.getElementById('modelProvider')?.value;
|
const provider = document.getElementById('modelProvider')?.value;
|
||||||
|
|
||||||
|
|
@ -194,6 +197,21 @@ async function saveConfiguration() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await window.apiClient.post('/config', config);
|
await window.apiClient.post('/config', config);
|
||||||
|
|
||||||
|
// 如果输入了新密码,单独保存密码
|
||||||
|
if (adminPassword) {
|
||||||
|
try {
|
||||||
|
await window.apiClient.post('/admin-password', { password: adminPassword });
|
||||||
|
// 清空密码输入框
|
||||||
|
const adminPasswordEl = document.getElementById('adminPassword');
|
||||||
|
if (adminPasswordEl) adminPasswordEl.value = '';
|
||||||
|
showToast('后台密码已更新,下次登录生效', 'success');
|
||||||
|
} catch (pwdError) {
|
||||||
|
console.error('Failed to save admin password:', pwdError);
|
||||||
|
showToast('保存后台密码失败: ' + pwdError.message, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await window.apiClient.post('/reload-config');
|
await window.apiClient.post('/reload-config');
|
||||||
showToast('配置已保存', 'success');
|
showToast('配置已保存', 'success');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -711,6 +711,18 @@
|
||||||
<label for="systemPrompt">系统提示</label>
|
<label for="systemPrompt">系统提示</label>
|
||||||
<textarea id="systemPrompt" class="form-control" rows="4" placeholder="输入系统提示..."></textarea>
|
<textarea id="systemPrompt" class="form-control" rows="4" placeholder="输入系统提示..."></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 后台登录密码配置 -->
|
||||||
|
<div class="form-group pool-section">
|
||||||
|
<label for="adminPassword">后台登录密码</label>
|
||||||
|
<div class="password-input-wrapper">
|
||||||
|
<input type="password" id="adminPassword" class="form-control" placeholder="设置后台登录密码(留空则不修改)" autocomplete="new-password">
|
||||||
|
<button type="button" class="password-toggle" data-target="adminPassword" aria-label="显示/隐藏密码">
|
||||||
|
<i class="fas fa-eye" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<small class="form-text">用于保护管理控制台的访问,修改后需要重新登录</small>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue