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;