*: merge with master

This commit is contained in:
Andrey Meshkov
2020-02-07 15:16:46 +03:00
27 changed files with 396 additions and 284 deletions

5
client/.eslintrc vendored
View File

@@ -17,6 +17,11 @@
"react": {
"pragma": "React",
"version": "16.4"
},
"import/resolver": {
"webpack": {
"config": "webpack.common.js"
}
}
},

109
client/package-lock.json generated vendored
View File

@@ -821,6 +821,7 @@
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz",
"integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==",
"dev": true,
"requires": {
"fast-deep-equal": "^2.0.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -837,7 +838,8 @@
"ajv-keywords": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz",
"integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo="
"integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=",
"dev": true
},
"align-text": {
"version": "0.1.4",
@@ -925,6 +927,12 @@
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
"dev": true
},
"array-find": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-find/-/array-find-1.0.0.tgz",
"integrity": "sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg=",
"dev": true
},
"array-find-index": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
@@ -2272,7 +2280,8 @@
"big.js": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
"integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q=="
"integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
"dev": true
},
"binary-extensions": {
"version": "1.11.0",
@@ -4212,7 +4221,8 @@
"emojis-list": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
"integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k="
"integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
"dev": true
},
"encodeurl": {
"version": "1.0.2",
@@ -4548,6 +4558,79 @@
}
}
},
"eslint-import-resolver-webpack": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.12.1.tgz",
"integrity": "sha512-O/sUAXk6GWrICiN8JUkkjdt9uZpqZHP+FVnTxtEILL6EZMaPSrnP4lGPSFwcKsv7O211maqq4Nz60+dh236hVg==",
"dev": true,
"requires": {
"array-find": "^1.0.0",
"debug": "^2.6.9",
"enhanced-resolve": "^0.9.1",
"find-root": "^1.1.0",
"has": "^1.0.3",
"interpret": "^1.2.0",
"lodash": "^4.17.15",
"node-libs-browser": "^1.0.0 || ^2.0.0",
"resolve": "^1.13.1",
"semver": "^5.7.1"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"enhanced-resolve": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz",
"integrity": "sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"memory-fs": "^0.2.0",
"tapable": "^0.1.8"
}
},
"interpret": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
"integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==",
"dev": true
},
"memory-fs": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz",
"integrity": "sha1-8rslNovBIeORwlIN6Slpyu4KApA=",
"dev": true
},
"resolve": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz",
"integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
},
"tapable": {
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz",
"integrity": "sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=",
"dev": true
}
}
},
"eslint-loader": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-1.9.0.tgz",
@@ -5152,7 +5235,8 @@
"fast-deep-equal": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
"dev": true
},
"fast-glob": {
"version": "2.2.6",
@@ -5171,7 +5255,8 @@
"fast-json-stable-stringify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
"dev": true
},
"fast-levenshtein": {
"version": "2.0.6",
@@ -7472,7 +7557,8 @@
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true
},
"json-stable-stringify-without-jsonify": {
"version": "1.0.1",
@@ -7489,7 +7575,8 @@
"json5": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE="
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
"dev": true
},
"jsx-ast-utils": {
"version": "1.4.1",
@@ -7627,6 +7714,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
"integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
"dev": true,
"requires": {
"big.js": "^3.1.3",
"emojis-list": "^2.0.0",
@@ -10208,7 +10296,8 @@
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
},
"q": {
"version": "1.5.1",
@@ -11058,6 +11147,7 @@
"version": "0.4.7",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz",
"integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==",
"dev": true,
"requires": {
"ajv": "^6.1.0",
"ajv-keywords": "^3.1.0"
@@ -12485,6 +12575,7 @@
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/svg-url-loader/-/svg-url-loader-2.3.2.tgz",
"integrity": "sha1-3YaybBn+O5FPBOoQ7zlZTq3gRGQ=",
"dev": true,
"requires": {
"file-loader": "1.1.11",
"loader-utils": "1.1.0"
@@ -12494,6 +12585,7 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz",
"integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==",
"dev": true,
"requires": {
"loader-utils": "^1.0.2",
"schema-utils": "^0.4.5"
@@ -12965,6 +13057,7 @@
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
"dev": true,
"requires": {
"punycode": "^2.1.0"
}

5
client/package.json vendored
View File

@@ -34,7 +34,6 @@
"redux-actions": "^2.4.0",
"redux-form": "^7.4.2",
"redux-thunk": "^2.3.0",
"svg-url-loader": "^2.3.2",
"url-polyfill": "^1.1.7"
},
"devDependencies": {
@@ -54,6 +53,7 @@
"eslint": "^4.19.1",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-config-react-app": "^2.1.0",
"eslint-import-resolver-webpack": "^0.12.1",
"eslint-loader": "1.9.0",
"eslint-plugin-import": "^2.12.0",
"eslint-plugin-jsx-a11y": "5.1.1",
@@ -74,6 +74,7 @@
"url-loader": "^1.0.1",
"webpack": "3.8.1",
"webpack-dev-server": "^3.1.14",
"webpack-merge": "^4.1.3"
"webpack-merge": "^4.1.3",
"svg-url-loader": "^2.3.2"
}
}

View File

@@ -3,7 +3,6 @@ import { t } from 'i18next';
import apiClient from '../api/Api';
import { addErrorToast, addSuccessToast } from './index';
import { getStats, getStatsConfig } from './stats';
import { normalizeTextarea } from '../helpers/helpers';
import { ACTION } from '../helpers/constants';
@@ -50,11 +49,13 @@ export const toggleClientBlockRequest = createAction('TOGGLE_CLIENT_BLOCK_REQUES
export const toggleClientBlockFailure = createAction('TOGGLE_CLIENT_BLOCK_FAILURE');
export const toggleClientBlockSuccess = createAction('TOGGLE_CLIENT_BLOCK_SUCCESS');
export const toggleClientBlock = (type, ip) => async (dispatch, getState) => {
export const toggleClientBlock = (type, ip) => async (dispatch) => {
dispatch(toggleClientBlockRequest());
try {
const { allowed_clients, disallowed_clients, blocked_hosts } = getState().access;
let updatedDisallowedClients = normalizeTextarea(disallowed_clients);
const {
allowed_clients, disallowed_clients, blocked_hosts,
} = await apiClient.getAccessList();
let updatedDisallowedClients = disallowed_clients;
if (type === ACTION.unblock && updatedDisallowedClients.includes(ip)) {
updatedDisallowedClients = updatedDisallowedClients.filter(client => client !== ip);
@@ -63,23 +64,19 @@ export const toggleClientBlock = (type, ip) => async (dispatch, getState) => {
}
const values = {
allowed_clients: normalizeTextarea(allowed_clients),
blocked_hosts: normalizeTextarea(blocked_hosts),
allowed_clients,
blocked_hosts,
disallowed_clients: updatedDisallowedClients,
};
await apiClient.setAccessList(values);
dispatch(toggleClientBlockSuccess());
dispatch(toggleClientBlockSuccess(values));
if (type === ACTION.unblock) {
dispatch(addSuccessToast(t('client_unblocked', { ip })));
} else if (type === ACTION.block) {
dispatch(addSuccessToast(t('client_blocked', { ip })));
}
dispatch(getStats());
dispatch(getStatsConfig());
dispatch(getAccessList());
} catch (error) {
dispatch(addErrorToast({ error }));
dispatch(toggleClientBlockFailure());

View File

@@ -2,7 +2,7 @@ import { createAction } from 'redux-actions';
import apiClient from '../api/Api';
import { addErrorToast, addSuccessToast } from './index';
import { normalizeTopStats, secondsToMilliseconds, getParamsForClientsSearch, addClientInfo, addClientStatus } from '../helpers/helpers';
import { normalizeTopStats, secondsToMilliseconds, getParamsForClientsSearch, addClientInfo } from '../helpers/helpers';
export const getStatsConfigRequest = createAction('GET_STATS_CONFIG_REQUEST');
export const getStatsConfigFailure = createAction('GET_STATS_CONFIG_FAILURE');
@@ -46,15 +46,12 @@ export const getStats = () => async (dispatch) => {
const normalizedTopClients = normalizeTopStats(stats.top_clients);
const clientsParams = getParamsForClientsSearch(normalizedTopClients, 'name');
const clients = await apiClient.findClients(clientsParams);
const accessData = await apiClient.getAccessList();
const { disallowed_clients } = accessData;
const topClientsWithInfo = addClientInfo(normalizedTopClients, clients, 'name');
const topClientsWithStatus = addClientStatus(topClientsWithInfo, disallowed_clients, 'name');
const normalizedStats = {
...stats,
top_blocked_domains: normalizeTopStats(stats.top_blocked_domains),
top_clients: topClientsWithStatus,
top_clients: topClientsWithInfo,
top_queried_domains: normalizeTopStats(stats.top_queried_domains),
avg_processing_time: secondsToMilliseconds(stats.avg_processing_time),
};

View File

@@ -57,10 +57,12 @@ const renderBlockingButton = (blocked, ip, handleClick, processing) => {
);
};
const clientCell = (t, toggleClientStatus, processing) =>
const isBlockedClient = (clients, ip) => !!(clients && clients.includes(ip));
const clientCell = (t, toggleClientStatus, processing, disallowedClients) =>
function cell(row) {
const { original, value } = row;
const { blocked } = original;
const { value } = row;
const blocked = isBlockedClient(disallowedClients, value);
return (
<Fragment>
@@ -80,6 +82,7 @@ const Clients = ({
dnsQueries,
toggleClientStatus,
processingAccessSet,
disallowedClients,
}) => (
<Card
title={t('top_clients')}
@@ -102,7 +105,7 @@ const Clients = ({
accessor: 'ip',
sortMethod: (a, b) =>
parseInt(a.replace(/\./g, ''), 10) - parseInt(b.replace(/\./g, ''), 10),
Cell: clientCell(t, toggleClientStatus, processingAccessSet),
Cell: clientCell(t, toggleClientStatus, processingAccessSet, disallowedClients),
},
{
Header: <Trans>requests_count</Trans>,
@@ -122,9 +125,9 @@ const Clients = ({
return {};
}
const { blocked } = rowInfo.original;
const { ip } = rowInfo.original;
if (blocked) {
if (isBlockedClient(disallowedClients, ip)) {
return {
className: 'red',
};
@@ -148,6 +151,7 @@ Clients.propTypes = {
t: PropTypes.func.isRequired,
toggleClientStatus: PropTypes.func.isRequired,
processingAccessSet: PropTypes.bool.isRequired,
disallowedClients: PropTypes.string.isRequired,
};
export default withNamespaces()(Clients);

View File

@@ -19,6 +19,7 @@ class Dashboard extends Component {
}
getAllStats = () => {
this.props.getAccessList();
this.props.getStats();
this.props.getStatsConfig();
};
@@ -53,7 +54,8 @@ class Dashboard extends Component {
dashboard, stats, access, t,
} = this.props;
const statsProcessing = stats.processingStats
|| stats.processingGetConfig;
|| stats.processingGetConfig
|| access.processing;
const subtitle =
stats.interval === 1
@@ -130,6 +132,7 @@ class Dashboard extends Component {
refreshButton={refreshButton}
toggleClientStatus={this.toggleClientStatus}
processingAccessSet={access.processingSet}
disallowedClients={access.disallowed_clients}
/>
</div>
<div className="col-lg-6">

View File

@@ -1,7 +1,9 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import { Trans, withNamespaces } from 'react-i18next';
import { REPOSITORY, LANGUAGES, PRIVACY_POLICY_LINK } from '../../helpers/constants';
import { REPOSITORY, PRIVACY_POLICY_LINK } from '../../helpers/constants';
import { LANGUAGES } from '../../helpers/twosky';
import i18n from '../../i18n';
import Version from './Version';
@@ -68,9 +70,9 @@ class Footer extends Component {
value={i18n.language}
onChange={this.changeLanguage}
>
{LANGUAGES.map(language => (
<option key={language.key} value={language.key}>
{language.name}
{Object.keys(LANGUAGES).map(lang => (
<option key={lang} value={lang}>
{LANGUAGES[lang]}
</option>
))}
</select>

View File

@@ -31,117 +31,6 @@ export const REPOSITORY = {
export const PRIVACY_POLICY_LINK = 'https://adguard.com/privacy/home.html';
export const LANGUAGES = [
{
key: 'da',
name: 'Dansk',
},
{
key: 'de',
name: 'Deutsch',
},
{
key: 'nl',
name: 'Dutch',
},
{
key: 'en',
name: 'English',
},
{
key: 'es',
name: 'Español',
},
{
key: 'fr',
name: 'Français',
},
{
key: 'id',
name: 'Indonesian',
},
{
key: 'it',
name: 'Italiano',
},
{
key: 'pl',
name: 'Polski',
},
{
key: 'pt-br',
name: 'Portuguese (BR)',
},
{
key: 'pt-pt',
name: 'Portuguese (PT)',
},
{
key: 'sk',
name: 'Slovenčina',
},
{
key: 'sl',
name: 'Slovenščina',
},
{
key: 'sv',
name: 'Svenska',
},
{
key: 'vi',
name: 'Tiếng Việt',
},
{
key: 'tr',
name: 'Türkçe',
},
{
key: 'cs',
name: 'Český',
},
{
key: 'bg',
name: 'Български',
},
{
key: 'ru',
name: 'Русский',
},
{
key: 'ja',
name: '日本語',
},
{
key: 'zh-tw',
name: '正體中文',
},
{
key: 'zh-cn',
name: '简体中文',
},
{
key: 'no',
name: 'Norsk',
},
{
key: 'sr-cs',
name: 'Srpski',
},
{
key: 'hr',
name: 'Hrvatski',
},
{
key: 'fa',
name: 'فارسی',
},
{
key: 'ko',
name: '한국어',
},
];
export const INSTALL_FIRST_STEP = 1;
export const INSTALL_TOTAL_STEPS = 5;

View File

@@ -122,17 +122,6 @@ export const addClientInfo = (data, clients, param) => (
})
);
export const addClientStatus = (data, disallowedClients, param) => (
data.map((row) => {
const clientIp = row[param];
const blocked = !!(disallowedClients && disallowedClients.includes(clientIp));
return {
...row,
blocked,
};
})
);
export const normalizeFilteringStatus = (filteringStatus) => {
const {
enabled, filters, user_rules: userRules, interval,

View File

@@ -96,6 +96,11 @@
"name": "Microsoft Azure",
"categoryId": 10,
"url": "https://azure.microsoft.com/"
},
"button": {
"name": "Button",
"categoryId": 4,
"url": "https://www.usebutton.com/"
}
},
"trackerDomains": {
@@ -119,6 +124,7 @@
"edgecastcdn.net": "markmonitor",
"appcenter.ms": "appcenter",
"unityads.unity3d.com": "unity_ads",
"azure.com": "azure"
"azure.com": "azure",
"bttn.io": "button"
}
}

View File

@@ -696,11 +696,6 @@
"categoryId": 4,
"url": "http://adgoto.com/"
},
"adguard": {
"name": "Adguard",
"categoryId": 12,
"url": "https://adguard.com/"
},
"adhands": {
"name": "AdHands",
"categoryId": 4,
@@ -16201,7 +16196,6 @@
"smartredirect.de": "adgoal",
"adgorithms.com": "adgorithms",
"adgoto.com": "adgoto",
"adguard.com": "adguard",
"adhands.ru": "adhands",
"adhese.be": "adhese",
"adhese.com": "adhese",

View File

@@ -0,0 +1,6 @@
import twosky from 'MainRoot/.twosky.json';
export const {
languages: LANGUAGES,
base_locale: BASE_LOCALE,
} = twosky[0];

View File

@@ -3,7 +3,7 @@ import { reactI18nextModule } from 'react-i18next';
import { initReactI18n } from 'react-i18next/hooks';
import langDetect from 'i18next-browser-languagedetector';
import { DEFAULT_LANGUAGE } from './helpers/constants';
import { LANGUAGES, BASE_LOCALE } from './helpers/twosky';
import vi from './__locales/vi.json';
import en from './__locales/en.json';
@@ -117,7 +117,7 @@ const resources = {
},
};
const availableLanguages = Object.keys(resources);
const availableLanguages = Object.keys(LANGUAGES);
i18n
.use(langDetect)
@@ -126,7 +126,7 @@ i18n
.init({
resources,
lowerCaseLng: true,
fallbackLng: DEFAULT_LANGUAGE,
fallbackLng: BASE_LOCALE,
keySeparator: false,
nsSeparator: false,
returnEmptyString: false,
@@ -136,9 +136,10 @@ i18n
react: {
wait: true,
},
whitelist: availableLanguages,
}, () => {
if (!availableLanguages.includes(i18n.language)) {
i18n.changeLanguage(DEFAULT_LANGUAGE);
i18n.changeLanguage(BASE_LOCALE);
}
});

View File

@@ -34,7 +34,21 @@ const access = handleActions(
[actions.toggleClientBlockRequest]: state => ({ ...state, processingSet: true }),
[actions.toggleClientBlockFailure]: state => ({ ...state, processingSet: false }),
[actions.toggleClientBlockSuccess]: state => ({ ...state, processingSet: false }),
[actions.toggleClientBlockSuccess]: (state, { payload }) => {
const {
allowed_clients,
disallowed_clients,
blocked_hosts,
} = payload;
const newState = {
...state,
allowed_clients: (allowed_clients && allowed_clients.join('\n')) || '',
disallowed_clients: (disallowed_clients && disallowed_clients.join('\n')) || '',
blocked_hosts: (blocked_hosts && blocked_hosts.join('\n')) || '',
processingSet: false,
};
return newState;
},
},
{
processing: true,

View File

@@ -32,6 +32,10 @@ const config = {
},
resolve: {
modules: ['node_modules'],
alias: {
MainRoot: path.resolve(__dirname, '../'),
ClientRoot: path.resolve(__dirname, './src'),
},
},
module: {
rules: [
@@ -101,7 +105,7 @@ const config = {
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
}),
new CleanWebpackPlugin(['*.*'], {
new CleanWebpackPlugin(['**/*.*'], {
root: PUBLIC_PATH,
verbose: false,
dry: false,