From 6c15ae35a1645a7ad51e428bb5345d9859715ffe Mon Sep 17 00:00:00 2001 From: v-me-50 Date: Tue, 13 Jan 2026 16:12:29 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91litessl=20?= =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91=E5=88=A0=E9=99=A4=E5=8E=86?= =?UTF-8?q?=E5=8F=B2=E8=AE=B0=E5=BD=95=20=E3=80=90=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E3=80=91=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4=E8=AF=81=E4=B9=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/workflow.go | 20 +++++++++ backend/internal/cert/apply/apply.go | 44 +++++++++++++++++++ backend/internal/cert/cert.go | 4 ++ backend/internal/workflow/workflow_history.go | 28 ++++++++++++ backend/migrations/init.go | 1 + backend/route/route.go | 1 + 6 files changed, 98 insertions(+) diff --git a/backend/app/api/workflow.go b/backend/app/api/workflow.go index 03ee978..919c5f5 100644 --- a/backend/app/api/workflow.go +++ b/backend/app/api/workflow.go @@ -234,3 +234,23 @@ func GetExecLog(c *gin.Context) { public.SuccessData(c, data, 0) return } + +func DelWorkflowHistory(c *gin.Context) { + var form struct { + ID string `form:"id"` + } + err := c.Bind(&form) + if err != nil { + public.FailMsg(c, err.Error()) + return + } + form.ID = strings.TrimSpace(form.ID) + + err = workflow.DelWorkflowHistory(form.ID) + if err != nil { + public.FailMsg(c, err.Error()) + return + } + public.SuccessMsg(c, "删除成功") + return +} diff --git a/backend/internal/cert/apply/apply.go b/backend/internal/cert/apply/apply.go index f2abaf2..5f82496 100644 --- a/backend/internal/cert/apply/apply.go +++ b/backend/internal/cert/apply/apply.go @@ -65,6 +65,7 @@ var CADirURLMap = map[string]string{ "sslcom-rsa": "https://acme.ssl.com/sslcom-dv-rsa", "sslcom-ecc": "https://acme.ssl.com/sslcom-dv-ecc", "buypass": "https://api.buypass.com/acme/directory", + "litessl": "https://acme.litessl.com/acme/v2/directory", } func GetSqlite() (*public.Sqlite, error) { @@ -286,6 +287,47 @@ func GetZeroSSLEabFromEmail(email string, httpClient *http.Client) (map[string]a }, nil } +func GetEabFromBt(httpClient *http.Client) (map[string]any, error) { + APIPath := "https://www.bt.cn/api/v3/litessl/eab" + data := map[string]any{} + jsonData, err := json.Marshal(data) + if err != nil { + return nil, err + } + req, err := http.NewRequest("POST", APIPath, strings.NewReader(string(jsonData))) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + if httpClient == nil { + httpClient = &http.Client{} + } + resp, err := httpClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("获取BT EAB信息失败,状态码:%d", resp.StatusCode) + } + var result map[string]any + err = json.NewDecoder(resp.Body).Decode(&result) + if err != nil { + return nil, fmt.Errorf("解析BT EAB信息失败:%v", err) + } + res, ok := result["res"].(map[string]map[string]any) + if !ok { + return nil, fmt.Errorf("BT EAB信息格式错误,缺少res字段") + } + if res["data"]["eab_kid"] == nil || res["data"]["eab_hmac"] == nil { + return nil, fmt.Errorf("BT EAB信息不完整,缺少kid或hmacEncoded") + } + return map[string]any{ + "Kid": res["data"]["eab_kid"], + "HmacEncoded": res["data"]["eab_hmac"], + }, nil +} + func getEABFromAccData(accData map[string]any, eabData *map[string]any) bool { if accData == nil { return false @@ -388,6 +430,8 @@ func GetAcmeClient(email, algorithm, eabId, ca string, httpClient *http.Client, if err != nil { return nil, fmt.Errorf("获取ZeroSSL EAB信息失败: %v", err) } + case "litessl": + eabData, err = GetEabFromBt(httpClient) case "sslcom", "google": return nil, fmt.Errorf("未找到EAB信息,请在账号管理中添加%s账号", ca) } diff --git a/backend/internal/cert/cert.go b/backend/internal/cert/cert.go index fa4f38d..a8a854f 100644 --- a/backend/internal/cert/cert.go +++ b/backend/internal/cert/cert.go @@ -145,6 +145,10 @@ func SaveCert(source, key, cert, issuerCert, historyId string) (string, error) { for _, dns := range certObj.DNSNames { domainSet[dns] = true } + // 处理 IP 地址 + for _, ip := range certObj.IPAddresses { + domainSet[ip.String()] = true + } // 转成切片并拼接成逗号分隔的字符串 var domains []string diff --git a/backend/internal/workflow/workflow_history.go b/backend/internal/workflow/workflow_history.go index c56f650..d812ec8 100644 --- a/backend/internal/workflow/workflow_history.go +++ b/backend/internal/workflow/workflow_history.go @@ -163,3 +163,31 @@ func CleanWorkflowHistory() error { } return nil } + +// DelWorkflowHistory 删除工作流执行历史记录 +func DelWorkflowHistory(ids string) error { + idArr := strings.Split(ids, ",") + s, err := GetSqliteObjWH() + if err != nil { + return err + } + defer s.Close() + _, err = s.Where("id IN ('"+strings.Join(idArr, "','")+"')", nil).Delete() + if err != nil { + return err + } + // 删除工作流执行日志 + logPath := public.GetSettingIgnoreError("workflow_log_path") + if logPath == "" { + logPath = "logs/workflow" + } + for _, id := range idArr { + logFile := filepath.Join(logPath, id+".log") + if _, err := os.Stat(logFile); err == nil { + if err := os.Remove(logFile); err != nil { + return err + } + } + } + return nil +} diff --git a/backend/migrations/init.go b/backend/migrations/init.go index 823b42b..27f0ee4 100644 --- a/backend/migrations/init.go +++ b/backend/migrations/init.go @@ -200,6 +200,7 @@ func init() { InsertIfNotExists(db, "access_type", map[string]any{"name": "webhook", "type": "host"}, []string{"name", "type"}, []any{"webhook", "host"}) InsertIfNotExists(db, "access_type", map[string]any{"name": "btdomain", "type": "dns"}, []string{"name", "type"}, []any{"btdomain", "dns"}) + InsertIfNotExists(db, "access_type", map[string]any{"name": "edgeone", "type": "dns"}, []string{"name", "type"}, []any{"edgeone", "dns"}) err = sqlite_migrate.EnsureDatabaseWithTables( "data/site_monitor.db", diff --git a/backend/route/route.go b/backend/route/route.go index d385173..aabaf1a 100644 --- a/backend/route/route.go +++ b/backend/route/route.go @@ -47,6 +47,7 @@ func Register(r *gin.Engine) { workflow.POST("/get_workflow_history", api.GetWorkflowHistory) workflow.POST("/get_exec_log", api.GetExecLog) workflow.POST("/stop", api.StopWorkflow) + workflow.POST("/del_workflow_history", api.DelWorkflowHistory) } access := v1.Group("/access") {