diff --git a/vendor/rustdesk/src/hbbs_http/sync.rs b/vendor/rustdesk/src/hbbs_http/sync.rs index baf524a..66f472d 100644 --- a/vendor/rustdesk/src/hbbs_http/sync.rs +++ b/vendor/rustdesk/src/hbbs_http/sync.rs @@ -413,9 +413,28 @@ fn heartbeat_url() -> String { format!("{}/api/heartbeat", url) } +/// LocalConfig key holding the JSON list of option keys the server's strategy +/// applied on the previous push, so we can make strategies *authoritative*. +const STRATEGY_MANAGED_KEYS: &str = "strategy_managed_keys"; + fn handle_config_options(config_options: HashMap) { let mut options = Config::get_options(); let default_settings = config::DEFAULT_SETTINGS.read().unwrap().clone(); + + // hello-agent local patch — authoritative strategies. The server's strategy + // owns exactly the keys it sends. Any key it managed on the previous push + // but no longer sends is reset to its default (the override is dropped), so + // removing a key/strategy on the server actually clears it on the device. + // Keys the server never managed (the user's own local settings) are left + // untouched, so this stays a managed-config overlay rather than a wipe. + let prev_managed: Vec = + serde_json::from_str(&LocalConfig::get_option(STRATEGY_MANAGED_KEYS)).unwrap_or_default(); + for k in prev_managed.iter() { + if !config_options.contains_key(k) { + options.remove(k); + } + } + config_options .iter() .map(|(k, v)| { @@ -429,6 +448,14 @@ fn handle_config_options(config_options: HashMap) { } }) .count(); + + // Remember the keys we now manage, for the next diff. + let managed: Vec<&String> = config_options.keys().collect(); + LocalConfig::set_option( + STRATEGY_MANAGED_KEYS.to_string(), + serde_json::to_string(&managed).unwrap_or_default(), + ); + Config::set_options(options); }