From 77537e70050ec1c095ebe5657c8af607a5deb279 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Fri, 27 Dec 2024 09:50:54 +0800 Subject: [PATCH] refactor: rename `Timeout` to `PropagationTimeout` during ACME DNS-01 authentication --- internal/applicant/acmehttpreq.go | 4 +- internal/applicant/aliyun.go | 4 +- internal/applicant/applicant.go | 17 ++----- internal/applicant/aws.go | 4 +- internal/applicant/cloudflare.go | 4 +- internal/applicant/godaddy.go | 4 +- internal/applicant/huaweicloud.go | 4 +- internal/applicant/namedotcom.go | 4 +- internal/applicant/namesilo.go | 4 +- internal/applicant/powerdns.go | 4 +- internal/applicant/tencentcloud.go | 4 +- internal/applicant/volcengine.go | 4 +- internal/domain/domains.go | 2 +- ui/src/components/access/AccessEditModal.tsx | 11 +++-- ui/src/components/workflow/AddNode.tsx | 17 ++++--- .../workflow/node/ApplyNodeForm.tsx | 40 ++++++++++----- .../workflow/node/NotifyNodeForm.tsx | 2 +- .../components/workflow/run/WorkflowRuns.tsx | 8 +++ ui/src/i18n/locales/en/nls.domain.json | 49 ------------------- ui/src/i18n/locales/en/nls.workflow.json | 14 +++--- ui/src/i18n/locales/zh/nls.domain.json | 49 ------------------- ui/src/i18n/locales/zh/nls.workflow.json | 16 +++--- ui/src/stores/access/index.ts | 15 +++--- ui/src/stores/contact/index.ts | 23 ++++++++- 24 files changed, 127 insertions(+), 180 deletions(-) diff --git a/internal/applicant/acmehttpreq.go b/internal/applicant/acmehttpreq.go index b836b657..45141ee3 100644 --- a/internal/applicant/acmehttpreq.go +++ b/internal/applicant/acmehttpreq.go @@ -30,8 +30,8 @@ func (a *acmeHttpReqApplicant) Apply() (*Certificate, error) { config.Mode = access.Mode config.Username = access.Username config.Password = access.Password - if a.option.Timeout != 0 { - config.PropagationTimeout = time.Duration(a.option.Timeout) * time.Second + if a.option.PropagationTimeout != 0 { + config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second } provider, err := httpreq.NewDNSProviderConfig(config) diff --git a/internal/applicant/aliyun.go b/internal/applicant/aliyun.go index 82047dc6..7ab861c4 100644 --- a/internal/applicant/aliyun.go +++ b/internal/applicant/aliyun.go @@ -26,8 +26,8 @@ func (a *aliyunApplicant) Apply() (*Certificate, error) { config := alidns.NewDefaultConfig() config.APIKey = access.AccessKeyId config.SecretKey = access.AccessKeySecret - if a.option.Timeout != 0 { - config.PropagationTimeout = time.Duration(a.option.Timeout) * time.Second + if a.option.PropagationTimeout != 0 { + config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second } provider, err := alidns.NewDNSProviderConfig(config) diff --git a/internal/applicant/applicant.go b/internal/applicant/applicant.go index d2056863..409ec66c 100644 --- a/internal/applicant/applicant.go +++ b/internal/applicant/applicant.go @@ -67,8 +67,6 @@ var sslProviderUrls = map[string]string{ const defaultEmail = "536464346@qq.com" -const defaultTimeout = 60 - type Certificate struct { CertUrl string `json:"certUrl"` CertStableUrl string `json:"certStableUrl"` @@ -84,7 +82,7 @@ type ApplyOption struct { Access string `json:"access"` KeyAlgorithm string `json:"keyAlgorithm"` Nameservers string `json:"nameservers"` - Timeout int64 `json:"timeout"` + PropagationTimeout int64 `json:"propagationTimeout"` DisableFollowCNAME bool `json:"disableFollowCNAME"` } @@ -164,17 +162,13 @@ func Get(record *models.Record) (Applicant, error) { applyConfig.Email = defaultEmail } - if applyConfig.Timeout == 0 { - applyConfig.Timeout = defaultTimeout - } - option := &ApplyOption{ Email: applyConfig.Email, Domain: record.GetString("domain"), Access: access.GetString("config"), KeyAlgorithm: applyConfig.KeyAlgorithm, Nameservers: applyConfig.Nameservers, - Timeout: applyConfig.Timeout, + PropagationTimeout: applyConfig.PropagationTimeout, DisableFollowCNAME: applyConfig.DisableFollowCNAME, } @@ -190,18 +184,13 @@ func GetWithApplyNode(node *domain.WorkflowNode) (Applicant, error) { return nil, fmt.Errorf("access record not found: %w", err) } - timeout := node.GetConfigInt64("timeout") - if timeout == 0 { - timeout = defaultTimeout - } - applyConfig := &ApplyOption{ Email: node.GetConfigString("email"), Domain: node.GetConfigString("domain"), Access: access.Config, KeyAlgorithm: node.GetConfigString("keyAlgorithm"), Nameservers: node.GetConfigString("nameservers"), - Timeout: timeout, + PropagationTimeout: node.GetConfigInt64("propagationTimeout"), DisableFollowCNAME: node.GetConfigBool("disableFollowCNAME"), } diff --git a/internal/applicant/aws.go b/internal/applicant/aws.go index 7563fb59..672ebaa5 100644 --- a/internal/applicant/aws.go +++ b/internal/applicant/aws.go @@ -28,8 +28,8 @@ func (a *awsApplicant) Apply() (*Certificate, error) { config.SecretAccessKey = access.SecretAccessKey config.Region = access.Region config.HostedZoneID = access.HostedZoneId - if a.option.Timeout != 0 { - config.PropagationTimeout = time.Duration(a.option.Timeout) * time.Second + if a.option.PropagationTimeout != 0 { + config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second } provider, err := route53.NewDNSProviderConfig(config) diff --git a/internal/applicant/cloudflare.go b/internal/applicant/cloudflare.go index 55605f57..dc7f0194 100644 --- a/internal/applicant/cloudflare.go +++ b/internal/applicant/cloudflare.go @@ -25,8 +25,8 @@ func (a *cloudflareApplicant) Apply() (*Certificate, error) { config := cloudflare.NewDefaultConfig() config.AuthToken = access.DnsApiToken - if a.option.Timeout != 0 { - config.PropagationTimeout = time.Duration(a.option.Timeout) * time.Second + if a.option.PropagationTimeout != 0 { + config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second } provider, err := cloudflare.NewDNSProviderConfig(config) diff --git a/internal/applicant/godaddy.go b/internal/applicant/godaddy.go index 95a628df..fd079cd1 100644 --- a/internal/applicant/godaddy.go +++ b/internal/applicant/godaddy.go @@ -26,8 +26,8 @@ func (a *godaddyApplicant) Apply() (*Certificate, error) { config := godaddy.NewDefaultConfig() config.APIKey = access.ApiKey config.APISecret = access.ApiSecret - if a.option.Timeout != 0 { - config.PropagationTimeout = time.Duration(a.option.Timeout) * time.Second + if a.option.PropagationTimeout != 0 { + config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second } provider, err := godaddy.NewDNSProviderConfig(config) diff --git a/internal/applicant/huaweicloud.go b/internal/applicant/huaweicloud.go index a5ada431..a2f9fafe 100644 --- a/internal/applicant/huaweicloud.go +++ b/internal/applicant/huaweicloud.go @@ -33,8 +33,8 @@ func (a *huaweicloudApplicant) Apply() (*Certificate, error) { config.AccessKeyID = access.AccessKeyId config.SecretAccessKey = access.SecretAccessKey config.Region = region - if a.option.Timeout != 0 { - config.PropagationTimeout = time.Duration(a.option.Timeout) * time.Second + if a.option.PropagationTimeout != 0 { + config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second } provider, err := huaweicloud.NewDNSProviderConfig(config) diff --git a/internal/applicant/namedotcom.go b/internal/applicant/namedotcom.go index 5bcc39f2..e2ccdad9 100644 --- a/internal/applicant/namedotcom.go +++ b/internal/applicant/namedotcom.go @@ -25,8 +25,8 @@ func (a *nameDotComApplicant) Apply() (*Certificate, error) { config := namedotcom.NewDefaultConfig() config.Username = access.Username config.APIToken = access.ApiToken - if a.option.Timeout != 0 { - config.PropagationTimeout = time.Duration(a.option.Timeout) * time.Second + if a.option.PropagationTimeout != 0 { + config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second } provider, err := namedotcom.NewDNSProviderConfig(config) diff --git a/internal/applicant/namesilo.go b/internal/applicant/namesilo.go index 43c25ae6..4c45924c 100644 --- a/internal/applicant/namesilo.go +++ b/internal/applicant/namesilo.go @@ -25,8 +25,8 @@ func (a *namesiloApplicant) Apply() (*Certificate, error) { config := namesilo.NewDefaultConfig() config.APIKey = access.ApiKey - if a.option.Timeout != 0 { - config.PropagationTimeout = time.Duration(a.option.Timeout) * time.Second + if a.option.PropagationTimeout != 0 { + config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second } provider, err := namesilo.NewDNSProviderConfig(config) diff --git a/internal/applicant/powerdns.go b/internal/applicant/powerdns.go index 92567131..689dd7a5 100644 --- a/internal/applicant/powerdns.go +++ b/internal/applicant/powerdns.go @@ -28,8 +28,8 @@ func (a *powerdnsApplicant) Apply() (*Certificate, error) { host, _ := url.Parse(access.ApiUrl) config.Host = host config.APIKey = access.ApiKey - if a.option.Timeout != 0 { - config.PropagationTimeout = time.Duration(a.option.Timeout) * time.Second + if a.option.PropagationTimeout != 0 { + config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second } provider, err := pdns.NewDNSProviderConfig(config) diff --git a/internal/applicant/tencentcloud.go b/internal/applicant/tencentcloud.go index eb340d62..98f13a02 100644 --- a/internal/applicant/tencentcloud.go +++ b/internal/applicant/tencentcloud.go @@ -26,8 +26,8 @@ func (a *tencentcloudApplicant) Apply() (*Certificate, error) { config := tencentcloud.NewDefaultConfig() config.SecretID = access.SecretId config.SecretKey = access.SecretKey - if a.option.Timeout != 0 { - config.PropagationTimeout = time.Duration(a.option.Timeout) * time.Second + if a.option.PropagationTimeout != 0 { + config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second } provider, err := tencentcloud.NewDNSProviderConfig(config) diff --git a/internal/applicant/volcengine.go b/internal/applicant/volcengine.go index 5222d26f..3ed0fcf5 100644 --- a/internal/applicant/volcengine.go +++ b/internal/applicant/volcengine.go @@ -25,8 +25,8 @@ func (a *volcengineApplicant) Apply() (*Certificate, error) { config := volcengine.NewDefaultConfig() config.AccessKey = access.AccessKeyId config.SecretKey = access.SecretAccessKey - if a.option.Timeout != 0 { - config.PropagationTimeout = time.Duration(a.option.Timeout) * time.Second + if a.option.PropagationTimeout != 0 { + config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second } provider, err := volcengine.NewDNSProviderConfig(config) diff --git a/internal/domain/domains.go b/internal/domain/domains.go index f3d04a53..b1078df3 100644 --- a/internal/domain/domains.go +++ b/internal/domain/domains.go @@ -12,7 +12,7 @@ type ApplyConfig struct { Access string `json:"access"` KeyAlgorithm string `json:"keyAlgorithm"` Nameservers string `json:"nameservers"` - Timeout int64 `json:"timeout"` + PropagationTimeout int64 `json:"propagationTimeout"` DisableFollowCNAME bool `json:"disableFollowCNAME"` } diff --git a/ui/src/components/access/AccessEditModal.tsx b/ui/src/components/access/AccessEditModal.tsx index 8c1ff16c..7447bd7b 100644 --- a/ui/src/components/access/AccessEditModal.tsx +++ b/ui/src/components/access/AccessEditModal.tsx @@ -15,9 +15,10 @@ export type AccessEditModalProps = { preset: AccessEditFormProps["preset"]; trigger?: React.ReactElement; onOpenChange?: (open: boolean) => void; + onSubmit?: (record: AccessModel) => void; }; -const AccessEditModal = ({ data, loading, trigger, preset, ...props }: AccessEditModalProps) => { +const AccessEditModal = ({ data, loading, trigger, preset, onSubmit, ...props }: AccessEditModalProps) => { const { t } = useTranslation(); const [notificationApi, NotificationContextHolder] = notification.useNotification(); @@ -57,20 +58,24 @@ const AccessEditModal = ({ data, loading, trigger, preset, ...props }: AccessEdi } try { + let res: AccessModel; if (preset === "add") { if (data?.id) { throw "Invalid props: `data`"; } - await createAccess(formRef.current!.getFieldsValue() as AccessModel); + res = await createAccess(formRef.current!.getFieldsValue() as AccessModel); } else if (preset === "edit") { if (!data?.id) { throw "Invalid props: `data`"; } - await updateAccess({ ...data, ...formRef.current!.getFieldsValue() } as AccessModel); + res = await updateAccess({ ...data, ...formRef.current!.getFieldsValue() } as AccessModel); + } else { + throw "Invalid props: `preset`"; } + onSubmit?.(res); setOpen(false); } catch (err) { notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) }); diff --git a/ui/src/components/workflow/AddNode.tsx b/ui/src/components/workflow/AddNode.tsx index e747478d..66a7f612 100644 --- a/ui/src/components/workflow/AddNode.tsx +++ b/ui/src/components/workflow/AddNode.tsx @@ -1,11 +1,12 @@ -import { Plus } from "lucide-react"; -import { BrandNodeProps, NodeProps } from "./types"; -import { newWorkflowNode, workflowNodeDropdownList, WorkflowNodeType } from "@/domain/workflow"; -import { useZustandShallowSelector } from "@/hooks"; -import { useWorkflowStore } from "@/stores/workflow"; -import { Dropdown } from "antd"; -import DropdownMenuItemIcon from "./DropdownMenuItemIcon"; import { useTranslation } from "react-i18next"; +import { Dropdown } from "antd"; +import { Plus as PlusIcon } from "lucide-react"; + +import { useZustandShallowSelector } from "@/hooks"; +import { newWorkflowNode, workflowNodeDropdownList, WorkflowNodeType } from "@/domain/workflow"; +import { useWorkflowStore } from "@/stores/workflow"; +import { type BrandNodeProps, type NodeProps } from "./types"; +import DropdownMenuItemIcon from "./DropdownMenuItemIcon"; const AddNode = ({ data }: NodeProps | BrandNodeProps) => { const { t } = useTranslation(); @@ -56,7 +57,7 @@ const AddNode = ({ data }: NodeProps | BrandNodeProps) => { trigger={["click"]} >
- +
diff --git a/ui/src/components/workflow/node/ApplyNodeForm.tsx b/ui/src/components/workflow/node/ApplyNodeForm.tsx index bece3565..029d2501 100644 --- a/ui/src/components/workflow/node/ApplyNodeForm.tsx +++ b/ui/src/components/workflow/node/ApplyNodeForm.tsx @@ -1,9 +1,9 @@ import { memo, useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { useControllableValue } from "ahooks"; -import { AutoComplete, Button, Divider, Form, Input, InputNumber, Select, Switch, Typography, type AutoCompleteProps } from "antd"; +import { AutoComplete, Button, Divider, Form, Input, InputNumber, Select, Switch, Tooltip, Typography, type AutoCompleteProps } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { PlusOutlined as PlusOutlinedIcon } from "@ant-design/icons"; +import { PlusOutlined as PlusOutlinedIcon, QuestionCircleOutlined as QuestionCircleOutlinedIcon } from "@ant-design/icons"; import z from "zod"; import AccessEditModal from "@/components/access/AccessEditModal"; @@ -24,7 +24,8 @@ const initFormModel = (): WorkflowNodeConfig => { return { domain: "", keyAlgorithm: "RSA2048", - timeout: 60, + nameservers: "", + propagationTimeout: 60, disableFollowCNAME: true, }; }; @@ -32,6 +33,7 @@ const initFormModel = (): WorkflowNodeConfig => { const ApplyNodeForm = ({ data }: ApplyNodeFormProps) => { const { t } = useTranslation(); + const { addEmail } = useContactStore(); const { updateNode } = useWorkflowStore(useZustandShallowSelector(["updateNode"])); const { hidePanel } = usePanel(); @@ -59,7 +61,7 @@ const ApplyNodeForm = ({ data }: ApplyNodeFormProps) => { { message: t("common.errmsg.host_invalid") } ) .nullish(), - timeout: z.number().gte(1, t("workflow.nodes.apply.form.timeout.placeholder")).nullish(), + timeout: z.number().gte(1, t("workflow.nodes.apply.form.propagation_timeout.placeholder")).nullish(), disableFollowCNAME: z.boolean().nullish(), }); const formRule = createSchemaFieldRule(formSchema); @@ -71,6 +73,7 @@ const ApplyNodeForm = ({ data }: ApplyNodeFormProps) => { initialValues: data?.config ?? initFormModel(), onSubmit: async (values) => { await updateNode({ ...data, config: { ...values }, validated: true }); + await addEmail(values.email); hidePanel(); }, }); @@ -96,18 +99,31 @@ const ApplyNodeForm = ({ data }: ApplyNodeFormProps) => { - } + tooltip={} > diff --git a/ui/src/components/workflow/node/NotifyNodeForm.tsx b/ui/src/components/workflow/node/NotifyNodeForm.tsx index 48b92c24..aa1e604f 100644 --- a/ui/src/components/workflow/node/NotifyNodeForm.tsx +++ b/ui/src/components/workflow/node/NotifyNodeForm.tsx @@ -70,7 +70,7 @@ const NotifyNodeForm = ({ data }: NotifyNodeFormProps) => { -