diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json
index 2bae1d12..36bd3501 100644
--- a/client/src/__locales/en.json
+++ b/client/src/__locales/en.json
@@ -210,5 +210,27 @@
"next": "Next",
"open_dashboard": "Open Dashboard",
"install_saved": "All settings saved",
+ "encryption_title": "Encryption",
+ "encryption_desc": "Encryption (HTTPS/TLS) support for both DNS and admin web interface",
+ "encryption_config_saved": "Encryption config saved",
+ "encryption_server": "Server name",
+ "encryption_server_enter": "Enter your domain name",
+ "encryption_server_desc": "In order to use HTTPS, you need yo enter the server name that matches your SSL certificate.",
+ "encryption_redirect": "Redirect to HTTPS automatically",
+ "encryption_redirect_desc": "If checked, AdGuard Home will automatically redirect you from HTTP to HTTPS addresses.",
+ "encryption_https": "HTTPS port",
+ "encryption_https_desc": "If HTTPS port is configured, AdGuard Home admin interface will be accessible via HTTPS, and it will also provide DNS-over-HTTPS on '\\dns-query' location.",
+ "encryption_dot": "DNS-over-TLS port",
+ "encryption_dot_desc": "If this port is configured, AdGuard Home will run a DNS-over-TLS server on this port.",
+ "encryption_certificates": "Certificates",
+ "encryption_certificates_desc": "In order to use encryption, you need to provide a valid SSL certificates chain for your domain. You can get a free certificate on letsencrypt.org or you can buy it from one of the trusted Certificate Authorities.",
+ "encryption_certificates_input": "Copy/paste your PEM-encoded cerificates here.",
+ "encryption_status": "Status",
+ "encryption_certificates_for": "Certificates for {{domains}}",
+ "encryption_expire": "Expire on {{date}}",
+ "encryption_key": "Private key",
+ "encryption_key_input": "Copy/paste your PEM-encoded private key for your cerficate here.",
+ "form_error_port_range": "Enter port value in the range of 80-65535",
+ "form_error_equal": "Shouldn't be equal",
"form_error_password": "Password mismatched"
}
\ No newline at end of file
diff --git a/client/src/actions/index.js b/client/src/actions/index.js
index 1bb99064..da33f0fe 100644
--- a/client/src/actions/index.js
+++ b/client/src/actions/index.js
@@ -650,3 +650,34 @@ export const toggleDhcp = config => async (dispatch) => {
}
}
};
+
+export const getTlsStatusRequest = createAction('GET_TLS_STATUS_REQUEST');
+export const getTlsStatusFailure = createAction('GET_TLS_STATUS_FAILURE');
+export const getTlsStatusSuccess = createAction('GET_TLS_STATUS_SUCCESS');
+
+export const getTlsStatus = () => async (dispatch) => {
+ dispatch(getTlsStatusRequest());
+ try {
+ const status = await apiClient.getTlsStatus();
+ dispatch(getTlsStatusSuccess(status));
+ } catch (error) {
+ dispatch(addErrorToast({ error }));
+ dispatch(getTlsStatusFailure());
+ }
+};
+
+export const setTlsConfigRequest = createAction('SET_TLS_CONFIG_REQUEST');
+export const setTlsConfigFailure = createAction('SET_TLS_CONFIG_FAILURE');
+export const setTlsConfigSuccess = createAction('SET_TLS_CONFIG_SUCCESS');
+
+export const setTlsConfig = config => async (dispatch) => {
+ dispatch(setTlsConfigRequest());
+ try {
+ await apiClient.setTlsConfig(config);
+ dispatch(setTlsConfigSuccess(config));
+ dispatch(addSuccessToast('encryption_config_saved'));
+ } catch (error) {
+ dispatch(addErrorToast({ error }));
+ dispatch(setTlsConfigFailure());
+ }
+};
diff --git a/client/src/api/Api.js b/client/src/api/Api.js
index 0dac781a..1971fe4a 100644
--- a/client/src/api/Api.js
+++ b/client/src/api/Api.js
@@ -354,4 +354,22 @@ export default class Api {
};
return this.makeRequest(path, method, parameters);
}
+
+ // DNS-over-HTTPS and DNS-over-TLS
+ TLS_STATUS = { path: 'tls/status', method: 'GET' };
+ TLS_CONFIG = { path: 'tls/configure', method: 'POST' };
+
+ getTlsStatus() {
+ const { path, method } = this.TLS_STATUS;
+ return this.makeRequest(path, method);
+ }
+
+ setTlsConfig(config) {
+ const { path, method } = this.TLS_CONFIG;
+ const parameters = {
+ data: config,
+ headers: { 'Content-Type': 'application/json' },
+ };
+ return this.makeRequest(path, method, parameters);
+ }
}
diff --git a/client/src/components/Settings/Dhcp/Form.js b/client/src/components/Settings/Dhcp/Form.js
index 5b810c7b..af7c1931 100644
--- a/client/src/components/Settings/Dhcp/Form.js
+++ b/client/src/components/Settings/Dhcp/Form.js
@@ -1,48 +1,10 @@
-import React, { Fragment } from 'react';
+import React from 'react';
import PropTypes from 'prop-types';
import { Field, reduxForm } from 'redux-form';
-import { withNamespaces, Trans } from 'react-i18next';
+import { withNamespaces } from 'react-i18next';
import flow from 'lodash/flow';
-import { R_IPV4 } from '../../../helpers/constants';
-
-const required = (value) => {
- if (value || value === 0) {
- return false;
- }
- return