mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-08 19:22:44 +08:00
feat: add launch guard and secure multi-user service ownership (#7569)
* feat(service): isolate macOS launch and owner runtime * ci(windows): run owner security tests * chore(deps): use kode-bridge v0.4.1 tag * fix(macos): classify installed service state * fix(macos): classify marked unavailable service * fix(macos): gate core startup on service migration * fix(macos): scope service init to supported platforms * feat(macos): prompt before migrating installed service * fix(macos): shorten sidecar IPC path * build(service): pin helper protocol and artifacts * fix(core): require confirmed service and sidecar readiness * fix(macos): harden launch roots and singleton state * fix(ui): refresh migration state before restart * fix(macos): linearize service migration lifecycle * fix(ui): keep service migration state fresh * feat(service): track authenticated owner sessions * fix(service): preserve newer owner sessions * feat(macos): route service proxy changes through helper * fix(macos): serialize service proxy guard * fix(macos): close service proxy owner lifecycle * fix(macos): close remaining proxy stop races * fix(app): do not cancel controlled service stop * fix(lifecycle): keep controlled updates cancellation-safe * fix(macos): stage dev core for service * test(macos): exercise staged core cleanup * fix(dev): await controlled macOS exit * chore: update changelog * fix(macos): recover sidecar after service install failure Allow the existing sidecar to continue when service installation leaves the manager in InstallRequired, then settle the session state as SidecarAllowed. Show neutral status text while the migration dialog waits for its final state. * fix(macos): stage dev service tools before elevation * fix(macos): localize launch guard prompts * fix(service): address cross-platform integration issues * feat: support seamless service migration * fix: pass Windows service installer path safely * fix(prebuild): derive service release from Cargo dependency * fix(dev): preserve service installation state * fix: resolve clippy warnings in service lifecycle
This commit is contained in:
@@ -9,8 +9,7 @@ use crate::{
|
||||
handle::Handle,
|
||||
hotkey::Hotkey,
|
||||
logger::Logger,
|
||||
service::{SERVICE_MANAGER, ServiceManager, is_service_ipc_path_exists},
|
||||
sysopt,
|
||||
service::{SERVICE_MANAGER, ServiceManager},
|
||||
tray::Tray,
|
||||
},
|
||||
feat,
|
||||
@@ -52,6 +51,7 @@ pub fn resolve_setup_async() {
|
||||
#[cfg(target_os = "macos")]
|
||||
resolve_dock_show().await;
|
||||
init_startup_script().await;
|
||||
init_service_manager().await;
|
||||
let config_initialized = init_verge_config_before_window().await;
|
||||
init_window().await;
|
||||
init_resources().await;
|
||||
@@ -64,10 +64,7 @@ pub fn resolve_setup_async() {
|
||||
Config::verify_config_initialization().await;
|
||||
|
||||
let core_init = AsyncHandler::spawn(|| async {
|
||||
init_service_manager().await;
|
||||
init_core_manager().await;
|
||||
init_system_proxy().await;
|
||||
init_system_proxy_guard().await;
|
||||
});
|
||||
|
||||
let _ = futures::join!(
|
||||
@@ -87,7 +84,6 @@ pub fn resolve_setup_async() {
|
||||
}
|
||||
|
||||
pub async fn resolve_reset_async() -> Result<(), anyhow::Error> {
|
||||
sysopt::Sysopt::global().reset_sysproxy().await?;
|
||||
CoreManager::global().stop_core().await?;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
@@ -152,7 +148,7 @@ async fn init_silent_updater() {
|
||||
// - macOS/Linux: binary is replaced, we restart the app
|
||||
if SilentUpdater::global().try_install_on_startup(app_handle).await {
|
||||
logging!(info, Type::Setup, "Update installed at startup, restarting...");
|
||||
app_handle.restart();
|
||||
feat::restart_app().await;
|
||||
}
|
||||
|
||||
// No pending install — start background check/download loop
|
||||
@@ -190,23 +186,20 @@ pub(super) async fn init_verge_config_before_window() -> bool {
|
||||
|
||||
pub(super) async fn init_service_manager() {
|
||||
clash_verge_service_ipc::set_config(Some(ServiceManager::config())).await;
|
||||
if is_service_ipc_path_exists() && SERVICE_MANAGER.init().await.is_ok() {
|
||||
logging_error!(Type::Setup, SERVICE_MANAGER.refresh().await);
|
||||
|
||||
SERVICE_MANAGER.detect_startup_status().await;
|
||||
}
|
||||
|
||||
pub(super) async fn init_core_manager() -> bool {
|
||||
match CoreManager::global().init().await {
|
||||
Ok(initialized) => initialized,
|
||||
Err(error) => {
|
||||
logging!(error, Type::Setup, "core manager initialization failed: {error:#}");
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) async fn init_core_manager() {
|
||||
logging_error!(Type::Setup, CoreManager::global().init().await);
|
||||
}
|
||||
|
||||
pub(super) async fn init_system_proxy() {
|
||||
logging_error!(Type::Setup, sysopt::Sysopt::global().update_sysproxy().await);
|
||||
}
|
||||
|
||||
pub(super) async fn init_system_proxy_guard() {
|
||||
sysopt::Sysopt::global().refresh_guard().await;
|
||||
}
|
||||
|
||||
pub(super) async fn refresh_tray_menu() {
|
||||
logging_error!(Type::Setup, Tray::global().update_part().await);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user