Fix #1069 install: check static ip

Squashed commit of the following:

commit 57466233cb
Merge: 2df5f281 867bf545
Author: Andrey Meshkov <am@adguard.com>
Date:   Thu Feb 13 18:39:15 2020 +0300

    Merge branch 'master' into 1069-install-static-ip

commit 2df5f281c4
Author: Andrey Meshkov <am@adguard.com>
Date:   Thu Feb 13 18:35:54 2020 +0300

    *: lang fix

commit b4649a6b27
Merge: c2785253 f61d5f0f
Author: Andrey Meshkov <am@adguard.com>
Date:   Thu Feb 13 16:47:30 2020 +0300

    *(home): fixed issues with setting static IP on Mac

commit c27852537d
Author: Andrey Meshkov <am@adguard.com>
Date:   Thu Feb 13 14:14:30 2020 +0300

    +(dhcpd): added static IP for MacOS

commit f61d5f0f85
Author: Ildar Kamalov <i.kamalov@adguard.com>
Date:   Thu Feb 13 14:13:35 2020 +0300

    + client: show confirm before setting static IP

commit 7afa16fbe7
Author: Ildar Kamalov <i.kamalov@adguard.com>
Date:   Thu Feb 13 13:51:52 2020 +0300

    - client: fix text

commit 019bff0851
Author: Ildar Kamalov <i.kamalov@adguard.com>
Date:   Thu Feb 13 13:49:16 2020 +0300

    - client: pass all params to the check_config request

commit 194bed72f5
Author: Andrey Meshkov <am@adguard.com>
Date:   Wed Feb 12 17:12:16 2020 +0300

    *: fix home_test

commit 9359f6b55f
Merge: ae299058 c5ca2a77
Author: Andrey Meshkov <am@adguard.com>
Date:   Wed Feb 12 15:54:54 2020 +0300

    Merge with master

commit ae2990582d
Author: Andrey Meshkov <am@adguard.com>
Date:   Wed Feb 12 15:53:36 2020 +0300

    *(global): refactoring - moved runtime properties to Context

commit d8d48c5386
Author: Andrey Meshkov <am@adguard.com>
Date:   Wed Feb 12 15:04:25 2020 +0300

    *(dhcpd): refactoring, use dhcpd/network_utils where possible

commit 8d039c572f
Author: Ildar Kamalov <i.kamalov@adguard.com>
Date:   Fri Feb 7 18:37:39 2020 +0300

    - client: fix button position

commit 26c47e59dd
Author: Ildar Kamalov <i.kamalov@adguard.com>
Date:   Fri Feb 7 18:08:56 2020 +0300

    - client: fix static ip description

commit cb12babc46
Author: Andrey Meshkov <am@adguard.com>
Date:   Fri Feb 7 17:08:39 2020 +0300

    *: lower log level for some commands

commit d9001ff848
Author: Andrey Meshkov <am@adguard.com>
Date:   Fri Feb 7 16:17:59 2020 +0300

    *(documentation): updated openapi

commit 1d213d53c8
Merge: 8406d7d2 80861860
Author: Andrey Meshkov <am@adguard.com>
Date:   Fri Feb 7 15:16:46 2020 +0300

    *: merge with master

commit 8406d7d288
Author: Ildar Kamalov <i.kamalov@adguard.com>
Date:   Fri Jan 31 16:52:22 2020 +0300

    - client: fix locales

commit fb476b0117
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jan 31 13:29:03 2020 +0300

    linter

commit 84b5708e71
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jan 31 13:27:53 2020 +0300

    linter

commit 143a86a28a
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jan 31 13:26:47 2020 +0300

    linter

... and 7 more commits
This commit is contained in:
Andrey Meshkov
2020-02-13 18:42:07 +03:00
parent 867bf5457f
commit 7a3eda02ce
38 changed files with 1319 additions and 781 deletions

View File

@@ -458,9 +458,16 @@
"check_reason": "Reason: {{reason}}",
"check_rule": "Rule: {{rule}}",
"check_service": "Service name: {{service}}",
"check_not_found": "Doesn't exist in any filter",
"check_not_found": "Not found in your filter lists",
"client_confirm_block": "Are you sure you want to block the client \"{{ip}}\"?",
"client_confirm_unblock": "Are you sure you want to unblock the client \"{{ip}}\"?",
"client_blocked": "Client \"{{ip}}\" successfully blocked",
"client_unblocked": "Client \"{{ip}}\" successfully unblocked"
"client_unblocked": "Client \"{{ip}}\" successfully unblocked",
"static_ip": "Static IP Address",
"static_ip_desc": "AdGuard Home is a server so it needs a static IP address to function properly. Otherwise, at some point, your router may assign a different IP address to this device.",
"set_static_ip": "Set a static IP address",
"install_static_ok": "Good news! The static IP address is already configured",
"install_static_error": "AdGuard Home cannot configure it automatically for this network interface. Please look for an instruction on how to do this manually.",
"install_static_configure": "We have detected that a dynamic IP address is used — <0>{{ip}}</0>. Do you want to use it as your static address?",
"confirm_static_ip": "AdGuard Home will configure {{ip}} to be your static IP address. Do you want to proceed?"
}

