Show list of addresses
This commit is contained in:
parent
f379d34813
commit
31b855f9ab
|
@ -164,10 +164,10 @@
|
|||
"install_settings_title": "Admin Web Interface",
|
||||
"install_settings_listen": "Listen interface",
|
||||
"install_settings_port": "Port",
|
||||
"install_settings_interface_link": "Your AdGuard Home admin web interface will be available on the following addresses: <0>{{link}}</0>",
|
||||
"install_settings_interface_link": "Your AdGuard Home admin web interface will be available on the following addresses:",
|
||||
"form_error_port": "Enter valid port value",
|
||||
"install_settings_dns": "DNS server",
|
||||
"install_settings_dns_desc": "You will need to configure your devices or router to use the DNS server at <0>{{ip}}</0>",
|
||||
"install_settings_dns_desc": "You will need to configure your devices or router to use the DNS server on the following addresses:",
|
||||
"install_settings_all_interfaces": "All interfaces",
|
||||
"install_auth_title": "Authentication",
|
||||
"install_auth_desc": "It is highly recommended to configure password authentication to your AdGuard Home admin web interface. Even if it is accessible only in your local network, it is still important to have it protected from unrestricted access.",
|
||||
|
|
|
@ -70,3 +70,5 @@ export const SETTINGS_NAMES = {
|
|||
parental: 'parental',
|
||||
safesearch: 'safesearch',
|
||||
};
|
||||
|
||||
export const STANDARD_DNS_PORT = 53;
|
||||
|
|
|
@ -4,7 +4,7 @@ import subHours from 'date-fns/sub_hours';
|
|||
import addHours from 'date-fns/add_hours';
|
||||
import round from 'lodash/round';
|
||||
|
||||
import { STATS_NAMES } from './constants';
|
||||
import { STATS_NAMES, STANDARD_DNS_PORT } from './constants';
|
||||
|
||||
export const formatTime = (time) => {
|
||||
const parsedTime = dateParse(time);
|
||||
|
@ -85,3 +85,46 @@ export const getPercent = (amount, number) => {
|
|||
};
|
||||
|
||||
export const captitalizeWords = text => text.split(/[ -_]/g).map(str => str.charAt(0).toUpperCase() + str.substr(1)).join(' ');
|
||||
|
||||
export const getInterfaceIp = (option) => {
|
||||
const onlyIPv6 = option.ip_addresses.every(ip => ip.includes(':'));
|
||||
let interfaceIP = option.ip_addresses[0];
|
||||
|
||||
if (!onlyIPv6) {
|
||||
option.ip_addresses.forEach((ip) => {
|
||||
if (!ip.includes(':')) {
|
||||
interfaceIP = ip;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return interfaceIP;
|
||||
};
|
||||
|
||||
export const getIpList = (interfaces) => {
|
||||
let list = [];
|
||||
|
||||
Object.keys(interfaces).forEach((item) => {
|
||||
list = [...list, ...interfaces[item].ip_addresses];
|
||||
});
|
||||
|
||||
return list.sort();
|
||||
};
|
||||
|
||||
export const getAddress = (ip, port = '', isDns = false) => {
|
||||
if (!port) {
|
||||
return isDns ? ip : `http://${ip}`;
|
||||
}
|
||||
|
||||
if (isDns) {
|
||||
if (ip.includes(':') && port !== STANDARD_DNS_PORT) {
|
||||
return `[${ip}]:${port}`;
|
||||
} else if (port !== STANDARD_DNS_PORT) {
|
||||
return `${ip}:${port}`;
|
||||
}
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
return ip.includes(':') ? `http://[${ip}]:${port}` : `http://${ip}:${port}`;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { getIpList, getAddress } from '../../helpers/helpers';
|
||||
|
||||
const AddressList = (props) => {
|
||||
let webAddress = getAddress(props.address, props.port);
|
||||
let dnsAddress = getAddress(props.address, props.port, true);
|
||||
|
||||
if (props.address === '0.0.0.0') {
|
||||
return getIpList(props.interfaces).map((ip) => {
|
||||
webAddress = getAddress(ip, props.port);
|
||||
dnsAddress = getAddress(ip, props.port, true);
|
||||
|
||||
if (props.isDns) {
|
||||
return (
|
||||
<li key={ip}>
|
||||
<strong>
|
||||
{dnsAddress}
|
||||
</strong>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<li key={ip}>
|
||||
<a href={webAddress}>
|
||||
{webAddress}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (props.isDns) {
|
||||
return (
|
||||
<strong>
|
||||
{dnsAddress}
|
||||
</strong>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<a href={webAddress}>
|
||||
{webAddress}
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
AddressList.propTypes = {
|
||||
interfaces: PropTypes.object.isRequired,
|
||||
address: PropTypes.string.isRequired,
|
||||
port: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.number,
|
||||
]),
|
||||
isDns: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default AddressList;
|
|
@ -4,26 +4,12 @@ import PropTypes from 'prop-types';
|
|||
import { Trans } from 'react-i18next';
|
||||
|
||||
import * as actionCreators from '../../actions/install';
|
||||
import { INSTALL_FIRST_STEP, INSTALL_TOTAL_STEPS } from '../../helpers/constants';
|
||||
|
||||
class Controls extends Component {
|
||||
nextStep = () => {
|
||||
if (this.props.step < INSTALL_TOTAL_STEPS) {
|
||||
this.props.nextStep();
|
||||
}
|
||||
}
|
||||
|
||||
prevStep = () => {
|
||||
if (this.props.step > INSTALL_FIRST_STEP) {
|
||||
this.props.prevStep();
|
||||
}
|
||||
}
|
||||
|
||||
renderPrevButton(step) {
|
||||
switch (step) {
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
|
@ -76,7 +62,7 @@ class Controls extends Component {
|
|||
<button
|
||||
type="button"
|
||||
className="btn btn-success btn-standard btn-lg"
|
||||
onClick={this.props.openDashboard}
|
||||
onClick={() => this.props.openDashboard(this.props.address)}
|
||||
>
|
||||
<Trans>open_dashboard</Trans>
|
||||
</button>
|
||||
|
@ -106,6 +92,7 @@ Controls.propTypes = {
|
|||
submitting: PropTypes.bool,
|
||||
invalid: PropTypes.bool,
|
||||
pristine: PropTypes.bool,
|
||||
address: PropTypes.string,
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
|
|
|
@ -8,6 +8,7 @@ import flow from 'lodash/flow';
|
|||
import Tabs from '../../components/ui/Tabs';
|
||||
import Icons from '../../components/ui/Icons';
|
||||
import Controls from './Controls';
|
||||
import AddressList from './AddressList';
|
||||
|
||||
let Devices = props => (
|
||||
<div className="setup__step">
|
||||
|
@ -20,8 +21,13 @@ let Devices = props => (
|
|||
<div className="mt-1">
|
||||
<Trans>install_devices_address</Trans>:
|
||||
</div>
|
||||
<div>
|
||||
<strong>{`${props.dnsIp}:${props.dnsPort}`}</strong>
|
||||
<div className="mt-1">
|
||||
<AddressList
|
||||
interfaces={props.interfaces}
|
||||
address={props.dnsIp}
|
||||
port={props.dnsPort}
|
||||
isDns={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Icons />
|
||||
|
@ -101,6 +107,7 @@ let Devices = props => (
|
|||
);
|
||||
|
||||
Devices.propTypes = {
|
||||
interfaces: PropTypes.object.isRequired,
|
||||
dnsIp: PropTypes.string.isRequired,
|
||||
dnsPort: PropTypes.number.isRequired,
|
||||
};
|
||||
|
|
|
@ -6,7 +6,9 @@ import { Trans, withNamespaces } from 'react-i18next';
|
|||
import flow from 'lodash/flow';
|
||||
|
||||
import Controls from './Controls';
|
||||
import AddressList from './AddressList';
|
||||
import renderField from './renderField';
|
||||
import { getInterfaceIp } from '../../helpers/helpers';
|
||||
|
||||
const required = (value) => {
|
||||
if (value || value === 0) {
|
||||
|
@ -28,20 +30,11 @@ const renderInterfaces = (interfaces => (
|
|||
Object.keys(interfaces).map((item) => {
|
||||
const option = interfaces[item];
|
||||
const { name } = option;
|
||||
const onlyIPv6 = option.ip_addresses.every(ip => ip.includes(':'));
|
||||
let interfaceIP = option.ip_addresses[0];
|
||||
|
||||
if (!onlyIPv6) {
|
||||
option.ip_addresses.forEach((ip) => {
|
||||
if (!ip.includes(':')) {
|
||||
interfaceIP = ip;
|
||||
}
|
||||
});
|
||||
}
|
||||
const ip = getInterfaceIp(option);
|
||||
|
||||
return (
|
||||
<option value={interfaceIP} key={name}>
|
||||
{name} - {interfaceIP}
|
||||
<option value={ip} key={name}>
|
||||
{name} - {ip}
|
||||
</option>
|
||||
);
|
||||
})
|
||||
|
@ -50,8 +43,8 @@ const renderInterfaces = (interfaces => (
|
|||
let Settings = (props) => {
|
||||
const {
|
||||
handleSubmit,
|
||||
interfaceIp,
|
||||
interfacePort,
|
||||
webIp,
|
||||
webPort,
|
||||
dnsIp,
|
||||
dnsPort,
|
||||
interfaces,
|
||||
|
@ -59,8 +52,6 @@ let Settings = (props) => {
|
|||
webWarning,
|
||||
dnsWarning,
|
||||
} = props;
|
||||
const dnsAddress = dnsPort && dnsPort !== 53 ? `${dnsIp}:${dnsPort}` : dnsIp;
|
||||
const interfaceAddress = interfacePort ? `http://${interfaceIp}:${interfacePort}` : `http://${interfaceIp}`;
|
||||
|
||||
return (
|
||||
<form className="setup__step" onSubmit={handleSubmit}>
|
||||
|
@ -104,12 +95,14 @@ let Settings = (props) => {
|
|||
</div>
|
||||
</div>
|
||||
<div className="setup__desc">
|
||||
<Trans
|
||||
components={[<a href={`http://${interfaceIp}`} key="0">link</a>]}
|
||||
values={{ link: interfaceAddress }}
|
||||
>
|
||||
install_settings_interface_link
|
||||
</Trans>
|
||||
<Trans>install_settings_interface_link</Trans>
|
||||
<div className="mt-1">
|
||||
<AddressList
|
||||
interfaces={interfaces}
|
||||
address={webIp}
|
||||
port={webPort}
|
||||
/>
|
||||
</div>
|
||||
{webWarning &&
|
||||
<div className="text-danger mt-2">
|
||||
{webWarning}
|
||||
|
@ -132,7 +125,7 @@ let Settings = (props) => {
|
|||
component="select"
|
||||
className="form-control custom-select"
|
||||
>
|
||||
<option value="0.0.0.0" defaultValue>
|
||||
<option value="0.0.0.0">
|
||||
<Trans>install_settings_all_interfaces</Trans>
|
||||
</option>
|
||||
{renderInterfaces(interfaces)}
|
||||
|
@ -157,12 +150,15 @@ let Settings = (props) => {
|
|||
</div>
|
||||
</div>
|
||||
<div className="setup__desc">
|
||||
<Trans
|
||||
components={[<strong key="0">ip</strong>]}
|
||||
values={{ ip: dnsAddress }}
|
||||
>
|
||||
install_settings_dns_desc
|
||||
</Trans>
|
||||
<Trans>install_settings_dns_desc</Trans>
|
||||
<div className="mt-1">
|
||||
<AddressList
|
||||
interfaces={interfaces}
|
||||
address={dnsIp}
|
||||
port={dnsPort}
|
||||
isDns={true}
|
||||
/>
|
||||
</div>
|
||||
{dnsWarning &&
|
||||
<div className="text-danger mt-2">
|
||||
{dnsWarning}
|
||||
|
@ -177,9 +173,9 @@ let Settings = (props) => {
|
|||
|
||||
Settings.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
interfaceIp: PropTypes.string.isRequired,
|
||||
webIp: PropTypes.string.isRequired,
|
||||
dnsIp: PropTypes.string.isRequired,
|
||||
interfacePort: PropTypes.oneOfType([
|
||||
webPort: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.number,
|
||||
]),
|
||||
|
@ -197,14 +193,14 @@ Settings.propTypes = {
|
|||
const selector = formValueSelector('install');
|
||||
|
||||
Settings = connect((state) => {
|
||||
const interfaceIp = selector(state, 'web.ip');
|
||||
const interfacePort = selector(state, 'web.port');
|
||||
const webIp = selector(state, 'web.ip');
|
||||
const webPort = selector(state, 'web.port');
|
||||
const dnsIp = selector(state, 'dns.ip');
|
||||
const dnsPort = selector(state, 'dns.port');
|
||||
|
||||
return {
|
||||
interfaceIp,
|
||||
interfacePort,
|
||||
webIp,
|
||||
webPort,
|
||||
dnsIp,
|
||||
dnsPort,
|
||||
};
|
||||
|
|
|
@ -6,6 +6,7 @@ import { Trans, withNamespaces } from 'react-i18next';
|
|||
import flow from 'lodash/flow';
|
||||
|
||||
import Controls from './Controls';
|
||||
import { getAddress } from '../../helpers/helpers';
|
||||
|
||||
let Submit = props => (
|
||||
<div className="setup__step">
|
||||
|
@ -17,33 +18,31 @@ let Submit = props => (
|
|||
<Trans>install_submit_desc</Trans>
|
||||
</p>
|
||||
</div>
|
||||
<form onSubmit={props.handleSubmit}>
|
||||
<Controls
|
||||
submitting={props.submitting}
|
||||
pristine={props.pristine}
|
||||
address={`http://${props.interfaceIp}`}
|
||||
openDashboard={props.openDashboard}
|
||||
address={getAddress(props.webIp, props.webPort)}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
|
||||
Submit.propTypes = {
|
||||
interfaceIp: PropTypes.string.isRequired,
|
||||
interfacePort: PropTypes.number.isRequired,
|
||||
webIp: PropTypes.string.isRequired,
|
||||
webPort: PropTypes.number.isRequired,
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
pristine: PropTypes.bool.isRequired,
|
||||
submitting: PropTypes.bool.isRequired,
|
||||
openDashboard: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
const selector = formValueSelector('install');
|
||||
|
||||
Submit = connect((state) => {
|
||||
const interfaceIp = selector(state, 'web.ip');
|
||||
const interfacePort = selector(state, 'web.port');
|
||||
const webIp = selector(state, 'web.ip');
|
||||
const webPort = selector(state, 'web.port');
|
||||
|
||||
return {
|
||||
interfaceIp,
|
||||
interfacePort,
|
||||
webIp,
|
||||
webPort,
|
||||
};
|
||||
})(Submit);
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@ class Setup extends Component {
|
|||
this.props.setAllSettings(values);
|
||||
};
|
||||
|
||||
openDashboard = () => {
|
||||
console.log('Open dashboard');
|
||||
openDashboard = (address) => {
|
||||
window.location.replace(address);
|
||||
}
|
||||
|
||||
nextStep = () => {
|
||||
|
@ -64,9 +64,9 @@ class Setup extends Component {
|
|||
<Auth onSubmit={this.handleFormSubmit} />
|
||||
);
|
||||
case 4:
|
||||
return <Devices />;
|
||||
return <Devices interfaces={interfaces} />;
|
||||
case 5:
|
||||
return <Submit onSubmit={this.openDashboard} />;
|
||||
return <Submit openDashboard={this.openDashboard} />;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue