refactor(desktop): move Tauri remote proxy into packages/server
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
"build": "tauri build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^2.9.4"
|
||||
"@tauri-apps/cli": "^2.9.4",
|
||||
"@tauri-apps/cli-darwin-arm64": "^2.9.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
#[cfg_attr(target_os = "linux", allow(dead_code))]
|
||||
#[allow(dead_code)]
|
||||
mod cert_manager;
|
||||
mod cli_manager;
|
||||
#[cfg(target_os = "linux")]
|
||||
mod linux_tls;
|
||||
#[cfg_attr(target_os = "linux", allow(dead_code))]
|
||||
mod remote_proxy;
|
||||
|
||||
use cli_manager::{CliProcessManager, CliStatus};
|
||||
use keepawake::KeepAwake;
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
use remote_proxy::start_remote_proxy;
|
||||
use remote_proxy::{ProxyTlsConfig, RemoteProxyHandle};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
@@ -56,7 +51,6 @@ pub struct AppState {
|
||||
pub remote_origins: Mutex<HashMap<String, String>>,
|
||||
pub remote_skip_tls_verify: Mutex<HashMap<String, bool>>,
|
||||
pub remote_tls_handlers: Mutex<HashSet<String>>,
|
||||
pub remote_proxies: Mutex<HashMap<String, RemoteProxyHandle>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@@ -65,6 +59,8 @@ struct RemoteWindowPayload {
|
||||
id: String,
|
||||
name: String,
|
||||
base_url: String,
|
||||
entry_url: Option<String>,
|
||||
#[allow(dead_code)]
|
||||
skip_tls_verify: bool,
|
||||
}
|
||||
|
||||
@@ -182,49 +178,21 @@ fn intercept_navigation<R: Runtime>(webview: &Webview<R>, url: &Url) -> bool {
|
||||
async fn open_remote_window_impl(
|
||||
app: AppHandle,
|
||||
payload: RemoteWindowPayload,
|
||||
_tls_config: Option<ProxyTlsConfig>,
|
||||
) -> Result<(), String> {
|
||||
let parsed = Url::parse(&payload.base_url).map_err(|err| err.to_string())?;
|
||||
let entry_url = payload.entry_url.as_deref().unwrap_or(payload.base_url.as_str());
|
||||
let parsed = Url::parse(entry_url).map_err(|err| err.to_string())?;
|
||||
let label = format!("remote-{}", payload.id);
|
||||
let title = format!(
|
||||
"{} - {}",
|
||||
payload.name,
|
||||
parsed.host_str().unwrap_or(payload.base_url.as_str())
|
||||
Url::parse(&payload.base_url)
|
||||
.ok()
|
||||
.and_then(|url| url.host_str().map(str::to_string))
|
||||
.unwrap_or_else(|| payload.base_url.clone())
|
||||
);
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
let window_url = parsed.clone();
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
let window_url = {
|
||||
let state = app.state::<AppState>();
|
||||
let reuses_existing_proxy = {
|
||||
let proxies = state.remote_proxies.lock().map_err(|err| err.to_string())?;
|
||||
proxies
|
||||
.get(&label)
|
||||
.map(|existing| existing.matches(&parsed, payload.skip_tls_verify))
|
||||
.unwrap_or(false)
|
||||
};
|
||||
|
||||
if reuses_existing_proxy {
|
||||
let proxies = state.remote_proxies.lock().map_err(|err| err.to_string())?;
|
||||
proxies
|
||||
.get(&label)
|
||||
.map(|handle| handle.entry_url().clone())
|
||||
.ok_or_else(|| "Remote proxy disappeared before reuse".to_string())?
|
||||
} else {
|
||||
let new_proxy =
|
||||
start_remote_proxy(parsed.clone(), payload.skip_tls_verify, _tls_config).await?;
|
||||
let local_url = new_proxy.entry_url().clone();
|
||||
let mut proxies = state.remote_proxies.lock().map_err(|err| err.to_string())?;
|
||||
if let Some(existing) = proxies.remove(&label) {
|
||||
existing.shutdown();
|
||||
}
|
||||
proxies.insert(label.clone(), new_proxy);
|
||||
local_url
|
||||
}
|
||||
};
|
||||
|
||||
app.state::<AppState>()
|
||||
.remote_origins
|
||||
.lock()
|
||||
@@ -234,7 +202,7 @@ async fn open_remote_window_impl(
|
||||
.remote_skip_tls_verify
|
||||
.lock()
|
||||
.map_err(|err| err.to_string())?
|
||||
.insert(label.clone(), payload.skip_tls_verify);
|
||||
.insert(label.clone(), parsed.scheme() == "https");
|
||||
|
||||
if let Some(existing) = app.get_webview_window(&label) {
|
||||
#[cfg(target_os = "linux")]
|
||||
@@ -287,11 +255,6 @@ async fn open_remote_window_impl(
|
||||
if let Ok(mut handlers) = app_handle.state::<AppState>().remote_tls_handlers.lock() {
|
||||
handlers.remove(&label_for_cleanup);
|
||||
}
|
||||
if let Ok(mut proxies) = app_handle.state::<AppState>().remote_proxies.lock() {
|
||||
if let Some(handle) = proxies.remove(&label_for_cleanup) {
|
||||
handle.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -300,33 +263,25 @@ async fn open_remote_window_impl(
|
||||
|
||||
#[tauri::command]
|
||||
async fn open_remote_window(app: AppHandle, payload: RemoteWindowPayload) -> Result<(), String> {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
return open_remote_window_impl(app, payload, None).await;
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
let tls_config = match cert_manager::ensure_local_cert() {
|
||||
Ok(local_cert) => {
|
||||
{
|
||||
let entry_url = payload.entry_url.as_deref().unwrap_or(payload.base_url.as_str());
|
||||
let parsed = Url::parse(entry_url).map_err(|err| err.to_string())?;
|
||||
if parsed.scheme() == "https" {
|
||||
let local_cert = cert_manager::ensure_local_cert().map_err(|err| {
|
||||
format!(
|
||||
"Failed to load the local HTTPS certificate for the remote proxy window: {err}"
|
||||
)
|
||||
})?;
|
||||
if let Err(err) = cert_manager::trust_cert_in_store(&local_cert.ca_cert_der) {
|
||||
return Err(format!(
|
||||
"Failed to trust the local CodeNomad CA certificate. Accept the certificate installation prompt and try again: {err}"
|
||||
));
|
||||
}
|
||||
Some(ProxyTlsConfig {
|
||||
cert_pem: local_cert.cert_pem,
|
||||
key_pem: local_cert.key_pem,
|
||||
})
|
||||
}
|
||||
Err(err) => {
|
||||
return Err(format!(
|
||||
"Failed to create the local HTTPS proxy certificate. This remote HTTPS connection cannot fall back to HTTP because secure cookies would break: {err}"
|
||||
));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
open_remote_window_impl(app, payload, tls_config).await
|
||||
open_remote_window_impl(app, payload).await
|
||||
}
|
||||
|
||||
fn collect_directory_paths(paths: &[std::path::PathBuf]) -> Vec<String> {
|
||||
@@ -487,7 +442,6 @@ fn main() {
|
||||
remote_origins: Mutex::new(HashMap::new()),
|
||||
remote_skip_tls_verify: Mutex::new(HashMap::new()),
|
||||
remote_tls_handlers: Mutex::new(HashSet::new()),
|
||||
remote_proxies: Mutex::new(HashMap::new()),
|
||||
})
|
||||
.setup(|app| {
|
||||
set_windows_app_user_model_id();
|
||||
|
||||
Reference in New Issue
Block a user