- Prevent 'nx9-wg version' from creating data directories by avoiding database initialization. - Create parent directories when an explicit --database path is provided. - Redact printed generated administrator passwords; announce file path or redact instead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
136 lines
4.2 KiB
Rust
136 lines
4.2 KiB
Rust
//! Client export modal presentation component.
|
|
|
|
use nx9_wg_core::types::client_profile::{
|
|
ConnectionType, DeviceCategory, NatType, ResolvedClientProfile,
|
|
};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
/// Client configuration export UI state.
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct ClientExportState {
|
|
pub selected_provider: Option<String>,
|
|
pub selected_device: Option<DeviceCategory>,
|
|
pub selected_connection: ConnectionType,
|
|
pub selected_nat: NatType,
|
|
pub manual_mtu_override: Option<u16>,
|
|
pub resolved_profile: Option<ResolvedClientProfile>,
|
|
pub is_override_enabled: bool,
|
|
pub qr_view_active: bool,
|
|
}
|
|
|
|
impl Default for ClientExportState {
|
|
fn default() -> Self {
|
|
Self {
|
|
selected_provider: None,
|
|
selected_device: None,
|
|
selected_connection: ConnectionType::Web,
|
|
selected_nat: NatType::Unknown,
|
|
manual_mtu_override: None,
|
|
resolved_profile: None,
|
|
is_override_enabled: false,
|
|
qr_view_active: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ClientExportState {
|
|
/// Create a new initial export state.
|
|
pub fn new() -> Self {
|
|
Self::default()
|
|
}
|
|
|
|
/// Set connection type and reset manual override if disabled.
|
|
pub fn set_connection(&mut self, connection: ConnectionType) {
|
|
self.selected_connection = connection;
|
|
}
|
|
|
|
/// Set NAT type.
|
|
pub fn set_nat(&mut self, nat: NatType) {
|
|
self.selected_nat = nat;
|
|
}
|
|
|
|
/// Set device category.
|
|
pub fn set_device(&mut self, device: Option<DeviceCategory>) {
|
|
self.selected_device = device;
|
|
}
|
|
|
|
/// Set provider.
|
|
pub fn set_provider(&mut self, provider: Option<String>) {
|
|
self.selected_provider = provider;
|
|
}
|
|
|
|
/// Toggle or set manual MTU override.
|
|
pub fn set_manual_mtu(&mut self, mtu: Option<u16>) {
|
|
self.manual_mtu_override = mtu;
|
|
self.is_override_enabled = mtu.is_some();
|
|
}
|
|
|
|
/// Get current effective MTU for display.
|
|
pub fn display_mtu(&self) -> u16 {
|
|
if let Some(m) = self.manual_mtu_override {
|
|
m
|
|
} else if let Some(ref res) = self.resolved_profile {
|
|
res.mtu
|
|
} else {
|
|
1420
|
|
}
|
|
}
|
|
|
|
/// Determine if an active manual override warning should be displayed.
|
|
pub fn has_manual_override_warning(&self) -> bool {
|
|
self.is_override_enabled && self.manual_mtu_override.is_some()
|
|
}
|
|
|
|
/// Format export query parameters for REST API call.
|
|
pub fn to_query_string(&self, profile_id: Option<&str>) -> String {
|
|
let mut params = Vec::new();
|
|
if let Some(ref p) = self.selected_provider {
|
|
params.push(format!("provider={}", urlencoding(p)));
|
|
}
|
|
if let Some(ref d) = self.selected_device {
|
|
params.push(format!("device={}", d.as_str()));
|
|
}
|
|
params.push(format!("connection={}", self.selected_connection.as_str()));
|
|
params.push(format!("nat={}", self.selected_nat.as_str()));
|
|
if let Some(m) = self.manual_mtu_override {
|
|
params.push(format!("mtu={m}"));
|
|
}
|
|
if let Some(id) = profile_id {
|
|
params.push(format!("profile={}", urlencoding(id)));
|
|
}
|
|
params.join("&")
|
|
}
|
|
}
|
|
|
|
fn urlencoding(s: &str) -> String {
|
|
s.replace(' ', "%20")
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_client_export_state_lifecycle() {
|
|
let mut state = ClientExportState::new();
|
|
assert_eq!(state.display_mtu(), 1420);
|
|
assert!(!state.has_manual_override_warning());
|
|
|
|
state.set_connection(ConnectionType::Mobile);
|
|
state.set_device(Some(DeviceCategory::Android));
|
|
state.set_nat(NatType::Cgnat);
|
|
state.set_provider(Some("tmobile".to_string()));
|
|
|
|
let query = state.to_query_string(None);
|
|
assert!(query.contains("connection=mobile"));
|
|
assert!(query.contains("device=android"));
|
|
assert!(query.contains("nat=cgnat"));
|
|
assert!(query.contains("provider=tmobile"));
|
|
|
|
state.set_manual_mtu(Some(1300));
|
|
assert_eq!(state.display_mtu(), 1300);
|
|
assert!(state.has_manual_override_warning());
|
|
assert!(state.to_query_string(None).contains("mtu=1300"));
|
|
}
|
|
}
|