mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 00:35:38 +08:00
fix(config): auto complete and patch secret field when loading config
- Ensure the 'secret' field is present and non-empty during config loading - Auto-fill with default value if missing to improve compatibility and security - Update config guard logic for robustness
This commit is contained in:
@@ -1,9 +1,12 @@
|
|||||||
## v2.2.4-alpha
|
## v2.2.4-alpha
|
||||||
|
|
||||||
|
尽管外部控制密钥已自动补全默认值且不允许为空。仍然推荐自行修改外部控制密钥。
|
||||||
|
|
||||||
#### 已知问题
|
#### 已知问题
|
||||||
- 仅在Ubuntu 22.04/24.04,Fedora 41 **Gnome桌面环境** 做过简单测试,不保证其他其他Linux发行版可用,将在未来做进一步适配和调优
|
- 仅在Ubuntu 22.04/24.04,Fedora 41 **Gnome桌面环境** 做过简单测试,不保证其他其他Linux发行版可用,将在未来做进一步适配和调优
|
||||||
- MacOS 下 墙贴主要为浅色,Tray 图标深色时图标闪烁;彩色 Tray 速率颜色淡
|
- MacOS 下 墙贴主要为浅色,Tray 图标深色时图标闪烁;彩色 Tray 速率颜色淡
|
||||||
- 窗口状态管理器已确定上游存在缺陷,暂时移除。当前不再内置窗口大小和位置记忆。
|
- 窗口状态管理器已确定上游存在缺陷,暂时移除。当前不再内置窗口大小和位置记忆。
|
||||||
|
- MacOS 下卸载服务后需手动重启软件才能与内核通信。
|
||||||
|
|
||||||
### 2.2.4 相对于 2.2.3
|
### 2.2.4 相对于 2.2.3
|
||||||
#### 修复了:
|
#### 修复了:
|
||||||
@@ -50,6 +53,7 @@
|
|||||||
- 切换、升级、重启内核的状态管理
|
- 切换、升级、重启内核的状态管理
|
||||||
- 更精细化控制自动日志清理,新增1天选项
|
- 更精细化控制自动日志清理,新增1天选项
|
||||||
- Winodws 快捷键名称改为 `Clash Verge`
|
- Winodws 快捷键名称改为 `Clash Verge`
|
||||||
|
- 配置加载阶段自动补全 external-controller secret 字段。
|
||||||
|
|
||||||
#### 优化了:
|
#### 优化了:
|
||||||
- 系统代理 Bypass 设置
|
- 系统代理 Bypass 设置
|
||||||
@@ -79,6 +83,7 @@
|
|||||||
- 优化端口设置退出和保存机制
|
- 优化端口设置退出和保存机制
|
||||||
- 强制为 Mihomo 配置补全并覆盖 external-controller-cors 字段,默认不允许跨域和仅本地请求,提升 cors 安全性,升级配置时自动覆盖
|
- 强制为 Mihomo 配置补全并覆盖 external-controller-cors 字段,默认不允许跨域和仅本地请求,提升 cors 安全性,升级配置时自动覆盖
|
||||||
- 修改 端口检测范围 (1111-65536)
|
- 修改 端口检测范围 (1111-65536)
|
||||||
|
- 配置文件缺失 secret 字段时自动填充默认值 set-your-secret
|
||||||
|
|
||||||
#### 移除了:
|
#### 移除了:
|
||||||
- 窗口状态管理器
|
- 窗口状态管理器
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ impl IClashTemp {
|
|||||||
map.insert(key.clone(), template.0.get(key).unwrap().clone());
|
map.insert(key.clone(), template.0.get(key).unwrap().clone());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// 确保 secret 字段存在且不为空
|
||||||
|
if let Some(Value::String(s)) = map.get_mut("secret") {
|
||||||
|
if s.is_empty() {
|
||||||
|
*s = "set-your-secret".to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
Self(Self::guard(map))
|
Self(Self::guard(map))
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -64,7 +70,7 @@ impl IClashTemp {
|
|||||||
]
|
]
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
map.insert("secret".into(), "".into());
|
map.insert("secret".into(), "set-your-secret".into());
|
||||||
map.insert("tun".into(), tun.into());
|
map.insert("tun".into(), tun.into());
|
||||||
map.insert("external-controller-cors".into(), cors_map.into());
|
map.insert("external-controller-cors".into(), cors_map.into());
|
||||||
map.insert("unified-delay".into(), true.into());
|
map.insert("unified-delay".into(), true.into());
|
||||||
|
|||||||
@@ -42,7 +42,12 @@ export const ControllerViewer = forwardRef<DialogRef>((props, ref) => {
|
|||||||
// 保存配置
|
// 保存配置
|
||||||
const onSave = useLockFn(async () => {
|
const onSave = useLockFn(async () => {
|
||||||
if (!controller.trim()) {
|
if (!controller.trim()) {
|
||||||
showNotice('info', t("Controller address cannot be empty"), 3000);
|
showNotice('error', t("Controller address cannot be empty"), 3000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!secret.trim()) {
|
||||||
|
showNotice('error', t("Secret cannot be empty"), 3000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,14 +100,13 @@ export const ControllerViewer = forwardRef<DialogRef>((props, ref) => {
|
|||||||
size="small"
|
size="small"
|
||||||
sx={{
|
sx={{
|
||||||
width: 175,
|
width: 175,
|
||||||
opacity: 0.7,
|
opacity: 1,
|
||||||
pointerEvents: 'none'
|
pointerEvents: 'auto'
|
||||||
}}
|
}}
|
||||||
value={controller}
|
value={controller}
|
||||||
placeholder="Required"
|
placeholder="Required"
|
||||||
onChange={() => {}}
|
onChange={e => setController(e.target.value)}
|
||||||
disabled={true}
|
disabled={isSaving}
|
||||||
inputProps={{ readOnly: true }}
|
|
||||||
/>
|
/>
|
||||||
<Tooltip title={t("Copy to clipboard")}>
|
<Tooltip title={t("Copy to clipboard")}>
|
||||||
<IconButton
|
<IconButton
|
||||||
@@ -124,14 +128,13 @@ export const ControllerViewer = forwardRef<DialogRef>((props, ref) => {
|
|||||||
size="small"
|
size="small"
|
||||||
sx={{
|
sx={{
|
||||||
width: 175,
|
width: 175,
|
||||||
opacity: 0.7,
|
opacity: 1,
|
||||||
pointerEvents: 'none'
|
pointerEvents: 'auto'
|
||||||
}}
|
}}
|
||||||
value={secret}
|
value={secret}
|
||||||
placeholder={t("Recommended")}
|
placeholder={t("Recommended")}
|
||||||
onChange={() => {}}
|
onChange={e => setSecret(e.target.value)}
|
||||||
disabled={true}
|
disabled={isSaving}
|
||||||
inputProps={{ readOnly: true }}
|
|
||||||
/>
|
/>
|
||||||
<Tooltip title={t("Copy to clipboard")}>
|
<Tooltip title={t("Copy to clipboard")}>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|||||||
Reference in New Issue
Block a user