refactor: 收敛单用户模型并优化可访问性与响应式体验

- 后端移除 is_admin 权限字段与相关逻辑,统一为单用户系统模型
- 修复会话过期清理的时间比较方式(改为 RFC3339 参数比较)
- /api/config 聚合配置增加敏感字段脱敏,避免暴露 TURN/RustDesk 密钥与密码
- 配置更新日志改为摘要,避免打印完整配置内容
- 前端修复可点击卡片语义与键盘可达,补齐图标按钮可访问名称
- 调整弹窗与抽屉的响应式尺寸,优化多端显示与交互
This commit is contained in:
mofeng-git
2026-02-10 22:30:52 +08:00
parent 394baca938
commit 261deb1303
13 changed files with 81 additions and 60 deletions

View File

@@ -50,10 +50,26 @@ use std::sync::Arc;
use crate::config::AppConfig;
use crate::state::AppState;
fn sanitize_config_for_api(config: &mut AppConfig) {
// Auth secrets
config.auth.totp_secret = None;
// Stream secrets
config.stream.turn_password = None;
// RustDesk secrets
config.rustdesk.device_password.clear();
config.rustdesk.relay_key = None;
config.rustdesk.public_key = None;
config.rustdesk.private_key = None;
config.rustdesk.signing_public_key = None;
config.rustdesk.signing_private_key = None;
}
/// 获取完整配置
pub async fn get_all_config(State(state): State<Arc<AppState>>) -> Json<AppConfig> {
let mut config = (*state.config.get()).clone();
// 不暴露敏感信息
config.auth.totp_secret = None;
sanitize_config_for_api(&mut config);
Json(config)
}

View File

@@ -139,7 +139,7 @@ pub async fn regenerate_device_password(
Ok(Json(RustDeskConfigResponse::from(&new_config)))
}
/// 获取设备密码(管理员专用
/// 获取设备密码(已认证用户
pub async fn get_device_password(State(state): State<Arc<AppState>>) -> Json<serde_json::Value> {
let config = state.config.get().rustdesk.clone();
Json(serde_json::json!({

View File

@@ -589,11 +589,8 @@ pub async fn setup_init(
));
}
// Create admin user
state
.users
.create(&req.username, &req.password, true)
.await?;
// Create single system user
state.users.create(&req.username, &req.password).await?;
// Update config
state
@@ -771,10 +768,7 @@ pub async fn setup_init(
}
}
tracing::info!(
"System initialized successfully with admin user: {}",
req.username
);
tracing::info!("System initialized successfully");
Ok(Json(LoginResponse {
success: true,
@@ -799,7 +793,7 @@ pub async fn update_config(
// Keep old config for rollback
let old_config = state.config.get();
tracing::info!("Received config update: {:?}", req.updates);
tracing::info!("Received config update request");
// Validate and merge config first (outside the update closure)
let config_json = serde_json::to_value(&old_config)
@@ -808,8 +802,6 @@ pub async fn update_config(
let merged = merge_json(config_json, req.updates.clone())
.map_err(|_| AppError::Internal("Failed to merge config".to_string()))?;
tracing::debug!("Merged config: {:?}", merged);
let new_config: AppConfig = serde_json::from_value(merged)
.map_err(|e| AppError::BadRequest(format!("Invalid config format: {}", e)))?;