mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-10-28 00:10:50 +08:00
fix(web): 修复初始化向导未应用所选 HID 配置
This commit is contained in:
@@ -30,7 +30,8 @@ pub struct SetupRequest {
|
||||
// Audio settings
|
||||
pub audio_device: Option<String>,
|
||||
// HID settings
|
||||
pub hid_backend: Option<String>,
|
||||
pub hid_backend: Option<crate::config::HidBackend>,
|
||||
pub hid_bluetooth: Option<crate::config::BluetoothHidConfig>,
|
||||
pub hid_ch9329_port: Option<String>,
|
||||
pub hid_ch9329_baudrate: Option<u32>,
|
||||
pub hid_otg_udc: Option<String>,
|
||||
@@ -42,6 +43,38 @@ pub struct SetupRequest {
|
||||
pub rustdesk_enabled: Option<bool>,
|
||||
}
|
||||
|
||||
impl SetupRequest {
|
||||
fn hid_config(&self, current: &crate::config::HidConfig) -> Result<crate::config::HidConfig> {
|
||||
let mut hid = current.clone();
|
||||
if let Some(backend) = &self.hid_backend {
|
||||
hid.backend = backend.clone();
|
||||
}
|
||||
if let Some(bluetooth) = &self.hid_bluetooth {
|
||||
hid.bluetooth = bluetooth.clone();
|
||||
}
|
||||
if let Some(port) = &self.hid_ch9329_port {
|
||||
hid.ch9329_port = port.clone();
|
||||
}
|
||||
if let Some(baudrate) = self.hid_ch9329_baudrate {
|
||||
hid.ch9329_baudrate = baudrate;
|
||||
}
|
||||
if let Some(udc) = &self.hid_otg_udc {
|
||||
hid.otg_udc = Some(udc.clone());
|
||||
}
|
||||
if let Some(profile) = &self.hid_otg_profile {
|
||||
if let Some(parsed) = crate::config::OtgHidProfile::from_legacy_str(profile) {
|
||||
hid.otg_profile = parsed;
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.hid_otg_keyboard_leds {
|
||||
hid.otg_keyboard_leds = enabled;
|
||||
}
|
||||
hid.bluetooth.validate()?;
|
||||
hid.validate_otg_functions()?;
|
||||
Ok(hid)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn setup_init(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Json(mut req): Json<SetupRequest>,
|
||||
@@ -97,6 +130,8 @@ pub async fn setup_init(
|
||||
}
|
||||
|
||||
let old_config = state.config.get();
|
||||
// Validate the selected HID configuration before creating the one-time account.
|
||||
let hid_config = req.hid_config(&old_config.hid)?;
|
||||
|
||||
// Create single system user
|
||||
state
|
||||
@@ -134,30 +169,7 @@ pub async fn setup_init(
|
||||
}
|
||||
|
||||
// HID settings
|
||||
if let Some(backend) = req.hid_backend.clone() {
|
||||
config.hid.backend = match backend.as_str() {
|
||||
"otg" => crate::config::HidBackend::Otg,
|
||||
"ch9329" => crate::config::HidBackend::Ch9329,
|
||||
_ => crate::config::HidBackend::None,
|
||||
};
|
||||
}
|
||||
if let Some(port) = req.hid_ch9329_port.clone() {
|
||||
config.hid.ch9329_port = port;
|
||||
}
|
||||
if let Some(baudrate) = req.hid_ch9329_baudrate {
|
||||
config.hid.ch9329_baudrate = baudrate;
|
||||
}
|
||||
if let Some(udc) = req.hid_otg_udc.clone() {
|
||||
config.hid.otg_udc = Some(udc);
|
||||
}
|
||||
if let Some(profile) = req.hid_otg_profile.clone() {
|
||||
if let Some(parsed) = crate::config::OtgHidProfile::from_legacy_str(&profile) {
|
||||
config.hid.otg_profile = parsed;
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = req.hid_otg_keyboard_leds {
|
||||
config.hid.otg_keyboard_leds = enabled;
|
||||
}
|
||||
config.hid = hid_config.clone();
|
||||
if let Some(enabled) = req.msd_enabled {
|
||||
config.msd.enabled = enabled;
|
||||
}
|
||||
@@ -265,3 +277,106 @@ pub async fn setup_init(
|
||||
message: Some("Setup completed".to_string()),
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::config::{AppConfig, HidBackend, HidConfig, OtgHidProfile};
|
||||
use serde_json::{json, Value};
|
||||
|
||||
fn request(mut hid: Value) -> SetupRequest {
|
||||
hid["username"] = json!("admin");
|
||||
hid["password"] = json!("test-password");
|
||||
serde_json::from_value(hid).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn setup_applies_selected_otg_device_and_legacy_options() {
|
||||
let req = request(json!({
|
||||
"hid_backend": "otg",
|
||||
"hid_otg_udc": "fe800000.usb",
|
||||
"hid_otg_profile": "full_no_consumer_no_msd",
|
||||
"hid_otg_keyboard_leds": true
|
||||
}));
|
||||
let hid = req.hid_config(&HidConfig::default()).unwrap();
|
||||
assert_eq!(hid.backend, HidBackend::Otg);
|
||||
assert_eq!(hid.otg_udc.as_deref(), Some("fe800000.usb"));
|
||||
assert_eq!(hid.otg_profile, OtgHidProfile::FullNoConsumer);
|
||||
assert!(hid.effective_otg_keyboard_leds());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn setup_applies_selected_ch9329_port_and_baudrate() {
|
||||
let req = request(json!({
|
||||
"hid_backend": "ch9329",
|
||||
"hid_ch9329_port": "/dev/ttyUSB2",
|
||||
"hid_ch9329_baudrate": 115200
|
||||
}));
|
||||
let hid = req.hid_config(&HidConfig::default()).unwrap();
|
||||
assert_eq!(hid.backend, HidBackend::Ch9329);
|
||||
assert_eq!(hid.ch9329_port, "/dev/ttyUSB2");
|
||||
assert_eq!(hid.ch9329_baudrate, 115200);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn setup_applies_bluetooth_selection_and_usb_invariants() {
|
||||
let req = request(json!({
|
||||
"hid_backend": "bluetooth",
|
||||
"hid_bluetooth": { "adapter": "hci1", "name": "My KVM" }
|
||||
}));
|
||||
let mut config = AppConfig::default();
|
||||
config.hid = req.hid_config(&config.hid).unwrap();
|
||||
config.hid.mouse_absolute = true;
|
||||
config.msd.enabled = true;
|
||||
config.otg_network.enabled = true;
|
||||
config.uac.enabled = true;
|
||||
config.enforce_invariants();
|
||||
|
||||
assert_eq!(config.hid.backend, HidBackend::Bluetooth);
|
||||
assert_eq!(config.hid.bluetooth.adapter, "hci1");
|
||||
assert_eq!(config.hid.bluetooth.name, "My KVM");
|
||||
assert_eq!(config.hid.bluetooth.peer, None);
|
||||
assert!(!config.hid.mouse_absolute);
|
||||
assert!(!config.msd.enabled && !config.otg_network.enabled && !config.uac.enabled);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn setup_preserves_omitted_settings_and_allows_explicit_disable() {
|
||||
let current = HidConfig {
|
||||
backend: HidBackend::Ch9329,
|
||||
ch9329_port: "COM7".into(),
|
||||
ch9329_baudrate: 57600,
|
||||
..Default::default()
|
||||
};
|
||||
assert_eq!(request(json!({})).hid_config(¤t).unwrap(), current);
|
||||
let disabled = request(json!({ "hid_backend": "none" }))
|
||||
.hid_config(¤t)
|
||||
.unwrap();
|
||||
assert_eq!(disabled.backend, HidBackend::None);
|
||||
assert_eq!(disabled.ch9329_port, current.ch9329_port);
|
||||
assert_eq!(disabled.ch9329_baudrate, current.ch9329_baudrate);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn setup_rejects_unknown_backend_instead_of_disabling_hid() {
|
||||
assert!(serde_json::from_value::<SetupRequest>(json!({
|
||||
"username": "admin", "password": "test-password",
|
||||
"hid_backend": "unsupported"
|
||||
}))
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn setup_rejects_invalid_bluetooth_configuration() {
|
||||
for bluetooth in [
|
||||
json!({ "adapter": "/dev/hci0", "name": "My KVM" }),
|
||||
json!({ "adapter": "hci0", "name": "" }),
|
||||
json!({ "adapter": "hci0", "name": "蓝".repeat(24) }),
|
||||
] {
|
||||
let req = request(json!({
|
||||
"hid_backend": "bluetooth", "hid_bluetooth": bluetooth
|
||||
}));
|
||||
assert!(req.hid_config(&HidConfig::default()).is_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user