Merge branch 'dev' into chore/i18n
This commit is contained in:
@@ -5,8 +5,10 @@ use aes_gcm::{
|
||||
};
|
||||
use base64::{Engine, engine::general_purpose::STANDARD};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::cell::Cell;
|
||||
|
||||
const NONCE_LENGTH: usize = 12;
|
||||
thread_local!(static ENCRYPTION_CONTEXT: Cell<bool> = const { Cell::new(false) });
|
||||
|
||||
/// Encrypt data
|
||||
#[allow(deprecated)]
|
||||
@@ -59,39 +61,62 @@ where
|
||||
T: Serialize,
|
||||
S: Serializer,
|
||||
{
|
||||
// 如果序列化失败,返回 None
|
||||
let json = match serde_json::to_string(value) {
|
||||
Ok(j) => j,
|
||||
Err(_) => return serializer.serialize_none(),
|
||||
};
|
||||
|
||||
// 如果加密失败,返回 None
|
||||
match encrypt_data(&json) {
|
||||
Ok(encrypted) => serializer.serialize_str(&encrypted),
|
||||
Err(_) => serializer.serialize_none(),
|
||||
if is_encryption_active() {
|
||||
let json = serde_json::to_string(value).map_err(serde::ser::Error::custom)?;
|
||||
let encrypted = encrypt_data(&json).map_err(serde::ser::Error::custom)?;
|
||||
serializer.serialize_str(&encrypted)
|
||||
} else {
|
||||
value.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserialize decrypted function
|
||||
pub fn deserialize_encrypted<'a, T, D>(deserializer: D) -> Result<T, D::Error>
|
||||
pub fn deserialize_encrypted<'a, D, T>(deserializer: D) -> Result<T, D::Error>
|
||||
where
|
||||
T: for<'de> Deserialize<'de> + Default,
|
||||
D: Deserializer<'a>,
|
||||
{
|
||||
// 如果反序列化字符串失败,返回默认值
|
||||
let encrypted = match String::deserialize(deserializer) {
|
||||
Ok(s) => s,
|
||||
Err(_) => return Ok(T::default()),
|
||||
};
|
||||
if is_encryption_active() {
|
||||
let encrypted_opt: Option<String> = Option::deserialize(deserializer)?;
|
||||
|
||||
// 如果解密失败,返回默认值
|
||||
let decrypted_string = match decrypt_data(&encrypted) {
|
||||
Ok(data) => data,
|
||||
Err(_) => return Ok(T::default()),
|
||||
};
|
||||
// 如果 JSON 解析失败,返回默认值
|
||||
match serde_json::from_str(&decrypted_string) {
|
||||
Ok(value) => Ok(value),
|
||||
Err(_) => Ok(T::default()),
|
||||
match encrypted_opt {
|
||||
Some(encrypted) if !encrypted.is_empty() => {
|
||||
let decrypted_string =
|
||||
decrypt_data(&encrypted).map_err(serde::de::Error::custom)?;
|
||||
serde_json::from_str(&decrypted_string).map_err(serde::de::Error::custom)
|
||||
}
|
||||
_ => Ok(T::default()),
|
||||
}
|
||||
} else {
|
||||
T::deserialize(deserializer)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EncryptionGuard;
|
||||
|
||||
impl EncryptionGuard {
|
||||
pub fn new() -> Self {
|
||||
ENCRYPTION_CONTEXT.with(|ctx| {
|
||||
ctx.set(true);
|
||||
});
|
||||
EncryptionGuard
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for EncryptionGuard {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for EncryptionGuard {
|
||||
fn drop(&mut self) {
|
||||
ENCRYPTION_CONTEXT.with(|ctx| {
|
||||
ctx.set(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn is_encryption_active() -> bool {
|
||||
ENCRYPTION_CONTEXT.with(|ctx| ctx.get())
|
||||
}
|
||||
|
||||
@@ -552,156 +552,3 @@ impl IVerge {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct IVergeResponse {
|
||||
pub app_log_level: Option<String>,
|
||||
pub app_log_max_size: Option<u64>,
|
||||
pub app_log_max_count: Option<usize>,
|
||||
pub language: Option<String>,
|
||||
pub theme_mode: Option<String>,
|
||||
pub tray_event: Option<String>,
|
||||
pub env_type: Option<String>,
|
||||
pub start_page: Option<String>,
|
||||
pub startup_script: Option<String>,
|
||||
pub traffic_graph: Option<bool>,
|
||||
pub enable_memory_usage: Option<bool>,
|
||||
pub enable_group_icon: Option<bool>,
|
||||
pub common_tray_icon: Option<bool>,
|
||||
#[cfg(target_os = "macos")]
|
||||
pub tray_icon: Option<String>,
|
||||
pub menu_icon: Option<String>,
|
||||
pub menu_order: Option<Vec<String>>,
|
||||
pub sysproxy_tray_icon: Option<bool>,
|
||||
pub tun_tray_icon: Option<bool>,
|
||||
pub enable_tun_mode: Option<bool>,
|
||||
pub enable_auto_launch: Option<bool>,
|
||||
pub enable_silent_start: Option<bool>,
|
||||
pub enable_system_proxy: Option<bool>,
|
||||
pub enable_proxy_guard: Option<bool>,
|
||||
pub enable_global_hotkey: Option<bool>,
|
||||
pub use_default_bypass: Option<bool>,
|
||||
pub system_proxy_bypass: Option<String>,
|
||||
pub proxy_guard_duration: Option<u64>,
|
||||
pub proxy_auto_config: Option<bool>,
|
||||
pub pac_file_content: Option<String>,
|
||||
pub proxy_host: Option<String>,
|
||||
pub theme_setting: Option<IVergeTheme>,
|
||||
pub web_ui_list: Option<Vec<String>>,
|
||||
pub clash_core: Option<String>,
|
||||
pub hotkeys: Option<Vec<String>>,
|
||||
pub auto_close_connection: Option<bool>,
|
||||
pub auto_check_update: Option<bool>,
|
||||
pub default_latency_test: Option<String>,
|
||||
pub default_latency_timeout: Option<i16>,
|
||||
pub enable_auto_delay_detection: Option<bool>,
|
||||
pub enable_builtin_enhanced: Option<bool>,
|
||||
pub proxy_layout_column: Option<u8>,
|
||||
pub test_list: Option<Vec<IVergeTestItem>>,
|
||||
pub auto_log_clean: Option<i32>,
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub verge_redir_port: Option<u16>,
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub verge_redir_enabled: Option<bool>,
|
||||
#[cfg(target_os = "linux")]
|
||||
pub verge_tproxy_port: Option<u16>,
|
||||
#[cfg(target_os = "linux")]
|
||||
pub verge_tproxy_enabled: Option<bool>,
|
||||
pub verge_mixed_port: Option<u16>,
|
||||
pub verge_socks_port: Option<u16>,
|
||||
pub verge_socks_enabled: Option<bool>,
|
||||
pub verge_port: Option<u16>,
|
||||
pub verge_http_enabled: Option<bool>,
|
||||
pub webdav_url: Option<String>,
|
||||
pub webdav_username: Option<String>,
|
||||
pub webdav_password: Option<String>,
|
||||
pub enable_tray_speed: Option<bool>,
|
||||
// pub enable_tray_icon: Option<bool>,
|
||||
pub tray_inline_proxy_groups: Option<bool>,
|
||||
pub enable_auto_light_weight_mode: Option<bool>,
|
||||
pub auto_light_weight_minutes: Option<u64>,
|
||||
pub enable_dns_settings: Option<bool>,
|
||||
pub home_cards: Option<serde_json::Value>,
|
||||
pub enable_hover_jump_navigator: Option<bool>,
|
||||
pub hover_jump_navigator_delay: Option<u64>,
|
||||
pub enable_external_controller: Option<bool>,
|
||||
}
|
||||
|
||||
impl From<IVerge> for IVergeResponse {
|
||||
fn from(verge: IVerge) -> Self {
|
||||
// 先获取验证后的clash_core值,避免后续借用冲突
|
||||
let valid_clash_core = verge.get_valid_clash_core();
|
||||
Self {
|
||||
app_log_level: verge.app_log_level,
|
||||
app_log_max_size: verge.app_log_max_size,
|
||||
app_log_max_count: verge.app_log_max_count,
|
||||
language: verge.language,
|
||||
theme_mode: verge.theme_mode,
|
||||
tray_event: verge.tray_event,
|
||||
env_type: verge.env_type,
|
||||
start_page: verge.start_page,
|
||||
startup_script: verge.startup_script,
|
||||
traffic_graph: verge.traffic_graph,
|
||||
enable_memory_usage: verge.enable_memory_usage,
|
||||
enable_group_icon: verge.enable_group_icon,
|
||||
common_tray_icon: verge.common_tray_icon,
|
||||
#[cfg(target_os = "macos")]
|
||||
tray_icon: verge.tray_icon,
|
||||
menu_icon: verge.menu_icon,
|
||||
menu_order: verge.menu_order,
|
||||
sysproxy_tray_icon: verge.sysproxy_tray_icon,
|
||||
tun_tray_icon: verge.tun_tray_icon,
|
||||
enable_tun_mode: verge.enable_tun_mode,
|
||||
enable_auto_launch: verge.enable_auto_launch,
|
||||
enable_silent_start: verge.enable_silent_start,
|
||||
enable_system_proxy: verge.enable_system_proxy,
|
||||
enable_proxy_guard: verge.enable_proxy_guard,
|
||||
enable_global_hotkey: verge.enable_global_hotkey,
|
||||
use_default_bypass: verge.use_default_bypass,
|
||||
system_proxy_bypass: verge.system_proxy_bypass,
|
||||
proxy_guard_duration: verge.proxy_guard_duration,
|
||||
proxy_auto_config: verge.proxy_auto_config,
|
||||
pac_file_content: verge.pac_file_content,
|
||||
proxy_host: verge.proxy_host,
|
||||
theme_setting: verge.theme_setting,
|
||||
web_ui_list: verge.web_ui_list,
|
||||
clash_core: Some(valid_clash_core),
|
||||
hotkeys: verge.hotkeys,
|
||||
auto_close_connection: verge.auto_close_connection,
|
||||
auto_check_update: verge.auto_check_update,
|
||||
default_latency_test: verge.default_latency_test,
|
||||
default_latency_timeout: verge.default_latency_timeout,
|
||||
enable_auto_delay_detection: verge.enable_auto_delay_detection,
|
||||
enable_builtin_enhanced: verge.enable_builtin_enhanced,
|
||||
proxy_layout_column: verge.proxy_layout_column,
|
||||
test_list: verge.test_list,
|
||||
auto_log_clean: verge.auto_log_clean,
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
verge_redir_port: verge.verge_redir_port,
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
verge_redir_enabled: verge.verge_redir_enabled,
|
||||
#[cfg(target_os = "linux")]
|
||||
verge_tproxy_port: verge.verge_tproxy_port,
|
||||
#[cfg(target_os = "linux")]
|
||||
verge_tproxy_enabled: verge.verge_tproxy_enabled,
|
||||
verge_mixed_port: verge.verge_mixed_port,
|
||||
verge_socks_port: verge.verge_socks_port,
|
||||
verge_socks_enabled: verge.verge_socks_enabled,
|
||||
verge_port: verge.verge_port,
|
||||
verge_http_enabled: verge.verge_http_enabled,
|
||||
webdav_url: verge.webdav_url,
|
||||
webdav_username: verge.webdav_username,
|
||||
webdav_password: verge.webdav_password,
|
||||
enable_tray_speed: verge.enable_tray_speed,
|
||||
// enable_tray_icon: verge.enable_tray_icon,
|
||||
tray_inline_proxy_groups: verge.tray_inline_proxy_groups,
|
||||
enable_auto_light_weight_mode: verge.enable_auto_light_weight_mode,
|
||||
auto_light_weight_minutes: verge.auto_light_weight_minutes,
|
||||
enable_dns_settings: verge.enable_dns_settings,
|
||||
home_cards: verge.home_cards,
|
||||
enable_hover_jump_navigator: verge.enable_hover_jump_navigator,
|
||||
hover_jump_navigator_delay: verge.hover_jump_navigator_delay,
|
||||
enable_external_controller: verge.enable_external_controller,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ impl WebDavClient {
|
||||
(*cfg_arc).clone()
|
||||
} else {
|
||||
// 释放锁后获取异步配置
|
||||
let verge = Config::verge().await.latest_arc();
|
||||
let verge = Config::verge().await.data_arc();
|
||||
if verge.webdav_url.is_none()
|
||||
|| verge.webdav_username.is_none()
|
||||
|| verge.webdav_password.is_none()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::{enhance::seq::SeqMap, logging, utils::logging::Type};
|
||||
use crate::{config::EncryptionGuard, enhance::seq::SeqMap, logging, utils::logging::Type};
|
||||
use anyhow::{Context, Result, anyhow, bail};
|
||||
use nanoid::nanoid;
|
||||
use serde::{Serialize, de::DeserializeOwned};
|
||||
@@ -11,6 +11,7 @@ pub async fn read_yaml<T: DeserializeOwned>(path: &PathBuf) -> Result<T> {
|
||||
bail!("file not found \"{}\"", path.display());
|
||||
}
|
||||
|
||||
let _guard = EncryptionGuard::new();
|
||||
let yaml_str = tokio::fs::read_to_string(path).await?;
|
||||
|
||||
Ok(serde_yaml_ng::from_str::<T>(&yaml_str)?)
|
||||
@@ -65,6 +66,7 @@ pub async fn save_yaml<T: Serialize + Sync>(
|
||||
data: &T,
|
||||
prefix: Option<&str>,
|
||||
) -> Result<()> {
|
||||
let _guard = EncryptionGuard::new();
|
||||
let data_str = serde_yaml_ng::to_string(data)?;
|
||||
|
||||
let yaml_str = match prefix {
|
||||
|
||||
Reference in New Issue
Block a user