Revert "feat(dns): protect provider DNS from unconfirmed overrides (#7902)"

This reverts commit 35a2b6c75c.

Closes #7994
Closes #7993
This commit is contained in:
Tunglies
2026-09-21 15:08:33 +08:00
parent c6a4de1c6a
commit df79ed3efb
37 changed files with 37 additions and 570 deletions
+2 -4
View File
@@ -33,7 +33,6 @@ 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'
@@ -184,8 +183,7 @@ const DEFAULT_DNS_CONFIG = {
export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
const { t } = useTranslation()
const { mutateClash } = useClash()
const { verge } = useVerge()
const { clash, mutateClash } = useClash()
const themeMode = useThemeMode()
const [open, setOpen] = useState(false)
@@ -550,7 +548,7 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
return
}
if (verge?.enable_dns_settings) {
if (clash?.dns?.enable) {
await invoke('apply_dns_config', { apply: true })
mutateClash()
}
+24 -47
View File
@@ -1,16 +1,17 @@
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 { BaseDialog, DialogRef, Switch, TooltipIcon } from '@/components/base'
import { 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, setDnsOverride } from '@/services/cmds'
import { invoke_uwp_tool } from '@/services/cmds'
import { showNotice } from '@/services/notice-service'
import getSystem from '@/utils/get-system'
@@ -35,7 +36,7 @@ const SettingClash = ({ onError }: Props) => {
const { t } = useTranslation()
const { clash, version, mutateClash, patchClash } = useClash()
const { verge, mutateVerge } = useVerge()
const { verge, patchVerge } = useVerge()
const displayedMixedPort = useDisplayedMixedPort()
const [, setClashLog] = useClashLog()
@@ -46,8 +47,10 @@ const SettingClash = ({ onError }: Props) => {
'unified-delay': unifiedDelay,
} = clash ?? {}
const [dnsConfirmation, setDnsConfirmation] = useState<string | null>(null)
const [dnsUpdating, setDnsUpdating] = useState(false)
// 独立跟踪DNS设置开关状态
const [dnsSettingsEnabled, setDnsSettingsEnabled] = useState(() => {
return verge?.enable_dns_settings ?? false
})
const webRef = useRef<DialogRef>(null)
const portRef = useRef<DialogRef>(null)
@@ -71,29 +74,22 @@ const SettingClash = ({ onError }: Props) => {
}
}
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()
// 实现DNS设置开关处理函数
const handleDnsToggle = useLockFn(async (enable: boolean) => {
try {
setDnsSettingsEnabled(enable)
await patchVerge({ enable_dns_settings: enable })
await invoke('apply_dns_config', { apply: enable })
setTimeout(() => {
mutateClash()
} catch (err: any) {
showNotice.error(err)
} finally {
setDnsUpdating(false)
}
},
)
const closeDnsConfirmation = () => {
if (!dnsUpdating) setDnsConfirmation(null)
}
}, 500)
} catch (err: any) {
setDnsSettingsEnabled(!enable)
showNotice.error(err)
await patchVerge({ enable_dns_settings: !enable }).catch(() => {})
throw err
}
})
return (
<SettingList title={t('settings.sections.clash.title')}>
@@ -103,24 +99,6 @@ 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
@@ -159,8 +137,7 @@ const SettingClash = ({ onError }: Props) => {
>
<Switch
edge="end"
checked={verge?.enable_dns_settings ?? false}
disabled={dnsUpdating || dnsConfirmation !== null}
checked={dnsSettingsEnabled}
onChange={(_, checked) => handleDnsToggle(checked)}
/>
</SettingItem>
-7
View File
@@ -510,13 +510,6 @@
"title": "DNS Overwrite",
"warning": "If you are not familiar with these settings, please do not modify them and keep DNS Overwrite disabled"
},
"protection": {
"title": "Enable DNS Overwrite?",
"message": "This subscription contains custom DNS settings. DNS Overwrite may replace them, preventing nodes from connecting or some websites from loading. Enable it anyway?",
"enableAnyway": "Enable anyway",
"keepDisabled": "Keep disabled",
"autoDisabled": "DNS Overwrite was disabled to preserve the custom DNS settings in the current subscription."
},
"sections": {
"general": "DNS Settings",
"fallbackFilter": "Fallback Filter Settings",
-7
View File
@@ -510,13 +510,6 @@
"title": "DNS-Überschreibung",
"warning": "Wenn Sie sich nicht mit diesen Einstellungen auskennen, ändern Sie sie nicht und lassen Sie die DNS-Überschreibung deaktiviert."
},
"protection": {
"title": "Enable DNS Overwrite?",
"message": "This subscription contains custom DNS settings. DNS Overwrite may replace them, preventing nodes from connecting or some websites from loading. Enable it anyway?",
"enableAnyway": "Enable anyway",
"keepDisabled": "Keep disabled",
"autoDisabled": "DNS Overwrite was disabled to preserve the custom DNS settings in the current subscription."
},
"sections": {
"general": "DNS-Einstellungen",
"fallbackFilter": "Rückfallfilter-Einstellungen",
-7
View File
@@ -510,13 +510,6 @@
"title": "DNS Overwrite",
"warning": "If you are not familiar with these settings, please do not modify them and keep DNS Overwrite disabled"
},
"protection": {
"title": "Enable DNS Overwrite?",
"message": "This subscription contains custom DNS settings. DNS Overwrite may replace them, preventing nodes from connecting or some websites from loading. Enable it anyway?",
"enableAnyway": "Enable anyway",
"keepDisabled": "Keep disabled",
"autoDisabled": "DNS Overwrite was disabled to preserve the custom DNS settings in the current subscription."
},
"sections": {
"general": "DNS Settings",
"fallbackFilter": "Fallback Filter Settings",
-7
View File
@@ -510,13 +510,6 @@
"title": "Sobrescritura de DNS",
"warning": "Si no está seguro de cómo configurar esto, no realice cambios y mantenga deshabilitada la sobrescritura de DNS."
},
"protection": {
"title": "Enable DNS Overwrite?",
"message": "This subscription contains custom DNS settings. DNS Overwrite may replace them, preventing nodes from connecting or some websites from loading. Enable it anyway?",
"enableAnyway": "Enable anyway",
"keepDisabled": "Keep disabled",
"autoDisabled": "DNS Overwrite was disabled to preserve the custom DNS settings in the current subscription."
},
"sections": {
"general": "Configuración de DNS",
"fallbackFilter": "Configuración de filtrado de respaldo",
-7
View File
@@ -510,13 +510,6 @@
"title": "بازنویسی DNS",
"warning": "اگر با این تنظیمات آشنا نیستید، لطفاً آنها را تغییر ندهید و DNS Overwrite را غیرفعال نگه دارید."
},
"protection": {
"title": "Enable DNS Overwrite?",
"message": "This subscription contains custom DNS settings. DNS Overwrite may replace them, preventing nodes from connecting or some websites from loading. Enable it anyway?",
"enableAnyway": "Enable anyway",
"keepDisabled": "Keep disabled",
"autoDisabled": "DNS Overwrite was disabled to preserve the custom DNS settings in the current subscription."
},
"sections": {
"general": "تنظیمات DNS",
"fallbackFilter": "Fallback Filter Settings",
-7
View File
@@ -510,13 +510,6 @@
"title": "DNS Overwrite",
"warning": "If you are not familiar with these settings, please do not modify them and keep DNS Overwrite disabled"
},
"protection": {
"title": "Enable DNS Overwrite?",
"message": "This subscription contains custom DNS settings. DNS Overwrite may replace them, preventing nodes from connecting or some websites from loading. Enable it anyway?",
"enableAnyway": "Enable anyway",
"keepDisabled": "Keep disabled",
"autoDisabled": "DNS Overwrite was disabled to preserve the custom DNS settings in the current subscription."
},
"sections": {
"general": "DNS Settings",
"fallbackFilter": "Fallback Filter Settings",
-7
View File
@@ -510,13 +510,6 @@
"title": "DNS上書き",
"warning": "ここの設定がわからない場合は、変更しないでください。DNS上書きを無効にしたままにしてください。"
},
"protection": {
"title": "Enable DNS Overwrite?",
"message": "This subscription contains custom DNS settings. DNS Overwrite may replace them, preventing nodes from connecting or some websites from loading. Enable it anyway?",
"enableAnyway": "Enable anyway",
"keepDisabled": "Keep disabled",
"autoDisabled": "DNS Overwrite was disabled to preserve the custom DNS settings in the current subscription."
},
"sections": {
"general": "DNS設定",
"fallbackFilter": "フォールバックフィルター設定",
-7
View File
@@ -510,13 +510,6 @@
"title": "DNS 덮어쓰기",
"warning": "이 설정에 익숙하지 않다면 수정하지 말고 DNS 덮어쓰기를 비활성화 상태로 유지하세요"
},
"protection": {
"title": "Enable DNS Overwrite?",
"message": "This subscription contains custom DNS settings. DNS Overwrite may replace them, preventing nodes from connecting or some websites from loading. Enable it anyway?",
"enableAnyway": "Enable anyway",
"keepDisabled": "Keep disabled",
"autoDisabled": "DNS Overwrite was disabled to preserve the custom DNS settings in the current subscription."
},
"sections": {
"general": "DNS 설정",
"fallbackFilter": "폴백 필터 설정",
-7
View File
@@ -510,13 +510,6 @@
"title": "Переопределение настроек DNS",
"warning": "Если вы не знакомы с этими настройками, пожалуйста, не изменяйте их и оставьте переопределение DNS отключённым"
},
"protection": {
"title": "Enable DNS Overwrite?",
"message": "This subscription contains custom DNS settings. DNS Overwrite may replace them, preventing nodes from connecting or some websites from loading. Enable it anyway?",
"enableAnyway": "Enable anyway",
"keepDisabled": "Keep disabled",
"autoDisabled": "DNS Overwrite was disabled to preserve the custom DNS settings in the current subscription."
},
"sections": {
"general": "Настройки DNS",
"fallbackFilter": "Настройки фильтра fallback",
-7
View File
@@ -510,13 +510,6 @@
"title": "DNS Üzerine Yazma",
"warning": "Bu ayarlarla ilgili bilginiz yoksa, lütfen bunları değiştirmeyin ve DNS Üzerine Yazma'yı devre dışı tutun"
},
"protection": {
"title": "DNS Üzerine Yazma etkinleştirilsin mi?",
"message": "Bu abonelik özel DNS ayarları içeriyor. DNS Üzerine Yazma bunların yerine geçebilir; bu da düğümlerin bağlanmasını veya bazı web sitelerinin yüklenmesini engelleyebilir. Yine de etkinleştirilsin mi?",
"enableAnyway": "Yine de etkinleştir",
"keepDisabled": "Devre dışı bırak",
"autoDisabled": "Geçerli abonelikteki özel DNS ayarlarını korumak için DNS Üzerine Yazma devre dışı bırakıldı."
},
"sections": {
"general": "DNS Ayarları",
"fallbackFilter": "Yedek Filtre Ayarları",
-7
View File
@@ -510,13 +510,6 @@
"title": "DNS Overwrite",
"warning": "If you are not familiar with these settings, please do not modify them and keep DNS Overwrite disabled"
},
"protection": {
"title": "Enable DNS Overwrite?",
"message": "This subscription contains custom DNS settings. DNS Overwrite may replace them, preventing nodes from connecting or some websites from loading. Enable it anyway?",
"enableAnyway": "Enable anyway",
"keepDisabled": "Keep disabled",
"autoDisabled": "DNS Overwrite was disabled to preserve the custom DNS settings in the current subscription."
},
"sections": {
"general": "DNS Settings",
"fallbackFilter": "Fallback Filter Settings",
-7
View File
@@ -510,13 +510,6 @@
"title": "DNS 覆写",
"warning": "如果你不清楚这里的设置请不要修改,并保持 DNS 覆写关闭"
},
"protection": {
"title": "是否开启 DNS 覆写?",
"message": "当前订阅包含自定义 DNS 配置。开启 DNS 覆写可能覆盖这些配置,导致节点无法连接或部分网站无法访问。是否仍要开启?",
"enableAnyway": "仍然开启",
"keepDisabled": "保持关闭",
"autoDisabled": "检测到当前订阅包含自定义 DNS 配置,已自动关闭 DNS 覆写。"
},
"sections": {
"general": "DNS 设置",
"fallbackFilter": "回退过滤设置",
-7
View File
@@ -510,13 +510,6 @@
"title": "DNS 覆寫",
"warning": "如果你不清楚這裡的設定請不要修改,並保持 DNS 覆寫關閉"
},
"protection": {
"title": "是否開啟 DNS 覆寫?",
"message": "目前訂閱包含自訂 DNS 設定。開啟 DNS 覆寫可能覆蓋這些設定,導致節點無法連線或部分網站無法存取。是否仍要開啟?",
"enableAnyway": "仍然開啟",
"keepDisabled": "保持關閉",
"autoDisabled": "偵測到目前訂閱包含自訂 DNS 設定,已自動關閉 DNS 覆寫。"
},
"sections": {
"general": "DNS 設定",
"fallbackFilter": "備援篩選設定",
@@ -1,55 +0,0 @@
import { beforeEach, expect, it, vi } from 'vitest'
import { takeDnsOverrideNotice } from '@/services/cmds'
import { subscribeVergeEvents } from '@/services/events'
import { showNotice } from '@/services/notice-service'
import { revalidateQueries } from '@/services/query-client'
import { handleNoticeMessage } from '../utils/notification-handlers'
import { useLayoutEvents } from './use-layout-events'
vi.mock('react', () => ({ useEffect: (effect: () => void) => effect() }))
vi.mock('@/hooks/use-profiles', () => ({ revalidateProfiles: vi.fn() }))
vi.mock('@/hooks/use-system-state', () => ({ runStateQueryKey: ['state'] }))
vi.mock('@/services/events', () => ({ subscribeVergeEvents: vi.fn() }))
vi.mock('@/services/cmds', () => ({
takeDnsOverrideNotice: vi.fn(),
takeServiceFallbackNotice: vi.fn().mockResolvedValue(false),
}))
vi.mock('@/services/notice-service', () => ({
showNotice: { info: vi.fn() },
}))
vi.mock('@/services/query-client', () => ({
revalidateQueries: vi.fn(),
setCacheData: vi.fn(),
}))
beforeEach(() => {
vi.clearAllMocks()
})
it('drains a DNS notice after listeners mount without duplicating its live event', async () => {
vi.mocked(takeDnsOverrideNotice)
.mockResolvedValueOnce(true)
.mockResolvedValue(false)
useLayoutEvents(([status, message]) => {
handleNoticeMessage(status, message, (key) => key, vi.fn())
})
expect(takeDnsOverrideNotice).not.toHaveBeenCalled()
const [handlers, onSubscribed] = vi.mocked(subscribeVergeEvents).mock.calls[0]
onSubscribed?.()
expect(takeDnsOverrideNotice).toHaveBeenCalledOnce()
handlers['verge://notice-message']?.(['dns_override::auto_disabled', ''])
await new Promise((resolve) => setTimeout(resolve, 0))
expect(showNotice.info).toHaveBeenCalledExactlyOnceWith(
'settings.modals.dns.protection.autoDisabled',
)
expect(revalidateQueries).toHaveBeenCalledWith([
['getRuntimeState'],
['getVergeConfig'],
])
})
+1 -2
View File
@@ -62,8 +62,7 @@ export const useLayoutEvents = (
},
// Re-read event-only state after subscribing to close the initial race window.
() => {
revalidateKeys(['getRuntimeState', 'getVergeConfig'])
handleNotice(['dns_override::auto_disabled', ''])
revalidateKeys(['getRuntimeState'])
handleNotice(['service_core::sidecar_fallback', ''])
},
)
@@ -1,7 +1,4 @@
import {
takeDnsOverrideNotice,
takeServiceFallbackNotice,
} from '@/services/cmds'
import { takeServiceFallbackNotice } from '@/services/cmds'
import { showNotice } from '@/services/notice-service'
type NavigateFunction = (path: string, options?: any) => void
@@ -44,17 +41,6 @@ export const handleNoticeMessage = (
)
})
},
'dns_override::auto_disabled': () => {
void takeDnsOverrideNotice()
.then((pending) => {
if (pending) {
showNotice.info('settings.modals.dns.protection.autoDisabled')
}
})
.catch((error) => {
console.error('Failed to read the pending DNS override notice', error)
})
},
'tun_mode::auto_disabled': () =>
showNotice.info(
'settings.sections.system.notifications.tunMode.autoDisabled',
-10
View File
@@ -172,16 +172,6 @@ export async function patchVergeConfig(payload: IVergeConfig) {
return invoke<void>('patch_verge_config', { payload })
}
export async function setDnsOverride(enabled: boolean, confirmation?: string) {
return invoke<
{ status: 'applied' } | { status: 'confirmation_required'; source: string }
>('set_dns_override', { enabled, confirmation })
}
export async function takeDnsOverrideNotice() {
return invoke<boolean>('take_dns_override_notice')
}
export async function takeServiceFallbackNotice() {
return invoke<boolean>('take_service_fallback_notice')
}
-5
View File
@@ -698,11 +698,6 @@ export const translationKeys = [
'settings.modals.tun.messages.routeExcludeAddressHint',
'settings.modals.dns.dialog.title',
'settings.modals.dns.dialog.warning',
'settings.modals.dns.protection.title',
'settings.modals.dns.protection.message',
'settings.modals.dns.protection.enableAnyway',
'settings.modals.dns.protection.keepDisabled',
'settings.modals.dns.protection.autoDisabled',
'settings.modals.dns.sections.general',
'settings.modals.dns.sections.fallbackFilter',
'settings.modals.dns.sections.hosts',
-7
View File
@@ -1041,13 +1041,6 @@ export interface TranslationResources {
configError: string
saved: string
}
protection: {
autoDisabled: string
enableAnyway: string
keepDisabled: string
message: string
title: string
}
sections: {
fallbackFilter: string
general: string