diff --git a/CHANGELOG.md b/CHANGELOG.md index c0fae395..95bfb899 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,10 @@ See also the [v0.107.20 GitHub milestone][ms-v0.107.20]. [ms-v0.107.20]: https://github.com/AdguardTeam/AdGuardHome/milestone/56?closed=1 --> +### Added + +- The ability to clear the DNS cache ([#5190]). + ### Changed - DHCP server initialization errors are now logged at debug level if the server @@ -39,6 +43,7 @@ See also the [v0.107.20 GitHub milestone][ms-v0.107.20]. [#4944]: https://github.com/AdguardTeam/AdGuardHome/issues/4944 [#5189]: https://github.com/AdguardTeam/AdGuardHome/issues/5189 +[#5190]: https://github.com/AdguardTeam/AdGuardHome/issues/5190 diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index 7ec9c779..0d1bb275 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -638,5 +638,8 @@ "safe_browsing": "Safe Browsing", "served_from_cache": "{{value}} (served from cache)", "form_error_password_length": "Password must be at least {{value}} characters long", - "anonymizer_notification": "<0>Note:0> IP anonymization is enabled. You can disable it in <1>General settings1>." + "anonymizer_notification": "<0>Note:0> IP anonymization is enabled. You can disable it in <1>General settings1>.", + "confirm_dns_cache_clear": "Are you sure you want to clear DNS cache?", + "cache_cleared": "DNS cache successfully cleared", + "clear_cache": "Clear cache" } diff --git a/client/src/actions/dnsConfig.js b/client/src/actions/dnsConfig.js index a0b93428..f8141fd5 100644 --- a/client/src/actions/dnsConfig.js +++ b/client/src/actions/dnsConfig.js @@ -1,4 +1,5 @@ import { createAction } from 'redux-actions'; +import i18next from 'i18next'; import apiClient from '../api/Api'; import { splitByNewLine } from '../helpers/helpers'; @@ -19,6 +20,22 @@ export const getDnsConfig = () => async (dispatch) => { } }; +export const clearDnsCacheRequest = createAction('CLEAR_DNS_CACHE_REQUEST'); +export const clearDnsCacheFailure = createAction('CLEAR_DNS_CACHE_FAILURE'); +export const clearDnsCacheSuccess = createAction('CLEAR_DNS_CACHE_SUCCESS'); + +export const clearDnsCache = () => async (dispatch) => { + dispatch(clearDnsCacheRequest()); + try { + const data = await apiClient.clearCache(); + dispatch(clearDnsCacheSuccess(data)); + dispatch(addSuccessToast(i18next.t('cache_cleared'))); + } catch (error) { + dispatch(addErrorToast({ error })); + dispatch(clearDnsCacheFailure()); + } +}; + export const setDnsConfigRequest = createAction('SET_DNS_CONFIG_REQUEST'); export const setDnsConfigFailure = createAction('SET_DNS_CONFIG_FAILURE'); export const setDnsConfigSuccess = createAction('SET_DNS_CONFIG_SUCCESS'); diff --git a/client/src/api/Api.js b/client/src/api/Api.js index bc030fa1..06f40c6c 100644 --- a/client/src/api/Api.js +++ b/client/src/api/Api.js @@ -593,6 +593,14 @@ class Api { }; return this.makeRequest(path, method, config); } + + // Cache + CLEAR_CACHE = { path: 'cache_clear', method: 'POST' }; + + clearCache() { + const { path, method } = this.CLEAR_CACHE; + return this.makeRequest(path, method); + } } const apiClient = new Api(); diff --git a/client/src/components/Settings/Dns/Cache/Form.js b/client/src/components/Settings/Dns/Cache/Form.js index 5b0fe6a2..0f51e117 100644 --- a/client/src/components/Settings/Dns/Cache/Form.js +++ b/client/src/components/Settings/Dns/Cache/Form.js @@ -2,10 +2,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Field, reduxForm } from 'redux-form'; import { Trans, useTranslation } from 'react-i18next'; -import { shallowEqual, useSelector } from 'react-redux'; +import { shallowEqual, useDispatch, useSelector } from 'react-redux'; + import { renderInputField, toNumber, CheckboxField } from '../../../../helpers/form'; import { CACHE_CONFIG_FIELDS, FORM_NAME, UINT32_RANGE } from '../../../../helpers/constants'; import { replaceZeroWithEmptyString } from '../../../../helpers/helpers'; +import { clearDnsCache } from '../../../../actions/dnsConfig'; const INPUTS_FIELDS = [ { @@ -32,6 +34,7 @@ const Form = ({ handleSubmit, submitting, invalid, }) => { const { t } = useTranslation(); + const dispatch = useDispatch(); const { processingSetConfig } = useSelector((state) => state.dnsConfig, shallowEqual); const { @@ -40,6 +43,12 @@ const Form = ({ const minExceedsMax = cache_ttl_min > cache_ttl_max; + const handleClearCache = () => { + if (window.confirm(t('confirm_dns_cache_clear'))) { + dispatch(clearDnsCache()); + } + }; + return