From 5cc2567ba2f301da0e4e0145af32855d3172cbc9 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Wed, 3 Sep 2025 21:39:07 +0800 Subject: [PATCH] feat: optimize acmedns provider --- internal/certapply/applicators/sp_acmedns.go | 5 +- internal/domain/access.go | 5 +- internal/tools/mproc/sender.go | 6 +- .../acme-dns01/providers/acmedns/acmedns.go | 25 +++++--- ui/public/imgs/providers/acmedns.png | Bin 0 -> 4852 bytes ui/public/imgs/providers/acmedns.svg | 2 - .../AccessConfigFieldsProviderACMEDNS.tsx | 57 ++++++++---------- ui/src/domain/provider.ts | 2 +- ui/src/i18n/locales/en/nls.access.json | 15 ++--- ui/src/i18n/locales/en/nls.provider.json | 2 +- ui/src/i18n/locales/zh/nls.access.json | 15 ++--- ui/src/i18n/locales/zh/nls.provider.json | 2 +- 12 files changed, 65 insertions(+), 71 deletions(-) create mode 100644 ui/public/imgs/providers/acmedns.png delete mode 100644 ui/public/imgs/providers/acmedns.svg diff --git a/internal/certapply/applicators/sp_acmedns.go b/internal/certapply/applicators/sp_acmedns.go index e0814fc9..2a9ca423 100644 --- a/internal/certapply/applicators/sp_acmedns.go +++ b/internal/certapply/applicators/sp_acmedns.go @@ -18,9 +18,8 @@ func init() { } provider, err := acmedns.NewChallengeProvider(&acmedns.ChallengeProviderConfig{ - ApiBase: credentials.ApiBase, - StorageBaseUrl: credentials.StorageBaseUrl, - StoragePath: credentials.StoragePath, + ServerUrl: credentials.ServerUrl, + Credentials: credentials.Credentials, }) return provider, err }); err != nil { diff --git a/internal/domain/access.go b/internal/domain/access.go index 4debd7f8..d43462ed 100644 --- a/internal/domain/access.go +++ b/internal/domain/access.go @@ -33,9 +33,8 @@ type AccessConfigForACMECA struct { } type AccessConfigForACMEDNS struct { - ApiBase string `json:"apiBase"` - StorageBaseUrl string `json:"storageBaseUrl,omitempty"` - StoragePath string `json:"storagePath,omitempty"` + ServerUrl string `json:"serverUrl"` + Credentials string `json:"credentials"` } type AccessConfigForACMEHttpReq struct { diff --git a/internal/tools/mproc/sender.go b/internal/tools/mproc/sender.go index 822be69c..2a2f3add 100644 --- a/internal/tools/mproc/sender.go +++ b/internal/tools/mproc/sender.go @@ -41,7 +41,7 @@ func (s *sender[TIn, TOut]) SendWithContext(ctx context.Context, params *TIn) (* aesCryptor := xcrypto.NewAESCryptor(aesKey) // 准备临时输入文件 - tempIn, err := os.CreateTemp("", "certimate_mprocin_*.tmp") + tempIn, err := os.CreateTemp("", "certimate.mprocin_*.tmp") if err != nil { return nil, fmt.Errorf("failed to create temp input file: %w", err) } else { @@ -64,7 +64,7 @@ func (s *sender[TIn, TOut]) SendWithContext(ctx context.Context, params *TIn) (* defer os.Remove(tempIn.Name()) // 准备临时输出文件 - tempOut, err := os.CreateTemp("", "certimate_mprocout_*.tmp") + tempOut, err := os.CreateTemp("", "certimate.mprocout_*.tmp") if err != nil { return nil, fmt.Errorf("failed to create temp output file: %w", err) } else { @@ -73,7 +73,7 @@ func (s *sender[TIn, TOut]) SendWithContext(ctx context.Context, params *TIn) (* defer os.Remove(tempOut.Name()) // 准备临时错误文件 - tempErr, err := os.CreateTemp("", "certimate_mprocerr_*.tmp") + tempErr, err := os.CreateTemp("", "certimate.mprocerr_*.tmp") if err != nil { return nil, fmt.Errorf("failed to create temp error file: %w", err) } else { diff --git a/pkg/core/ssl-applicator/acme-dns01/providers/acmedns/acmedns.go b/pkg/core/ssl-applicator/acme-dns01/providers/acmedns/acmedns.go index 992766f8..33f95652 100644 --- a/pkg/core/ssl-applicator/acme-dns01/providers/acmedns/acmedns.go +++ b/pkg/core/ssl-applicator/acme-dns01/providers/acmedns/acmedns.go @@ -2,7 +2,8 @@ package acmedns import ( "errors" - "net/url" + "fmt" + "os" "github.com/go-acme/lego/v4/providers/dns/acmedns" @@ -10,9 +11,8 @@ import ( ) type ChallengeProviderConfig struct { - ApiBase string `json:"apiBase,omitempty"` - StorageBaseUrl string `json:"storageBaseUrl,omitempty"` - StoragePath string `json:"storagePath,omitempty"` + ServerUrl string `json:"serverUrl"` + Credentials string `json:"credentials"` } func NewChallengeProvider(config *ChallengeProviderConfig) (core.ACMEChallenger, error) { @@ -20,11 +20,20 @@ func NewChallengeProvider(config *ChallengeProviderConfig) (core.ACMEChallenger, return nil, errors.New("the configuration of the acme challenge provider is nil") } - ApiBase, _ := url.Parse(config.ApiBase) + tempfile, err := os.CreateTemp("", "certimate.acmedns_*.tmp") + if err != nil { + return nil, fmt.Errorf("failed to create temp credentials file: %w", err) + } else { + if _, err := tempfile.Write([]byte(config.Credentials)); err != nil { + return nil, fmt.Errorf("failed to write temp credentials file: %w", err) + } + + tempfile.Close() + } + providerConfig := acmedns.NewDefaultConfig() - providerConfig.APIBase = ApiBase.String() - providerConfig.StorageBaseURL = config.StorageBaseUrl - providerConfig.StoragePath = config.StoragePath + providerConfig.APIBase = config.ServerUrl + providerConfig.StoragePath = tempfile.Name() provider, err := acmedns.NewDNSProviderConfig(providerConfig) if err != nil { diff --git a/ui/public/imgs/providers/acmedns.png b/ui/public/imgs/providers/acmedns.png new file mode 100644 index 0000000000000000000000000000000000000000..9d0f5a9fea4de550f85edb006e7806707a8a764b GIT binary patch literal 4852 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 afB^uvSa~XS`(k+j0000 - diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderACMEDNS.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderACMEDNS.tsx index 3a0c21a1..c26cd012 100644 --- a/ui/src/components/access/forms/AccessConfigFieldsProviderACMEDNS.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderACMEDNS.tsx @@ -3,6 +3,8 @@ import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod/v4"; +import TextFileInput from "@/components/TextFileInput"; + import { useFormNestedFieldsContext } from "./_context"; const AccessConfigFieldsProviderACMEDNS = () => { @@ -18,33 +20,22 @@ const AccessConfigFieldsProviderACMEDNS = () => { return ( <> } > - + } + tooltip={} > - - - - } - > - + ); @@ -52,9 +43,8 @@ const AccessConfigFieldsProviderACMEDNS = () => { const getInitialValues = (): Nullish>> => { return { - apiBase: "https://auth.acme-dns.io/", - storageBaseUrl: "", - storagePath: "", + serverUrl: "https://auth.acme-dns.io/", + credentials: "", }; }; @@ -62,15 +52,20 @@ const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) = const { t } = i18n; return z.object({ - apiBase: z.url(t("common.errmsg.url_invalid")), - storageBaseUrl: z + serverUrl: z.url(t("common.errmsg.url_invalid")), + credentials: z .string() - .max(256, t("common.errmsg.string_max", { max: 256 })) - .nullish(), - storagePath: z - .string() - .max(256, t("common.errmsg.string_max", { max: 256 })) - .nullish(), + .max(20480, t("common.errmsg.string_max", { max: 20480 })) + .refine((v) => { + if (!v) return false; + + try { + const obj = JSON.parse(v); + return typeof obj === "object" && !Array.isArray(obj); + } catch { + return false; + } + }, t("access.form.acmedns_credentials.errmsg.json_invalid")), }); }; diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts index 4e2102e3..13bd180d 100644 --- a/ui/src/domain/provider.ts +++ b/ui/src/domain/provider.ts @@ -174,7 +174,7 @@ export const accessProvidersMap: Maphttps://go-acme.github.io/lego/dns/acme-dns/", - "access.form.acmedns_storage_base_url.label": "ACME-DNS Credentials URL PATH", - "access.form.acmedns_storage_base_url.placeholder": "Enter the URL path to the ACME-DNS JSON credentials JSON file. Each credentials are stored in a separate JSON file. This file will be used for TXT record updates.", - "access.form.acmedns_storage_base_url.tooltip": "For more information, see https://go-acme.github.io/lego/dns/acme-dns/", - "access.form.acmedns_storage_path.label": "ACME-DNS Credentials Local Path", - "access.form.acmedns_storage_path.placeholder": "Please enter the ACME-DNS JSON Credentials JSON File Path. Each credentials are in a separate JSON file. It will be used for TXT record updates.", - "access.form.acmedns_storage_path.tooltip": "For more information, see https://go-acme.github.io/lego/dns/acme-dns/", + "access.form.acmedns_server_url.label": "ACME-DNS server URL", + "access.form.acmedns_server_url.placeholder": "Please enter ACME-DNS server URL", + "access.form.acmedns_credentials.label": "ACME-DNS credentials", + "access.form.acmedns_credentials.placeholder": "Please enter ACME-DNS credentials", + "access.form.acmedns_credentials.tooltip": "For more information, see https://github.com/joohoi/acme-dns", + "access.form.acmedns_credentials.errmsg.json_invalid": "Please enter a valiod JSON string", "access.form.acmehttpreq_endpoint.label": "Endpoint", "access.form.acmehttpreq_endpoint.placeholder": "Please enter endpoint", "access.form.acmehttpreq_endpoint.tooltip": "For more information, see https://go-acme.github.io/lego/dns/httpreq/", diff --git a/ui/src/i18n/locales/en/nls.provider.json b/ui/src/i18n/locales/en/nls.provider.json index eb0b16b6..0607dbbf 100644 --- a/ui/src/i18n/locales/en/nls.provider.json +++ b/ui/src/i18n/locales/en/nls.provider.json @@ -3,7 +3,7 @@ "provider.1panel.console": "1Panel - Console itself", "provider.1panel.site": "1Panel - Website", "provider.acmeca": "ACME Custom CA Endpoint", - "provider.acmedns": "ACME DNS", + "provider.acmedns": "ACME-DNS", "provider.acmehttpreq": "ACME Custom HTTP Endpoint", "provider.aliyun": "Alibaba Cloud", "provider.aliyun.alb": "Alibaba Cloud - ALB (Application Load Balancer)", diff --git a/ui/src/i18n/locales/zh/nls.access.json b/ui/src/i18n/locales/zh/nls.access.json index 4d232911..d97447a7 100644 --- a/ui/src/i18n/locales/zh/nls.access.json +++ b/ui/src/i18n/locales/zh/nls.access.json @@ -58,15 +58,12 @@ "access.form.acmeca_eab_kid.placeholder": "请输入 ACME EAB KID", "access.form.acmeca_eab_hmac_key.label": "ACME EAB HMAC Key(可选)", "access.form.acmeca_eab_hmac_key.placeholder": "请输入 ACME EAB HMAC Key", - "access.form.acmedns_api_base.label": "ACME-DNS API 地址", - "access.form.acmedns_api_base.placeholder": "请输入 ACME-DNS API 地址", - "access.form.acmedns_api_base.tooltip": "这是什么?请参阅 https://go-acme.github.io/lego/dns/acme-dns/", - "access.form.acmedns_storage_base_url.label": "ACME-DNS JSON 帐户数据服务器", - "access.form.acmedns_storage_base_url.placeholder": "请输入 ACME-DNS JSON 帐户数据服务器地址", - "access.form.acmedns_storage_base_url.tooltip": "这是什么?请参阅 https://go-acme.github.io/lego/dns/acme-dns/", - "access.form.acmedns_storage_path.label": "ACME-DNS JSON 帐户数据文件", - "access.form.acmedns_storage_path.placeholder": "ACME-DNS JSON 帐户数据文件。每个域的帐户都将注册/保存到此文件,并用于 TXT 更新。", - "access.form.acmedns_storage_path.tooltip": "这是什么?请参阅 https://go-acme.github.io/lego/dns/acme-dns/", + "access.form.acmedns_server_url.label": "ACME-DNS 服务地址", + "access.form.acmedns_server_url.placeholder": "请输入 ACME-DNS 服务地址", + "access.form.acmedns_credentials.label": "ACME-DNS 凭证文件", + "access.form.acmedns_credentials.placeholder": "请输入 ACME-DNS 凭证文件", + "access.form.acmedns_credentials.tooltip": "这是什么?请参阅 https://github.com/joohoi/acme-dns", + "access.form.acmedns_credentials.errmsg.json_invalid": "请输入有效的 JSON 格式字符串", "access.form.acmehttpreq_endpoint.label": "服务端点", "access.form.acmehttpreq_endpoint.placeholder": "请输入服务端点", "access.form.acmehttpreq_endpoint.tooltip": "这是什么?请参阅 https://go-acme.github.io/lego/dns/httpreq/", diff --git a/ui/src/i18n/locales/zh/nls.provider.json b/ui/src/i18n/locales/zh/nls.provider.json index c4592212..2f1b6429 100644 --- a/ui/src/i18n/locales/zh/nls.provider.json +++ b/ui/src/i18n/locales/zh/nls.provider.json @@ -3,7 +3,7 @@ "provider.1panel.console": "1Panel - 面板自身", "provider.1panel.site": "1Panel - 网站", "provider.acmeca": "ACME 自定义 CA 端点", - "provider.acmedns": "ACME DNS", + "provider.acmedns": "ACME-DNS", "provider.acmehttpreq": "ACME 自定义 HTTP 端点", "provider.aliyun": "阿里云", "provider.aliyun.alb": "阿里云 - 应用型负载均衡 ALB",