diff --git a/README.md b/README.md index 0c9b73a2..5aea2374 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ make local.run | [AWS Route53](https://aws.amazon.com/route53/) | | | [Azure](https://azure.microsoft.com/) | | | [CloudFlare](https://www.cloudflare.com/) | | +| [ClouDNS](https://www.cloudns.net//) | | | [GoDaddy](https://www.godaddy.com/) | | | [Name.com](https://www.name.com/) | | | [NameSilo](https://www.namesilo.com/) | | diff --git a/README_EN.md b/README_EN.md index b915cb95..c360ce63 100644 --- a/README_EN.md +++ b/README_EN.md @@ -94,6 +94,7 @@ The following DNS providers are supported: | [AWS Route53](https://aws.amazon.com/route53/) | | | [Azure DNS](https://azure.microsoft.com/) | | | [CloudFlare](https://www.cloudflare.com/) | | +| [ClouDNS](https://www.cloudns.net//) | | | [GoDaddy](https://www.godaddy.com/) | | | [Name.com](https://www.name.com/) | | | [NameSilo](https://www.namesilo.com/) | | diff --git a/internal/applicant/providers.go b/internal/applicant/providers.go index 75d9d3ce..8329ff54 100644 --- a/internal/applicant/providers.go +++ b/internal/applicant/providers.go @@ -11,6 +11,7 @@ import ( providerAWSRoute53 "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws-route53" providerAzureDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/azure-dns" providerCloudflare "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare" + providerClouDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudns" providerGoDaddy "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy" providerHuaweiCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud" providerNameDotCom "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom" @@ -114,6 +115,22 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) { return applicant, err } + case domain.ApplyDNSProviderTypeClouDNS: + { + access := domain.AccessConfigForClouDNS{} + if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { + return nil, fmt.Errorf("failed to decode provider access config: %w", err) + } + + applicant, err := providerClouDNS.NewChallengeProvider(&providerClouDNS.ClouDNSApplicantConfig{ + AuthId: access.AuthId, + AuthPassword: access.AuthPassword, + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, + }) + return applicant, err + } + case domain.ApplyDNSProviderTypeGoDaddy: { access := domain.AccessConfigForGoDaddy{} diff --git a/internal/domain/access.go b/internal/domain/access.go index 7f49c897..70128622 100644 --- a/internal/domain/access.go +++ b/internal/domain/access.go @@ -63,6 +63,11 @@ type AccessConfigForCloudflare struct { DnsApiToken string `json:"dnsApiToken"` } +type AccessConfigForClouDNS struct { + AuthId string `json:"authId"` + AuthPassword string `json:"authPassword"` +} + type AccessConfigForDogeCloud struct { AccessKey string `json:"accessKey"` SecretKey string `json:"secretKey"` diff --git a/internal/domain/provider.go b/internal/domain/provider.go index ea950bbd..71e048b3 100644 --- a/internal/domain/provider.go +++ b/internal/domain/provider.go @@ -16,6 +16,7 @@ const ( AccessProviderTypeBaiduCloud = AccessProviderType("baiducloud") AccessProviderTypeBytePlus = AccessProviderType("byteplus") AccessProviderTypeCloudflare = AccessProviderType("cloudflare") + AccessProviderTypeClouDNS = AccessProviderType("cloudns") AccessProviderTypeDogeCloud = AccessProviderType("dogecloud") AccessProviderTypeEdgio = AccessProviderType("edgio") AccessProviderTypeGoDaddy = AccessProviderType("godaddy") @@ -53,6 +54,7 @@ const ( ApplyDNSProviderTypeAWSRoute53 = ApplyDNSProviderType("aws-route53") ApplyDNSProviderTypeAzureDNS = ApplyDNSProviderType("azure-dns") ApplyDNSProviderTypeCloudflare = ApplyDNSProviderType("cloudflare") + ApplyDNSProviderTypeClouDNS = ApplyDNSProviderType("cloudns") ApplyDNSProviderTypeGoDaddy = ApplyDNSProviderType("godaddy") ApplyDNSProviderTypeHuaweiCloud = ApplyDNSProviderType("huaweicloud") // 兼容旧值,等同于 [ApplyDNSProviderTypeHuaweiCloudDNS] ApplyDNSProviderTypeHuaweiCloudDNS = ApplyDNSProviderType("huaweicloud-dns") diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudns/cloudns.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudns/cloudns.go new file mode 100644 index 00000000..09aac6df --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudns/cloudns.go @@ -0,0 +1,39 @@ +package cloudns + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/cloudns" +) + +type ClouDNSApplicantConfig struct { + AuthId string `json:"authId"` + AuthPassword string `json:"authPassword"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int32 `json:"dnsTTL,omitempty"` +} + +func NewChallengeProvider(config *ClouDNSApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := cloudns.NewDefaultConfig() + providerConfig.AuthID = config.AuthId + providerConfig.AuthPassword = config.AuthPassword + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = int(config.DnsTTL) + } + + provider, err := cloudns.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/ui/.eslintrc.cjs b/ui/.eslintrc.cjs index 6bd9b5fd..d82915f5 100644 --- a/ui/.eslintrc.cjs +++ b/ui/.eslintrc.cjs @@ -84,6 +84,7 @@ module.exports = { pathGroupsExcludedImportTypes: ["builtin"], alphabetize: { order: "asc", + caseInsensitive: true, }, }, ], diff --git a/ui/public/imgs/providers/cloudns.svg b/ui/public/imgs/providers/cloudns.svg new file mode 100644 index 00000000..44cf1ed2 --- /dev/null +++ b/ui/public/imgs/providers/cloudns.svg @@ -0,0 +1,99 @@ + + diff --git a/ui/src/components/access/AccessForm.tsx b/ui/src/components/access/AccessForm.tsx index 9671ffa2..e007eb89 100644 --- a/ui/src/components/access/AccessForm.tsx +++ b/ui/src/components/access/AccessForm.tsx @@ -10,21 +10,22 @@ import { ACCESS_PROVIDERS } from "@/domain/provider"; import { useAntdForm, useAntdFormName } from "@/hooks"; import AccessFormACMEHttpReqConfig from "./AccessFormACMEHttpReqConfig"; -import AccessFormAWSConfig from "./AccessFormAWSConfig"; import AccessFormAliyunConfig from "./AccessFormAliyunConfig"; +import AccessFormAWSConfig from "./AccessFormAWSConfig"; import AccessFormAzureConfig from "./AccessFormAzureConfig"; import AccessFormBaiduCloudConfig from "./AccessFormBaiduCloudConfig"; import AccessFormBytePlusConfig from "./AccessFormBytePlusConfig"; import AccessFormCloudflareConfig from "./AccessFormCloudflareConfig"; +import AccessFormClouDNSConfig from "./AccessFormClouDNSConfig"; import AccessFormDogeCloudConfig from "./AccessFormDogeCloudConfig"; import AccessFormEdgioConfig from "./AccessFormEdgioConfig"; import AccessFormGoDaddyConfig from "./AccessFormGoDaddyConfig"; import AccessFormHuaweiCloudConfig from "./AccessFormHuaweiCloudConfig"; import AccessFormKubernetesConfig from "./AccessFormKubernetesConfig"; import AccessFormLocalConfig from "./AccessFormLocalConfig"; -import AccessFormNS1Config from "./AccessFormNS1Config"; import AccessFormNameDotComConfig from "./AccessFormNameDotComConfig"; import AccessFormNameSiloConfig from "./AccessFormNameSiloConfig"; +import AccessFormNS1Config from "./AccessFormNS1Config"; import AccessFormPowerDNSConfig from "./AccessFormPowerDNSConfig"; import AccessFormQiniuConfig from "./AccessFormQiniuConfig"; import AccessFormRainYunConfig from "./AccessFormRainYunConfig"; @@ -101,6 +102,8 @@ const AccessForm = forwardRef(({ className, return ; case ACCESS_PROVIDERS.CLOUDFLARE: return ; + case ACCESS_PROVIDERS.CLOUDNS: + return ; case ACCESS_PROVIDERS.DOGECLOUD: return ; case ACCESS_PROVIDERS.GODADDY: diff --git a/ui/src/components/access/AccessFormClouDNSConfig.tsx b/ui/src/components/access/AccessFormClouDNSConfig.tsx new file mode 100644 index 00000000..4472eeea --- /dev/null +++ b/ui/src/components/access/AccessFormClouDNSConfig.tsx @@ -0,0 +1,76 @@ +import { useTranslation } from "react-i18next"; +import { Form, type FormInstance, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { type AccessConfigForClouDNS } from "@/domain/access"; + +type AccessFormClouDNSConfigFieldValues = Nullish; + +export type AccessFormClouDNSConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: AccessFormClouDNSConfigFieldValues; + onValuesChange?: (values: AccessFormClouDNSConfigFieldValues) => void; +}; + +const initFormModel = (): AccessFormClouDNSConfigFieldValues => { + return { + authId: "", + authPassword: "", + }; +}; + +const AccessFormClouDNSConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormClouDNSConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + authId: z + .string() + .trim() + .min(1, t("access.form.cloudns_auth_id.placeholder")) + .max(64, t("common.errmsg.string_max", { max: 64 })), + authPassword: z + .string() + .min(1, t("access.form.cloudns_auth_password.placeholder")) + .max(64, t("common.errmsg.string_max", { max: 64 })) + .trim(), + }); + const formRule = createSchemaFieldRule(formSchema); + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( +
+ } + > + + + + } + > + + +
+ ); +}; + +export default AccessFormClouDNSConfig; diff --git a/ui/src/components/notification/NotifyChannelEditForm.tsx b/ui/src/components/notification/NotifyChannelEditForm.tsx index 2fa9b5b3..d818ee4c 100644 --- a/ui/src/components/notification/NotifyChannelEditForm.tsx +++ b/ui/src/components/notification/NotifyChannelEditForm.tsx @@ -10,8 +10,8 @@ import NotifyChannelEditFormEmailFields from "./NotifyChannelEditFormEmailFields import NotifyChannelEditFormLarkFields from "./NotifyChannelEditFormLarkFields"; import NotifyChannelEditFormServerChanFields from "./NotifyChannelEditFormServerChanFields"; import NotifyChannelEditFormTelegramFields from "./NotifyChannelEditFormTelegramFields"; -import NotifyChannelEditFormWeComFields from "./NotifyChannelEditFormWeComFields"; import NotifyChannelEditFormWebhookFields from "./NotifyChannelEditFormWebhookFields"; +import NotifyChannelEditFormWeComFields from "./NotifyChannelEditFormWeComFields"; type NotifyChannelEditFormFieldValues = NotifyChannelsSettingsContent[keyof NotifyChannelsSettingsContent]; diff --git a/ui/src/components/workflow/WorkflowElement.tsx b/ui/src/components/workflow/WorkflowElement.tsx index d2272ef0..3aa70ff3 100644 --- a/ui/src/components/workflow/WorkflowElement.tsx +++ b/ui/src/components/workflow/WorkflowElement.tsx @@ -64,4 +64,3 @@ const WorkflowElement = ({ node, disabled, branchId, branchIndex }: WorkflowElem }; export default memo(WorkflowElement); - diff --git a/ui/src/components/workflow/node/ApplyNode.tsx b/ui/src/components/workflow/node/ApplyNode.tsx index 556188d9..6e090616 100644 --- a/ui/src/components/workflow/node/ApplyNode.tsx +++ b/ui/src/components/workflow/node/ApplyNode.tsx @@ -8,8 +8,8 @@ import { useZustandShallowSelector } from "@/hooks"; import { useContactEmailsStore } from "@/stores/contact"; import { useWorkflowStore } from "@/stores/workflow"; -import ApplyNodeConfigForm, { type ApplyNodeConfigFormInstance } from "./ApplyNodeConfigForm"; import SharedNode, { type SharedNodeProps } from "./_SharedNode"; +import ApplyNodeConfigForm, { type ApplyNodeConfigFormInstance } from "./ApplyNodeConfigForm"; export type ApplyNodeProps = SharedNodeProps; diff --git a/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx b/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx index 2280fbb8..1792163e 100644 --- a/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx @@ -21,10 +21,10 @@ import { import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import ModalForm from "@/components/ModalForm"; -import MultipleInput from "@/components/MultipleInput"; import AccessEditModal from "@/components/access/AccessEditModal"; import AccessSelect from "@/components/access/AccessSelect"; +import ModalForm from "@/components/ModalForm"; +import MultipleInput from "@/components/MultipleInput"; import ApplyDNSProviderSelect from "@/components/provider/ApplyDNSProviderSelect"; import { ACCESS_USAGES, APPLY_DNS_PROVIDERS, accessProvidersMap, applyDNSProvidersMap } from "@/domain/provider"; import { type WorkflowNodeConfigForApply } from "@/domain/workflow"; diff --git a/ui/src/components/workflow/node/ConditionNode.tsx b/ui/src/components/workflow/node/ConditionNode.tsx index d84e8550..56639692 100644 --- a/ui/src/components/workflow/node/ConditionNode.tsx +++ b/ui/src/components/workflow/node/ConditionNode.tsx @@ -2,8 +2,8 @@ import { memo } from "react"; import { MoreOutlined as MoreOutlinedIcon } from "@ant-design/icons"; import { Button, Card, Popover } from "antd"; -import AddNode from "./AddNode"; import SharedNode, { type SharedNodeProps } from "./_SharedNode"; +import AddNode from "./AddNode"; export type ConditionNodeProps = SharedNodeProps & { branchId: string; diff --git a/ui/src/components/workflow/node/DeployNode.tsx b/ui/src/components/workflow/node/DeployNode.tsx index db5830da..9eca1248 100644 --- a/ui/src/components/workflow/node/DeployNode.tsx +++ b/ui/src/components/workflow/node/DeployNode.tsx @@ -8,8 +8,8 @@ import { type WorkflowNodeConfigForDeploy, WorkflowNodeType } from "@/domain/wor import { useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; -import DeployNodeConfigForm, { type DeployNodeConfigFormInstance } from "./DeployNodeConfigForm"; import SharedNode, { type SharedNodeProps } from "./_SharedNode"; +import DeployNodeConfigForm, { type DeployNodeConfigFormInstance } from "./DeployNodeConfigForm"; export type DeployNodeProps = SharedNodeProps; diff --git a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx index 77d110c6..3d85e6de 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx @@ -5,11 +5,11 @@ import { Alert, Button, Divider, Flex, Form, type FormInstance, Select, Switch, import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import Show from "@/components/Show"; import AccessEditModal from "@/components/access/AccessEditModal"; import AccessSelect from "@/components/access/AccessSelect"; import DeployProviderPicker from "@/components/provider/DeployProviderPicker"; import DeployProviderSelect from "@/components/provider/DeployProviderSelect"; +import Show from "@/components/Show"; import { ACCESS_USAGES, DEPLOY_PROVIDERS, accessProvidersMap, deployProvidersMap } from "@/domain/provider"; import { type WorkflowNode, type WorkflowNodeConfigForDeploy } from "@/domain/workflow"; import { useAntdForm, useAntdFormName, useZustandShallowSelector } from "@/hooks"; diff --git a/ui/src/components/workflow/node/ExecuteResultNode.tsx b/ui/src/components/workflow/node/ExecuteResultNode.tsx index b53b2a8c..69a0949c 100644 --- a/ui/src/components/workflow/node/ExecuteResultNode.tsx +++ b/ui/src/components/workflow/node/ExecuteResultNode.tsx @@ -8,8 +8,8 @@ import { import { Button, Card, Popover, theme } from "antd"; import { WorkflowNodeType } from "@/domain/workflow"; -import AddNode from "./AddNode"; import SharedNode, { type SharedNodeProps } from "./_SharedNode"; +import AddNode from "./AddNode"; export type ConditionNodeProps = SharedNodeProps & { branchId: string; diff --git a/ui/src/components/workflow/node/NotifyNode.tsx b/ui/src/components/workflow/node/NotifyNode.tsx index 1b739e8f..4ac35ab5 100644 --- a/ui/src/components/workflow/node/NotifyNode.tsx +++ b/ui/src/components/workflow/node/NotifyNode.tsx @@ -8,8 +8,8 @@ import { type WorkflowNodeConfigForNotify, WorkflowNodeType } from "@/domain/wor import { useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; -import NotifyNodeConfigForm, { type NotifyNodeConfigFormInstance } from "./NotifyNodeConfigForm"; import SharedNode, { type SharedNodeProps } from "./_SharedNode"; +import NotifyNodeConfigForm, { type NotifyNodeConfigFormInstance } from "./NotifyNodeConfigForm"; export type NotifyNodeProps = SharedNodeProps; diff --git a/ui/src/components/workflow/node/StartNode.tsx b/ui/src/components/workflow/node/StartNode.tsx index 1df65bc1..900793fa 100644 --- a/ui/src/components/workflow/node/StartNode.tsx +++ b/ui/src/components/workflow/node/StartNode.tsx @@ -7,8 +7,8 @@ import { WORKFLOW_TRIGGERS, type WorkflowNodeConfigForStart, WorkflowNodeType } import { useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; -import StartNodeConfigForm, { type StartNodeConfigFormInstance } from "./StartNodeConfigForm"; import SharedNode, { type SharedNodeProps } from "./_SharedNode"; +import StartNodeConfigForm, { type StartNodeConfigFormInstance } from "./StartNodeConfigForm"; export type StartNodeProps = SharedNodeProps; diff --git a/ui/src/components/workflow/node/UploadNode.tsx b/ui/src/components/workflow/node/UploadNode.tsx index 3d0e20c3..25850743 100644 --- a/ui/src/components/workflow/node/UploadNode.tsx +++ b/ui/src/components/workflow/node/UploadNode.tsx @@ -8,8 +8,8 @@ import { WorkflowNodeType } from "@/domain/workflow"; import { useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; -import UploadNodeConfigForm, { type UploadNodeConfigFormInstance } from "./UploadNodeConfigForm"; import SharedNode, { type SharedNodeProps } from "./_SharedNode"; +import UploadNodeConfigForm, { type UploadNodeConfigFormInstance } from "./UploadNodeConfigForm"; export type UploadNodeProps = SharedNodeProps; diff --git a/ui/src/domain/access.ts b/ui/src/domain/access.ts index 8efe8b27..14b31be6 100644 --- a/ui/src/domain/access.ts +++ b/ui/src/domain/access.ts @@ -15,6 +15,7 @@ export interface AccessModel extends BaseModel { | AccessConfigForBaiduCloud | AccessConfigForBytePlus | AccessConfigForCloudflare + | AccessConfigForClouDNS | AccessConfigForDogeCloud | AccessConfigForEdgio | AccessConfigForGoDaddy @@ -75,6 +76,11 @@ export type AccessConfigForCloudflare = { dnsApiToken: string; }; +export type AccessConfigForClouDNS = { + authId: string; + authPassword: string; +}; + export type AccessConfigForDogeCloud = { accessKey: string; secretKey: string; diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts index b6004053..9a05d180 100644 --- a/ui/src/domain/provider.ts +++ b/ui/src/domain/provider.ts @@ -11,6 +11,7 @@ export const ACCESS_PROVIDERS = Object.freeze({ BAIDUCLOUD: "baiducloud", BYTEPLUS: "byteplus", CLOUDFLARE: "cloudflare", + CLOUDNS: "cloudns", DOGECLOUD: "dogecloud", GODADDY: "godaddy", EDGIO: "edgio", @@ -71,6 +72,7 @@ export const accessProvidersMap: Maphttps://developers.cloudflare.com/fundamentals/api/get-started/create-token/", + "access.form.cloudns_auth_id.label": "ClouDNS API user ID", + "access.form.cloudns_auth_id.placeholder": "Please enter ClouDNS API user ID", + "access.form.cloudns_auth_id.tooltip": "For more information, see https://www.cloudns.net/wiki/article/42/", + "access.form.cloudns_auth_password.label": "ClouDNS API user password", + "access.form.cloudns_auth_password.placeholder": "Please enter ClouDNS API user password", + "access.form.cloudns_auth_password.tooltip": "For more information, see https://www.cloudns.net/wiki/article/42/", "access.form.dogecloud_access_key.label": "Doge Cloud AccessKey", "access.form.dogecloud_access_key.placeholder": "Please enter Doge Cloud AccessKey", "access.form.dogecloud_access_key.tooltip": "For more information, see https://console.dogecloud.com/", diff --git a/ui/src/i18n/locales/en/nls.common.json b/ui/src/i18n/locales/en/nls.common.json index 40c4837d..dbe271e7 100644 --- a/ui/src/i18n/locales/en/nls.common.json +++ b/ui/src/i18n/locales/en/nls.common.json @@ -55,6 +55,7 @@ "common.provider.byteplus": "BytePlus", "common.provider.byteplus.cdn": "BytePlus - CDN (Content Delivery Network)", "common.provider.cloudflare": "Cloudflare", + "common.provider.cloudns": "ClouDNS", "common.provider.dogecloud": "Doge Cloud", "common.provider.dogecloud.cdn": "Doge Cloud - CDN (Content Delivery Network)", "common.provider.edgio": "Edgio", diff --git a/ui/src/i18n/locales/zh/nls.access.json b/ui/src/i18n/locales/zh/nls.access.json index 8be0c1cc..7d51ad43 100644 --- a/ui/src/i18n/locales/zh/nls.access.json +++ b/ui/src/i18n/locales/zh/nls.access.json @@ -72,6 +72,12 @@ "access.form.cloudflare_dns_api_token.label": "Cloudflare API Token", "access.form.cloudflare_dns_api_token.placeholder": "请输入 Cloudflare API Token", "access.form.cloudflare_dns_api_token.tooltip": "这是什么?请参阅 https://developers.cloudflare.com/fundamentals/api/get-started/create-token/", + "access.form.cloudns_auth_id.label": "ClouDNS API 用户 ID", + "access.form.cloudns_auth_id.placeholder": "请输入 ClouDNS API 用户 ID", + "access.form.cloudns_auth_id.tooltip": "这是什么?请参阅 https://www.cloudns.net/wiki/article/42/", + "access.form.cloudns_auth_password.label": "ClouDNS API 用户密码", + "access.form.cloudns_auth_password.placeholder": "请输入 ClouDNS API 用户密码", + "access.form.cloudns_auth_password.tooltip": "这是什么?请参阅 https://www.cloudns.net/wiki/article/42/", "access.form.dogecloud_access_key.label": "多吉云 AccessKey", "access.form.dogecloud_access_key.placeholder": "请输入多吉云 AccessKey", "access.form.dogecloud_access_key.tooltip": "这是什么?请参阅 https://console.dogecloud.com/", diff --git a/ui/src/i18n/locales/zh/nls.common.json b/ui/src/i18n/locales/zh/nls.common.json index e7e742b8..45072e74 100644 --- a/ui/src/i18n/locales/zh/nls.common.json +++ b/ui/src/i18n/locales/zh/nls.common.json @@ -55,6 +55,7 @@ "common.provider.byteplus": "BytePlus", "common.provider.byteplus.cdn": "BytePlus - 内容分发网络 CDN", "common.provider.cloudflare": "Cloudflare", + "common.provider.cloudns": "ClouDNS", "common.provider.dogecloud": "多吉云", "common.provider.dogecloud.cdn": "多吉云 - 内容分发网络 CDN", "common.provider.edgio": "Edgio", diff --git a/ui/src/router.tsx b/ui/src/router.tsx index 31265f6b..0bfa8b41 100644 --- a/ui/src/router.tsx +++ b/ui/src/router.tsx @@ -1,9 +1,9 @@ import { createHashRouter } from "react-router-dom"; -import AuthLayout from "./pages/AuthLayout"; -import ConsoleLayout from "./pages/ConsoleLayout"; import AccessList from "./pages/accesses/AccessList"; +import AuthLayout from "./pages/AuthLayout"; import CertificateList from "./pages/certificates/CertificateList"; +import ConsoleLayout from "./pages/ConsoleLayout"; import Dashboard from "./pages/dashboard/Dashboard"; import Login from "./pages/login/Login"; import Settings from "./pages/settings/Settings";