diff --git a/CHANGELOG.md b/CHANGELOG.md index 39f44fc1..a8f44577 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,7 @@ NOTE: Add new changes BELOW THIS COMMENT. - The ability to manage safesearch for each service by using the new `safe_search` field ([#1163]). -### Changed +### Changed - ARPA domain names containing a subnet within private networks now also considered private, behaving closer to [RFC 6761][rfc6761] ([#5567]). @@ -90,6 +90,17 @@ In this release, the schema version has changed from 17 to 20. ### Deprecated +- The `POST /control/safesearch/enable` HTTP API is deprecated. Use the new + `PUT /control/safesearch/settings` API. +- The `POST /control/safesearch/disable` HTTP API is deprecated. Use the new + `PUT /control/safesearch/settings` API +- The `safesearch_enabled` field is deprecated in the following HTTP APIs: + - `GET /control/clients` + - `POST /control/clients/add` + - `POST /control/clients/update` + - `GET /control/clients/find?ip0=...&ip1=...&ip2=...` + + Check `openapi/openapi.yaml` for more details. - The `GET /control/stats_info` HTTP API; use the new `GET /control/stats/config` API instead. diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index 902fc4d3..08f3c08f 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Enabled Parental Control", "disabled_safe_search_toast": "Disabled Safe Search", "enabled_save_search_toast": "Enabled Safe Search", + "updated_save_search_toast": "Safe Search settings updated", "enabled_table_header": "Enabled", "name_table_header": "Name", "list_url_table_header": "List URL", diff --git a/client/src/actions/index.js b/client/src/actions/index.js index 2780c94d..a164f51a 100644 --- a/client/src/actions/index.js +++ b/client/src/actions/index.js @@ -24,6 +24,12 @@ import { getFilteringStatus, setRules } from './filtering'; export const toggleSettingStatus = createAction('SETTING_STATUS_TOGGLE'); export const showSettingsFailure = createAction('SETTINGS_FAILURE_SHOW'); +/** + * + * @param {*} settingKey = SETTINGS_NAMES + * @param {*} status: boolean | SafeSearchConfig + * @returns + */ export const toggleSetting = (settingKey, status) => async (dispatch) => { let successMessage = ''; try { @@ -49,14 +55,9 @@ export const toggleSetting = (settingKey, status) => async (dispatch) => { dispatch(toggleSettingStatus({ settingKey })); break; case SETTINGS_NAMES.safesearch: - if (status) { - successMessage = 'disabled_safe_search_toast'; - await apiClient.disableSafesearch(); - } else { - successMessage = 'enabled_save_search_toast'; - await apiClient.enableSafesearch(); - } - dispatch(toggleSettingStatus({ settingKey })); + successMessage = 'updated_save_search_toast'; + await apiClient.updateSafesearch(status); + dispatch(toggleSettingStatus({ settingKey, value: status })); break; default: break; @@ -71,7 +72,9 @@ export const initSettingsRequest = createAction('SETTINGS_INIT_REQUEST'); export const initSettingsFailure = createAction('SETTINGS_INIT_FAILURE'); export const initSettingsSuccess = createAction('SETTINGS_INIT_SUCCESS'); -export const initSettings = (settingsList) => async (dispatch) => { +export const initSettings = (settingsList = { + safebrowsing: {}, parental: {}, +}) => async (dispatch) => { dispatch(initSettingsRequest()); try { const safebrowsingStatus = await apiClient.getSafebrowsingStatus(); @@ -80,7 +83,6 @@ export const initSettings = (settingsList) => async (dispatch) => { const { safebrowsing, parental, - safesearch, } = settingsList; const newSettingsList = { safebrowsing: { @@ -92,8 +94,7 @@ export const initSettings = (settingsList) => async (dispatch) => { enabled: parentalStatus.enabled, }, safesearch: { - ...safesearch, - enabled: safesearchStatus.enabled, + ...safesearchStatus, }, }; dispatch(initSettingsSuccess({ settingsList: newSettingsList })); diff --git a/client/src/api/Api.js b/client/src/api/Api.js index 60f1faad..caf836b8 100644 --- a/client/src/api/Api.js +++ b/client/src/api/Api.js @@ -208,24 +208,40 @@ class Api { // Safesearch SAFESEARCH_STATUS = { path: 'safesearch/status', method: 'GET' }; - SAFESEARCH_ENABLE = { path: 'safesearch/enable', method: 'POST' }; - - SAFESEARCH_DISABLE = { path: 'safesearch/disable', method: 'POST' }; + SAFESEARCH_UPDATE = { path: 'safesearch/settings', method: 'PUT' }; getSafesearchStatus() { const { path, method } = this.SAFESEARCH_STATUS; return this.makeRequest(path, method); } - enableSafesearch() { - const { path, method } = this.SAFESEARCH_ENABLE; - return this.makeRequest(path, method); + /** + * interface SafeSearchConfig { + "enabled": boolean, + "bing": boolean, + "duckduckgo": boolean, + "google": boolean, + "pixabay": boolean, + "yandex": boolean, + "youtube": boolean + * } + * @param {*} data - SafeSearchConfig + * @returns 200 ok + */ + updateSafesearch(data) { + const { path, method } = this.SAFESEARCH_UPDATE; + return this.makeRequest(path, method, { data }); } - disableSafesearch() { - const { path, method } = this.SAFESEARCH_DISABLE; - return this.makeRequest(path, method); - } + // enableSafesearch() { + // const { path, method } = this.SAFESEARCH_ENABLE; + // return this.makeRequest(path, method); + // } + + // disableSafesearch() { + // const { path, method } = this.SAFESEARCH_DISABLE; + // return this.makeRequest(path, method); + // } // Language diff --git a/client/src/components/Settings/Clients/ClientsTable/ClientsTable.js b/client/src/components/Settings/Clients/ClientsTable/ClientsTable.js index 2d2b893b..41ed4e3b 100644 --- a/client/src/components/Settings/Clients/ClientsTable/ClientsTable.js +++ b/client/src/components/Settings/Clients/ClientsTable/ClientsTable.js @@ -7,6 +7,7 @@ import { useDispatch, useSelector } from 'react-redux'; import ReactTable from 'react-table'; import { getAllBlockedServices } from '../../../../actions/services'; +import { initSettings } from '../../../../actions'; import { splitByNewLine, countClientsStatistics, @@ -38,9 +39,13 @@ const ClientsTable = ({ const [t] = useTranslation(); const dispatch = useDispatch(); const services = useSelector((store) => store?.services); + const globalSettings = useSelector((store) => store?.settings.settingsList) || {}; + + const { safesearch } = globalSettings; useEffect(() => { dispatch(getAllBlockedServices()); + dispatch(initSettings()); }, []); const handleFormAdd = (values) => { @@ -107,6 +112,7 @@ const ClientsTable = ({ tags: [], use_global_settings: true, use_global_blocked_services: true, + safe_search: { ...(safesearch || {}) }, }; }; diff --git a/client/src/components/Settings/Clients/Form.js b/client/src/components/Settings/Clients/Form.js index f6b12d1c..6e5763e6 100644 --- a/client/src/components/Settings/Clients/Form.js +++ b/client/src/components/Settings/Clients/Form.js @@ -11,7 +11,7 @@ import Select from 'react-select'; import i18n from '../../../i18n'; import Tabs from '../../ui/Tabs'; import Examples from '../Dns/Upstream/Examples'; -import { toggleAllServices, trimLinesAndRemoveEmpty } from '../../../helpers/helpers'; +import { toggleAllServices, trimLinesAndRemoveEmpty, captitalizeWords } from '../../../helpers/helpers'; import { renderInputField, renderGroupField, @@ -40,10 +40,6 @@ const settingsCheckboxes = [ name: 'parental_enabled', placeholder: 'use_adguard_parental', }, - { - name: 'safesearch_enabled', - placeholder: 'enforce_safe_search', - }, ]; const validate = (values) => { const errors = {}; @@ -139,8 +135,12 @@ let Form = (props) => { processingUpdating, invalid, tagsOptions, + initialValues, } = props; const services = useSelector((store) => store?.services); + const { safe_search } = initialValues; + const safeSearchServices = { ...safe_search }; + delete safeSearchServices.enabled; const [activeTabLabel, setActiveTabLabel] = useState('settings'); @@ -163,6 +163,28 @@ let Form = (props) => { /> ))} +
+ +
+
+ {Object.keys(safeSearchServices).map((searchKey) => ( +
+ +
+ ))} +
, }, block_services: { @@ -358,6 +380,7 @@ Form.propTypes = { processingUpdating: PropTypes.bool.isRequired, invalid: PropTypes.bool.isRequired, tagsOptions: PropTypes.array.isRequired, + initialValues: PropTypes.object, }; const selector = formValueSelector(FORM_NAME.CLIENT); diff --git a/client/src/components/Settings/index.js b/client/src/components/Settings/index.js index f4e191c3..43aff62e 100644 --- a/client/src/components/Settings/index.js +++ b/client/src/components/Settings/index.js @@ -10,7 +10,7 @@ import Checkbox from '../ui/Checkbox'; import Loading from '../ui/Loading'; import PageTitle from '../ui/PageTitle'; import Card from '../ui/Card'; -import { getObjectKeysSorted } from '../../helpers/helpers'; +import { getObjectKeysSorted, captitalizeWords } from '../../helpers/helpers'; import './Settings.css'; const ORDER_KEY = 'order'; @@ -28,12 +28,6 @@ const SETTINGS = { subtitle: 'use_adguard_parental_hint', [ORDER_KEY]: 1, }, - safesearch: { - enabled: false, - title: 'enforce_safe_search', - subtitle: 'enforce_save_search_hint', - [ORDER_KEY]: 2, - }, }; class Settings extends Component { @@ -44,7 +38,7 @@ class Settings extends Component { this.props.getFilteringStatus(); } - renderSettings = (settings) => getObjectKeysSorted(settings, ORDER_KEY) + renderSettings = (settings) => getObjectKeysSorted(SETTINGS, ORDER_KEY) .map((key) => { const setting = settings[key]; const { enabled } = setting; @@ -55,6 +49,35 @@ class Settings extends Component { />; }); + renderSafeSearch = () => { + const { settings: { settingsList: { safesearch } } } = this.props; + const { enabled } = safesearch || {}; + const searches = { ...(safesearch || {}) }; + delete searches.enabled; + return ( + <> + this.props.toggleSetting('safesearch', { ...safesearch, enabled })} + /> +
+ {Object.keys(searches).map((searchKey) => ( + this.props.toggleSetting('safesearch', { ...safesearch, [searchKey]: checked })} + /> + ))} +
+ + ); + }; + render() { const { settings, @@ -92,6 +115,7 @@ class Settings extends Component { setFiltersConfig={setFiltersConfig} /> {this.renderSettings(settings.settingsList)} + {this.renderSafeSearch()} diff --git a/client/src/components/ui/Checkbox.js b/client/src/components/ui/Checkbox.js index ce5b990a..2079cdb9 100644 --- a/client/src/components/ui/Checkbox.js +++ b/client/src/components/ui/Checkbox.js @@ -11,13 +11,14 @@ class Checkbox extends Component { subtitle, enabled, handleChange, + disabled, t, } = this.props; return (