From 773e4fad36015e6657ea353b3a8c8109da83214f Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Tue, 23 Dec 2025 23:37:19 +0800 Subject: [PATCH] fix(ui): incorrect regexp to determine whether is a domain name --- .../access/forms/AccessConfigFieldsProviderRFC2136.tsx | 4 ++-- .../access/forms/AccessConfigFieldsProviderSSH.tsx | 4 ++-- .../workflow/designer/forms/BizApplyNodeConfigForm.tsx | 4 ++-- .../workflow/designer/forms/BizMonitorNodeConfigForm.tsx | 4 ++-- ui/src/utils/validator.ts | 8 ++++++-- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderRFC2136.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderRFC2136.tsx index 34924b075..dba269ab4 100644 --- a/ui/src/components/access/forms/AccessConfigFieldsProviderRFC2136.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderRFC2136.tsx @@ -3,7 +3,7 @@ import { Form, Input, InputNumber, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { isDomain, isIPv4, isIPv6, isPortNumber } from "@/utils/validator"; +import { isHostname, isPortNumber } from "@/utils/validator"; import { useFormNestedFieldsContext } from "./_context"; @@ -81,7 +81,7 @@ const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) = const { t } = i18n; return z.object({ - host: z.string().refine((v) => isDomain(v) || isIPv4(v) || isIPv6(v), t("common.errmsg.host_invalid")), + host: z.string().refine((v) => isHostname(v), t("common.errmsg.host_invalid")), port: z.coerce.number().refine((v) => isPortNumber(v), t("common.errmsg.port_invalid")), tsigAlgorithm: z.string().nonempty(t("access.form.rfc2136_tsig_algorithm.placeholder")), tsigKey: z.string().nullish(), diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderSSH.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderSSH.tsx index 5b0bc0aa0..67dc6fc58 100644 --- a/ui/src/components/access/forms/AccessConfigFieldsProviderSSH.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderSSH.tsx @@ -7,7 +7,7 @@ import { z } from "zod"; import FileTextInput from "@/components/FileTextInput"; import Show from "@/components/Show"; import { mergeCls } from "@/utils/css"; -import { isDomain, isIPv4, isIPv6, isPortNumber } from "@/utils/validator"; +import { isHostname, isPortNumber } from "@/utils/validator"; import { useFormNestedFieldsContext } from "./_context"; @@ -234,7 +234,7 @@ const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) = const baseSchema = z .object({ - host: z.string().refine((v) => isDomain(v) || isIPv4(v) || isIPv6(v), t("common.errmsg.host_invalid")), + host: z.string().refine((v) => isHostname(v), t("common.errmsg.host_invalid")), port: z.coerce.number().refine((v) => isPortNumber(v), t("common.errmsg.port_invalid")), authMethod: z.literal([AUTH_METHOD_NONE, AUTH_METHOD_PASSWORD, AUTH_METHOD_KEY], t("access.form.ssh_auth_method.placeholder")), username: z.string().nonempty(t("access.form.ssh_username.placeholder")), diff --git a/ui/src/components/workflow/designer/forms/BizApplyNodeConfigForm.tsx b/ui/src/components/workflow/designer/forms/BizApplyNodeConfigForm.tsx index b152c2b81..15307f2c8 100644 --- a/ui/src/components/workflow/designer/forms/BizApplyNodeConfigForm.tsx +++ b/ui/src/components/workflow/designer/forms/BizApplyNodeConfigForm.tsx @@ -25,7 +25,7 @@ import { useAccessesStore } from "@/stores/access"; import { useContactEmailsStore } from "@/stores/settings"; import { getErrMsg } from "@/utils/error"; import { matchSearchOption } from "@/utils/search"; -import { isDomain, isIPv4, isIPv6 } from "@/utils/validator"; +import { isDomain, isHostname } from "@/utils/validator"; import { FormNestedFieldsContextProvider, NodeFormContextProvider } from "./_context"; import BizApplyNodeConfigFieldsProvider from "./BizApplyNodeConfigFieldsProvider"; @@ -886,7 +886,7 @@ const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType }) return String(v) .split(MULTIPLE_INPUT_SEPARATOR) - .every((e) => isIPv4(e) || isIPv6(e) || isDomain(e)); + .every((e) => isHostname(e) || isDomain(e)); }, t("common.errmsg.host_invalid")), dnsPropagationWait: z.preprocess( (v) => (v == null || v === "" ? void 0 : Number(v)), diff --git a/ui/src/components/workflow/designer/forms/BizMonitorNodeConfigForm.tsx b/ui/src/components/workflow/designer/forms/BizMonitorNodeConfigForm.tsx index 1e1be7a2a..c9b0a981f 100644 --- a/ui/src/components/workflow/designer/forms/BizMonitorNodeConfigForm.tsx +++ b/ui/src/components/workflow/designer/forms/BizMonitorNodeConfigForm.tsx @@ -8,7 +8,7 @@ import { z } from "zod"; import Tips from "@/components/Tips"; import { type WorkflowNodeConfigForBizMonitor, defaultNodeConfigForBizMonitor } from "@/domain/workflow"; import { useAntdForm } from "@/hooks"; -import { isDomain, isIPv4, isIPv6, isPortNumber } from "@/utils/validator"; +import { isDomain, isHostname, isPortNumber } from "@/utils/validator"; import { NodeFormContextProvider } from "./_context"; import { NodeType } from "../nodes/typings"; @@ -90,7 +90,7 @@ const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType }) const { t } = i18n; return z.object({ - host: z.string().refine((v) => isDomain(v) || isIPv4(v) || isIPv6(v), t("common.errmsg.host_invalid")), + host: z.string().refine((v) => isHostname(v), t("common.errmsg.host_invalid")), port: z.coerce.number().refine((v) => isPortNumber(v), t("common.errmsg.port_invalid")), domain: z .string() diff --git a/ui/src/utils/validator.ts b/ui/src/utils/validator.ts index f3da667b4..02bf457b8 100644 --- a/ui/src/utils/validator.ts +++ b/ui/src/utils/validator.ts @@ -8,8 +8,8 @@ export const isCron = (value: string) => { export const isDomain = (value: string, { allowWildcard = false }: { allowWildcard?: boolean } = {}) => { const re = allowWildcard - ? /^(?:\*\.)?(?!-)[A-Za-z0-9-]{1,}(? { return z.email().safeParse(value).success; }; +export const isHostname = (value: string) => { + return isDomain(value, { allowWildcard: false }) || isIPv4(value) || isIPv6(value); +}; + export const isIPv4 = (value: string) => { return z.ipv4().safeParse(value).success; };