mirror of
https://github.com/certimate-go/certimate.git
synced 2026-09-24 23:10:13 +08:00
Merge branch 'main' into dev
This commit is contained in:
@@ -35,6 +35,7 @@ require (
|
||||
github.com/blinkbean/dingtalk v1.1.3
|
||||
github.com/byteplus-sdk/byteplus-sdk-golang v1.0.56
|
||||
github.com/go-acme/lego/v4 v4.25.2
|
||||
github.com/go-cmd/cmd v1.4.3
|
||||
github.com/go-lark/lark v1.16.0
|
||||
github.com/go-resty/resty/v2 v2.16.5
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0
|
||||
@@ -65,6 +66,7 @@ require (
|
||||
github.com/volcengine/ve-tos-golang-sdk/v2 v2.7.21
|
||||
github.com/volcengine/volc-sdk-golang v1.0.219
|
||||
github.com/volcengine/volcengine-go-sdk v1.1.30
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0
|
||||
gitlab.ecloud.com/ecloud/ecloudsdkclouddns v1.0.1
|
||||
gitlab.ecloud.com/ecloud/ecloudsdkcore v1.0.0
|
||||
golang.org/x/crypto v0.41.0
|
||||
@@ -97,7 +99,6 @@ require (
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||
github.com/go-acme/alidns-20150109/v4 v4.5.10 // indirect
|
||||
github.com/go-acme/tencentclouddnspod v1.0.1208 // indirect
|
||||
github.com/go-cmd/cmd v1.4.3 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
@@ -127,6 +128,7 @@ require (
|
||||
github.com/namedotcom/go/v4 v4.0.2 // indirect
|
||||
github.com/nrdcg/bunny-go v0.0.0-20250327222614-988a091fc7ea // indirect
|
||||
github.com/nrdcg/desec v0.11.0 // indirect
|
||||
github.com/nrdcg/goacmedns v0.2.0 // indirect
|
||||
github.com/nrdcg/mailinabox v0.2.0 // indirect
|
||||
github.com/nrdcg/porkbun v0.4.0 // indirect
|
||||
github.com/peterhellberg/link v1.2.0 // indirect
|
||||
@@ -206,7 +208,7 @@ require (
|
||||
github.com/nrdcg/namesilo v0.2.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/spf13/cast v1.9.2 // indirect
|
||||
github.com/spf13/cobra v1.9.1 // indirect
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/pflag v1.0.9
|
||||
github.com/tjfoc/gmsm v1.4.1 // indirect
|
||||
golang.org/x/image v0.29.0 // indirect
|
||||
@@ -217,7 +219,7 @@ require (
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/term v0.34.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/time v0.12.0
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
golang.org/x/tools v0.36.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
|
||||
@@ -404,9 +404,8 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8Wd
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
|
||||
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
|
||||
@@ -691,6 +690,8 @@ github.com/nrdcg/bunny-go v0.0.0-20250327222614-988a091fc7ea h1:OSgRS4kqOs/WuxuF
|
||||
github.com/nrdcg/bunny-go v0.0.0-20250327222614-988a091fc7ea/go.mod h1:IDRRngAngb2eTEaWgpO0hukQFI/vJId46fT1KErMytA=
|
||||
github.com/nrdcg/desec v0.11.0 h1:XZVHy07sg12y8FozMp+l7XvzPsdzog0AYXuQMaHBsfs=
|
||||
github.com/nrdcg/desec v0.11.0/go.mod h1:5+4vyhMRTs49V9CNoODF/HwT8Mwxv9DJ6j+7NekUnBs=
|
||||
github.com/nrdcg/goacmedns v0.2.0 h1:ADMbThobzEMnr6kg2ohs4KGa3LFqmgiBA22/6jUWJR0=
|
||||
github.com/nrdcg/goacmedns v0.2.0/go.mod h1:T5o6+xvSLrQpugmwHvrSNkzWht0UGAwj2ACBMhh73Cg=
|
||||
github.com/nrdcg/mailinabox v0.2.0 h1:IKq8mfKiVwNW2hQii/ng1dJ4yYMMv3HAP3fMFIq2CFk=
|
||||
github.com/nrdcg/mailinabox v0.2.0/go.mod h1:0yxqeYOiGyxAu7Sb94eMxHPIOsPYXAjTeA9ZhePhGnc=
|
||||
github.com/nrdcg/namesilo v0.2.1 h1:kLjCjsufdW/IlC+iSfAqj0iQGgKjlbUUeDJio5Y6eMg=
|
||||
@@ -893,6 +894,8 @@ github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package applicators
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-acme/lego/v4/challenge"
|
||||
|
||||
"github.com/certimate-go/certimate/internal/domain"
|
||||
"github.com/certimate-go/certimate/pkg/core/ssl-applicator/acme-dns01/providers/acmedns"
|
||||
xmaps "github.com/certimate-go/certimate/pkg/utils/maps"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if err := ACMEDns01Registries.Register(domain.ACMEDns01ProviderTypeACMEDNS, func(options *ProviderFactoryOptions) (challenge.Provider, error) {
|
||||
credentials := domain.AccessConfigForACMEDNS{}
|
||||
if err := xmaps.Populate(options.ProviderAccessConfig, &credentials); err != nil {
|
||||
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
|
||||
}
|
||||
|
||||
provider, err := acmedns.NewChallengeProvider(&acmedns.ChallengeProviderConfig{
|
||||
ApiBase: credentials.ApiBase,
|
||||
StorageBaseUrl: credentials.StorageBaseUrl,
|
||||
StoragePath: credentials.StoragePath,
|
||||
})
|
||||
return provider, err
|
||||
}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -16,14 +16,16 @@ import (
|
||||
"github.com/go-acme/lego/v4/challenge/http01"
|
||||
"github.com/go-acme/lego/v4/log"
|
||||
"github.com/samber/lo"
|
||||
"github.com/xhit/go-str2duration/v2"
|
||||
|
||||
"github.com/certimate-go/certimate/internal/certapply/applicators"
|
||||
"github.com/certimate-go/certimate/internal/domain"
|
||||
)
|
||||
|
||||
type ObtainCertificateRequest struct {
|
||||
Domains []string
|
||||
KeyType certcrypto.KeyType
|
||||
Domains []string
|
||||
KeyType certcrypto.KeyType
|
||||
LifeTime string
|
||||
|
||||
// 提供商相关
|
||||
ChallengeType string
|
||||
@@ -155,6 +157,13 @@ func (c *ACMEClient) ObtainCertificate(request *ObtainCertificateRequest) (*Obta
|
||||
Profile: request.ACMEProfile,
|
||||
ReplacesCertID: lo.If(request.ARIReplacesAcctUrl == c.account.ACMEAcctUrl, request.ARIReplacesCertId).Else(""),
|
||||
}
|
||||
if request.LifeTime != "" {
|
||||
lifeTime, err := str2duration.ParseDuration(request.LifeTime)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid lifetime: %w", err)
|
||||
}
|
||||
req.NotAfter = time.Now().Add(lifeTime)
|
||||
}
|
||||
resp, err := c.client.Certificate.Obtain(req)
|
||||
if err != nil {
|
||||
ariErr := &acme.AlreadyReplacedError{}
|
||||
|
||||
@@ -32,6 +32,12 @@ type AccessConfigForACMECA struct {
|
||||
Endpoint string `json:"endpoint"`
|
||||
}
|
||||
|
||||
type AccessConfigForACMEDNS struct {
|
||||
ApiBase string `json:"apiBase"`
|
||||
StorageBaseUrl string `json:"storageBaseUrl,omitempty"`
|
||||
StoragePath string `json:"storagePath,omitempty"`
|
||||
}
|
||||
|
||||
type AccessConfigForACMEHttpReq struct {
|
||||
Endpoint string `json:"endpoint"`
|
||||
Mode string `json:"mode,omitempty"`
|
||||
|
||||
@@ -11,6 +11,7 @@ NOTICE: If you add new constant, please keep ASCII order.
|
||||
const (
|
||||
AccessProviderType1Panel = AccessProviderType("1panel")
|
||||
AccessProviderTypeACMECA = AccessProviderType("acmeca")
|
||||
AccessProviderTypeACMEDNS = AccessProviderType("acmedns")
|
||||
AccessProviderTypeACMEHttpReq = AccessProviderType("acmehttpreq")
|
||||
AccessProviderTypeAkamai = AccessProviderType("akamai") // Akamai(预留)
|
||||
AccessProviderTypeAliyun = AccessProviderType("aliyun")
|
||||
@@ -121,6 +122,7 @@ ACME DNS-01 提供商常量值。
|
||||
NOTICE: If you add new constant, please keep ASCII order.
|
||||
*/
|
||||
const (
|
||||
ACMEDns01ProviderTypeACMEDNS = ACMEDns01ProviderType(AccessProviderTypeACMEDNS)
|
||||
ACMEDns01ProviderTypeACMEHttpReq = ACMEDns01ProviderType(AccessProviderTypeACMEHttpReq)
|
||||
ACMEDns01ProviderTypeAliyun = ACMEDns01ProviderType(AccessProviderTypeAliyun) // 兼容旧值,等同于 [ACMEDns01ProviderTypeAliyunDNS]
|
||||
ACMEDns01ProviderTypeAliyunDNS = ACMEDns01ProviderType(AccessProviderTypeAliyun + "-dns")
|
||||
|
||||
@@ -150,6 +150,7 @@ func (c WorkflowNodeConfig) AsBizApply() WorkflowNodeConfigForBizApply {
|
||||
CAProvider: xmaps.GetString(c, "caProvider"),
|
||||
CAProviderAccessId: xmaps.GetString(c, "caProviderAccessId"),
|
||||
CAProviderConfig: xmaps.GetKVMapAny(c, "caProviderConfig"),
|
||||
LifeTime: xmaps.GetString(c, "lifeTime"),
|
||||
ACMEProfile: xmaps.GetString(c, "acmeProfile"),
|
||||
Nameservers: nameservers,
|
||||
DnsPropagationWait: xmaps.GetInt32(c, "dnsPropagationWait"),
|
||||
@@ -216,10 +217,11 @@ type WorkflowNodeConfigForBizApply struct {
|
||||
Provider string `json:"provider"` // 质询提供商
|
||||
ProviderAccessId string `json:"providerAccessId"` // 质询提供商授权记录 ID
|
||||
ProviderConfig map[string]any `json:"providerConfig,omitempty"` // 质询提供商额外配置
|
||||
KeyAlgorithm string `json:"keyAlgorithm,omitempty"` // 证书算法
|
||||
CAProvider string `json:"caProvider,omitempty"` // CA 提供商(零值时使用全局配置)
|
||||
CAProviderAccessId string `json:"caProviderAccessId,omitempty"` // CA 提供商授权记录 ID
|
||||
CAProviderConfig map[string]any `json:"caProviderConfig,omitempty"` // CA 提供商额外配置
|
||||
KeyAlgorithm string `json:"keyAlgorithm,omitempty"` // 证书算法
|
||||
LifeTime string `json:"lifeTime,omitempty"` // 证书有效期
|
||||
ACMEProfile string `json:"acmeProfile,omitempty"` // ACME Profiles Extension
|
||||
Nameservers []string `json:"nameservers,omitempty"` // DNS 服务器列表,以半角分号分隔
|
||||
DnsPropagationWait int32 `json:"dnsPropagationWait,omitempty"` // DNS 传播等待时间,等同于 lego 的 `--dns-propagation-wait` 参数
|
||||
|
||||
@@ -261,6 +261,7 @@ func (ne *bizApplyNodeExecutor) executeObtain(execCtx *NodeExecutionContext, nod
|
||||
DnsPropagationTimeout: nodeCfg.DnsPropagationTimeout,
|
||||
DnsTTL: nodeCfg.DnsTTL,
|
||||
HttpDelayWait: nodeCfg.HttpDelayWait,
|
||||
LifeTime: nodeCfg.LifeTime,
|
||||
ACMEProfile: nodeCfg.ACMEProfile,
|
||||
ARIReplacesAcctUrl: lo.If(lastCertificate == nil, "").
|
||||
ElseF(func() string {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package acmedns
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/url"
|
||||
|
||||
"github.com/go-acme/lego/v4/providers/dns/acmedns"
|
||||
|
||||
"github.com/certimate-go/certimate/pkg/core"
|
||||
)
|
||||
|
||||
type ChallengeProviderConfig struct {
|
||||
ApiBase string `json:"apiBase,omitempty"`
|
||||
StorageBaseUrl string `json:"storageBaseUrl,omitempty"`
|
||||
StoragePath string `json:"storagePath,omitempty"`
|
||||
}
|
||||
|
||||
func NewChallengeProvider(config *ChallengeProviderConfig) (core.ACMEChallenger, error) {
|
||||
if config == nil {
|
||||
return nil, errors.New("the configuration of the acme challenge provider is nil")
|
||||
}
|
||||
|
||||
ApiBase, _ := url.Parse(config.ApiBase)
|
||||
providerConfig := acmedns.NewDefaultConfig()
|
||||
providerConfig.APIBase = ApiBase.String()
|
||||
providerConfig.StorageBaseURL = config.StorageBaseUrl
|
||||
providerConfig.StoragePath = config.StoragePath
|
||||
|
||||
provider, err := acmedns.NewDNSProviderConfig(providerConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return provider, nil
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<svg viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" height="200" width="200">
|
||||
<circle style="fill:#32BEA6;" cx="256" cy="256" r="256"/><g><path style="fill:#FFFFFF;" d="M58.016,202.296h18.168v42.48h0.296c2.192-3.368,5.128-6.152,8.936-8.2 c3.512-2.056,7.76-3.224,12.304-3.224c12.16,0,24.896,8.064,24.896,30.912v42.04H104.6v-39.992c0-10.4-3.808-18.168-13.776-18.168 c-7.032,0-12.008,4.688-13.912,10.112c-0.584,1.472-0.728,3.368-0.728,5.424v42.624H58.016V202.296z"/><path style="fill:#FFFFFF;" d="M161.76,214.6v20.368h17.144v13.48H161.76v31.496c0,8.64,2.344,13.176,9.224,13.176 c3.08,0,5.424-0.44,7.032-0.872l0.296,13.768c-2.64,1.032-7.328,1.768-13.04,1.768c-6.584,0-12.16-2.2-15.52-5.856 c-3.816-4.112-5.568-10.544-5.568-19.92v-33.544h-10.248V234.96h10.248v-16.12L161.76,214.6z"/><path style="fill:#FFFFFF;" d="M213.192,214.6v20.368h17.144v13.48h-17.144v31.496c0,8.64,2.344,13.176,9.224,13.176 c3.08,0,5.424-0.44,7.032-0.872l0.296,13.768c-2.64,1.032-7.328,1.768-13.04,1.768c-6.584,0-12.16-2.2-15.52-5.856 c-3.816-4.112-5.568-10.544-5.568-19.92v-33.544h-10.248V234.96h10.248v-16.12L213.192,214.6z"/><path style="fill:#FFFFFF;" d="M243.984,258.688c0-9.376-0.296-16.992-0.592-23.728h15.832l0.872,10.984h0.296 c5.264-8.056,13.616-12.6,24.464-12.6c16.408,0,30.024,14.064,30.024,36.328c0,25.784-16.256,38.232-32.512,38.232 c-8.936,0-16.408-3.808-20.072-9.512H262v36.904h-18.016V258.688z M262,276.416c0,1.76,0.144,3.368,0.584,4.976 c1.76,7.328,8.2,12.6,15.824,12.6c11.424,0,18.168-9.52,18.168-23.584c0-12.592-6.16-22.848-17.728-22.848 c-7.472,0-14.36,5.424-16.112,13.336c-0.448,1.464-0.736,3.072-0.736,4.536L262,276.416L262,276.416z"/><path style="fill:#FFFFFF;" d="M327.504,247.12c0-6.744,4.688-11.568,11.136-11.568c6.592,0,10.984,4.832,11.136,11.568 c0,6.592-4.392,11.432-11.136,11.432C332.048,258.552,327.504,253.712,327.504,247.12z M327.504,296.488 c0-6.744,4.688-11.576,11.136-11.576c6.592,0,10.984,4.688,11.136,11.576c0,6.448-4.392,11.424-11.136,11.424 C332.048,307.912,327.504,302.936,327.504,296.488z"/><path style="fill:#FFFFFF;" d="M355.8,312.16l35.744-106.2h12.6l-35.752,106.2H355.8z"/><path style="fill:#FFFFFF;" d="M405.176,312.16l35.744-106.2h12.592l-35.728,106.2H405.176z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -13,6 +13,7 @@ import { FormNestedFieldsContextProvider } from "./forms/_context";
|
||||
import { useProviderFilterByUsage } from "./forms/_hooks";
|
||||
import AccessConfigFieldsProvider1Panel from "./forms/AccessConfigFieldsProvider1Panel";
|
||||
import AccessConfigFieldsProviderACMECA from "./forms/AccessConfigFieldsProviderACMECA";
|
||||
import AccessConfigFieldsProviderACMEDNS from "./forms/AccessConfigFieldsProviderACMEDNS";
|
||||
import AccessConfigFieldsProviderACMEHttpReq from "./forms/AccessConfigFieldsProviderACMEHttpReq";
|
||||
import AccessConfigFieldsProviderAliyun from "./forms/AccessConfigFieldsProviderAliyun";
|
||||
import AccessConfigFieldsProviderAPISIX from "./forms/AccessConfigFieldsProviderAPISIX";
|
||||
@@ -133,6 +134,9 @@ const AccessForm = ({ className, style, disabled, initialValues, mode, usage, ..
|
||||
case ACCESS_PROVIDERS.ACMECA: {
|
||||
return <AccessConfigFieldsProviderACMECA />;
|
||||
}
|
||||
case ACCESS_PROVIDERS.ACMEDNS: {
|
||||
return <AccessConfigFieldsProviderACMEDNS />;
|
||||
}
|
||||
case ACCESS_PROVIDERS.ACMEHTTPREQ: {
|
||||
return <AccessConfigFieldsProviderACMEHttpReq />;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
import { getI18n, useTranslation } from "react-i18next";
|
||||
import { Form, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
import { useFormNestedFieldsContext } from "./_context";
|
||||
|
||||
const AccessConfigFieldsProviderACMEDNS = () => {
|
||||
const { i18n, t } = useTranslation();
|
||||
|
||||
const { parentNamePath } = useFormNestedFieldsContext();
|
||||
const formSchema = z.object({
|
||||
[parentNamePath]: getSchema({ i18n }),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const initialValues = getInitialValues();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name="apiBase"
|
||||
initialValue={initialValues.apiBase}
|
||||
label={t("access.form.acmedns_api_base.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.acmedns_api_base.tooltip") }}></span>}
|
||||
>
|
||||
<Input placeholder={t("access.form.acmedns_api_base.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="storageBaseUrl"
|
||||
initialValue={initialValues.storageBaseUrl}
|
||||
label={t("access.form.acmedns_storage_base_url.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.acmedns_storage_base_url.tooltip") }}></span>}
|
||||
>
|
||||
<Input allowClear placeholder={t("access.form.acmedns_storage_base_url.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="storagePath"
|
||||
initialValue={initialValues.storagePath}
|
||||
label={t("access.form.acmedns_storage_path.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.acmedns_storage_path.tooltip") }}></span>}
|
||||
>
|
||||
<Input allowClear placeholder={t("access.form.acmedns_storage_path.placeholder")} />
|
||||
</Form.Item>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
return {
|
||||
apiBase: "https://auth.acme-dns.io/",
|
||||
storageBaseUrl: "",
|
||||
storagePath: "",
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
apiBase: z.url(t("common.errmsg.url_invalid")),
|
||||
storageBaseUrl: 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(),
|
||||
});
|
||||
};
|
||||
|
||||
const _default = Object.assign(AccessConfigFieldsProviderACMEDNS, {
|
||||
getInitialValues,
|
||||
getSchema,
|
||||
});
|
||||
|
||||
export default _default;
|
||||
@@ -1,90 +0,0 @@
|
||||
import { getI18n, useTranslation } from "react-i18next";
|
||||
import { Form, Input, Select, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import { useFormNestedFieldsContext } from "./_context";
|
||||
|
||||
const AccessConfigFormFieldsProvider1Panel = () => {
|
||||
const { i18n, t } = useTranslation();
|
||||
|
||||
const { parentNamePath } = useFormNestedFieldsContext();
|
||||
const formSchema = z.object({
|
||||
[parentNamePath]: getSchema({ i18n }),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const initialValues = getInitialValues();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name={[parentNamePath, "serverUrl"]}
|
||||
initialValue={initialValues.serverUrl}
|
||||
label={t("access.form.1panel_server_url.label")}
|
||||
rules={[formRule]}
|
||||
>
|
||||
<Input placeholder={t("access.form.1panel_server_url.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "apiVersion"]}
|
||||
initialValue={initialValues.apiVersion}
|
||||
label={t("access.form.1panel_api_version.label")}
|
||||
rules={[formRule]}
|
||||
>
|
||||
<Select options={["v1", "v2"].map((s) => ({ label: s, value: s }))} placeholder={t("access.form.1panel_api_version.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "apiKey"]}
|
||||
initialValue={initialValues.apiKey}
|
||||
label={t("access.form.1panel_api_key.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.1panel_api_key.tooltip") }}></span>}
|
||||
>
|
||||
<Input.Password autoComplete="new-password" placeholder={t("access.form.1panel_api_key.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "allowInsecureConnections"]}
|
||||
initialValue={initialValues.allowInsecureConnections}
|
||||
label={t("access.form.common_allow_insecure_conns.label")}
|
||||
rules={[formRule]}
|
||||
>
|
||||
<Switch
|
||||
checkedChildren={t("access.form.common_allow_insecure_conns.switch.on")}
|
||||
unCheckedChildren={t("access.form.common_allow_insecure_conns.switch.off")}
|
||||
/>
|
||||
</Form.Item>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
return {
|
||||
serverUrl: "http://<your-host-addr>:20410/",
|
||||
apiVersion: "v1",
|
||||
apiKey: "",
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
serverUrl: z.url(t("common.errmsg.url_invalid")),
|
||||
apiVersion: z.string().nonempty(t("access.form.1panel_api_version.placeholder")),
|
||||
apiKey: z
|
||||
.string()
|
||||
.min(1, t("access.form.1panel_api_key.placeholder"))
|
||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
||||
allowInsecureConnections: z.boolean().nullish(),
|
||||
});
|
||||
};
|
||||
|
||||
const _default = Object.assign(AccessConfigFormFieldsProvider1Panel, {
|
||||
getInitialValues,
|
||||
getSchema,
|
||||
});
|
||||
|
||||
export default _default;
|
||||
@@ -317,6 +317,15 @@ const BizApplyNodeConfigForm = ({ node, ...props }: BizApplyNodeConfigFormProps)
|
||||
</Form.Item>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="lifeTime"
|
||||
label={t("workflow_node.apply.form.life_time.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.apply.form.life_time.tooltip") }}></span>}
|
||||
>
|
||||
<Input allowClear type="string" placeholder={t("workflow_node.apply.form.life_time.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="acmeProfile"
|
||||
label={t("workflow_node.apply.form.acme_profile.label")}
|
||||
@@ -595,6 +604,13 @@ const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> })
|
||||
(v) => (v == null || v === "" ? void 0 : Number(v)),
|
||||
z.number().int(t("workflow_node.apply.form.dns_ttl.placeholder")).gte(1, t("workflow_node.apply.form.dns_ttl.placeholder")).nullish()
|
||||
),
|
||||
lifeTime: z
|
||||
.string()
|
||||
.nullish()
|
||||
.refine((v) => {
|
||||
if (!v) return true;
|
||||
return /^\d+[d|h]$/.test(v) && parseInt(v) > 0;
|
||||
}, t("workflow_node.apply.form.life_time.placeholder")),
|
||||
acmeProfile: z.string().nullish(),
|
||||
disableFollowCNAME: z.boolean().nullish(),
|
||||
disableARI: z.boolean().nullish(),
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
export const ACCESS_PROVIDERS = Object.freeze({
|
||||
["1PANEL"]: "1panel",
|
||||
ACMECA: "acmeca",
|
||||
ACMEDNS: "acmedns",
|
||||
ACMEHTTPREQ: "acmehttpreq",
|
||||
ALIYUN: "aliyun",
|
||||
APISIX: "apisix",
|
||||
@@ -173,6 +174,7 @@ export const accessProvidersMap: Map<AccessProvider["type"] | string, AccessProv
|
||||
[ACCESS_PROVIDERS.CMCCCLOUD, "provider.cmcccloud", "/imgs/providers/cmcccloud.svg", [ACCESS_USAGES.DNS]],
|
||||
[ACCESS_PROVIDERS.WESTCN, "provider.westcn", "/imgs/providers/westcn.svg", [ACCESS_USAGES.DNS]],
|
||||
[ACCESS_PROVIDERS.POWERDNS, "provider.powerdns", "/imgs/providers/powerdns.svg", [ACCESS_USAGES.DNS]],
|
||||
[ACCESS_PROVIDERS.ACMEDNS, "provider.acmedns", "/imgs/providers/acmedns.svg", [ACCESS_USAGES.DNS]],
|
||||
[ACCESS_PROVIDERS.ACMEHTTPREQ, "provider.acmehttpreq", "/imgs/providers/acmehttpreq.svg", [ACCESS_USAGES.DNS]],
|
||||
|
||||
[ACCESS_PROVIDERS.LETSENCRYPT, "provider.letsencrypt", "/imgs/providers/letsencrypt.svg", [ACCESS_USAGES.CA], "builtin"],
|
||||
@@ -264,6 +266,7 @@ export const caProvidersMap: Map<CAProvider["type"] | string, CAProvider> = new
|
||||
NOTICE: If you add new constant, please keep ASCII order.
|
||||
*/
|
||||
export const ACME_DNS01_PROVIDERS = Object.freeze({
|
||||
ACMEDNS: `${ACCESS_PROVIDERS.ACMEDNS}`,
|
||||
ACMEHTTPREQ: `${ACCESS_PROVIDERS.ACMEHTTPREQ}`,
|
||||
ALIYUN: `${ACCESS_PROVIDERS.ALIYUN}`, // 兼容旧值,等同于 `ALIYUN_DNS`
|
||||
ALIYUN_DNS: `${ACCESS_PROVIDERS.ALIYUN}-dns`,
|
||||
@@ -369,6 +372,7 @@ export const acmeDns01ProvidersMap: Map<ACMEDns01Provider["type"] | string, ACME
|
||||
[ACME_DNS01_PROVIDERS.UCLOUD_UDNR, "provider.ucloud.udnr"],
|
||||
[ACME_DNS01_PROVIDERS.WESTCN, "provider.westcn"],
|
||||
[ACME_DNS01_PROVIDERS.POWERDNS, "provider.powerdns"],
|
||||
[ACME_DNS01_PROVIDERS.ACMEDNS, "provider.acmedns"],
|
||||
[ACME_DNS01_PROVIDERS.ACMEHTTPREQ, "provider.acmehttpreq"],
|
||||
] satisfies Array<[ACMEDns01ProviderType, string]>
|
||||
).map(([type, name]) => [
|
||||
|
||||
@@ -102,6 +102,7 @@ export type WorkflowNodeConfigForBizApply = {
|
||||
caProviderAccessId?: string;
|
||||
caProviderConfig?: Record<string, unknown>;
|
||||
keyAlgorithm: string;
|
||||
lifeTime?: string;
|
||||
acmeProfile?: string;
|
||||
nameservers?: string;
|
||||
dnsPropagationTimeout?: number;
|
||||
|
||||
@@ -59,6 +59,15 @@
|
||||
"access.form.acmeca_eab_kid.placeholder": "Please enter ACME EAB KID",
|
||||
"access.form.acmeca_eab_hmac_key.label": "ACME EAB HMAC key (Optional)",
|
||||
"access.form.acmeca_eab_hmac_key.placeholder": "Please enter ACME EAB HMAC key",
|
||||
"access.form.acmedns_api_base.label": "ACME-DNS API URL",
|
||||
"access.form.acmedns_api_base.placeholder": "Please enter ACME-DNS API URL",
|
||||
"access.form.acmedns_api_base.tooltip": "For more information, see <a href=\"https://go-acme.github.io/lego/dns/acme-dns/\" target=\"_blank\">https://go-acme.github.io/lego/dns/acme-dns/</a>",
|
||||
"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 <a href=\"https://go-acme.github.io/lego/dns/acme-dns/\" target=\"_blank\">https://go-acme.github.io/lego/dns/acme-dns/</a>",
|
||||
"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 <a href=\"https://go-acme.github.io/lego/dns/acme-dns/\" target=\"_blank\">https://go-acme.github.io/lego/dns/acme-dns/</a>",
|
||||
"access.form.acmehttpreq_endpoint.label": "Endpoint",
|
||||
"access.form.acmehttpreq_endpoint.placeholder": "Please enter endpoint",
|
||||
"access.form.acmehttpreq_endpoint.tooltip": "For more information, see <a href=\"https://go-acme.github.io/lego/dns/httpreq/\" target=\"_blank\">https://go-acme.github.io/lego/dns/httpreq/</a>",
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"provider.1panel.console": "1Panel - Console itself",
|
||||
"provider.1panel.site": "1Panel - Website",
|
||||
"provider.acmeca": "ACME Custom CA Endpoint",
|
||||
"provider.acmedns": "ACME DNS",
|
||||
"provider.acmehttpreq": "ACME Custom HTTP Endpoint",
|
||||
"provider.aliyun": "Alibaba Cloud",
|
||||
"provider.aliyun.alb": "Alibaba Cloud - ALB (Application Load Balancer)",
|
||||
|
||||
@@ -71,6 +71,9 @@
|
||||
"workflow_node.apply.form.ca_provider_access.label": "Certificate authority credential",
|
||||
"workflow_node.apply.form.ca_provider_access.placeholder": "Please select an credential of the certificate authority",
|
||||
"workflow_node.apply.form.ca_provider_access.button": "Create",
|
||||
"workflow_node.apply.form.life_time.label": "Certificate lifetime (Optional)",
|
||||
"workflow_node.apply.form.life_time.placeholder": "Please enter certificate lifetime, unit support: h, d. e.g. 30d",
|
||||
"workflow_node.apply.form.life_time.tooltip": "It determines the lifetime of the certificate. If you don't understand this option, just keep it by default.",
|
||||
"workflow_node.apply.form.acme_profile.label": "ACME certificate profile (Optional)",
|
||||
"workflow_node.apply.form.acme_profile.placeholder": "Please enter ACME certificate profile",
|
||||
"workflow_node.apply.form.acme_profile.tooltip": "It determines the ACME profile which will be used to affect issuance of the certificate requested. If you don't understand this option, just keep it by default. <br><a href=\"https://letsencrypt.org/docs/profiles/\" target=\"_blank\">Click here to learn more</a>.",
|
||||
|
||||
@@ -58,6 +58,15 @@
|
||||
"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": "这是什么?请参阅 <a href=\"https://go-acme.github.io/lego/dns/acme-dns/\" target=\"_blank\">https://go-acme.github.io/lego/dns/acme-dns/</a>",
|
||||
"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": "这是什么?请参阅 <a href=\"https://go-acme.github.io/lego/dns/acme-dns/\" target=\"_blank\">https://go-acme.github.io/lego/dns/acme-dns/</a>",
|
||||
"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": "这是什么?请参阅 <a href=\"https://go-acme.github.io/lego/dns/acme-dns/\" target=\"_blank\">https://go-acme.github.io/lego/dns/acme-dns/</a>",
|
||||
"access.form.acmehttpreq_endpoint.label": "服务端点",
|
||||
"access.form.acmehttpreq_endpoint.placeholder": "请输入服务端点",
|
||||
"access.form.acmehttpreq_endpoint.tooltip": "这是什么?请参阅 <a href=\"https://go-acme.github.io/lego/dns/httpreq/\" target=\"_blank\">https://go-acme.github.io/lego/dns/httpreq/</a>",
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"provider.1panel.console": "1Panel - 面板自身",
|
||||
"provider.1panel.site": "1Panel - 网站",
|
||||
"provider.acmeca": "ACME 自定义 CA 端点",
|
||||
"provider.acmedns": "ACME DNS",
|
||||
"provider.acmehttpreq": "ACME 自定义 HTTP 端点",
|
||||
"provider.aliyun": "阿里云",
|
||||
"provider.aliyun.alb": "阿里云 - 应用型负载均衡 ALB",
|
||||
|
||||
@@ -70,6 +70,9 @@
|
||||
"workflow_node.apply.form.ca_provider_access.label": "证书颁发机构授权",
|
||||
"workflow_node.apply.form.ca_provider_access.placeholder": "请选择证书颁发机构授权",
|
||||
"workflow_node.apply.form.ca_provider_access.button": "新建",
|
||||
"workflow_node.apply.form.life_time.label": "证书有效期(可选)",
|
||||
"workflow_node.apply.form.life_time.placeholder": "请输入证书有效期,单位支持:h、d,例如:30d",
|
||||
"workflow_node.apply.form.life_time.tooltip": "表示证书的有效期。如果你不了解该选项的用途,保持默认即可。",
|
||||
"workflow_node.apply.form.acme_profile.label": "ACME 证书配置(可选)",
|
||||
"workflow_node.apply.form.acme_profile.placeholder": "请输入 ACME 证书配置",
|
||||
"workflow_node.apply.form.acme_profile.tooltip": "表示证书颁发时使用的 ACME 证书配置。如果你不了解该选项的用途,保持默认即可。<br><a href=\"https://letsencrypt.org/zh-cn/docs/profiles/\" target=\"_blank\">点此了解更多</a>。",
|
||||
|
||||
Reference in New Issue
Block a user