View File

@@ -240,6 +240,13 @@ export const port = (value) => {
return undefined;
};
export const validInstallPort = (value) => {
if (value < 1 || value > 65535) {
return <Trans>form_error_port</Trans>;
}
return undefined;
};
export const portTLS = (value) => {
if (value === 0) {
return undefined;

View File

@@ -7,26 +7,17 @@ import flow from 'lodash/flow';
import Controls from './Controls';
import AddressList from './AddressList';
import { getInterfaceIp } from '../../helpers/helpers';
import { ALL_INTERFACES_IP } from '../../helpers/constants';
import { renderInputField } from '../../helpers/form';
import { renderInputField, required, validInstallPort, toNumber } from '../../helpers/form';
const required = (value) => {
if (value || value === 0) {
return false;
}
return <Trans>form_error_required</Trans>;
const STATIC_STATUS = {
ENABLED: 'yes',
DISABLED: 'no',
ERROR: 'error',
};
const port = (value) => {
if (value < 1 || value > 65535) {
return <Trans>form_error_port</Trans>;
}
return false;
};
const toNumber = value => value && parseInt(value, 10);
const renderInterfaces = (interfaces => (
Object.keys(interfaces).map((item) => {
const option = interfaces[item];
@@ -79,11 +70,91 @@ class Settings extends Component {
});
}
getStaticIpMessage = (staticIp) => {
const { static: status, ip } = staticIp;
if (!status) {
return '';
}
return (
<Fragment>
{status === STATIC_STATUS.DISABLED && (
<Fragment>
<div className="mb-2">
<Trans values={{ ip }} components={[<strong key="0">text</strong>]}>
install_static_configure
</Trans>
</div>
<button
type="button"
className="btn btn-outline-primary btn-sm"
onClick={() => this.handleStaticIp(ip)}
>
<Trans>set_static_ip</Trans>
</button>
</Fragment>
)}
{status === STATIC_STATUS.ERROR && (
<div className="text-danger">
<Trans>install_static_error</Trans>
</div>
)}
{status === STATIC_STATUS.ENABLED && (
<div className="text-success">
<Trans>
install_static_ok
</Trans>
</div>
)}
</Fragment>
);
};
handleAutofix = (type) => {
const {
webIp,
webPort,
dnsIp,
dnsPort,
handleFix,
} = this.props;
const web = { ip: webIp, port: webPort, autofix: false };
const dns = { ip: dnsIp, port: dnsPort, autofix: false };
const set_static_ip = false;
if (type === 'web') {
web.autofix = true;
} else {
dns.autofix = true;
}
handleFix(web, dns, set_static_ip);
};
handleStaticIp = (ip) => {
const {
webIp,
webPort,
dnsIp,
dnsPort,
handleFix,
} = this.props;
const web = { ip: webIp, port: webPort, autofix: false };
const dns = { ip: dnsIp, port: dnsPort, autofix: false };
const set_static_ip = true;
if (window.confirm(this.props.t('confirm_static_ip', { ip }))) {
handleFix(web, dns, set_static_ip);
}
};
render() {
const {
handleSubmit,
handleChange,
handleAutofix,
webIp,
webPort,
dnsIp,
@@ -100,6 +171,7 @@ class Settings extends Component {
status: dnsStatus,
can_autofix: isDnsFixAvailable,
} = config.dns;
const { staticIp } = config;
return (
<form className="setup__step" onSubmit={handleSubmit}>
@@ -137,7 +209,7 @@ class Settings extends Component {
type="number"
className="form-control"
placeholder="80"
validate={[port, required]}
validate={[validInstallPort, required]}
normalize={toNumber}
onChange={handleChange}
/>
@@ -151,11 +223,12 @@ class Settings extends Component {
<button
type="button"
className="btn btn-secondary btn-sm ml-2"
onClick={() => handleAutofix('web', webIp, webPort)}
onClick={() => this.handleAutofix('web')}
>
<Trans>fix</Trans>
</button>
}
<hr className="divider--small" />
</div>
}
</div>
@@ -171,6 +244,7 @@ class Settings extends Component {
</div>
</div>
</div>
<div className="setup__group">
<div className="setup__subtitle">
<Trans>install_settings_dns</Trans>
@@ -205,7 +279,7 @@ class Settings extends Component {
type="number"
className="form-control"
placeholder="80"
validate={[port, required]}
validate={[validInstallPort, required]}
normalize={toNumber}
onChange={handleChange}
/>
@@ -220,7 +294,7 @@ class Settings extends Component {
<button
type="button"
className="btn btn-secondary btn-sm ml-2"
onClick={() => handleAutofix('dns', dnsIp, dnsPort)}
onClick={() => this.handleAutofix('dns')}
>
<Trans>fix</Trans>
</button>
@@ -237,6 +311,7 @@ class Settings extends Component {
<Trans>autofix_warning_result</Trans>
</p>
</div>
<hr className="divider--small" />
</Fragment>
}
</div>
@@ -253,6 +328,19 @@ class Settings extends Component {
</div>
</div>
</div>
<div className="setup__group">
<div className="setup__subtitle">
<Trans>static_ip</Trans>
</div>
<div className="mb-2">
<Trans>static_ip_desc</Trans>
</div>
{this.getStaticIpMessage(staticIp)}
</div>
<Controls invalid={invalid} />
</form>
);
@@ -262,7 +350,7 @@ class Settings extends Component {
Settings.propTypes = {
handleSubmit: PropTypes.func.isRequired,
handleChange: PropTypes.func,
handleAutofix: PropTypes.func,
handleFix: PropTypes.func.isRequired,
validateForm: PropTypes.func,
webIp: PropTypes.string.isRequired,
dnsIp: PropTypes.string.isRequired,
@@ -278,6 +366,7 @@ Settings.propTypes = {
interfaces: PropTypes.object.isRequired,
invalid: PropTypes.bool.isRequired,
initialValues: PropTypes.object,
t: PropTypes.func.isRequired,
};
const selector = formValueSelector('install');

View File

@@ -119,3 +119,8 @@
.setup__error {
margin: -5px 0 5px;
}
.divider--small {
margin-top: 1rem;
margin-bottom: 1rem;
}

View File

@@ -33,31 +33,19 @@ class Setup extends Component {
}
handleFormSubmit = (values) => {
this.props.setAllSettings(values);
const { staticIp, ...config } = values;
this.props.setAllSettings(config);
};
handleFormChange = debounce((values) => {
if (values && values.web.port && values.dns.port) {
this.props.checkConfig(values);
const { web, dns } = values;
if (values && web.port && dns.port) {
this.props.checkConfig({ web, dns, set_static_ip: false });
}
}, DEBOUNCE_TIMEOUT);
handleAutofix = (type, ip, port) => {
const data = {
ip,
port,
autofix: true,
};
if (type === 'web') {
this.props.checkConfig({
web: { ...data },
});
} else {
this.props.checkConfig({
dns: { ...data },
});
}
handleFix = (web, dns, set_static_ip) => {
this.props.checkConfig({ web, dns, set_static_ip });
};
openDashboard = (ip, port) => {
@@ -95,7 +83,7 @@ class Setup extends Component {
onSubmit={this.nextStep}
onChange={this.handleFormChange}
validateForm={this.handleFormChange}
handleAutofix={this.handleAutofix}
handleFix={this.handleFix}
/>
);
case 3:
@@ -117,6 +105,7 @@ class Setup extends Component {
step,
web,
dns,
staticIp,
interfaces,
} = this.props.install;
@@ -128,7 +117,7 @@ class Setup extends Component {
<div className="setup">
<div className="setup__container">
<img src={logo} className="setup__logo" alt="logo" />
{this.renderPage(step, { web, dns }, interfaces)}
{this.renderPage(step, { web, dns, staticIp }, interfaces)}
<Progress step={step} />
</div>
</div>

View File

@@ -32,9 +32,10 @@ const install = handleActions({
[actions.checkConfigSuccess]: (state, { payload }) => {
const web = { ...state.web, ...payload.web };
const dns = { ...state.dns, ...payload.dns };
const staticIp = { ...state.staticIp, ...payload.static_ip };
const newState = {
...state, web, dns, processingCheck: false,
...state, web, dns, staticIp, processingCheck: false,
};
return newState;
},
@@ -55,6 +56,11 @@ const install = handleActions({
status: '',
can_autofix: false,
},
staticIp: {
static: '',
ip: '',
error: '',
},
interfaces: {},
});