diff --git a/internal/applicant/applicant.go b/internal/applicant/applicant.go index b70f216e..cdaab89e 100644 --- a/internal/applicant/applicant.go +++ b/internal/applicant/applicant.go @@ -7,6 +7,8 @@ import ( "crypto/rand" "errors" "fmt" + "os" + "strconv" "strings" "github.com/usual2970/certimate/internal/domain" @@ -63,12 +65,13 @@ type Certificate struct { } type ApplyOption struct { - Email string `json:"email"` - Domain string `json:"domain"` - Access string `json:"access"` - KeyAlgorithm string `json:"keyAlgorithm"` - Nameservers string `json:"nameservers"` - Timeout int64 `json:"timeout"` + Email string `json:"email"` + Domain string `json:"domain"` + Access string `json:"access"` + KeyAlgorithm string `json:"keyAlgorithm"` + Nameservers string `json:"nameservers"` + Timeout int64 `json:"timeout"` + DisableFollowCNAME bool `json:"disableFollowCNAME"` } type ApplyUser struct { @@ -115,12 +118,13 @@ func Get(record *models.Record) (Applicant, error) { } option := &ApplyOption{ - Email: applyConfig.Email, - Domain: record.GetString("domain"), - Access: access.GetString("config"), - KeyAlgorithm: applyConfig.KeyAlgorithm, - Nameservers: applyConfig.Nameservers, - Timeout: applyConfig.Timeout, + Email: applyConfig.Email, + Domain: record.GetString("domain"), + Access: access.GetString("config"), + KeyAlgorithm: applyConfig.KeyAlgorithm, + Nameservers: applyConfig.Nameservers, + Timeout: applyConfig.Timeout, + DisableFollowCNAME: applyConfig.DisableFollowCNAME, } switch access.GetString("configType") { @@ -177,6 +181,10 @@ func apply(option *ApplyOption, provider challenge.Provider) (*Certificate, erro return nil, err } + // Some unified lego environment variables are configured here. + // link: https://github.com/go-acme/lego/issues/1867 + os.Setenv("LEGO_DISABLE_CNAME_SUPPORT", strconv.FormatBool(option.DisableFollowCNAME)) + myUser := ApplyUser{ Email: option.Email, key: privateKey, diff --git a/internal/domain/domains.go b/internal/domain/domains.go index 97fa1d7d..7aaa9051 100644 --- a/internal/domain/domains.go +++ b/internal/domain/domains.go @@ -1,11 +1,12 @@ package domain type ApplyConfig struct { - Email string `json:"email"` - Access string `json:"access"` - KeyAlgorithm string `json:"keyAlgorithm"` - Nameservers string `json:"nameservers"` - Timeout int64 `json:"timeout"` + Email string `json:"email"` + Access string `json:"access"` + KeyAlgorithm string `json:"keyAlgorithm"` + Nameservers string `json:"nameservers"` + Timeout int64 `json:"timeout"` + DisableFollowCNAME bool `json:"disableFollowCNAME"` } type DeployConfig struct { diff --git a/ui/src/components/ui/tooltip.tsx b/ui/src/components/ui/tooltip.tsx index ed4fa100..54f6e5bb 100644 --- a/ui/src/components/ui/tooltip.tsx +++ b/ui/src/components/ui/tooltip.tsx @@ -24,4 +24,31 @@ const TooltipContent = React.forwardRef & { + contentView?: JSX.Element; + }; + +const TooltipLink = React.forwardRef((props: React.PropsWithChildren, forwardedRef: React.ForwardedRef) => ( + + {props.children} + +)); + +function TooltipFast({ children, contentView, open, defaultOpen, onOpenChange, ...props }: TooltipFastProps) { + return ( + + + + {children} + + + {contentView} + + + + ); +} + +export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, TooltipFast }; diff --git a/ui/src/domain/domain.ts b/ui/src/domain/domain.ts index f7a0a58f..6d31ee63 100644 --- a/ui/src/domain/domain.ts +++ b/ui/src/domain/domain.ts @@ -53,6 +53,7 @@ export type ApplyConfig = { keyAlgorithm?: string; nameservers?: string; timeout?: number; + disableFollowCNAME?: boolean; }; export type Statistic = { diff --git a/ui/src/i18n/locales/en/nls.domain.json b/ui/src/i18n/locales/en/nls.domain.json index f0c9c9a9..74e5ee57 100644 --- a/ui/src/i18n/locales/en/nls.domain.json +++ b/ui/src/i18n/locales/en/nls.domain.json @@ -41,6 +41,9 @@ "domain.application.form.key_algorithm.placeholder": "Please select certificate key algorithm", "domain.application.form.timeout.label": "DNS Propagation Timeout (Seconds)", "domain.application.form.timeoue.placeholder": "Please enter maximum waiting time for DNS propagation", + "domain.application.form.disable_follow_cname.label": "Disable DNS CNAME following", + "domain.application.form.disable_follow_cname.tips": "This option will disable Acme DNS authentication CNAME follow. If you don't understand this option, just keep it by default. ", + "domain.application.form.disable_follow_cname.tips_link": "Learn more", "domain.application.unsaved.message": "Please save applyment configuration first", "domain.deployment.tab": "Deploy Settings", diff --git a/ui/src/i18n/locales/zh/nls.domain.json b/ui/src/i18n/locales/zh/nls.domain.json index a550c5cd..62767c5d 100644 --- a/ui/src/i18n/locales/zh/nls.domain.json +++ b/ui/src/i18n/locales/zh/nls.domain.json @@ -41,6 +41,9 @@ "domain.application.form.key_algorithm.placeholder": "请选择数字证书算法", "domain.application.form.timeout.label": "DNS 传播检查超时时间(单位:秒)", "domain.application.form.timeoue.placeholder": "请输入 DNS 传播检查超时时间", + "domain.application.form.disable_follow_cname.label": "禁用 DNS CNAME 跟随", + "domain.application.form.disable_follow_cname.tips": "该选项将禁用 Acme DNS 认证 CNAME 跟随,如果你不了解此选项保持默认即可,", + "domain.application.form.disable_follow_cname.tips_link": "了解更多", "domain.application.unsaved.message": "请先保存申请配置", "domain.deployment.tab": "部署配置", diff --git a/ui/src/pages/domains/Edit.tsx b/ui/src/pages/domains/Edit.tsx index db5c65e0..dc1d2bb9 100644 --- a/ui/src/pages/domains/Edit.tsx +++ b/ui/src/pages/domains/Edit.tsx @@ -4,7 +4,7 @@ import { useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import z from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; -import { ChevronsUpDown, Plus } from "lucide-react"; +import { ChevronsUpDown, Plus, CircleHelp } from "lucide-react"; import { ClientResponseError } from "pocketbase"; import { Button } from "@/components/ui/button"; @@ -26,6 +26,8 @@ import { EmailsSetting } from "@/domain/settings"; import { DeployConfig, Domain } from "@/domain/domain"; import { save, get } from "@/repository/domains"; import { useConfig } from "@/providers/config"; +import { Switch } from "@/components/ui/switch"; +import { TooltipFast } from "@/components/ui/tooltip"; const Edit = () => { const { @@ -64,6 +66,7 @@ const Edit = () => { keyAlgorithm: z.string().optional(), nameservers: z.string().optional(), timeout: z.number().optional(), + disableFollowCNAME: z.boolean().optional(), }); const form = useForm>({ @@ -76,6 +79,7 @@ const Edit = () => { keyAlgorithm: "RSA2048", nameservers: "", timeout: 60, + disableFollowCNAME: true, }, }); @@ -89,6 +93,7 @@ const Edit = () => { keyAlgorithm: domain.applyConfig?.keyAlgorithm, nameservers: domain.applyConfig?.nameservers, timeout: domain.applyConfig?.timeout, + disableFollowCNAME: domain.applyConfig?.disableFollowCNAME, }); } }, [domain, form]); @@ -108,6 +113,7 @@ const Edit = () => { keyAlgorithm: data.keyAlgorithm, nameservers: data.nameservers, timeout: data.timeout, + disableFollowCNAME: data.disableFollowCNAME, }, }; @@ -176,7 +182,7 @@ const Edit = () => { <>
-
+
@@ -190,7 +196,7 @@ const Edit = () => {
-
+
{ name="email" render={({ field }) => ( - +
{t("domain.application.form.email.label") + " " + t("domain.application.form.email.tips")}
+
{t("common.add")}
@@ -293,11 +299,11 @@ const Edit = () => { name="access" render={({ field }) => ( - +
{t("domain.application.form.access.label")}
+
{t("common.add")}
@@ -344,8 +350,8 @@ const Edit = () => {
- {t("domain.application.form.advanced_settings.label")} - + {t("domain.application.form.advanced_settings.label")} +
@@ -424,6 +430,49 @@ const Edit = () => {
)} /> + + {/* 禁用 CNAME 跟随 */} + ( + + +
+ {t("domain.application.form.disable_follow_cname.label")} + + {t("domain.application.form.disable_follow_cname.tips")} + + {t("domain.application.form.disable_follow_cname.tips_link")} + +

+ } + > + +
+
+
+ +
+ { + form.setValue(field.name, value); + }} + /> +
+
+ +
+ )} + />