From 5755cd888661ead17678a0421b9d71517659ab21 Mon Sep 17 00:00:00 2001 From: Hoan Luu Huu <110280845+xquanluu@users.noreply.github.com> Date: Thu, 15 Aug 2024 05:30:24 +0700 Subject: [PATCH] support admin settings private network CIDR (#447) * support admin settings private network CIDR * support admin settings private network CIDR * fix review comment --- src/api/types.ts | 7 ++-- .../views/settings/admin-settings.tsx | 40 ++++++++++++++++--- src/utils/index.ts | 16 ++++++++ 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/api/types.ts b/src/api/types.ts index e7f616e..7e5ddad 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -122,9 +122,10 @@ export interface ForgotPassword { } export interface SystemInformation { - domain_name: string; - sip_domain_name: string; - monitoring_domain_name: string; + domain_name: null | string; + sip_domain_name: null | string; + monitoring_domain_name: null | string; + private_network_cidr: null | string; } export interface TtsCache { diff --git a/src/containers/internal/views/settings/admin-settings.tsx b/src/containers/internal/views/settings/admin-settings.tsx index b035069..a373323 100644 --- a/src/containers/internal/views/settings/admin-settings.tsx +++ b/src/containers/internal/views/settings/admin-settings.tsx @@ -10,7 +10,7 @@ import { import { PasswordSettings, SystemInformation, TtsCache } from "src/api/types"; import { toastError, toastSuccess } from "src/store"; import { Selector } from "src/components/forms"; -import { hasValue } from "src/utils"; +import { hasValue, isvalidIpv4OrCidr } from "src/utils"; import { PASSWORD_LENGTHS_OPTIONS, PASSWORD_MIN } from "src/api/constants"; import { Modal } from "src/components"; @@ -25,6 +25,7 @@ export const AdminSettings = () => { const [requireDigit, setRequireDigit] = useState(false); const [requireSpecialCharacter, setRequireSpecialCharacter] = useState(false); const [domainName, setDomainName] = useState(""); + const [privateNetworkCidr, setPrivateNetworkCidr] = useState(""); const [sipDomainName, setSipDomainName] = useState(""); const [monitoringDomainName, setMonitoringDomainName] = useState(""); const [clearTtsCacheFlag, setClearTtsCacheFlag] = useState(false); @@ -44,10 +45,21 @@ export const AdminSettings = () => { const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); + if (privateNetworkCidr) { + const cidrs = privateNetworkCidr.split(","); + for (const cidr of cidrs) { + if (cidr && !isvalidIpv4OrCidr(cidr)) { + toastError(`Invalid private network CIDR "${cidr}"`); + return; + } + } + } + const systemInformationPayload: Partial = { - domain_name: domainName, - sip_domain_name: sipDomainName, - monitoring_domain_name: monitoringDomainName, + domain_name: domainName || null, + sip_domain_name: sipDomainName || null, + monitoring_domain_name: monitoringDomainName || null, + private_network_cidr: privateNetworkCidr || null, }; const passwordSettingsPayload: Partial = { min_password_length: minPasswordLength, @@ -61,7 +73,7 @@ export const AdminSettings = () => { .then(() => { passwordSettingsFetcher(); systemInformationFetcher(); - toastSuccess("Password settings successfully updated"); + toastSuccess("Admin settings updated successfully"); }) .catch((error) => { toastError(error.msg); @@ -78,11 +90,18 @@ export const AdminSettings = () => { setMinPasswordLength(passwordSettings.min_password_length); } } - if (hasValue(systemInformation)) { + if (systemInformation?.domain_name) { setDomainName(systemInformation.domain_name); + } + if (systemInformation?.sip_domain_name) { setSipDomainName(systemInformation.sip_domain_name); + } + if (systemInformation?.monitoring_domain_name) { setMonitoringDomainName(systemInformation.monitoring_domain_name); } + if (systemInformation?.private_network_cidr) { + setPrivateNetworkCidr(systemInformation.private_network_cidr); + } }, [passwordSettings, systemInformation]); return ( @@ -107,6 +126,15 @@ export const AdminSettings = () => { value={sipDomainName} onChange={(e) => setSipDomainName(e.target.value)} /> + + setPrivateNetworkCidr(e.target.value)} + /> { return type; }; +function isValidIPV4(ip: string): boolean { + const ipv4Pattern = + /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; + return ipv4Pattern.test(ip); +} + +function isValidCIDR(cidr: string): boolean { + const cidrPattern = + /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(\/([0-9]|[1-2][0-9]|3[0-2]))$/; + return cidrPattern.test(cidr); +} + +export function isvalidIpv4OrCidr(input: string): boolean { + return isValidIPV4(input) || isValidCIDR(input); +} + export const getObscured = (str: string, sub = 4, char = "*") => { const len = str.length - sub; const obscured = str.substring(0, len).replace(/[a-zA-Z0-9]/g, char);