From 9246878d0e228b0754852366b882869399ec6ef0 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Sat, 4 Jan 2025 13:52:11 +0800 Subject: [PATCH] feat: rename `domain` to `subjectAltNames` --- internal/applicant/applicant.go | 6 +- internal/certificate/service.go | 2 +- internal/deployer/deployer.go | 66 +------------------ internal/domain/certificate.go | 2 +- internal/repository/workflow_output.go | 4 +- .../workflow/node-processor/apply_node.go | 2 +- .../workflow/node-processor/deploy_node.go | 4 +- .../components/workflow/WorkflowElement.tsx | 26 ++++++-- .../workflow/node/ApplyNodeForm.tsx | 22 +++---- .../workflow/node/DeployNodeForm.tsx | 6 +- .../workflow/node/NotifyNodeForm.tsx | 6 +- .../workflow/node/StartNodeForm.tsx | 6 +- ui/src/domain/workflow.ts | 16 ++--- 13 files changed, 59 insertions(+), 109 deletions(-) diff --git a/internal/applicant/applicant.go b/internal/applicant/applicant.go index 992cf3ad..da3e36b6 100644 --- a/internal/applicant/applicant.go +++ b/internal/applicant/applicant.go @@ -54,8 +54,8 @@ type Certificate struct { } type ApplyOption struct { + Domains string `json:"domains"` ContactEmail string `json:"contactEmail"` - SubjectAltNames string `json:"subjectAltNames"` AccessConfig string `json:"accessConfig"` KeyAlgorithm string `json:"keyAlgorithm"` Nameservers string `json:"nameservers"` @@ -132,8 +132,8 @@ func GetWithApplyNode(node *domain.WorkflowNode) (Applicant, error) { } applyConfig := &ApplyOption{ + Domains: node.GetConfigString("domains"), ContactEmail: node.GetConfigString("contactEmail"), - SubjectAltNames: node.GetConfigString("subjectAltNames"), AccessConfig: access.Config, KeyAlgorithm: node.GetConfigString("keyAlgorithm"), Nameservers: node.GetConfigString("nameservers"), @@ -243,7 +243,7 @@ func apply(option *ApplyOption, provider challenge.Provider) (*Certificate, erro myUser.Registration = reg } - domains := strings.Split(option.SubjectAltNames, ";") + domains := strings.Split(option.Domains, ";") request := certificate.ObtainRequest{ Domains: domains, Bundle: true, diff --git a/internal/certificate/service.go b/internal/certificate/service.go index d59fccc4..20c6f6f0 100644 --- a/internal/certificate/service.go +++ b/internal/certificate/service.go @@ -83,7 +83,7 @@ func buildMsg(records []domain.Certificate) *domain.NotifyMessage { domains := make([]string, count) for i, record := range records { - domains[i] = record.SAN + domains[i] = record.SubjectAltNames } countStr := strconv.Itoa(count) diff --git a/internal/deployer/deployer.go b/internal/deployer/deployer.go index a90dc1b8..79b031aa 100644 --- a/internal/deployer/deployer.go +++ b/internal/deployer/deployer.go @@ -4,13 +4,10 @@ import ( "context" "fmt" - "github.com/pocketbase/pocketbase/models" - "github.com/usual2970/certimate/internal/applicant" "github.com/usual2970/certimate/internal/domain" "github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/logger" - "github.com/usual2970/certimate/internal/repository" ) /* @@ -47,8 +44,8 @@ const ( ) type DeployerOption struct { - DomainId string `json:"domainId"` - Domain string `json:"domain"` + NodeId string `json:"nodeId"` + Domains string `json:"domains"` AccessConfig string `json:"accessConfig"` AccessRecord *domain.Access `json:"-"` DeployConfig domain.DeployConfig `json:"deployConfig"` @@ -62,66 +59,7 @@ type Deployer interface { GetID() string } -func Gets(record *models.Record, cert *applicant.Certificate) ([]Deployer, error) { - rs := make([]Deployer, 0) - if record.GetString("deployConfig") == "" { - return rs, nil - } - - deployConfigs := make([]domain.DeployConfig, 0) - - err := record.UnmarshalJSONField("deployConfig", &deployConfigs) - if err != nil { - return nil, fmt.Errorf("解析部署配置失败: %w", err) - } - - if len(deployConfigs) == 0 { - return rs, nil - } - - for _, deployConfig := range deployConfigs { - deployer, err := newWithDeployConfig(record, cert, deployConfig) - if err != nil { - return nil, err - } - - rs = append(rs, deployer) - } - - return rs, nil -} - func GetWithTypeAndOption(deployType string, option *DeployerOption) (Deployer, error) { - return newWithTypeAndOption(deployType, option) -} - -func newWithDeployConfig(record *models.Record, cert *applicant.Certificate, deployConfig domain.DeployConfig) (Deployer, error) { - accessRepo := repository.NewAccessRepository() - access, err := accessRepo.GetById(context.Background(), deployConfig.ProviderAccessId) - if err != nil { - return nil, fmt.Errorf("获取access失败:%w", err) - } - - option := &DeployerOption{ - DomainId: record.Id, - Domain: record.GetString("domain"), - AccessConfig: access.Config, - AccessRecord: access, - DeployConfig: deployConfig, - } - if cert != nil { - option.Certificate = *cert - } else { - option.Certificate = applicant.Certificate{ - Certificate: record.GetString("certificate"), - PrivateKey: record.GetString("privateKey"), - } - } - - return newWithTypeAndOption(deployConfig.Provider, option) -} - -func newWithTypeAndOption(deployType string, option *DeployerOption) (Deployer, error) { deployer, logger, err := createDeployer(deployType, option.AccessRecord.Config, option.DeployConfig.NodeConfig) if err != nil { return nil, err diff --git a/internal/domain/certificate.go b/internal/domain/certificate.go index 7e11a92e..a4e20d66 100644 --- a/internal/domain/certificate.go +++ b/internal/domain/certificate.go @@ -6,7 +6,7 @@ var ValidityDuration = time.Hour * 24 * 10 type Certificate struct { Meta - SAN string `json:"san" db:"san"` + SubjectAltNames string `json:"san" db:"san"` Certificate string `json:"certificate" db:"certificate"` PrivateKey string `json:"privateKey" db:"privateKey"` IssuerCertificate string `json:"issuerCertificate" db:"issuerCertificate"` diff --git a/internal/repository/workflow_output.go b/internal/repository/workflow_output.go index cf99d82f..34376c73 100644 --- a/internal/repository/workflow_output.go +++ b/internal/repository/workflow_output.go @@ -79,7 +79,7 @@ func (w *WorkflowOutputRepository) GetCertificate(ctx context.Context, nodeId st Certificate: record.GetString("certificate"), PrivateKey: record.GetString("privateKey"), IssuerCertificate: record.GetString("issuerCertificate"), - SAN: record.GetString("san"), + SubjectAltNames: record.GetString("san"), WorkflowOutputId: record.GetString("output"), ExpireAt: record.GetDateTime("expireAt").Time(), CertUrl: record.GetString("certUrl"), @@ -131,7 +131,7 @@ func (w *WorkflowOutputRepository) Save(ctx context.Context, output *domain.Work certRecord.Set("certificate", certificate.Certificate) certRecord.Set("privateKey", certificate.PrivateKey) certRecord.Set("issuerCertificate", certificate.IssuerCertificate) - certRecord.Set("san", certificate.SAN) + certRecord.Set("san", certificate.SubjectAltNames) certRecord.Set("output", certificate.WorkflowOutputId) certRecord.Set("expireAt", certificate.ExpireAt) certRecord.Set("certUrl", certificate.CertUrl) diff --git a/internal/workflow/node-processor/apply_node.go b/internal/workflow/node-processor/apply_node.go index 9ab4baa8..fe415026 100644 --- a/internal/workflow/node-processor/apply_node.go +++ b/internal/workflow/node-processor/apply_node.go @@ -96,7 +96,7 @@ func (a *applyNode) Run(ctx context.Context) error { } certificateRecord := &domain.Certificate{ - SAN: strings.Join(cert.DNSNames, ";"), + SubjectAltNames: strings.Join(cert.DNSNames, ";"), Certificate: certificate.Certificate, PrivateKey: certificate.PrivateKey, IssuerCertificate: certificate.IssuerCertificate, diff --git a/internal/workflow/node-processor/deploy_node.go b/internal/workflow/node-processor/deploy_node.go index ff20eb3b..e93d0eaf 100644 --- a/internal/workflow/node-processor/deploy_node.go +++ b/internal/workflow/node-processor/deploy_node.go @@ -66,8 +66,8 @@ func (d *deployNode) Run(ctx context.Context) error { } option := &deployer.DeployerOption{ - DomainId: d.node.Id, - Domain: cert.SAN, + NodeId: d.node.Id, + Domains: cert.SubjectAltNames, AccessConfig: access.Config, AccessRecord: access, Certificate: applicant.Certificate{ diff --git a/ui/src/components/workflow/WorkflowElement.tsx b/ui/src/components/workflow/WorkflowElement.tsx index c609853f..1578a08d 100644 --- a/ui/src/components/workflow/WorkflowElement.tsx +++ b/ui/src/components/workflow/WorkflowElement.tsx @@ -6,7 +6,15 @@ import { produce } from "immer"; import Show from "@/components/Show"; import { deployProvidersMap } from "@/domain/provider"; import { notifyChannelsMap } from "@/domain/settings"; -import { WORKFLOW_TRIGGERS, type WorkflowNode, WorkflowNodeType } from "@/domain/workflow"; +import { + WORKFLOW_TRIGGERS, + type WorkflowNode, + type WorkflowNodeConfigAsApply, + type WorkflowNodeConfigAsDeploy, + type WorkflowNodeConfigAsNotify, + type WorkflowNodeConfigAsStart, + WorkflowNodeType, +} from "@/domain/workflow"; import { useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; @@ -32,28 +40,31 @@ const WorkflowElement = ({ node, disabled }: NodeProps) => { switch (node.type) { case WorkflowNodeType.Start: { + const config = (node.config as WorkflowNodeConfigAsStart) ?? {}; return (
- {node.config?.trigger === WORKFLOW_TRIGGERS.AUTO + {config.trigger === WORKFLOW_TRIGGERS.AUTO ? t("workflow.props.trigger.auto") - : node.config?.trigger === WORKFLOW_TRIGGERS.MANUAL + : config.trigger === WORKFLOW_TRIGGERS.MANUAL ? t("workflow.props.trigger.manual") : " "} - {node.config?.trigger === WORKFLOW_TRIGGERS.AUTO ? (node.config?.triggerCron as string) : ""} + {config.trigger === WORKFLOW_TRIGGERS.AUTO ? config.triggerCron : ""}
); } case WorkflowNodeType.Apply: { - return {(node.config?.domain as string) || " "}; + const config = (node.config as WorkflowNodeConfigAsApply) ?? {}; + return {config.domains || " "}; } case WorkflowNodeType.Deploy: { - const provider = deployProvidersMap.get(node.config?.provider as string); + const config = (node.config as WorkflowNodeConfigAsDeploy) ?? {}; + const provider = deployProvidersMap.get(config.provider); return ( @@ -63,7 +74,8 @@ const WorkflowElement = ({ node, disabled }: NodeProps) => { } case WorkflowNodeType.Notify: { - const channel = notifyChannelsMap.get(node.config?.channel as string); + const config = (node.config as WorkflowNodeConfigAsNotify) ?? {}; + const channel = notifyChannelsMap.get(config.channel as string); return (
{t(channel?.name ?? " ")} diff --git a/ui/src/components/workflow/node/ApplyNodeForm.tsx b/ui/src/components/workflow/node/ApplyNodeForm.tsx index dd370ebf..8628b245 100644 --- a/ui/src/components/workflow/node/ApplyNodeForm.tsx +++ b/ui/src/components/workflow/node/ApplyNodeForm.tsx @@ -12,7 +12,7 @@ import MultipleInput from "@/components/MultipleInput"; import AccessEditModal from "@/components/access/AccessEditModal"; import AccessSelect from "@/components/access/AccessSelect"; import { ACCESS_USAGES, accessProvidersMap } from "@/domain/provider"; -import { type WorkflowApplyNodeConfig, type WorkflowNode } from "@/domain/workflow"; +import { type WorkflowNode, type WorkflowNodeConfigAsApply } from "@/domain/workflow"; import { useAntdForm, useZustandShallowSelector } from "@/hooks"; import { useAccessesStore } from "@/stores/access"; import { useContactEmailsStore } from "@/stores/contact"; @@ -26,7 +26,7 @@ export type ApplyNodeFormProps = { const MULTIPLE_INPUT_DELIMITER = ";"; -const initFormModel = (): Partial => { +const initFormModel = (): Partial => { return { keyAlgorithm: "RSA2048", propagationTimeout: 60, @@ -43,12 +43,12 @@ const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => { const { hidePanel } = usePanel(); const formSchema = z.object({ - domain: z.string({ message: t("workflow_node.apply.form.domains.placeholder") }).refine((v) => { + domains: z.string({ message: t("workflow_node.apply.form.domains.placeholder") }).refine((v) => { return String(v) .split(MULTIPLE_INPUT_DELIMITER) .every((e) => validDomainName(e, true)); }, t("common.errmsg.domain_invalid")), - email: z.string({ message: t("workflow_node.apply.form.contact_email.placeholder") }).email("common.errmsg.email_invalid"), + contactEmail: z.string({ message: t("workflow_node.apply.form.contact_email.placeholder") }).email("common.errmsg.email_invalid"), providerAccessId: z .string({ message: t("workflow_node.apply.form.provider_access.placeholder") }) .min(1, t("workflow_node.apply.form.provider_access.placeholder")), @@ -76,16 +76,16 @@ const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => { formPending, formProps, } = useAntdForm>({ - initialValues: (node?.config as WorkflowApplyNodeConfig) ?? initFormModel(), + initialValues: (node?.config as WorkflowNodeConfigAsApply) ?? initFormModel(), onSubmit: async (values) => { await formInst.validateFields(); - await addEmail(values.email); + await addEmail(values.contactEmail); await updateNode( produce(node, (draft) => { draft.config = { provider: accesses.find((e) => e.id === values.providerAccessId)?.provider, ...values, - } as WorkflowApplyNodeConfig; + } as WorkflowNodeConfigAsApply; draft.validated = true; }) ); @@ -93,13 +93,13 @@ const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => { }, }); - const [fieldDomains, setFieldDomains] = useState(node?.config?.domain as string); + const [fieldDomains, setFieldDomains] = useState(node?.config?.domains as string); const [fieldNameservers, setFieldNameservers] = useState(node?.config?.nameservers as string); const handleFieldDomainsChange = (e: React.ChangeEvent) => { const value = e.target.value; setFieldDomains(value); - formInst.setFieldValue("domain", value); + formInst.setFieldValue("domains", value); }; const handleFieldNameserversChange = (e: React.ChangeEvent) => { @@ -111,7 +111,7 @@ const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => { return (
} @@ -132,7 +132,7 @@ const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => { } onFinish={(v) => { setFieldDomains(v); - formInst.setFieldValue("domain", v); + formInst.setFieldValue("domains", v); }} /> diff --git a/ui/src/components/workflow/node/DeployNodeForm.tsx b/ui/src/components/workflow/node/DeployNodeForm.tsx index 0363aaa4..364e26a5 100644 --- a/ui/src/components/workflow/node/DeployNodeForm.tsx +++ b/ui/src/components/workflow/node/DeployNodeForm.tsx @@ -12,7 +12,7 @@ import AccessSelect from "@/components/access/AccessSelect"; import DeployProviderPicker from "@/components/provider/DeployProviderPicker"; import DeployProviderSelect from "@/components/provider/DeployProviderSelect"; import { ACCESS_USAGES, DEPLOY_PROVIDERS, accessProvidersMap, deployProvidersMap } from "@/domain/provider"; -import { type WorkflowDeployNodeConfig, type WorkflowNode } from "@/domain/workflow"; +import { type WorkflowNode, type WorkflowNodeConfigAsDeploy } from "@/domain/workflow"; import { useAntdForm, useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; import { usePanel } from "../PanelProvider"; @@ -44,7 +44,7 @@ export type DeployFormProps = { node: WorkflowNode; }; -const initFormModel = (): Partial => { +const initFormModel = (): Partial => { return {}; }; @@ -67,7 +67,7 @@ const DeployNodeForm = ({ node }: DeployFormProps) => { formPending, formProps, } = useAntdForm>({ - initialValues: (node?.config as WorkflowDeployNodeConfig) ?? initFormModel(), + initialValues: (node?.config as WorkflowNodeConfigAsDeploy) ?? initFormModel(), onSubmit: async (values) => { await formInst.validateFields(); await updateNode( diff --git a/ui/src/components/workflow/node/NotifyNodeForm.tsx b/ui/src/components/workflow/node/NotifyNodeForm.tsx index eacecda3..539562b4 100644 --- a/ui/src/components/workflow/node/NotifyNodeForm.tsx +++ b/ui/src/components/workflow/node/NotifyNodeForm.tsx @@ -8,7 +8,7 @@ import { produce } from "immer"; import { z } from "zod"; import { notifyChannelsMap } from "@/domain/settings"; -import { type WorkflowNode, type WorkflowNotifyNodeConfig } from "@/domain/workflow"; +import { type WorkflowNode, type WorkflowNodeConfigAsNotify } from "@/domain/workflow"; import { useAntdForm, useZustandShallowSelector } from "@/hooks"; import { useNotifyChannelsStore } from "@/stores/notify"; import { useWorkflowStore } from "@/stores/workflow"; @@ -18,7 +18,7 @@ export type NotifyNodeFormProps = { node: WorkflowNode; }; -const initFormModel = (): Partial => { +const initFormModel = (): Partial => { return { subject: "Completed!", message: "Your workflow has been completed on Certimate.", @@ -57,7 +57,7 @@ const NotifyNodeForm = ({ node }: NotifyNodeFormProps) => { formPending, formProps, } = useAntdForm>({ - initialValues: (node?.config as WorkflowNotifyNodeConfig) ?? initFormModel(), + initialValues: (node?.config as WorkflowNodeConfigAsNotify) ?? initFormModel(), onSubmit: async (values) => { await formInst.validateFields(); await updateNode( diff --git a/ui/src/components/workflow/node/StartNodeForm.tsx b/ui/src/components/workflow/node/StartNodeForm.tsx index 01d7541a..326d7f32 100644 --- a/ui/src/components/workflow/node/StartNodeForm.tsx +++ b/ui/src/components/workflow/node/StartNodeForm.tsx @@ -7,7 +7,7 @@ import { produce } from "immer"; import { z } from "zod"; import Show from "@/components/Show"; -import { WORKFLOW_TRIGGERS, type WorkflowNode, type WorkflowStartNodeConfig } from "@/domain/workflow"; +import { WORKFLOW_TRIGGERS, type WorkflowNode, type WorkflowNodeConfigAsStart } from "@/domain/workflow"; import { useAntdForm, useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; import { getNextCronExecutions, validCronExpression } from "@/utils/cron"; @@ -17,7 +17,7 @@ export type StartNodeFormProps = { node: WorkflowNode; }; -const initFormModel = (): WorkflowStartNodeConfig => { +const initFormModel = (): WorkflowNodeConfigAsStart => { return { trigger: WORKFLOW_TRIGGERS.AUTO, triggerCron: "0 0 * * *", @@ -54,7 +54,7 @@ const StartNodeForm = ({ node }: StartNodeFormProps) => { formPending, formProps, } = useAntdForm>({ - initialValues: (node?.config as WorkflowStartNodeConfig) ?? initFormModel(), + initialValues: (node?.config as WorkflowNodeConfigAsStart) ?? initFormModel(), onSubmit: async (values) => { await formInst.validateFields(); await updateNode( diff --git a/ui/src/domain/workflow.ts b/ui/src/domain/workflow.ts index 06f17829..996fa6d4 100644 --- a/ui/src/domain/workflow.ts +++ b/ui/src/domain/workflow.ts @@ -92,14 +92,14 @@ export type WorkflowNode = { validated?: boolean; }; -export type WorkflowStartNodeConfig = { +export type WorkflowNodeConfigAsStart = { trigger: string; triggerCron?: string; }; -export type WorkflowApplyNodeConfig = { - domain: string; - email: string; +export type WorkflowNodeConfigAsApply = { + domains: string; + contactEmail: string; provider: string; providerAccessId: string; keyAlgorithm: string; @@ -108,22 +108,22 @@ export type WorkflowApplyNodeConfig = { disableFollowCNAME?: boolean; }; -export type WorkflowDeployNodeConfig = { +export type WorkflowNodeConfigAsDeploy = { provider: string; providerAccessId: string; certificate: string; [key: string]: unknown; }; -export type WorkflowNotifyNodeConfig = { +export type WorkflowNodeConfigAsNotify = { channel: string; subject: string; message: string; }; -export type WorkflowBranchNodeConfig = never; +export type WorkflowNodeConfigAsBranch = never; -export type WorkflowEndNodeConfig = never; +export type WorkflowNodeConfigAsEnd = never; export type WorkflowNodeIO = { name: string;