diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index 7830de81..7b166c3a 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -201,12 +201,12 @@ "install_auth_password_enter": "Enter password", "install_step": "Step", "install_devices_title": "Configure your devices", - "install_devices_desc": "In order for AdGuard Home to start working, you need to configure your devices to use it.", + "install_devices_desc": "To start using AdGuard Home, you need to configure your devices to use it.", "install_submit_title": "Congratulations!", "install_submit_desc": "The setup procedure is finished and you are ready to start using AdGuard Home.", "install_devices_router": "Router", "install_devices_router_desc": "This setup will automatically cover all the devices connected to your home router and you will not need to configure each of them manually.", - "install_devices_address": "AdGuard Home DNS server is listening to the following addresses", + "install_devices_address": "AdGuard Home DNS server is listening on the following addresses", "install_devices_router_list_1": "Open the preferences for your router. Usually, you can access it from your browser via a URL (like http:\/\/192.168.0.1\/ or http:\/\/192.168.1.1\/). You may be asked to enter the password. If you don't remember it, you can often reset the password by pressing a button on the router itself. Some routers require a specific application, which in that case should be already installed on your computer\/phone.", "install_devices_router_list_2": "Find the DHCP\/DNS settings. Look for the DNS letters next to a field which allows two or three sets of numbers, each broken into four groups of one to three digits.", "install_devices_router_list_3": "Enter your AdGuard Home server addresses there.", @@ -329,5 +329,6 @@ "setup_dns_privacy_other_2": "<0>dnsproxy</0> supports all known secure DNS protocols.", "setup_dns_privacy_other_3": "<0>dnscrypt-proxy</0> supports <1>DNS-over-HTTPS</1>.", "setup_dns_privacy_other_4": "<0>Mozilla Firefox</0> supports <1>DNS-over-HTTPS</1>.", - "setup_dns_privacy_other_5": "You will find more implementations <0>here</0> and <1>here</1>." + "setup_dns_privacy_other_5": "You will find more implementations <0>here</0> and <1>here</1>.", + "setup_dns_notice": "In order to use <1>DNS-over-HTTPS</1> or <1>DNS-over-TLS</1>, you need to <0>configure Encryption</0> in AdGuard Home settings." } \ No newline at end of file diff --git a/client/src/components/Settings/Encryption/Form.js b/client/src/components/Settings/Encryption/Form.js index 0b60271a..94e9923c 100644 --- a/client/src/components/Settings/Encryption/Form.js +++ b/client/src/components/Settings/Encryption/Form.js @@ -6,7 +6,7 @@ import { Trans, withNamespaces } from 'react-i18next'; import flow from 'lodash/flow'; import format from 'date-fns/format'; -import { renderField, renderSelectField, toNumber, port, isSafePort } from '../../../helpers/form'; +import { renderField, renderSelectField, toNumber, port, portTLS, isSafePort } from '../../../helpers/form'; import { EMPTY_DATE } from '../../../helpers/constants'; import i18n from '../../../i18n'; @@ -167,7 +167,7 @@ let Form = (props) => { type="number" className="form-control" placeholder={t('encryption_dot')} - validate={[port]} + validate={[portTLS]} normalize={toNumber} onChange={handleChange} disabled={!isEnabled} diff --git a/client/src/components/SetupGuide/index.js b/client/src/components/SetupGuide/index.js index 103f9fa5..4fb68d64 100644 --- a/client/src/components/SetupGuide/index.js +++ b/client/src/components/SetupGuide/index.js @@ -28,7 +28,7 @@ const SetupGuide = ({ {dnsAddresses.map(ip => <li key={ip}>{ip}</li>)} </div> </div> - <Guide /> + <Guide dnsAddresses={dnsAddresses} /> </Card> </div> ); diff --git a/client/src/components/ui/Guide.js b/client/src/components/ui/Guide.js index 640b114d..ba8eb54b 100644 --- a/client/src/components/ui/Guide.js +++ b/client/src/components/ui/Guide.js @@ -1,299 +1,372 @@ -import React from 'react'; +import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import { Trans, withNamespaces } from 'react-i18next'; import Tabs from '../ui/Tabs'; import Icons from '../ui/Icons'; -const Guide = props => ( - <div> - <Icons /> - <Tabs> - <div label="Router"> - <div className="tab__title"> - <Trans>install_devices_router</Trans> - </div> - <div className="tab__text"> - <p><Trans>install_devices_router_desc</Trans></p> - <ol> - <li><Trans>install_devices_router_list_1</Trans></li> - <li><Trans>install_devices_router_list_2</Trans></li> - <li><Trans>install_devices_router_list_3</Trans></li> - </ol> - </div> - </div> - <div label="Windows"> - <div className="tab__title"> - Windows - </div> - <div className="tab__text"> - <ol> - <li><Trans>install_devices_windows_list_1</Trans></li> - <li><Trans>install_devices_windows_list_2</Trans></li> - <li><Trans>install_devices_windows_list_3</Trans></li> - <li><Trans>install_devices_windows_list_4</Trans></li> - <li><Trans>install_devices_windows_list_5</Trans></li> - <li><Trans>install_devices_windows_list_6</Trans></li> - </ol> - </div> - </div> - <div label="macOS"> - <div className="tab__title"> - macOS - </div> - <div className="tab__text"> - <ol> - <li><Trans>install_devices_macos_list_1</Trans></li> - <li><Trans>install_devices_macos_list_2</Trans></li> - <li><Trans>install_devices_macos_list_3</Trans></li> - <li><Trans>install_devices_macos_list_4</Trans></li> - </ol> - </div> - </div> - <div label="Android"> - <div className="tab__title"> - Android - </div> - <div className="tab__text"> - <ol> - <li><Trans>install_devices_android_list_1</Trans></li> - <li><Trans>install_devices_android_list_2</Trans></li> - <li><Trans>install_devices_android_list_3</Trans></li> - <li><Trans>install_devices_android_list_4</Trans></li> - <li><Trans>install_devices_android_list_5</Trans></li> - </ol> - </div> - </div> - <div label="iOS"> - <div className="tab__title"> - iOS - </div> - <div className="tab__text"> - <ol> - <li><Trans>install_devices_ios_list_1</Trans></li> - <li><Trans>install_devices_ios_list_2</Trans></li> - <li><Trans>install_devices_ios_list_3</Trans></li> - <li><Trans>install_devices_ios_list_4</Trans></li> - </ol> - </div> - </div> - <div label="dns_privacy" title={props.t('dns_privacy')}> - <div className="tab__title"> - <Trans>dns_privacy</Trans> - </div> - <div className="tab__text"> - <div className="tab__paragraph"> - <Trans - values={{ address: window.location.hostname }} - components={[ - <strong key="0">text</strong>, - <code key="1">text</code>, - ]} - > - setup_dns_privacy_1 - </Trans> - </div> - <div className="tab__paragraph"> - <Trans - values={{ address: `https://${window.location.hostname}/dns-query` }} - components={[ - <strong key="0">text</strong>, - <code key="1">text</code>, - ]} - > - setup_dns_privacy_2 - </Trans> - </div> - <div className="tab__paragraph"> - <Trans - components={[ - <p key="0">text</p>, - ]} - > - setup_dns_privacy_3 - </Trans> - </div> - <div className="tab__paragraph"> - <strong>Android</strong> - <ul> - <li> - <Trans>setup_dns_privacy_android_1</Trans> - </li> - <li> - <Trans - components={[ - <a - href="https://adguard.com/adguard-android/overview.html" - target="_blank" - rel="noopener noreferrer" - key="0" - > - link - </a>, - <code key="1">text</code>, - ]} - > - setup_dns_privacy_android_2 - </Trans> - </li> - <li> - <Trans - components={[ - <a - href="https://getintra.org/" - target="_blank" - rel="noopener noreferrer" - key="0" - > - link - </a>, - <code key="1">text</code>, - ]} - > - setup_dns_privacy_android_3 - </Trans> - </li> - </ul> - </div> - <div className="tab__paragraph"> - <strong>iOS</strong> - <ul> - <li> - <Trans - components={[ - <a - href="https://itunes.apple.com/app/id1452162351" - target="_blank" - rel="noopener noreferrer" - key="0" - > - link - </a>, - <code key="1">text</code>, - <a - href="https://dnscrypt.info/stamps" - target="_blank" - rel="noopener noreferrer" - key="2" - > - link - </a>, - ]} - > - setup_dns_privacy_ios_1 - </Trans> - </li> - <li> - <Trans - components={[ - <a - href="https://adguard.com/adguard-ios/overview.html" - target="_blank" - rel="noopener noreferrer" - key="0" - > - link - </a>, - <code key="1">text</code>, - ]} - > - setup_dns_privacy_ios_2 - </Trans> - </li> - </ul> - </div> - <div className="tab__paragraph"> - <strong> - <Trans>setup_dns_privacy_other_title</Trans> - </strong> - <ul> - <li> - <Trans>setup_dns_privacy_other_1</Trans> - </li> - <li> - <Trans - components={[ - <a - href="https://github.com/AdguardTeam/dnsproxy" - target="_blank" - rel="noopener noreferrer" - key="0" - > - link - </a>, - ]} - > - setup_dns_privacy_other_2 - </Trans> - </li> - <li> - <Trans - components={[ - <a - href="https://github.com/jedisct1/dnscrypt-proxy" - target="_blank" - rel="noopener noreferrer" - key="0" - > - link - </a>, - <code key="1">text</code>, - ]} - > - setup_dns_privacy_other_3 - </Trans> - </li> - <li> - <Trans - components={[ - <a - href="https://www.mozilla.org/firefox/" - target="_blank" - rel="noopener noreferrer" - key="0" - > - link - </a>, - <code key="1">text</code>, - ]} - > - setup_dns_privacy_other_4 - </Trans> - </li> - <li> - <Trans - components={[ - <a - href="https://dnscrypt.info/implementations" - target="_blank" - rel="noopener noreferrer" - key="0" - > - link - </a>, - <a - href="https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Clients" - target="_blank" - rel="noopener noreferrer" - key="1" - > - link - </a>, - ]} - > - setup_dns_privacy_other_5 - </Trans> - </li> - </ul> - </div> - </div> - </div> - </Tabs> - </div> -); +const Guide = (props) => { + const { dnsAddresses } = props; + const tlsAddress = (dnsAddresses && dnsAddresses.filter(item => item.includes('tls://'))) || ''; + const httpsAddress = + (dnsAddresses && dnsAddresses.filter(item => item.includes('https://'))) || ''; + const showDnsPrivacyNotice = httpsAddress.length < 1 && tlsAddress.length < 1; + return ( + <div> + <Icons /> + <Tabs> + <div label="Router"> + <div className="tab__title"> + <Trans>install_devices_router</Trans> + </div> + <div className="tab__text"> + <p> + <Trans>install_devices_router_desc</Trans> + </p> + <ol> + <li> + <Trans>install_devices_router_list_1</Trans> + </li> + <li> + <Trans>install_devices_router_list_2</Trans> + </li> + <li> + <Trans>install_devices_router_list_3</Trans> + </li> + </ol> + </div> + </div> + <div label="Windows"> + <div className="tab__title">Windows</div> + <div className="tab__text"> + <ol> + <li> + <Trans>install_devices_windows_list_1</Trans> + </li> + <li> + <Trans>install_devices_windows_list_2</Trans> + </li> + <li> + <Trans>install_devices_windows_list_3</Trans> + </li> + <li> + <Trans>install_devices_windows_list_4</Trans> + </li> + <li> + <Trans>install_devices_windows_list_5</Trans> + </li> + <li> + <Trans>install_devices_windows_list_6</Trans> + </li> + </ol> + </div> + </div> + <div label="macOS"> + <div className="tab__title">macOS</div> + <div className="tab__text"> + <ol> + <li> + <Trans>install_devices_macos_list_1</Trans> + </li> + <li> + <Trans>install_devices_macos_list_2</Trans> + </li> + <li> + <Trans>install_devices_macos_list_3</Trans> + </li> + <li> + <Trans>install_devices_macos_list_4</Trans> + </li> + </ol> + </div> + </div> + <div label="Android"> + <div className="tab__title">Android</div> + <div className="tab__text"> + <ol> + <li> + <Trans>install_devices_android_list_1</Trans> + </li> + <li> + <Trans>install_devices_android_list_2</Trans> + </li> + <li> + <Trans>install_devices_android_list_3</Trans> + </li> + <li> + <Trans>install_devices_android_list_4</Trans> + </li> + <li> + <Trans>install_devices_android_list_5</Trans> + </li> + </ol> + </div> + </div> + <div label="iOS"> + <div className="tab__title">iOS</div> + <div className="tab__text"> + <ol> + <li> + <Trans>install_devices_ios_list_1</Trans> + </li> + <li> + <Trans>install_devices_ios_list_2</Trans> + </li> + <li> + <Trans>install_devices_ios_list_3</Trans> + </li> + <li> + <Trans>install_devices_ios_list_4</Trans> + </li> + </ol> + </div> + </div> + <div label="dns_privacy" title={props.t('dns_privacy')}> + <div className="tab__title"> + <Trans>dns_privacy</Trans> + </div> + <div className="tab__text"> + {tlsAddress && tlsAddress.length > 0 && ( + <div className="tab__paragraph"> + <Trans + values={{ address: tlsAddress[0] }} + components={[ + <strong key="0">text</strong>, + <code key="1">text</code>, + ]} + > + setup_dns_privacy_1 + </Trans> + </div> + )} + {httpsAddress && httpsAddress.length > 0 && ( + <div className="tab__paragraph"> + <Trans + values={{ address: `${httpsAddress[0]}/dns-query` }} + components={[ + <strong key="0">text</strong>, + <code key="1">text</code>, + ]} + > + setup_dns_privacy_2 + </Trans> + </div> + )} + {showDnsPrivacyNotice && ( + <div className="tab__paragraph"> + <Trans + components={[ + <a + href="https://github.com/AdguardTeam/AdguardHome/wiki/Encryption" + target="_blank" + rel="noopener noreferrer" + key="0" + > + link + </a>, + <code key="1">text</code>, + ]} + > + setup_dns_notice + </Trans> + </div> + )} + {!showDnsPrivacyNotice && ( + <Fragment> + <div className="tab__paragraph"> + <Trans components={[<p key="0">text</p>]}> + setup_dns_privacy_3 + </Trans> + </div> + <div className="tab__paragraph"> + <strong>Android</strong> + <ul> + <li> + <Trans>setup_dns_privacy_android_1</Trans> + </li> + <li> + <Trans + components={[ + <a + href="https://adguard.com/adguard-android/overview.html" + target="_blank" + rel="noopener noreferrer" + key="0" + > + link + </a>, + <code key="1">text</code>, + ]} + > + setup_dns_privacy_android_2 + </Trans> + </li> + <li> + <Trans + components={[ + <a + href="https://getintra.org/" + target="_blank" + rel="noopener noreferrer" + key="0" + > + link + </a>, + <code key="1">text</code>, + ]} + > + setup_dns_privacy_android_3 + </Trans> + </li> + </ul> + </div> + <div className="tab__paragraph"> + <strong>iOS</strong> + <ul> + <li> + <Trans + components={[ + <a + href="https://itunes.apple.com/app/id1452162351" + target="_blank" + rel="noopener noreferrer" + key="0" + > + link + </a>, + <code key="1">text</code>, + <a + href="https://dnscrypt.info/stamps" + target="_blank" + rel="noopener noreferrer" + key="2" + > + link + </a>, + ]} + > + setup_dns_privacy_ios_1 + </Trans> + </li> + <li> + <Trans + components={[ + <a + href="https://adguard.com/adguard-ios/overview.html" + target="_blank" + rel="noopener noreferrer" + key="0" + > + link + </a>, + <code key="1">text</code>, + ]} + > + setup_dns_privacy_ios_2 + </Trans> + </li> + </ul> + </div> + <div className="tab__paragraph"> + <strong> + <Trans>setup_dns_privacy_other_title</Trans> + </strong> + <ul> + <li> + <Trans>setup_dns_privacy_other_1</Trans> + </li> + <li> + <Trans + components={[ + <a + href="https://github.com/AdguardTeam/dnsproxy" + target="_blank" + rel="noopener noreferrer" + key="0" + > + link + </a>, + ]} + > + setup_dns_privacy_other_2 + </Trans> + </li> + <li> + <Trans + components={[ + <a + href="https://github.com/jedisct1/dnscrypt-proxy" + target="_blank" + rel="noopener noreferrer" + key="0" + > + link + </a>, + <code key="1">text</code>, + ]} + > + setup_dns_privacy_other_3 + </Trans> + </li> + <li> + <Trans + components={[ + <a + href="https://www.mozilla.org/firefox/" + target="_blank" + rel="noopener noreferrer" + key="0" + > + link + </a>, + <code key="1">text</code>, + ]} + > + setup_dns_privacy_other_4 + </Trans> + </li> + <li> + <Trans + components={[ + <a + href="https://dnscrypt.info/implementations" + target="_blank" + rel="noopener noreferrer" + key="0" + > + link + </a>, + <a + href="https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Clients" + target="_blank" + rel="noopener noreferrer" + key="1" + > + link + </a>, + ]} + > + setup_dns_privacy_other_5 + </Trans> + </li> + </ul> + </div> + </Fragment> + )} + </div> + </div> + </Tabs> + </div> + ); +}; + +Guide.defaultProps = { + dnsAddresses: [], +}; Guide.propTypes = { + dnsAddresses: PropTypes.array, t: PropTypes.func.isRequired, }; diff --git a/client/src/helpers/form.js b/client/src/helpers/form.js index 72397396..39c4b7aa 100644 --- a/client/src/helpers/form.js +++ b/client/src/helpers/form.js @@ -76,6 +76,15 @@ export const port = (value) => { return false; }; +export const portTLS = (value) => { + if (value === 0) { + return false; + } else if (value && (value < 80 || value > 65535)) { + return <Trans>form_error_port_range</Trans>; + } + return false; +}; + export const isSafePort = (value) => { if (UNSAFE_PORTS.includes(value)) { return <Trans>form_error_port_unsafe</Trans>;