Merge branch 'main' into dev

This commit is contained in:
Fu Diwei
2025-09-03 18:55:06 +08:00
22 changed files with 232 additions and 98 deletions
+5 -3
View File
@@ -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
+5 -2
View File
@@ -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)
}
}
+11 -2
View File
@@ -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{}
+6
View File
@@ -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"`
+2
View File
@@ -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")
+3 -1
View File
@@ -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
}
+2
View File
@@ -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

+4
View File
@@ -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(),
+4
View File
@@ -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]) => [
+1
View File
@@ -102,6 +102,7 @@ export type WorkflowNodeConfigForBizApply = {
caProviderAccessId?: string;
caProviderConfig?: Record<string, unknown>;
keyAlgorithm: string;
lifeTime?: string;
acmeProfile?: string;
nameservers?: string;
dnsPropagationTimeout?: number;
+9
View File
@@ -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>",
+1
View File
@@ -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>.",
+9
View File
@@ -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>",
+1
View File
@@ -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>。",