From ea3dca79aa7caf658ba0928c009de056bb9b0de9 Mon Sep 17 00:00:00 2001 From: ssongliu <73214554+ssongliu@users.noreply.github.com> Date: Fri, 7 Jul 2023 17:41:13 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=B3=BB=E7=BB=9F=E6=AD=A3=E5=88=99?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=20ipv6=20(#1575)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/port-jump/index.vue | 6 +++- frontend/src/global/form-rules.ts | 34 +++++++++++++++++++ frontend/src/utils/util.ts | 27 +++++++++++++++ .../container/container/operate/index.vue | 4 +-- .../views/host/firewall/ip/operate/index.vue | 4 +-- .../host/firewall/port/operate/index.vue | 6 ++-- .../src/views/host/ssh/ssh/address/index.vue | 2 +- .../views/setting/panel/systemip/index.vue | 2 +- .../src/views/setting/safe/allowips/index.vue | 4 +-- .../config/safety/simple-list/index.vue | 4 +-- 10 files changed, 79 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/port-jump/index.vue b/frontend/src/components/port-jump/index.vue index ef9ca2fff..2a140ccd1 100644 --- a/frontend/src/components/port-jump/index.vue +++ b/frontend/src/components/port-jump/index.vue @@ -26,6 +26,7 @@ import { getSettingInfo } from '@/api/modules/setting'; import i18n from '@/lang'; import { MsgError } from '@/utils/message'; import { useRouter } from 'vue-router'; +import { checkIp } from '@/utils/util'; const router = useRouter(); const dialogVisiable = ref(); @@ -44,7 +45,10 @@ const acceptParams = async (params: DialogProps): Promise => { dialogVisiable.value = true; return; } - window.open(`http://${res.data.systemIP}:${params.port}`, '_blank'); + if (!checkIp(res.data.systemIP)) { + window.open(`http://${res.data.systemIP}:${params.port}`, '_blank'); + } + window.open(`http://[${res.data.systemIP}]:${params.port}`, '_blank'); }; const goRouter = async (path: string) => { diff --git a/frontend/src/global/form-rules.ts b/frontend/src/global/form-rules.ts index 2ad637d8d..fd9baf85d 100644 --- a/frontend/src/global/form-rules.ts +++ b/frontend/src/global/form-rules.ts @@ -15,6 +15,34 @@ const checkIp = (rule: any, value: any, callback: any) => { } }; +const checkIpV4V6 = (rule: any, value: any, callback: any) => { + if (value === '' || typeof value === 'undefined' || value == null) { + callback(new Error(i18n.global.t('commons.rule.requiredInput'))); + } else { + const IPv4SegmentFormat = '(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'; + const IPv4AddressFormat = `(${IPv4SegmentFormat}[.]){3}${IPv4SegmentFormat}`; + const IPv4AddressRegExp = new RegExp(`^${IPv4AddressFormat}$`); + const IPv6SegmentFormat = '(?:[0-9a-fA-F]{1,4})'; + const IPv6AddressRegExp = new RegExp( + '^(' + + `(?:${IPv6SegmentFormat}:){7}(?:${IPv6SegmentFormat}|:)|` + + `(?:${IPv6SegmentFormat}:){6}(?:${IPv4AddressFormat}|:${IPv6SegmentFormat}|:)|` + + `(?:${IPv6SegmentFormat}:){5}(?::${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,2}|:)|` + + `(?:${IPv6SegmentFormat}:){4}(?:(:${IPv6SegmentFormat}){0,1}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,3}|:)|` + + `(?:${IPv6SegmentFormat}:){3}(?:(:${IPv6SegmentFormat}){0,2}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,4}|:)|` + + `(?:${IPv6SegmentFormat}:){2}(?:(:${IPv6SegmentFormat}){0,3}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,5}|:)|` + + `(?:${IPv6SegmentFormat}:){1}(?:(:${IPv6SegmentFormat}){0,4}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,6}|:)|` + + `(?::((?::${IPv6SegmentFormat}){0,5}:${IPv4AddressFormat}|(?::${IPv6SegmentFormat}){1,7}|:))` + + ')(%[0-9a-zA-Z-.:]{1,})?$', + ); + if (!IPv4AddressRegExp.test(value) && !IPv6AddressRegExp.test(value) && value !== '') { + callback(new Error(i18n.global.t('commons.rule.ip'))); + } else { + callback(); + } + } +}; + const checkHost = (rule: any, value: any, callback: any) => { if (value === '' || typeof value === 'undefined' || value == null) { callback(new Error(i18n.global.t('commons.rule.requiredInput'))); @@ -353,6 +381,7 @@ interface CommonRule { number: FormItemRule; integerNumber: FormItemRule; ip: FormItemRule; + ipV4V6: FormItemRule; host: FormItemRule; illegal: FormItemRule; port: FormItemRule; @@ -457,6 +486,11 @@ export const Rules: CommonRule = { required: true, trigger: 'blur', }, + ipV4V6: { + validator: checkIpV4V6, + required: true, + trigger: 'blur', + }, host: { validator: checkHost, required: true, diff --git a/frontend/src/utils/util.ts b/frontend/src/utils/util.ts index 432a88a2b..44c06dcfe 100644 --- a/frontend/src/utils/util.ts +++ b/frontend/src/utils/util.ts @@ -185,6 +185,33 @@ export function checkIp(value: string): boolean { } } +export function checkIpV4V6(value: string): boolean { + if (value === '') { + return true; + } + const IPv4SegmentFormat = '(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'; + const IPv4AddressFormat = `(${IPv4SegmentFormat}[.]){3}${IPv4SegmentFormat}`; + const IPv4AddressRegExp = new RegExp(`^${IPv4AddressFormat}$`); + const IPv6SegmentFormat = '(?:[0-9a-fA-F]{1,4})'; + const IPv6AddressRegExp = new RegExp( + '^(' + + `(?:${IPv6SegmentFormat}:){7}(?:${IPv6SegmentFormat}|:)|` + + `(?:${IPv6SegmentFormat}:){6}(?:${IPv4AddressFormat}|:${IPv6SegmentFormat}|:)|` + + `(?:${IPv6SegmentFormat}:){5}(?::${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,2}|:)|` + + `(?:${IPv6SegmentFormat}:){4}(?:(:${IPv6SegmentFormat}){0,1}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,3}|:)|` + + `(?:${IPv6SegmentFormat}:){3}(?:(:${IPv6SegmentFormat}){0,2}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,4}|:)|` + + `(?:${IPv6SegmentFormat}:){2}(?:(:${IPv6SegmentFormat}){0,3}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,5}|:)|` + + `(?:${IPv6SegmentFormat}:){1}(?:(:${IPv6SegmentFormat}){0,4}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,6}|:)|` + + `(?::((?::${IPv6SegmentFormat}){0,5}:${IPv4AddressFormat}|(?::${IPv6SegmentFormat}){1,7}|:))` + + ')(%[0-9a-zA-Z-.:]{1,})?$', + ); + if (!IPv4AddressRegExp.test(value) && !IPv6AddressRegExp.test(value) && value !== '') { + return true; + } else { + return false; + } +} + export function checkPort(value: string): boolean { if (Number(value) <= 0) { return true; diff --git a/frontend/src/views/container/container/operate/index.vue b/frontend/src/views/container/container/operate/index.vue index 702e71d66..b0c27e9b0 100644 --- a/frontend/src/views/container/container/operate/index.vue +++ b/frontend/src/views/container/container/operate/index.vue @@ -225,7 +225,7 @@ import DrawerHeader from '@/components/drawer-header/index.vue'; import { listImage, listVolume, createContainer, updateContainer, loadResourceLimit } from '@/api/modules/container'; import { Container } from '@/api/interface/container'; import { MsgError, MsgSuccess } from '@/utils/message'; -import { checkIp, checkPort } from '@/utils/util'; +import { checkIpV4V6, checkPort } from '@/utils/util'; const loading = ref(false); interface DialogProps { @@ -406,7 +406,7 @@ const checkPortValid = () => { for (const port of dialogData.value.rowData!.exposedPorts) { if (port.host.indexOf(':') !== -1) { port.hostIP = port.host.split(':')[0]; - if (checkIp(port.hostIP)) { + if (checkIpV4V6(port.hostIP)) { MsgError(i18n.global.t('firewall.addressFormatError')); return false; } diff --git a/frontend/src/views/host/firewall/ip/operate/index.vue b/frontend/src/views/host/firewall/ip/operate/index.vue index da88fe6dd..8697c4d0e 100644 --- a/frontend/src/views/host/firewall/ip/operate/index.vue +++ b/frontend/src/views/host/firewall/ip/operate/index.vue @@ -48,7 +48,7 @@ import DrawerHeader from '@/components/drawer-header/index.vue'; import { MsgError, MsgSuccess } from '@/utils/message'; import { Host } from '@/api/interface/host'; import { operateIPRule, updateAddrRule } from '@/api/modules/host'; -import { checkIp, deepCopy } from '@/utils/util'; +import { checkIpV4V6, deepCopy } from '@/utils/util'; const loading = ref(); const oldRule = ref(); @@ -99,7 +99,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => { ips.push(dialogData.value.rowData.address); } for (const ip of ips) { - if (checkIp(ip)) { + if (checkIpV4V6(ip)) { MsgError(i18n.global.t('firewall.addressFormatError')); return; } diff --git a/frontend/src/views/host/firewall/port/operate/index.vue b/frontend/src/views/host/firewall/port/operate/index.vue index 085c8bba4..da27d1c30 100644 --- a/frontend/src/views/host/firewall/port/operate/index.vue +++ b/frontend/src/views/host/firewall/port/operate/index.vue @@ -73,7 +73,7 @@ import DrawerHeader from '@/components/drawer-header/index.vue'; import { MsgError, MsgSuccess } from '@/utils/message'; import { Host } from '@/api/interface/host'; import { operatePortRule, updatePortRule } from '@/api/modules/host'; -import { checkIp, checkPort, deepCopy } from '@/utils/util'; +import { checkIpV4V6, checkPort, deepCopy } from '@/utils/util'; const loading = ref(); const oldRule = ref(); @@ -126,12 +126,12 @@ const onSubmit = async (formEl: FormInstance | undefined) => { dialogData.value.rowData.address = ''; } else { if (dialogData.value.rowData.address.indexOf('/') !== -1) { - if (checkIp(dialogData.value.rowData.address.split('/')[0])) { + if (checkIpV4V6(dialogData.value.rowData.address.split('/')[0])) { MsgError(i18n.global.t('firewall.addressFormatError')); return; } } else { - if (checkIp(dialogData.value.rowData.address)) { + if (checkIpV4V6(dialogData.value.rowData.address)) { MsgError(i18n.global.t('firewall.addressFormatError')); return; } diff --git a/frontend/src/views/host/ssh/ssh/address/index.vue b/frontend/src/views/host/ssh/ssh/address/index.vue index 7aab962bf..279c76e96 100644 --- a/frontend/src/views/host/ssh/ssh/address/index.vue +++ b/frontend/src/views/host/ssh/ssh/address/index.vue @@ -13,7 +13,7 @@ - + diff --git a/frontend/src/views/setting/panel/systemip/index.vue b/frontend/src/views/setting/panel/systemip/index.vue index f3042079e..f66c2da52 100644 --- a/frontend/src/views/setting/panel/systemip/index.vue +++ b/frontend/src/views/setting/panel/systemip/index.vue @@ -7,7 +7,7 @@ - + diff --git a/frontend/src/views/setting/safe/allowips/index.vue b/frontend/src/views/setting/safe/allowips/index.vue index 3ebe5a647..6c0014808 100644 --- a/frontend/src/views/setting/safe/allowips/index.vue +++ b/frontend/src/views/setting/safe/allowips/index.vue @@ -36,7 +36,7 @@ import i18n from '@/lang'; import { MsgError, MsgSuccess } from '@/utils/message'; import { updateSetting } from '@/api/modules/setting'; import { ElMessageBox } from 'element-plus'; -import { checkIp } from '@/utils/util'; +import { checkIpV4V6 } from '@/utils/util'; import DrawerHeader from '@/components/drawer-header/index.vue'; const emit = defineEmits<{ (e: 'search'): void }>(); @@ -58,7 +58,7 @@ const onSave = async () => { let ips = allowIPs.value.split('\n'); for (const ip of ips) { if (ip) { - if (checkIp(ip) || ip === '0.0.0.0') { + if (checkIpV4V6(ip) || ip === '0.0.0.0') { MsgError(i18n.global.t('firewall.addressFormatError')); return false; } diff --git a/frontend/src/views/website/website/config/safety/simple-list/index.vue b/frontend/src/views/website/website/config/safety/simple-list/index.vue index 7422ed5b2..c096c1f14 100644 --- a/frontend/src/views/website/website/config/safety/simple-list/index.vue +++ b/frontend/src/views/website/website/config/safety/simple-list/index.vue @@ -36,7 +36,7 @@ import { GetWafConfig, UpdateWafEnable } from '@/api/modules/website'; import { computed, onMounted, reactive, ref } from 'vue'; import { SaveFileContent } from '@/api/modules/files'; import i18n from '@/lang'; -import { checkIp } from '@/utils/util'; +import { checkIpV4V6 } from '@/utils/util'; import { MsgSuccess } from '@/utils/message'; import { MsgError } from '@/utils/message'; @@ -127,7 +127,7 @@ const openCreate = () => { } if (req.value.rule.indexOf('ip') > -1) { for (const id in newIpArray) { - if (checkIp(newIpArray[id])) { + if (checkIpV4V6(newIpArray[id])) { MsgError(i18n.global.t('commons.rule.ipErr', [ipArray[id]])); return; }