+ client: Refactor DHCP settings
This commit is contained in:
committed by
Simon Zolin
parent
c9f58ce4a7
commit
1d35d73fc5
@@ -48,7 +48,6 @@ export const PRIVACY_POLICY_LINK = 'https://adguard.com/privacy/home.html';
|
||||
export const PORT_53_FAQ_LINK = 'https://github.com/AdguardTeam/AdGuardHome/wiki/FAQ#bindinuse';
|
||||
|
||||
export const ADDRESS_IN_USE_TEXT = 'address already in use';
|
||||
export const UBUNTU_SYSTEM_PORT = 53;
|
||||
|
||||
export const INSTALL_FIRST_STEP = 1;
|
||||
export const INSTALL_TOTAL_STEPS = 5;
|
||||
@@ -63,6 +62,8 @@ export const SETTINGS_NAMES = {
|
||||
export const STANDARD_DNS_PORT = 53;
|
||||
export const STANDARD_WEB_PORT = 80;
|
||||
export const STANDARD_HTTPS_PORT = 443;
|
||||
export const DNS_OVER_TLS_PORT = 853;
|
||||
export const MAX_PORT = 65535;
|
||||
|
||||
export const EMPTY_DATE = '0001-01-01T00:00:00Z';
|
||||
|
||||
@@ -144,7 +145,7 @@ export const UNSAFE_PORTS = [
|
||||
|
||||
export const ALL_INTERFACES_IP = '0.0.0.0';
|
||||
|
||||
export const DHCP_STATUS_RESPONSE = {
|
||||
export const STATUS_RESPONSE = {
|
||||
YES: 'yes',
|
||||
NO: 'no',
|
||||
ERROR: 'error',
|
||||
@@ -458,6 +459,12 @@ export const IP_MATCH_LIST_STATUS = {
|
||||
CIDR: 'CIDR', // the ip is in the specified CIDR range
|
||||
};
|
||||
|
||||
export const DHCP_FORM_NAMES = {
|
||||
DHCPv4: 'dhcpv4',
|
||||
DHCPv6: 'dhcpv6',
|
||||
DHCP_INTERFACES: 'dhcpInterfaces',
|
||||
};
|
||||
|
||||
export const FORM_NAME = {
|
||||
UPSTREAM: 'upstream',
|
||||
DOMAIN_CHECK: 'domainCheck',
|
||||
@@ -465,7 +472,6 @@ export const FORM_NAME = {
|
||||
REWRITES: 'rewrites',
|
||||
LOGS_FILTER: 'logsFilter',
|
||||
CLIENT: 'client',
|
||||
DHCP: 'dhcp',
|
||||
LEASE: 'lease',
|
||||
ACCESS: 'access',
|
||||
BLOCKING_MODE: 'blockingMode',
|
||||
@@ -477,9 +483,39 @@ export const FORM_NAME = {
|
||||
INSTALL: 'install',
|
||||
LOGIN: 'login',
|
||||
CACHE: 'cache',
|
||||
...DHCP_FORM_NAMES,
|
||||
};
|
||||
|
||||
export const SMALL_SCREEN_SIZE = 767;
|
||||
export const MEDIUM_SCREEN_SIZE = 1023;
|
||||
|
||||
export const SECONDS_IN_HOUR = 60 * 60;
|
||||
|
||||
export const SECONDS_IN_DAY = SECONDS_IN_HOUR * 24;
|
||||
|
||||
export const DHCP_VALUES_PLACEHOLDERS = {
|
||||
ipv4: {
|
||||
subnet_mask: '255.255.255.0',
|
||||
lease_duration: SECONDS_IN_DAY.toString(),
|
||||
},
|
||||
ipv6: {
|
||||
range_start: '2001::1',
|
||||
range_end: 'ff',
|
||||
lease_duration: SECONDS_IN_DAY.toString(),
|
||||
},
|
||||
};
|
||||
|
||||
export const DHCP_DESCRIPTION_PLACEHOLDERS = {
|
||||
ipv4: {
|
||||
gateway_ip: 'dhcp_form_gateway_input',
|
||||
subnet_mask: 'dhcp_form_subnet_input',
|
||||
range_start: 'dhcp_form_range_start',
|
||||
range_end: 'dhcp_form_range_end',
|
||||
lease_duration: 'dhcp_form_lease_input',
|
||||
},
|
||||
ipv6: {
|
||||
range_start: 'dhcp_form_range_start',
|
||||
range_end: 'dhcp_form_range_end',
|
||||
lease_duration: 'dhcp_form_lease_input',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Trans } from 'react-i18next';
|
||||
import classNames from 'classnames';
|
||||
import { createOnBlurHandler } from './helpers';
|
||||
import { R_UNIX_ABSOLUTE_PATH, R_WIN_ABSOLUTE_PATH } from './constants';
|
||||
|
||||
@@ -24,11 +26,12 @@ export const renderField = (props, elementType) => {
|
||||
step,
|
||||
onBlur,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
{element}
|
||||
{!disabled && touched && error
|
||||
&& <span className="form__message form__message--error">{error}</span>}
|
||||
&& <span className="form__message form__message--error"><Trans>{error}</Trans></span>}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -47,7 +50,7 @@ renderField.propTypes = {
|
||||
step: PropTypes.number,
|
||||
meta: PropTypes.shape({
|
||||
touched: PropTypes.bool,
|
||||
error: PropTypes.object,
|
||||
error: PropTypes.string,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
@@ -71,7 +74,7 @@ export const renderGroupField = ({
|
||||
const onBlur = (event) => createOnBlurHandler(event, input, normalizeOnBlur);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<>
|
||||
<div className="input-group">
|
||||
<input
|
||||
{...input}
|
||||
@@ -98,8 +101,8 @@ export const renderGroupField = ({
|
||||
}
|
||||
</div>
|
||||
{!disabled && touched && error
|
||||
&& <span className="form__message form__message--error">{error}</span>}
|
||||
</Fragment>
|
||||
&& <span className="form__message form__message--error"><Trans>{error}</Trans></span>}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -115,7 +118,7 @@ renderGroupField.propTypes = {
|
||||
removeField: PropTypes.func,
|
||||
meta: PropTypes.shape({
|
||||
touched: PropTypes.bool,
|
||||
error: PropTypes.object,
|
||||
error: PropTypes.string,
|
||||
}).isRequired,
|
||||
normalizeOnBlur: PropTypes.func,
|
||||
};
|
||||
@@ -137,7 +140,8 @@ export const renderRadioField = ({
|
||||
</label>
|
||||
{!disabled
|
||||
&& touched
|
||||
&& (error && <span className="form__message form__message--error">{error}</span>)}
|
||||
&& error
|
||||
&& <span className="form__message form__message--error"><Trans>{error}</Trans></span>}
|
||||
</Fragment>;
|
||||
|
||||
renderRadioField.propTypes = {
|
||||
@@ -147,11 +151,11 @@ renderRadioField.propTypes = {
|
||||
disabled: PropTypes.bool,
|
||||
meta: PropTypes.shape({
|
||||
touched: PropTypes.bool,
|
||||
error: PropTypes.object,
|
||||
error: PropTypes.string,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export const renderSelectField = ({
|
||||
export const renderCheckboxField = ({
|
||||
input,
|
||||
placeholder,
|
||||
subtitle,
|
||||
@@ -163,7 +167,8 @@ export const renderSelectField = ({
|
||||
}) => <>
|
||||
<label className={`checkbox ${modifier}`} onClick={onClick}>
|
||||
<span className="checkbox__marker" />
|
||||
<input {...input} type="checkbox" className="checkbox__input" disabled={disabled} checked={input.checked || checked}/>
|
||||
<input {...input} type="checkbox" className="checkbox__input" disabled={disabled}
|
||||
checked={input.checked || checked} />
|
||||
<span className="checkbox__label">
|
||||
<span className="checkbox__label-text checkbox__label-text--long">
|
||||
<span className="checkbox__label-title">{placeholder}</span>
|
||||
@@ -178,10 +183,11 @@ export const renderSelectField = ({
|
||||
</label>
|
||||
{!disabled
|
||||
&& touched
|
||||
&& error && <span className="form__message form__message--error">{error}</span>}
|
||||
&& error
|
||||
&& <span className="form__message form__message--error"><Trans>{error}</Trans></span>}
|
||||
</>;
|
||||
|
||||
renderSelectField.propTypes = {
|
||||
renderCheckboxField.propTypes = {
|
||||
input: PropTypes.object.isRequired,
|
||||
placeholder: PropTypes.string,
|
||||
subtitle: PropTypes.string,
|
||||
@@ -191,7 +197,37 @@ renderSelectField.propTypes = {
|
||||
checked: PropTypes.bool,
|
||||
meta: PropTypes.shape({
|
||||
touched: PropTypes.bool,
|
||||
error: PropTypes.object,
|
||||
error: PropTypes.string,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export const renderSelectField = ({
|
||||
input,
|
||||
meta: { touched, error },
|
||||
children,
|
||||
label,
|
||||
}) => {
|
||||
const showWarning = touched && error;
|
||||
const selectClass = classNames('form-control custom-select', {
|
||||
'select--no-warning': !showWarning,
|
||||
});
|
||||
|
||||
return <>
|
||||
{label && <label><Trans>{label}</Trans></label>}
|
||||
<select {...input} className={selectClass}>{children}</select>
|
||||
{showWarning
|
||||
&& <span className="form__message form__message--error form__message--left-pad"><Trans>{error}</Trans></span>}
|
||||
</>;
|
||||
};
|
||||
|
||||
renderSelectField.propTypes = {
|
||||
input: PropTypes.object.isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
label: PropTypes.string,
|
||||
children: PropTypes.oneOfType([PropTypes.array, PropTypes.element]).isRequired,
|
||||
meta: PropTypes.shape({
|
||||
touched: PropTypes.bool,
|
||||
error: PropTypes.string,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
@@ -218,7 +254,7 @@ export const renderServiceField = ({
|
||||
</svg>
|
||||
</label>
|
||||
{!disabled && touched && error
|
||||
&& <span className="form__message form__message--error">{error}</span>}
|
||||
&& <span className="form__message form__message--error"><Trans>{error}</Trans></span>}
|
||||
</Fragment>;
|
||||
|
||||
renderServiceField.propTypes = {
|
||||
@@ -229,10 +265,12 @@ renderServiceField.propTypes = {
|
||||
icon: PropTypes.string,
|
||||
meta: PropTypes.shape({
|
||||
touched: PropTypes.bool,
|
||||
error: PropTypes.object,
|
||||
error: PropTypes.string,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export const getLastIpv4Octet = (ipv4) => parseInt(ipv4.slice(ipv4.lastIndexOf('.') + 1), 10);
|
||||
|
||||
/**
|
||||
* @param value {string}
|
||||
* @returns {*|number}
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
DEFAULT_LANGUAGE,
|
||||
DEFAULT_TIME_FORMAT,
|
||||
DETAILED_DATE_FORMAT_OPTIONS,
|
||||
DHCP_VALUES_PLACEHOLDERS,
|
||||
FILTERED,
|
||||
FILTERED_STATUS,
|
||||
IP_MATCH_LIST_STATUS,
|
||||
@@ -190,7 +191,7 @@ export const captitalizeWords = (text) => text.split(/[ -_]/g)
|
||||
|
||||
export const getInterfaceIp = (option) => {
|
||||
const onlyIPv6 = option.ip_addresses.every((ip) => ip.includes(':'));
|
||||
let interfaceIP = option.ip_addresses[0];
|
||||
let [interfaceIP] = option.ip_addresses;
|
||||
|
||||
if (!onlyIPv6) {
|
||||
option.ip_addresses.forEach((ip) => {
|
||||
@@ -203,16 +204,9 @@ export const getInterfaceIp = (option) => {
|
||||
return interfaceIP;
|
||||
};
|
||||
|
||||
export const getIpList = (interfaces) => {
|
||||
let list = [];
|
||||
|
||||
Object.keys(interfaces)
|
||||
.forEach((item) => {
|
||||
list = [...list, ...interfaces[item].ip_addresses];
|
||||
});
|
||||
|
||||
return list.sort();
|
||||
};
|
||||
export const getIpList = (interfaces) => Object.values(interfaces)
|
||||
.reduce((acc, curr) => acc.concat(curr.ip_addresses), [])
|
||||
.sort();
|
||||
|
||||
export const getDnsAddress = (ip, port = '') => {
|
||||
const isStandardDnsPort = port === STANDARD_DNS_PORT;
|
||||
@@ -668,11 +662,12 @@ export const getLogsUrlParams = (search, response_status) => `?${queryString.str
|
||||
response_status,
|
||||
})}`;
|
||||
|
||||
export const processContent = (content) => (Array.isArray(content)
|
||||
? content.filter(([, value]) => value).reduce((acc, val) => acc.concat(val), [])
|
||||
: content
|
||||
);
|
||||
|
||||
export const processContent = (
|
||||
content,
|
||||
) => (Array.isArray(content)
|
||||
? content.filter(([, value]) => value)
|
||||
.reduce((acc, val) => acc.concat(val), [])
|
||||
: content);
|
||||
/**
|
||||
* @param object {object}
|
||||
* @param sortKey {string}
|
||||
@@ -746,3 +741,65 @@ export const sortIp = (a, b) => {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param ip {string}
|
||||
* @param gateway_ip {string}
|
||||
* @returns {{range_end: string, subnet_mask: string, range_start: string,
|
||||
* lease_duration: string, gateway_ip: string}}
|
||||
*/
|
||||
export const calculateDhcpPlaceholdersIpv4 = (ip, gateway_ip) => {
|
||||
const LAST_OCTET_IDX = 3;
|
||||
const LAST_OCTET_RANGE_START = 100;
|
||||
const LAST_OCTET_RANGE_END = 200;
|
||||
|
||||
const addr = ipaddr.parse(ip);
|
||||
addr.octets[LAST_OCTET_IDX] = LAST_OCTET_RANGE_START;
|
||||
const range_start = addr.toString();
|
||||
|
||||
addr.octets[LAST_OCTET_IDX] = LAST_OCTET_RANGE_END;
|
||||
const range_end = addr.toString();
|
||||
|
||||
const {
|
||||
subnet_mask,
|
||||
lease_duration,
|
||||
} = DHCP_VALUES_PLACEHOLDERS.ipv4;
|
||||
|
||||
return {
|
||||
gateway_ip: gateway_ip || ip,
|
||||
subnet_mask,
|
||||
range_start,
|
||||
range_end,
|
||||
lease_duration,
|
||||
};
|
||||
};
|
||||
|
||||
export const calculateDhcpPlaceholdersIpv6 = () => {
|
||||
const {
|
||||
range_start,
|
||||
range_end,
|
||||
lease_duration,
|
||||
} = DHCP_VALUES_PLACEHOLDERS.ipv6;
|
||||
|
||||
return {
|
||||
range_start,
|
||||
range_end,
|
||||
lease_duration,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Add ip_addresses property - concatenated ipv4_addresses and ipv6_addresses for every interface
|
||||
* @param interfaces
|
||||
* @param interfaces.ipv4_addresses {string[]}
|
||||
* @param interfaces.ipv6_addresses {string[]}
|
||||
* @returns interfaces Interfaces enriched with ip_addresses property
|
||||
*/
|
||||
export const enrichWithConcatenatedIpAddresses = (interfaces) => Object.entries(interfaces)
|
||||
.reduce((acc, [k, v]) => {
|
||||
const ipv4_addresses = v.ipv4_addresses ?? [];
|
||||
const ipv6_addresses = v.ipv6_addresses ?? [];
|
||||
|
||||
acc[k].ip_addresses = ipv4_addresses.concat(ipv6_addresses);
|
||||
return acc;
|
||||
}, interfaces);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Trans } from 'react-i18next';
|
||||
import React from 'react';
|
||||
import i18next from 'i18next';
|
||||
import {
|
||||
MAX_PORT,
|
||||
R_CIDR,
|
||||
R_CIDR_IPV6,
|
||||
R_HOST,
|
||||
@@ -9,10 +8,10 @@ import {
|
||||
R_IPV6,
|
||||
R_MAC,
|
||||
R_URL_REQUIRES_PROTOCOL,
|
||||
STANDARD_WEB_PORT,
|
||||
UNSAFE_PORTS,
|
||||
} from './constants';
|
||||
import { isValidAbsolutePath } from './form';
|
||||
|
||||
import { getLastIpv4Octet, isValidAbsolutePath } from './form';
|
||||
|
||||
// Validation functions
|
||||
// https://redux-form.com/8.3.0/examples/fieldlevelvalidation/
|
||||
@@ -26,7 +25,7 @@ export const validateRequiredValue = (value) => {
|
||||
if (formattedValue || formattedValue === 0 || (formattedValue && formattedValue.length !== 0)) {
|
||||
return undefined;
|
||||
}
|
||||
return <Trans>form_error_required</Trans>;
|
||||
return 'form_error_required';
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -35,11 +34,28 @@ export const validateRequiredValue = (value) => {
|
||||
*/
|
||||
export const getMaxValueValidator = (maximum) => (value) => {
|
||||
if (value && value > maximum) {
|
||||
i18next.t('value_not_larger_than', { maximum });
|
||||
return i18next.t('value_not_larger_than', { maximum });
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param value {string}
|
||||
* @returns {undefined|string}
|
||||
*/
|
||||
export const validateIpv4RangeEnd = (_, allValues) => {
|
||||
if (!allValues || !allValues.v4 || !allValues.v4.range_end || !allValues.v4.range_start) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const { range_end, range_start } = allValues.v4;
|
||||
|
||||
if (getLastIpv4Octet(range_end) <= getLastIpv4Octet(range_start)) {
|
||||
return 'range_end_error';
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param value {string}
|
||||
@@ -47,7 +63,7 @@ export const getMaxValueValidator = (maximum) => (value) => {
|
||||
*/
|
||||
export const validateIpv4 = (value) => {
|
||||
if (value && !R_IPV4.test(value)) {
|
||||
return <Trans>form_error_ip4_format</Trans>;
|
||||
return 'form_error_ip4_format';
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
@@ -63,12 +79,12 @@ export const validateClientId = (value) => {
|
||||
const formattedValue = value ? value.trim() : value;
|
||||
if (formattedValue && !(
|
||||
R_IPV4.test(formattedValue)
|
||||
|| R_IPV6.test(formattedValue)
|
||||
|| R_MAC.test(formattedValue)
|
||||
|| R_CIDR.test(formattedValue)
|
||||
|| R_CIDR_IPV6.test(formattedValue)
|
||||
|| R_IPV6.test(formattedValue)
|
||||
|| R_MAC.test(formattedValue)
|
||||
|| R_CIDR.test(formattedValue)
|
||||
|| R_CIDR_IPV6.test(formattedValue)
|
||||
)) {
|
||||
return <Trans>form_error_client_id_format</Trans>;
|
||||
return 'form_error_client_id_format';
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
@@ -79,7 +95,7 @@ export const validateClientId = (value) => {
|
||||
*/
|
||||
export const validateIpv6 = (value) => {
|
||||
if (value && !R_IPV6.test(value)) {
|
||||
return <Trans>form_error_ip6_format</Trans>;
|
||||
return 'form_error_ip6_format';
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
@@ -90,7 +106,7 @@ export const validateIpv6 = (value) => {
|
||||
*/
|
||||
export const validateIp = (value) => {
|
||||
if (value && !R_IPV4.test(value) && !R_IPV6.test(value)) {
|
||||
return <Trans>form_error_ip_format</Trans>;
|
||||
return 'form_error_ip_format';
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
@@ -101,76 +117,76 @@ export const validateIp = (value) => {
|
||||
*/
|
||||
export const validateMac = (value) => {
|
||||
if (value && !R_MAC.test(value)) {
|
||||
return <Trans>form_error_mac_format</Trans>;
|
||||
return 'form_error_mac_format';
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param value {string}
|
||||
* @param value {number}
|
||||
* @returns {undefined|string}
|
||||
*/
|
||||
export const validateIsPositiveValue = (value) => {
|
||||
if ((value || value === 0) && value <= 0) {
|
||||
return <Trans>form_error_positive</Trans>;
|
||||
return 'form_error_positive';
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param value {string}
|
||||
* @param value {number}
|
||||
* @returns {boolean|*}
|
||||
*/
|
||||
export const validateBiggerOrEqualZeroValue = (value) => {
|
||||
if (value < 0) {
|
||||
return <Trans>form_error_negative</Trans>;
|
||||
return 'form_error_negative';
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param value {string}
|
||||
* @param value {number}
|
||||
* @returns {undefined|string}
|
||||
*/
|
||||
export const validatePort = (value) => {
|
||||
if ((value || value === 0) && (value < 80 || value > 65535)) {
|
||||
return <Trans>form_error_port_range</Trans>;
|
||||
if ((value || value === 0) && (value < STANDARD_WEB_PORT || value > MAX_PORT)) {
|
||||
return 'form_error_port_range';
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param value {string}
|
||||
* @param value {number}
|
||||
* @returns {undefined|string}
|
||||
*/
|
||||
export const validateInstallPort = (value) => {
|
||||
if (value < 1 || value > 65535) {
|
||||
return <Trans>form_error_port</Trans>;
|
||||
if (value < 1 || value > MAX_PORT) {
|
||||
return 'form_error_port';
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param value {string}
|
||||
* @param value {number}
|
||||
* @returns {undefined|string}
|
||||
*/
|
||||
export const validatePortTLS = (value) => {
|
||||
if (value === 0) {
|
||||
return undefined;
|
||||
}
|
||||
if (value && (value < 80 || value > 65535)) {
|
||||
return <Trans>form_error_port_range</Trans>;
|
||||
if (value && (value < STANDARD_WEB_PORT || value > MAX_PORT)) {
|
||||
return 'form_error_port_range';
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param value {string}
|
||||
* @param value {number}
|
||||
* @returns {undefined|string}
|
||||
*/
|
||||
export const validateIsSafePort = (value) => {
|
||||
if (UNSAFE_PORTS.includes(value)) {
|
||||
return <Trans>form_error_port_unsafe</Trans>;
|
||||
return 'form_error_port_unsafe';
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
@@ -181,7 +197,7 @@ export const validateIsSafePort = (value) => {
|
||||
*/
|
||||
export const validateDomain = (value) => {
|
||||
if (value && !R_HOST.test(value)) {
|
||||
return <Trans>form_error_domain_format</Trans>;
|
||||
return 'form_error_domain_format';
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
@@ -192,7 +208,7 @@ export const validateDomain = (value) => {
|
||||
*/
|
||||
export const validateAnswer = (value) => {
|
||||
if (value && (!R_IPV4.test(value) && !R_IPV6.test(value) && !R_HOST.test(value))) {
|
||||
return <Trans>form_error_answer_format</Trans>;
|
||||
return 'form_error_answer_format';
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
@@ -203,7 +219,7 @@ export const validateAnswer = (value) => {
|
||||
*/
|
||||
export const validatePath = (value) => {
|
||||
if (value && !isValidAbsolutePath(value) && !R_URL_REQUIRES_PROTOCOL.test(value)) {
|
||||
return <Trans>form_error_url_or_path_format</Trans>;
|
||||
return 'form_error_url_or_path_format';
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user