feat: 添加新插件支持及多项功能改进

- 新增磁盘加密、打印审计和剪贴板管控插件支持
- 优化水印插件显示效果,支持中文及更多Unicode字符
- 改进硬件资产收集逻辑,更准确获取磁盘和显卡信息
- 增强API错误处理,添加详细日志记录
- 完善前端界面,新增插件管理页面
- 修复多个UI问题,优化页面过渡效果
- 添加环境变量覆盖配置功能
- 实现插件状态管理API
- 更新文档和变更日志
- 添加安装程序脚本支持
This commit is contained in:
iven
2026-04-10 22:21:05 +08:00
parent 3d39f0e426
commit b5333d8c93
101 changed files with 4487 additions and 661 deletions

View File

@@ -3,7 +3,7 @@ use std::time::Duration;
use tokio::net::TcpStream;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tracing::{info, debug, warn};
use csm_protocol::{Frame, MessageType, RegisterRequest, RegisterResponse, HeartbeatPayload, WatermarkConfigPayload, UsbPolicyPayload};
use csm_protocol::{Frame, MessageType, RegisterRequest, RegisterResponse, HeartbeatPayload, WatermarkConfigPayload, UsbPolicyPayload, DiskEncryptionConfigPayload};
use hmac::{Hmac, Mac};
use sha2::Sha256;
@@ -18,6 +18,9 @@ pub struct PluginChannels {
pub usb_audit_tx: tokio::sync::watch::Sender<crate::usb_audit::UsbAuditConfig>,
pub usage_timer_tx: tokio::sync::watch::Sender<crate::usage_timer::UsageConfig>,
pub usb_policy_tx: tokio::sync::watch::Sender<Option<UsbPolicyPayload>>,
pub disk_encryption_tx: tokio::sync::watch::Sender<crate::disk_encryption::DiskEncryptionConfig>,
pub print_audit_tx: tokio::sync::watch::Sender<crate::print_audit::PrintAuditConfig>,
pub clipboard_control_tx: tokio::sync::watch::Sender<crate::clipboard_control::ClipboardControlConfig>,
}
/// Connect to server and run the main communication loop
@@ -286,6 +289,16 @@ fn handle_server_message(frame: Frame, plugins: &PluginChannels) -> Result<()> {
let config = crate::popup_blocker::PopupBlockerConfig { enabled: true, rules };
plugins.popup_blocker_tx.send(config)?;
}
MessageType::DiskEncryptionConfig => {
let config: DiskEncryptionConfigPayload = frame.decode_payload()
.map_err(|e| anyhow::anyhow!("Invalid disk encryption config: {}", e))?;
info!("Received disk encryption config: enabled={}, interval={}s", config.enabled, config.report_interval_secs);
let plugin_config = crate::disk_encryption::DiskEncryptionConfig {
enabled: config.enabled,
report_interval_secs: config.report_interval_secs,
};
plugins.disk_encryption_tx.send(plugin_config)?;
}
MessageType::PluginEnable => {
let payload: csm_protocol::PluginControlPayload = frame.decode_payload()
.map_err(|e| anyhow::anyhow!("Invalid plugin enable: {}", e))?;
@@ -299,6 +312,16 @@ fn handle_server_message(frame: Frame, plugins: &PluginChannels) -> Result<()> {
info!("Plugin disabled: {}", payload.plugin_name);
handle_plugin_control(&payload, plugins, false)?;
}
MessageType::ClipboardRules => {
let payload: csm_protocol::ClipboardRulesPayload = frame.decode_payload()
.map_err(|e| anyhow::anyhow!("Invalid clipboard rules: {}", e))?;
info!("Received clipboard rules update: {} rules", payload.rules.len());
let config = crate::clipboard_control::ClipboardControlConfig {
enabled: true,
rules: payload.rules,
};
plugins.clipboard_control_tx.send(config)?;
}
_ => {
debug!("Unhandled message type: {:?}", frame.msg_type);
}
@@ -346,6 +369,21 @@ fn handle_plugin_control(
plugins.usage_timer_tx.send(crate::usage_timer::UsageConfig { enabled: false, ..Default::default() })?;
}
}
"disk_encryption" => {
if !enabled {
plugins.disk_encryption_tx.send(crate::disk_encryption::DiskEncryptionConfig { enabled: false, ..Default::default() })?;
}
}
"print_audit" => {
if !enabled {
plugins.print_audit_tx.send(crate::print_audit::PrintAuditConfig { enabled: false, ..Default::default() })?;
}
}
"clipboard_control" => {
if !enabled {
plugins.clipboard_control_tx.send(crate::clipboard_control::ClipboardControlConfig { enabled: false, ..Default::default() })?;
}
}
_ => {
warn!("Unknown plugin: {}", payload.plugin_name);
}