2018-08-30 14:25:33 +00:00
|
|
|
import { createAction } from 'redux-actions';
|
2020-05-22 14:06:05 +00:00
|
|
|
import i18next from 'i18next';
|
2019-05-17 13:57:38 +00:00
|
|
|
import axios from 'axios';
|
2018-08-30 14:25:33 +00:00
|
|
|
|
2020-09-01 13:30:30 +00:00
|
|
|
import endsWith from 'lodash/endsWith';
|
|
|
|
import escapeRegExp from 'lodash/escapeRegExp';
|
2020-09-08 10:18:19 +00:00
|
|
|
import React from 'react';
|
2020-09-22 12:04:17 +00:00
|
|
|
import { compose } from 'redux';
|
|
|
|
import { splitByNewLine, sortClients, filterOutComments } from '../helpers/helpers';
|
2020-08-20 10:50:40 +00:00
|
|
|
import {
|
2020-09-22 12:04:17 +00:00
|
|
|
BLOCK_ACTIONS,
|
|
|
|
CHECK_TIMEOUT,
|
|
|
|
STATUS_RESPONSE,
|
|
|
|
SETTINGS_NAMES,
|
|
|
|
FORM_NAME,
|
|
|
|
GETTING_STARTED_LINK,
|
2020-08-20 10:50:40 +00:00
|
|
|
} from '../helpers/constants';
|
2020-07-23 09:27:14 +00:00
|
|
|
import { areEqualVersions } from '../helpers/version';
|
2019-07-01 12:04:07 +00:00
|
|
|
import { getTlsStatus } from './encryption';
|
2019-09-05 09:12:58 +00:00
|
|
|
import apiClient from '../api/Api';
|
2020-05-22 14:06:05 +00:00
|
|
|
import { addErrorToast, addNoticeToast, addSuccessToast } from './toasts';
|
2020-09-01 13:30:30 +00:00
|
|
|
import { getFilteringStatus, setRules } from './filtering';
|
2018-09-14 12:37:35 +00:00
|
|
|
|
2018-08-30 14:25:33 +00:00
|
|
|
export const toggleSettingStatus = createAction('SETTING_STATUS_TOGGLE');
|
|
|
|
export const showSettingsFailure = createAction('SETTINGS_FAILURE_SHOW');
|
|
|
|
|
|
|
|
export const toggleSetting = (settingKey, status) => async (dispatch) => {
|
2018-09-14 13:41:34 +00:00
|
|
|
let successMessage = '';
|
|
|
|
try {
|
|
|
|
switch (settingKey) {
|
2019-01-22 14:17:33 +00:00
|
|
|
case SETTINGS_NAMES.safebrowsing:
|
2018-09-14 13:41:34 +00:00
|
|
|
if (status) {
|
2018-11-09 06:51:28 +00:00
|
|
|
successMessage = 'disabled_safe_browsing_toast';
|
2018-09-14 13:41:34 +00:00
|
|
|
await apiClient.disableSafebrowsing();
|
|
|
|
} else {
|
2018-11-09 06:51:28 +00:00
|
|
|
successMessage = 'enabled_safe_browsing_toast';
|
2018-09-14 13:41:34 +00:00
|
|
|
await apiClient.enableSafebrowsing();
|
|
|
|
}
|
|
|
|
dispatch(toggleSettingStatus({ settingKey }));
|
|
|
|
break;
|
2019-01-22 14:17:33 +00:00
|
|
|
case SETTINGS_NAMES.parental:
|
2018-09-14 13:41:34 +00:00
|
|
|
if (status) {
|
2018-11-09 06:51:28 +00:00
|
|
|
successMessage = 'disabled_parental_toast';
|
2018-09-14 13:41:34 +00:00
|
|
|
await apiClient.disableParentalControl();
|
|
|
|
} else {
|
2018-11-09 06:51:28 +00:00
|
|
|
successMessage = 'enabled_parental_toast';
|
2018-09-14 13:41:34 +00:00
|
|
|
await apiClient.enableParentalControl();
|
|
|
|
}
|
|
|
|
dispatch(toggleSettingStatus({ settingKey }));
|
|
|
|
break;
|
2019-01-22 14:17:33 +00:00
|
|
|
case SETTINGS_NAMES.safesearch:
|
2018-09-14 13:41:34 +00:00
|
|
|
if (status) {
|
2018-11-09 06:51:28 +00:00
|
|
|
successMessage = 'disabled_safe_search_toast';
|
2018-09-14 13:41:34 +00:00
|
|
|
await apiClient.disableSafesearch();
|
|
|
|
} else {
|
2018-11-09 06:51:28 +00:00
|
|
|
successMessage = 'enabled_save_search_toast';
|
2018-09-14 13:41:34 +00:00
|
|
|
await apiClient.enableSafesearch();
|
|
|
|
}
|
|
|
|
dispatch(toggleSettingStatus({ settingKey }));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
dispatch(addSuccessToast(successMessage));
|
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
2018-08-30 14:25:33 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export const initSettingsRequest = createAction('SETTINGS_INIT_REQUEST');
|
|
|
|
export const initSettingsFailure = createAction('SETTINGS_INIT_FAILURE');
|
|
|
|
export const initSettingsSuccess = createAction('SETTINGS_INIT_SUCCESS');
|
|
|
|
|
2020-05-22 14:06:05 +00:00
|
|
|
export const initSettings = (settingsList) => async (dispatch) => {
|
2018-08-30 14:25:33 +00:00
|
|
|
dispatch(initSettingsRequest());
|
|
|
|
try {
|
|
|
|
const safebrowsingStatus = await apiClient.getSafebrowsingStatus();
|
|
|
|
const parentalStatus = await apiClient.getParentalStatus();
|
|
|
|
const safesearchStatus = await apiClient.getSafesearchStatus();
|
|
|
|
const {
|
|
|
|
safebrowsing,
|
|
|
|
parental,
|
|
|
|
safesearch,
|
|
|
|
} = settingsList;
|
|
|
|
const newSettingsList = {
|
2020-07-03 08:14:54 +00:00
|
|
|
safebrowsing: {
|
|
|
|
...safebrowsing,
|
|
|
|
enabled: safebrowsingStatus.enabled,
|
|
|
|
},
|
|
|
|
parental: {
|
|
|
|
...parental,
|
|
|
|
enabled: parentalStatus.enabled,
|
|
|
|
},
|
|
|
|
safesearch: {
|
|
|
|
...safesearch,
|
|
|
|
enabled: safesearchStatus.enabled,
|
|
|
|
},
|
2018-08-30 14:25:33 +00:00
|
|
|
};
|
|
|
|
dispatch(initSettingsSuccess({ settingsList: newSettingsList }));
|
|
|
|
} catch (error) {
|
2018-09-14 12:37:35 +00:00
|
|
|
dispatch(addErrorToast({ error }));
|
2018-08-30 14:25:33 +00:00
|
|
|
dispatch(initSettingsFailure());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-10-11 07:57:36 +00:00
|
|
|
export const toggleProtectionRequest = createAction('TOGGLE_PROTECTION_REQUEST');
|
|
|
|
export const toggleProtectionFailure = createAction('TOGGLE_PROTECTION_FAILURE');
|
|
|
|
export const toggleProtectionSuccess = createAction('TOGGLE_PROTECTION_SUCCESS');
|
2018-09-26 14:12:31 +00:00
|
|
|
|
2020-05-22 14:06:05 +00:00
|
|
|
export const toggleProtection = (status) => async (dispatch) => {
|
2018-10-11 07:57:36 +00:00
|
|
|
dispatch(toggleProtectionRequest());
|
2018-09-26 14:12:31 +00:00
|
|
|
try {
|
2019-12-04 18:52:38 +00:00
|
|
|
const successMessage = status ? 'disabled_protection' : 'enabled_protection';
|
|
|
|
await apiClient.setDnsConfig({ protection_enabled: !status });
|
2018-09-26 14:12:31 +00:00
|
|
|
dispatch(addSuccessToast(successMessage));
|
2018-10-11 07:57:36 +00:00
|
|
|
dispatch(toggleProtectionSuccess());
|
2018-09-26 14:12:31 +00:00
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
2018-10-11 07:57:36 +00:00
|
|
|
dispatch(toggleProtectionFailure());
|
2018-09-26 14:12:31 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-03-28 08:45:31 +00:00
|
|
|
export const getVersionRequest = createAction('GET_VERSION_REQUEST');
|
|
|
|
export const getVersionFailure = createAction('GET_VERSION_FAILURE');
|
|
|
|
export const getVersionSuccess = createAction('GET_VERSION_SUCCESS');
|
|
|
|
|
2019-07-05 15:21:46 +00:00
|
|
|
export const getVersion = (recheck = false) => async (dispatch, getState) => {
|
2019-03-28 08:45:31 +00:00
|
|
|
dispatch(getVersionRequest());
|
|
|
|
try {
|
2019-07-05 15:21:46 +00:00
|
|
|
const data = await apiClient.getGlobalVersion({ recheck_now: recheck });
|
|
|
|
dispatch(getVersionSuccess(data));
|
|
|
|
|
2019-06-25 14:56:50 +00:00
|
|
|
if (recheck) {
|
2019-07-05 15:21:46 +00:00
|
|
|
const { dnsVersion } = getState().dashboard;
|
|
|
|
const currentVersion = dnsVersion === 'undefined' ? 0 : dnsVersion;
|
|
|
|
|
2020-07-23 09:27:14 +00:00
|
|
|
if (data && !areEqualVersions(currentVersion, data.new_version)) {
|
2019-07-05 15:21:46 +00:00
|
|
|
dispatch(addSuccessToast('updates_checked'));
|
|
|
|
} else {
|
|
|
|
dispatch(addSuccessToast('updates_version_equal'));
|
|
|
|
}
|
2019-06-25 14:56:50 +00:00
|
|
|
}
|
2019-03-28 08:45:31 +00:00
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
|
|
|
dispatch(getVersionFailure());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-05-16 14:24:30 +00:00
|
|
|
export const getUpdateRequest = createAction('GET_UPDATE_REQUEST');
|
|
|
|
export const getUpdateFailure = createAction('GET_UPDATE_FAILURE');
|
|
|
|
export const getUpdateSuccess = createAction('GET_UPDATE_SUCCESS');
|
|
|
|
|
2019-12-06 15:00:01 +00:00
|
|
|
const checkStatus = async (handleRequestSuccess, handleRequestError, attempts = 60) => {
|
|
|
|
let timeout;
|
2019-06-05 13:11:26 +00:00
|
|
|
|
2019-12-06 15:00:01 +00:00
|
|
|
if (attempts === 0) {
|
|
|
|
handleRequestError();
|
|
|
|
}
|
2019-05-16 14:24:30 +00:00
|
|
|
|
2020-05-22 14:06:05 +00:00
|
|
|
const rmTimeout = (t) => t && clearTimeout(t);
|
2019-05-17 13:57:38 +00:00
|
|
|
|
2019-12-06 15:00:01 +00:00
|
|
|
try {
|
2020-08-13 08:15:45 +00:00
|
|
|
const response = await axios.get(`${apiClient.baseUrl}/status`);
|
2019-12-06 15:00:01 +00:00
|
|
|
rmTimeout(timeout);
|
2020-07-03 16:17:58 +00:00
|
|
|
if (response?.status === 200) {
|
2019-12-06 15:00:01 +00:00
|
|
|
handleRequestSuccess(response);
|
|
|
|
if (response.data.running === false) {
|
|
|
|
timeout = setTimeout(
|
|
|
|
checkStatus,
|
|
|
|
CHECK_TIMEOUT,
|
|
|
|
handleRequestSuccess,
|
|
|
|
handleRequestError,
|
|
|
|
attempts - 1,
|
|
|
|
);
|
2019-05-16 14:24:30 +00:00
|
|
|
}
|
2019-12-06 15:00:01 +00:00
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
rmTimeout(timeout);
|
|
|
|
timeout = setTimeout(
|
|
|
|
checkStatus,
|
|
|
|
CHECK_TIMEOUT,
|
|
|
|
handleRequestSuccess,
|
|
|
|
handleRequestError,
|
|
|
|
attempts - 1,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
};
|
2019-05-17 13:57:38 +00:00
|
|
|
|
2019-12-06 15:00:01 +00:00
|
|
|
export const getUpdate = () => async (dispatch, getState) => {
|
|
|
|
const { dnsVersion } = getState().dashboard;
|
2019-05-17 13:57:38 +00:00
|
|
|
|
2019-12-06 15:00:01 +00:00
|
|
|
dispatch(getUpdateRequest());
|
|
|
|
const handleRequestError = () => {
|
2020-09-08 10:18:19 +00:00
|
|
|
const options = {
|
|
|
|
components: {
|
|
|
|
a: <a href={GETTING_STARTED_LINK} target="_blank"
|
|
|
|
rel="noopener noreferrer" />,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
dispatch(addNoticeToast({ error: 'update_failed', options }));
|
2019-05-16 14:24:30 +00:00
|
|
|
dispatch(getUpdateFailure());
|
2019-12-06 15:00:01 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const handleRequestSuccess = (response) => {
|
2020-07-03 16:17:58 +00:00
|
|
|
const responseVersion = response.data?.version;
|
2019-12-06 15:00:01 +00:00
|
|
|
|
|
|
|
if (dnsVersion !== responseVersion) {
|
|
|
|
dispatch(getUpdateSuccess());
|
|
|
|
window.location.reload(true);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
try {
|
|
|
|
await apiClient.getUpdate();
|
|
|
|
checkStatus(handleRequestSuccess, handleRequestError);
|
|
|
|
} catch (error) {
|
|
|
|
handleRequestError();
|
2019-05-16 14:24:30 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-03-28 08:45:31 +00:00
|
|
|
export const getClientsRequest = createAction('GET_CLIENTS_REQUEST');
|
|
|
|
export const getClientsFailure = createAction('GET_CLIENTS_FAILURE');
|
|
|
|
export const getClientsSuccess = createAction('GET_CLIENTS_SUCCESS');
|
|
|
|
|
|
|
|
export const getClients = () => async (dispatch) => {
|
|
|
|
dispatch(getClientsRequest());
|
|
|
|
try {
|
2019-05-23 11:14:22 +00:00
|
|
|
const data = await apiClient.getClients();
|
|
|
|
const sortedClients = data.clients && sortClients(data.clients);
|
|
|
|
const sortedAutoClients = data.auto_clients && sortClients(data.auto_clients);
|
|
|
|
|
|
|
|
dispatch(getClientsSuccess({
|
|
|
|
clients: sortedClients || [],
|
|
|
|
autoClients: sortedAutoClients || [],
|
2020-01-28 11:07:47 +00:00
|
|
|
supportedTags: data.supported_tags || [],
|
2019-05-23 11:14:22 +00:00
|
|
|
}));
|
2019-03-28 08:45:31 +00:00
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
|
|
|
dispatch(getClientsFailure());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-10-23 07:31:54 +00:00
|
|
|
export const getProfileRequest = createAction('GET_PROFILE_REQUEST');
|
|
|
|
export const getProfileFailure = createAction('GET_PROFILE_FAILURE');
|
|
|
|
export const getProfileSuccess = createAction('GET_PROFILE_SUCCESS');
|
|
|
|
|
|
|
|
export const getProfile = () => async (dispatch) => {
|
|
|
|
dispatch(getProfileRequest());
|
|
|
|
try {
|
|
|
|
const profile = await apiClient.getProfile();
|
|
|
|
dispatch(getProfileSuccess(profile));
|
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
|
|
|
dispatch(getProfileFailure());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-08-30 14:25:33 +00:00
|
|
|
export const dnsStatusRequest = createAction('DNS_STATUS_REQUEST');
|
|
|
|
export const dnsStatusFailure = createAction('DNS_STATUS_FAILURE');
|
|
|
|
export const dnsStatusSuccess = createAction('DNS_STATUS_SUCCESS');
|
2019-12-17 15:54:28 +00:00
|
|
|
export const setDnsRunningStatus = createAction('SET_DNS_RUNNING_STATUS');
|
2018-08-30 14:25:33 +00:00
|
|
|
|
|
|
|
export const getDnsStatus = () => async (dispatch) => {
|
|
|
|
dispatch(dnsStatusRequest());
|
2019-12-06 15:00:01 +00:00
|
|
|
|
|
|
|
const handleRequestError = () => {
|
|
|
|
dispatch(addErrorToast({ error: 'dns_status_error' }));
|
|
|
|
dispatch(dnsStatusFailure());
|
|
|
|
window.location.reload(true);
|
|
|
|
};
|
2020-04-22 16:32:07 +00:00
|
|
|
|
2019-12-06 15:00:01 +00:00
|
|
|
const handleRequestSuccess = (response) => {
|
|
|
|
const dnsStatus = response.data;
|
2019-12-17 15:54:28 +00:00
|
|
|
const { running } = dnsStatus;
|
|
|
|
const runningStatus = dnsStatus && running;
|
|
|
|
if (runningStatus === true) {
|
2019-12-06 15:00:01 +00:00
|
|
|
dispatch(dnsStatusSuccess(dnsStatus));
|
|
|
|
dispatch(getVersion());
|
|
|
|
dispatch(getTlsStatus());
|
|
|
|
dispatch(getProfile());
|
2019-12-17 15:54:28 +00:00
|
|
|
} else {
|
|
|
|
dispatch(setDnsRunningStatus(running));
|
2019-12-06 15:00:01 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-08-30 14:25:33 +00:00
|
|
|
try {
|
2019-12-06 15:00:01 +00:00
|
|
|
checkStatus(handleRequestSuccess, handleRequestError);
|
2018-08-30 14:25:33 +00:00
|
|
|
} catch (error) {
|
2020-12-21 13:51:48 +00:00
|
|
|
handleRequestError();
|
2019-09-17 09:22:15 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-09-21 15:08:39 +00:00
|
|
|
export const testUpstreamRequest = createAction('TEST_UPSTREAM_REQUEST');
|
|
|
|
export const testUpstreamFailure = createAction('TEST_UPSTREAM_FAILURE');
|
|
|
|
export const testUpstreamSuccess = createAction('TEST_UPSTREAM_SUCCESS');
|
|
|
|
|
2020-09-22 12:04:17 +00:00
|
|
|
export const testUpstream = (
|
2021-04-07 17:16:06 +00:00
|
|
|
{ bootstrap_dns, upstream_dns, local_ptr_upstreams }, upstream_dns_file,
|
2020-09-22 12:04:17 +00:00
|
|
|
) => async (dispatch) => {
|
2018-09-21 15:08:39 +00:00
|
|
|
dispatch(testUpstreamRequest());
|
|
|
|
try {
|
2020-09-22 12:04:17 +00:00
|
|
|
const removeComments = compose(filterOutComments, splitByNewLine);
|
2019-03-06 13:35:21 +00:00
|
|
|
|
2020-09-22 12:04:17 +00:00
|
|
|
const config = {
|
|
|
|
bootstrap_dns: splitByNewLine(bootstrap_dns),
|
2021-04-07 17:16:06 +00:00
|
|
|
private_upstream: splitByNewLine(local_ptr_upstreams),
|
2020-09-22 12:04:17 +00:00
|
|
|
...(upstream_dns_file ? null : {
|
|
|
|
upstream_dns: removeComments(upstream_dns),
|
|
|
|
}),
|
|
|
|
};
|
|
|
|
|
|
|
|
const upstreamResponse = await apiClient.testUpstream(config);
|
2020-07-03 08:14:54 +00:00
|
|
|
const testMessages = Object.keys(upstreamResponse)
|
|
|
|
.map((key) => {
|
|
|
|
const message = upstreamResponse[key];
|
|
|
|
if (message !== 'OK') {
|
|
|
|
dispatch(addErrorToast({ error: i18next.t('dns_test_not_ok_toast', { key }) }));
|
|
|
|
}
|
|
|
|
return message;
|
|
|
|
});
|
2018-09-21 15:08:39 +00:00
|
|
|
|
2020-05-22 14:06:05 +00:00
|
|
|
if (testMessages.every((message) => message === 'OK')) {
|
2018-11-09 06:51:28 +00:00
|
|
|
dispatch(addSuccessToast('dns_test_ok_toast'));
|
2018-09-21 15:08:39 +00:00
|
|
|
}
|
2018-09-21 15:50:06 +00:00
|
|
|
|
|
|
|
dispatch(testUpstreamSuccess());
|
2018-09-21 15:08:39 +00:00
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
|
|
|
dispatch(testUpstreamFailure());
|
|
|
|
}
|
|
|
|
};
|
2018-11-22 14:56:57 +00:00
|
|
|
|
2020-09-22 12:04:17 +00:00
|
|
|
export const testUpstreamWithFormValues = () => async (dispatch, getState) => {
|
|
|
|
const { upstream_dns_file } = getState().dnsConfig;
|
2021-04-07 17:16:06 +00:00
|
|
|
const {
|
|
|
|
bootstrap_dns,
|
|
|
|
upstream_dns,
|
|
|
|
local_ptr_upstreams,
|
|
|
|
} = getState().form[FORM_NAME.UPSTREAM].values;
|
|
|
|
|
|
|
|
return dispatch(testUpstream({
|
|
|
|
bootstrap_dns,
|
|
|
|
upstream_dns,
|
|
|
|
local_ptr_upstreams,
|
|
|
|
}, upstream_dns_file));
|
2020-09-22 12:04:17 +00:00
|
|
|
};
|
|
|
|
|
2018-11-22 14:56:57 +00:00
|
|
|
export const changeLanguageRequest = createAction('CHANGE_LANGUAGE_REQUEST');
|
|
|
|
export const changeLanguageFailure = createAction('CHANGE_LANGUAGE_FAILURE');
|
|
|
|
export const changeLanguageSuccess = createAction('CHANGE_LANGUAGE_SUCCESS');
|
|
|
|
|
2020-05-22 14:06:05 +00:00
|
|
|
export const changeLanguage = (lang) => async (dispatch) => {
|
2018-11-22 14:56:57 +00:00
|
|
|
dispatch(changeLanguageRequest());
|
|
|
|
try {
|
|
|
|
await apiClient.changeLanguage(lang);
|
|
|
|
dispatch(changeLanguageSuccess());
|
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
|
|
|
dispatch(changeLanguageFailure());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export const getLanguageRequest = createAction('GET_LANGUAGE_REQUEST');
|
|
|
|
export const getLanguageFailure = createAction('GET_LANGUAGE_FAILURE');
|
|
|
|
export const getLanguageSuccess = createAction('GET_LANGUAGE_SUCCESS');
|
|
|
|
|
|
|
|
export const getLanguage = () => async (dispatch) => {
|
|
|
|
dispatch(getLanguageRequest());
|
|
|
|
try {
|
|
|
|
const language = await apiClient.getCurrentLanguage();
|
|
|
|
dispatch(getLanguageSuccess(language));
|
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
|
|
|
dispatch(getLanguageFailure());
|
|
|
|
}
|
|
|
|
};
|
2018-12-12 15:12:51 +00:00
|
|
|
|
|
|
|
export const getDhcpStatusRequest = createAction('GET_DHCP_STATUS_REQUEST');
|
|
|
|
export const getDhcpStatusSuccess = createAction('GET_DHCP_STATUS_SUCCESS');
|
|
|
|
export const getDhcpStatusFailure = createAction('GET_DHCP_STATUS_FAILURE');
|
|
|
|
|
|
|
|
export const getDhcpStatus = () => async (dispatch) => {
|
|
|
|
dispatch(getDhcpStatusRequest());
|
|
|
|
try {
|
2020-08-19 15:23:05 +00:00
|
|
|
const globalStatus = await apiClient.getGlobalStatus();
|
2020-11-16 16:01:12 +00:00
|
|
|
if (globalStatus.dhcp_available) {
|
|
|
|
const status = await apiClient.getDhcpStatus();
|
|
|
|
status.dhcp_available = globalStatus.dhcp_available;
|
|
|
|
dispatch(getDhcpStatusSuccess(status));
|
|
|
|
} else {
|
|
|
|
dispatch(getDhcpStatusFailure());
|
|
|
|
}
|
2018-12-12 15:12:51 +00:00
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
|
|
|
dispatch(getDhcpStatusFailure());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-12-24 08:48:23 +00:00
|
|
|
export const getDhcpInterfacesRequest = createAction('GET_DHCP_INTERFACES_REQUEST');
|
|
|
|
export const getDhcpInterfacesSuccess = createAction('GET_DHCP_INTERFACES_SUCCESS');
|
|
|
|
export const getDhcpInterfacesFailure = createAction('GET_DHCP_INTERFACES_FAILURE');
|
|
|
|
|
|
|
|
export const getDhcpInterfaces = () => async (dispatch) => {
|
|
|
|
dispatch(getDhcpInterfacesRequest());
|
|
|
|
try {
|
|
|
|
const interfaces = await apiClient.getDhcpInterfaces();
|
|
|
|
dispatch(getDhcpInterfacesSuccess(interfaces));
|
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
|
|
|
dispatch(getDhcpInterfacesFailure());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-12-29 15:43:17 +00:00
|
|
|
export const findActiveDhcpRequest = createAction('FIND_ACTIVE_DHCP_REQUEST');
|
|
|
|
export const findActiveDhcpSuccess = createAction('FIND_ACTIVE_DHCP_SUCCESS');
|
|
|
|
export const findActiveDhcpFailure = createAction('FIND_ACTIVE_DHCP_FAILURE');
|
2018-12-12 15:12:51 +00:00
|
|
|
|
2020-08-19 15:23:05 +00:00
|
|
|
export const findActiveDhcp = (name) => async (dispatch, getState) => {
|
2018-12-29 15:43:17 +00:00
|
|
|
dispatch(findActiveDhcpRequest());
|
2018-12-12 15:12:51 +00:00
|
|
|
try {
|
2018-12-29 15:43:17 +00:00
|
|
|
const activeDhcp = await apiClient.findActiveDhcp(name);
|
|
|
|
dispatch(findActiveDhcpSuccess(activeDhcp));
|
2020-08-20 10:50:40 +00:00
|
|
|
const { check, interface_name, interfaces } = getState().dhcp;
|
|
|
|
const selectedInterface = getState().form[FORM_NAME.DHCP_INTERFACES].values.interface_name;
|
2020-08-19 15:23:05 +00:00
|
|
|
const v4 = check?.v4 ?? { static_ip: {}, other_server: {} };
|
|
|
|
const v6 = check?.v6 ?? { other_server: {} };
|
|
|
|
|
|
|
|
let isError = false;
|
2020-08-20 11:37:57 +00:00
|
|
|
let isStaticIPError = false;
|
2020-08-19 15:23:05 +00:00
|
|
|
|
2020-08-20 10:50:40 +00:00
|
|
|
const hasV4Interface = !!interfaces[selectedInterface]?.ipv4_addresses;
|
|
|
|
const hasV6Interface = !!interfaces[selectedInterface]?.ipv6_addresses;
|
|
|
|
|
2020-08-20 11:25:00 +00:00
|
|
|
if (hasV4Interface && v4.other_server.found === STATUS_RESPONSE.ERROR) {
|
2020-08-19 15:23:05 +00:00
|
|
|
isError = true;
|
|
|
|
if (v4.other_server.error) {
|
|
|
|
dispatch(addErrorToast({ error: v4.other_server.error }));
|
|
|
|
}
|
2020-08-20 11:25:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (hasV6Interface && v6.other_server.found === STATUS_RESPONSE.ERROR) {
|
|
|
|
isError = true;
|
2020-08-19 15:23:05 +00:00
|
|
|
if (v6.other_server.error) {
|
|
|
|
dispatch(addErrorToast({ error: v6.other_server.error }));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-20 10:50:40 +00:00
|
|
|
if (hasV4Interface && v4.static_ip.static === STATUS_RESPONSE.ERROR) {
|
2020-08-20 11:37:57 +00:00
|
|
|
isStaticIPError = true;
|
2020-08-19 15:23:05 +00:00
|
|
|
dispatch(addErrorToast({ error: 'dhcp_static_ip_error' }));
|
|
|
|
}
|
|
|
|
|
2020-08-20 11:37:57 +00:00
|
|
|
|
2020-08-19 15:23:05 +00:00
|
|
|
if (isError) {
|
2020-08-20 11:25:00 +00:00
|
|
|
dispatch(addErrorToast({ error: 'dhcp_error' }));
|
2020-08-20 11:37:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (isStaticIPError || isError) {
|
|
|
|
// No need to proceed if there was an error discovering DHCP server
|
2020-08-19 15:23:05 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-20 10:50:40 +00:00
|
|
|
if ((hasV4Interface && v4.other_server.found === STATUS_RESPONSE.YES)
|
|
|
|
|| (hasV6Interface && v6.other_server.found === STATUS_RESPONSE.YES)) {
|
2020-08-19 15:23:05 +00:00
|
|
|
dispatch(addErrorToast({ error: 'dhcp_found' }));
|
2020-08-20 10:50:40 +00:00
|
|
|
} else if (hasV4Interface && v4.static_ip.static === STATUS_RESPONSE.NO
|
2020-08-19 15:23:05 +00:00
|
|
|
&& v4.static_ip.ip
|
|
|
|
&& interface_name) {
|
|
|
|
const warning = i18next.t('dhcp_dynamic_ip_found', {
|
|
|
|
interfaceName: interface_name,
|
|
|
|
ipAddress: v4.static_ip.ip,
|
|
|
|
interpolation: {
|
|
|
|
prefix: '<0>{{',
|
|
|
|
suffix: '}}</0>',
|
|
|
|
},
|
|
|
|
});
|
|
|
|
dispatch(addErrorToast({ error: warning }));
|
|
|
|
} else {
|
|
|
|
dispatch(addSuccessToast('dhcp_not_found'));
|
|
|
|
}
|
2018-12-12 15:12:51 +00:00
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
2018-12-29 15:43:17 +00:00
|
|
|
dispatch(findActiveDhcpFailure());
|
2018-12-12 15:12:51 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-12-29 15:43:17 +00:00
|
|
|
export const setDhcpConfigRequest = createAction('SET_DHCP_CONFIG_REQUEST');
|
|
|
|
export const setDhcpConfigSuccess = createAction('SET_DHCP_CONFIG_SUCCESS');
|
|
|
|
export const setDhcpConfigFailure = createAction('SET_DHCP_CONFIG_FAILURE');
|
2018-12-12 15:12:51 +00:00
|
|
|
|
2020-08-19 15:23:05 +00:00
|
|
|
export const setDhcpConfig = (values) => async (dispatch) => {
|
2018-12-29 15:43:17 +00:00
|
|
|
dispatch(setDhcpConfigRequest());
|
2019-05-28 12:07:46 +00:00
|
|
|
try {
|
2020-08-19 15:23:05 +00:00
|
|
|
await apiClient.setDhcpConfig(values);
|
|
|
|
dispatch(setDhcpConfigSuccess(values));
|
2019-05-28 12:07:46 +00:00
|
|
|
dispatch(addSuccessToast('dhcp_config_saved'));
|
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
|
|
|
dispatch(setDhcpConfigFailure());
|
2018-12-12 15:12:51 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export const toggleDhcpRequest = createAction('TOGGLE_DHCP_REQUEST');
|
|
|
|
export const toggleDhcpFailure = createAction('TOGGLE_DHCP_FAILURE');
|
|
|
|
export const toggleDhcpSuccess = createAction('TOGGLE_DHCP_SUCCESS');
|
|
|
|
|
2020-05-22 14:06:05 +00:00
|
|
|
export const toggleDhcp = (values) => async (dispatch) => {
|
2018-12-12 15:12:51 +00:00
|
|
|
dispatch(toggleDhcpRequest());
|
2020-07-03 08:14:54 +00:00
|
|
|
let config = {
|
|
|
|
...values,
|
|
|
|
enabled: false,
|
|
|
|
};
|
2019-05-28 12:07:46 +00:00
|
|
|
let successMessage = 'disabled_dhcp';
|
2018-12-12 15:12:51 +00:00
|
|
|
|
2019-05-28 12:07:46 +00:00
|
|
|
if (!values.enabled) {
|
2020-07-03 08:14:54 +00:00
|
|
|
config = {
|
|
|
|
...values,
|
|
|
|
enabled: true,
|
|
|
|
};
|
2019-05-28 12:07:46 +00:00
|
|
|
successMessage = 'enabled_dhcp';
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
await apiClient.setDhcpConfig(config);
|
|
|
|
dispatch(toggleDhcpSuccess());
|
|
|
|
dispatch(addSuccessToast(successMessage));
|
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
|
|
|
dispatch(toggleDhcpFailure());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-10-15 14:14:24 +00:00
|
|
|
export const resetDhcpRequest = createAction('RESET_DHCP_REQUEST');
|
|
|
|
export const resetDhcpSuccess = createAction('RESET_DHCP_SUCCESS');
|
|
|
|
export const resetDhcpFailure = createAction('RESET_DHCP_FAILURE');
|
|
|
|
|
|
|
|
export const resetDhcp = () => async (dispatch) => {
|
|
|
|
dispatch(resetDhcpRequest());
|
|
|
|
try {
|
|
|
|
const status = await apiClient.resetDhcp();
|
|
|
|
dispatch(resetDhcpSuccess(status));
|
|
|
|
dispatch(addSuccessToast('dhcp_config_saved'));
|
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
|
|
|
dispatch(resetDhcpFailure());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-05-28 12:07:46 +00:00
|
|
|
export const toggleLeaseModal = createAction('TOGGLE_LEASE_MODAL');
|
|
|
|
|
|
|
|
export const addStaticLeaseRequest = createAction('ADD_STATIC_LEASE_REQUEST');
|
|
|
|
export const addStaticLeaseFailure = createAction('ADD_STATIC_LEASE_FAILURE');
|
|
|
|
export const addStaticLeaseSuccess = createAction('ADD_STATIC_LEASE_SUCCESS');
|
|
|
|
|
2020-05-22 14:06:05 +00:00
|
|
|
export const addStaticLease = (config) => async (dispatch) => {
|
2019-05-28 12:07:46 +00:00
|
|
|
dispatch(addStaticLeaseRequest());
|
|
|
|
try {
|
2019-05-28 15:02:02 +00:00
|
|
|
const name = config.hostname || config.ip;
|
2019-05-28 12:07:46 +00:00
|
|
|
await apiClient.addStaticLease(config);
|
2019-05-28 15:02:02 +00:00
|
|
|
dispatch(addStaticLeaseSuccess(config));
|
2020-05-22 14:06:05 +00:00
|
|
|
dispatch(addSuccessToast(i18next.t('dhcp_lease_added', { key: name })));
|
2019-05-28 12:07:46 +00:00
|
|
|
dispatch(toggleLeaseModal());
|
2021-06-10 11:54:47 +00:00
|
|
|
dispatch(getDhcpStatus());
|
2019-05-28 12:07:46 +00:00
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
|
|
|
dispatch(addStaticLeaseFailure());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export const removeStaticLeaseRequest = createAction('REMOVE_STATIC_LEASE_REQUEST');
|
|
|
|
export const removeStaticLeaseFailure = createAction('REMOVE_STATIC_LEASE_FAILURE');
|
|
|
|
export const removeStaticLeaseSuccess = createAction('REMOVE_STATIC_LEASE_SUCCESS');
|
|
|
|
|
2020-05-22 14:06:05 +00:00
|
|
|
export const removeStaticLease = (config) => async (dispatch) => {
|
2019-05-28 12:07:46 +00:00
|
|
|
dispatch(removeStaticLeaseRequest());
|
|
|
|
try {
|
2019-05-28 15:02:02 +00:00
|
|
|
const name = config.hostname || config.ip;
|
2019-05-28 12:07:46 +00:00
|
|
|
await apiClient.removeStaticLease(config);
|
2019-05-28 15:02:02 +00:00
|
|
|
dispatch(removeStaticLeaseSuccess(config));
|
2020-05-22 14:06:05 +00:00
|
|
|
dispatch(addSuccessToast(i18next.t('dhcp_lease_deleted', { key: name })));
|
2019-05-28 12:07:46 +00:00
|
|
|
} catch (error) {
|
|
|
|
dispatch(addErrorToast({ error }));
|
|
|
|
dispatch(removeStaticLeaseFailure());
|
2018-12-12 15:12:51 +00:00
|
|
|
}
|
|
|
|
};
|
2020-05-22 14:06:05 +00:00
|
|
|
|
|
|
|
export const removeToast = createAction('REMOVE_TOAST');
|
2020-09-01 13:30:30 +00:00
|
|
|
|
2020-09-05 07:22:47 +00:00
|
|
|
export const toggleBlocking = (
|
|
|
|
type, domain, baseRule, baseUnblocking,
|
|
|
|
) => async (dispatch, getState) => {
|
|
|
|
const baseBlockingRule = baseRule || `||${domain}^$important`;
|
|
|
|
const baseUnblockingRule = baseUnblocking || `@@${baseBlockingRule}`;
|
2020-09-01 13:30:30 +00:00
|
|
|
const { userRules } = getState().filtering;
|
|
|
|
|
|
|
|
const lineEnding = !endsWith(userRules, '\n') ? '\n' : '';
|
|
|
|
|
2020-09-05 07:22:47 +00:00
|
|
|
const blockingRule = type === BLOCK_ACTIONS.BLOCK ? baseUnblockingRule : baseBlockingRule;
|
|
|
|
const unblockingRule = type === BLOCK_ACTIONS.BLOCK ? baseBlockingRule : baseUnblockingRule;
|
2020-09-01 13:30:30 +00:00
|
|
|
const preparedBlockingRule = new RegExp(`(^|\n)${escapeRegExp(blockingRule)}($|\n)`);
|
|
|
|
const preparedUnblockingRule = new RegExp(`(^|\n)${escapeRegExp(unblockingRule)}($|\n)`);
|
|
|
|
|
|
|
|
const matchPreparedBlockingRule = userRules.match(preparedBlockingRule);
|
|
|
|
const matchPreparedUnblockingRule = userRules.match(preparedUnblockingRule);
|
|
|
|
|
|
|
|
if (matchPreparedBlockingRule) {
|
2020-09-03 20:05:11 +00:00
|
|
|
await dispatch(setRules(userRules.replace(`${blockingRule}`, '')));
|
2020-09-01 13:30:30 +00:00
|
|
|
dispatch(addSuccessToast(i18next.t('rule_removed_from_custom_filtering_toast', { rule: blockingRule })));
|
|
|
|
} else if (!matchPreparedUnblockingRule) {
|
2020-09-03 20:05:11 +00:00
|
|
|
await dispatch(setRules(`${userRules}${lineEnding}${unblockingRule}\n`));
|
2020-09-01 13:30:30 +00:00
|
|
|
dispatch(addSuccessToast(i18next.t('rule_added_to_custom_filtering_toast', { rule: unblockingRule })));
|
|
|
|
} else if (matchPreparedUnblockingRule) {
|
|
|
|
dispatch(addSuccessToast(i18next.t('rule_added_to_custom_filtering_toast', { rule: unblockingRule })));
|
|
|
|
return;
|
|
|
|
} else if (!matchPreparedBlockingRule) {
|
|
|
|
dispatch(addSuccessToast(i18next.t('rule_removed_from_custom_filtering_toast', { rule: blockingRule })));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
dispatch(getFilteringStatus());
|
|
|
|
};
|
2020-09-05 07:22:47 +00:00
|
|
|
|
|
|
|
export const toggleBlockingForClient = (type, domain, client) => {
|
|
|
|
const baseRule = `||${domain}^$client='${client.replace(/'/g, '/\'')}'`;
|
|
|
|
const baseUnblocking = `@@${baseRule}`;
|
|
|
|
|
|
|
|
return toggleBlocking(type, domain, baseRule, baseUnblocking);
|
|
|
|
};
|