mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-08 02:52:07 +08:00
feat(dns): protect provider DNS from unconfirmed overrides (#7902)
Fixes #7292
This commit is contained in:
@@ -33,6 +33,7 @@ import {
|
||||
Switch,
|
||||
} from '@/components/base'
|
||||
import { useClash } from '@/hooks/use-clash'
|
||||
import { useVerge } from '@/hooks/use-verge'
|
||||
import { showNotice } from '@/services/notice-service'
|
||||
import { useThemeMode } from '@/services/states'
|
||||
import type { MonacoEditorInstance } from '@/types/monaco'
|
||||
@@ -187,7 +188,8 @@ const DEFAULT_DNS_CONFIG = {
|
||||
|
||||
export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
const { t } = useTranslation()
|
||||
const { clash, mutateClash } = useClash()
|
||||
const { mutateClash } = useClash()
|
||||
const { verge } = useVerge()
|
||||
const themeMode = useThemeMode()
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
@@ -563,7 +565,7 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
return
|
||||
}
|
||||
|
||||
if (clash?.dns?.enable) {
|
||||
if (verge?.enable_dns_settings) {
|
||||
await invoke('apply_dns_config', { apply: true })
|
||||
mutateClash()
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import { LanRounded, SettingsRounded } from '@mui/icons-material'
|
||||
import { MenuItem, Select, TextField, Typography } from '@mui/material'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { useLockFn } from 'ahooks'
|
||||
import { useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { updateGeo, type LogLevel } from 'tauri-plugin-mihomo-api'
|
||||
|
||||
import { DialogRef, Switch, TooltipIcon } from '@/components/base'
|
||||
import { BaseDialog, DialogRef, Switch, TooltipIcon } from '@/components/base'
|
||||
import { useClash } from '@/hooks/use-clash'
|
||||
import { useClashLog } from '@/hooks/use-clash-log'
|
||||
import { useDisplayedMixedPort } from '@/hooks/use-displayed-mixed-port'
|
||||
import { useVerge } from '@/hooks/use-verge'
|
||||
import { invoke_uwp_tool } from '@/services/cmds'
|
||||
import { invoke_uwp_tool, setDnsOverride } from '@/services/cmds'
|
||||
import { showNotice } from '@/services/notice-service'
|
||||
import getSystem from '@/utils/get-system'
|
||||
|
||||
@@ -36,7 +35,7 @@ const SettingClash = ({ onError }: Props) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const { clash, version, mutateClash, patchClash } = useClash()
|
||||
const { verge, patchVerge } = useVerge()
|
||||
const { verge, mutateVerge } = useVerge()
|
||||
const displayedMixedPort = useDisplayedMixedPort()
|
||||
const [, setClashLog] = useClashLog()
|
||||
|
||||
@@ -47,10 +46,8 @@ const SettingClash = ({ onError }: Props) => {
|
||||
'unified-delay': unifiedDelay,
|
||||
} = clash ?? {}
|
||||
|
||||
// 独立跟踪DNS设置开关状态
|
||||
const [dnsSettingsEnabled, setDnsSettingsEnabled] = useState(() => {
|
||||
return verge?.enable_dns_settings ?? false
|
||||
})
|
||||
const [dnsConfirmation, setDnsConfirmation] = useState<string | null>(null)
|
||||
const [dnsUpdating, setDnsUpdating] = useState(false)
|
||||
|
||||
const webRef = useRef<DialogRef>(null)
|
||||
const portRef = useRef<DialogRef>(null)
|
||||
@@ -74,22 +71,29 @@ const SettingClash = ({ onError }: Props) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 实现DNS设置开关处理函数
|
||||
const handleDnsToggle = useLockFn(async (enable: boolean) => {
|
||||
try {
|
||||
setDnsSettingsEnabled(enable)
|
||||
await patchVerge({ enable_dns_settings: enable })
|
||||
await invoke('apply_dns_config', { apply: enable })
|
||||
setTimeout(() => {
|
||||
const handleDnsToggle = useLockFn(
|
||||
async (enable: boolean, confirmation?: string) => {
|
||||
setDnsUpdating(true)
|
||||
try {
|
||||
const outcome = await setDnsOverride(enable, confirmation)
|
||||
if (outcome.status === 'confirmation_required') {
|
||||
setDnsConfirmation(outcome.source)
|
||||
} else {
|
||||
setDnsConfirmation(null)
|
||||
}
|
||||
mutateVerge()
|
||||
mutateClash()
|
||||
}, 500)
|
||||
} catch (err: any) {
|
||||
setDnsSettingsEnabled(!enable)
|
||||
showNotice.error(err)
|
||||
await patchVerge({ enable_dns_settings: !enable }).catch(() => {})
|
||||
throw err
|
||||
}
|
||||
})
|
||||
} catch (err: any) {
|
||||
showNotice.error(err)
|
||||
} finally {
|
||||
setDnsUpdating(false)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
const closeDnsConfirmation = () => {
|
||||
if (!dnsUpdating) setDnsConfirmation(null)
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingList title={t('settings.sections.clash.title')}>
|
||||
@@ -99,6 +103,24 @@ const SettingClash = ({ onError }: Props) => {
|
||||
<ClashCoreViewer ref={coreRef} />
|
||||
<NetworkInterfaceViewer ref={networkRef} />
|
||||
<DnsViewer ref={dnsRef} />
|
||||
<BaseDialog
|
||||
open={dnsConfirmation !== null}
|
||||
title={t('settings.modals.dns.protection.title')}
|
||||
okBtn={t('settings.modals.dns.protection.enableAnyway')}
|
||||
cancelBtn={t('settings.modals.dns.protection.keepDisabled')}
|
||||
contentSx={{ width: { xs: 320, sm: 420 } }}
|
||||
loading={dnsUpdating}
|
||||
disableCancel={dnsUpdating}
|
||||
onCancel={closeDnsConfirmation}
|
||||
onClose={closeDnsConfirmation}
|
||||
onOk={() => {
|
||||
if (dnsConfirmation) void handleDnsToggle(true, dnsConfirmation)
|
||||
}}
|
||||
>
|
||||
<Typography variant="body2">
|
||||
{t('settings.modals.dns.protection.message')}
|
||||
</Typography>
|
||||
</BaseDialog>
|
||||
<HeaderConfiguration ref={corsRef} />
|
||||
<TunnelsViewer ref={tunnelRef} />
|
||||
<SettingItem
|
||||
@@ -137,7 +159,8 @@ const SettingClash = ({ onError }: Props) => {
|
||||
>
|
||||
<Switch
|
||||
edge="end"
|
||||
checked={dnsSettingsEnabled}
|
||||
checked={verge?.enable_dns_settings ?? false}
|
||||
disabled={dnsUpdating || dnsConfirmation !== null}
|
||||
onChange={(_, checked) => handleDnsToggle(checked)}
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
Reference in New Issue
Block a user