feat(安全): 添加后台登录密码配置功能

实现后台管理密码的设置和更新功能,包括:
- 在前端添加密码输入框和显示/隐藏切换按钮
- 在后端添加密码验证和存储逻辑
- 密码修改后需要重新登录生效
This commit is contained in:
hex2077 2025-12-14 20:20:31 +08:00
parent c2bc2f1c07
commit 7c976bdf0a
3 changed files with 70 additions and 0 deletions

View file

@ -478,6 +478,46 @@ export async function handleUIApiRequests(method, pathParam, req, res, currentCo
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
if (method === 'GET' && pathParam === '/api/config') {
let systemPrompt = '';

View file

@ -133,6 +133,9 @@ async function saveConfiguration() {
systemPrompt: document.getElementById('systemPrompt')?.value || '',
};
// 获取后台登录密码(如果有输入)
const adminPassword = document.getElementById('adminPassword')?.value || '';
// 根据不同提供商保存不同的配置
const provider = document.getElementById('modelProvider')?.value;
@ -194,6 +197,21 @@ async function saveConfiguration() {
try {
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');
showToast('配置已保存', 'success');

View file

@ -711,6 +711,18 @@
<label for="systemPrompt">系统提示</label>
<textarea id="systemPrompt" class="form-control" rows="4" placeholder="输入系统提示..."></textarea>
</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 class="form-actions">