From 3a2baba746a6341daeeeaee618da2537274d5c63 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Thu, 16 Jan 2025 21:53:51 +0800 Subject: [PATCH] feat: support removing certificates --- internal/certificate/service.go | 6 ++-- internal/repository/access.go | 3 +- internal/repository/certificate.go | 3 +- ui/src/domain/settings.ts | 2 +- ui/src/i18n/locales/en/nls.certificate.json | 1 + ui/src/i18n/locales/en/nls.dashboard.json | 4 +-- ui/src/i18n/locales/zh/nls.access.json | 2 +- ui/src/i18n/locales/zh/nls.certificate.json | 1 + ui/src/i18n/locales/zh/nls.workflow.json | 2 +- .../i18n/locales/zh/nls.workflow.nodes.json | 2 +- ui/src/pages/accesses/AccessList.tsx | 3 +- ui/src/pages/certificates/CertificateList.tsx | 36 +++++++++++++------ ui/src/pages/dashboard/Dashboard.tsx | 4 +-- ui/src/pages/workflows/WorkflowDetail.tsx | 2 +- ui/src/pages/workflows/WorkflowList.tsx | 5 +-- ui/src/repository/access.ts | 1 + ui/src/repository/certificate.ts | 1 + 17 files changed, 48 insertions(+), 30 deletions(-) diff --git a/internal/certificate/service.go b/internal/certificate/service.go index a4558e74..af46c202 100644 --- a/internal/certificate/service.go +++ b/internal/certificate/service.go @@ -13,7 +13,7 @@ import ( ) const ( - defaultExpireSubject = "您有 ${COUNT} 张证书即将过期" + defaultExpireSubject = "有 ${COUNT} 张证书即将过期" defaultExpireMessage = "有 ${COUNT} 张证书即将过期,域名分别为 ${DOMAINS},请保持关注!" ) @@ -36,7 +36,7 @@ func (s *CertificateService) InitSchedule(ctx context.Context) error { err := scheduler.Add("certificate", "0 0 * * *", func() { certs, err := s.repo.ListExpireSoon(context.Background()) if err != nil { - app.GetLogger().Error("failed to get expire soon certificate", "err", err) + app.GetLogger().Error("failed to get certificates which expire soon", "err", err) return } @@ -46,7 +46,7 @@ func (s *CertificateService) InitSchedule(ctx context.Context) error { } if err := notify.SendToAllChannels(notification.Subject, notification.Message); err != nil { - app.GetLogger().Error("failed to send expire soon certificate", "err", err) + app.GetLogger().Error("failed to send notification", "err", err) } }) if err != nil { diff --git a/internal/repository/access.go b/internal/repository/access.go index 9612c123..9244a112 100644 --- a/internal/repository/access.go +++ b/internal/repository/access.go @@ -9,7 +9,6 @@ import ( "github.com/pocketbase/pocketbase/models" "github.com/usual2970/certimate/internal/app" "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/pkg/utils/types" ) type AccessRepository struct{} @@ -27,7 +26,7 @@ func (r *AccessRepository) GetById(ctx context.Context, id string) (*domain.Acce return nil, err } - if !types.IsNil(record.Get("deleted")) { + if !record.GetDateTime("deleted").Time().IsZero() { return nil, domain.ErrRecordNotFound } diff --git a/internal/repository/certificate.go b/internal/repository/certificate.go index 1ff31ac0..0499eb48 100644 --- a/internal/repository/certificate.go +++ b/internal/repository/certificate.go @@ -10,7 +10,6 @@ import ( "github.com/pocketbase/pocketbase/models" "github.com/usual2970/certimate/internal/app" "github.com/usual2970/certimate/internal/domain" - "github.com/usual2970/certimate/internal/pkg/utils/types" ) type CertificateRepository struct{} @@ -52,7 +51,7 @@ func (r *CertificateRepository) GetById(ctx context.Context, id string) (*domain return nil, err } - if !types.IsNil(record.Get("deleted")) { + if !record.GetDateTime("deleted").Time().IsZero() { return nil, domain.ErrRecordNotFound } diff --git a/ui/src/domain/settings.ts b/ui/src/domain/settings.ts index 9df3dc05..977d80fc 100644 --- a/ui/src/domain/settings.ts +++ b/ui/src/domain/settings.ts @@ -29,7 +29,7 @@ export type NotifyTemplate = { }; export const defaultNotifyTemplate: NotifyTemplate = { - subject: "您有 ${COUNT} 张证书即将过期", + subject: "有 ${COUNT} 张证书即将过期", message: "有 ${COUNT} 张证书即将过期,域名分别为 ${DOMAINS},请保持关注!", }; // #endregion diff --git a/ui/src/i18n/locales/en/nls.certificate.json b/ui/src/i18n/locales/en/nls.certificate.json index dd9aa4c2..deb6508d 100644 --- a/ui/src/i18n/locales/en/nls.certificate.json +++ b/ui/src/i18n/locales/en/nls.certificate.json @@ -5,6 +5,7 @@ "certificate.action.view": "View certificate", "certificate.action.delete": "Delete certificate", + "certificate.action.delete.confirm": "Are you sure to delete this certificate?", "certificate.action.download": "Download certificate", "certificate.props.subject_alt_names": "Name", diff --git a/ui/src/i18n/locales/en/nls.dashboard.json b/ui/src/i18n/locales/en/nls.dashboard.json index e179f20f..8ae9d94d 100644 --- a/ui/src/i18n/locales/en/nls.dashboard.json +++ b/ui/src/i18n/locales/en/nls.dashboard.json @@ -13,6 +13,6 @@ "dashboard.quick_actions": "Quick actions", "dashboard.quick_actions.create_workflow": "Create workflow", "dashboard.quick_actions.change_login_password": "Change login password", - "dashboard.quick_actions.notification_settings": "Notification settings", - "dashboard.quick_actions.certificate_authority_configuration": "Certificate authority configuration" + "dashboard.quick_actions.cofigure_notification": "Configure notificaion", + "dashboard.quick_actions.configure_ca": "Configure certificate authority" } diff --git a/ui/src/i18n/locales/zh/nls.access.json b/ui/src/i18n/locales/zh/nls.access.json index dc8d8c93..35a10eda 100644 --- a/ui/src/i18n/locales/zh/nls.access.json +++ b/ui/src/i18n/locales/zh/nls.access.json @@ -20,7 +20,7 @@ "access.form.name.placeholder": "请输入授权名称", "access.form.provider.label": "提供商", "access.form.provider.placeholder": "请选择提供商", - "access.form.provider.tooltip": "提供商分为两种类型:
【DNS 提供商】您的 DNS 托管方,通常等同于域名注册商,用于在申请证书时管理您的域名解析记录。
【主机提供商】您的服务器或云服务的托管方,用于部署签发的证书。

该字段保存后不可修改。", + "access.form.provider.tooltip": "提供商分为两种类型:
【DNS 提供商】你的 DNS 托管方,通常等同于域名注册商,用于在申请证书时管理您的域名解析记录。
【主机提供商】你的服务器或云服务的托管方,用于部署签发的证书。

该字段保存后不可修改。", "access.form.acmehttpreq_endpoint.label": "服务端点", "access.form.acmehttpreq_endpoint.placeholder": "请输入服务端点", "access.form.acmehttpreq_endpoint.tooltip": "这是什么?请参阅 https://go-acme.github.io/lego/dns/httpreq/", diff --git a/ui/src/i18n/locales/zh/nls.certificate.json b/ui/src/i18n/locales/zh/nls.certificate.json index bf14655b..f4a86d95 100644 --- a/ui/src/i18n/locales/zh/nls.certificate.json +++ b/ui/src/i18n/locales/zh/nls.certificate.json @@ -5,6 +5,7 @@ "certificate.action.view": "查看证书", "certificate.action.delete": "删除证书", + "certificate.action.delete.confirm": "确定要删除此证书吗?", "certificate.action.download": "下载证书", "certificate.props.subject_alt_names": "名称", diff --git a/ui/src/i18n/locales/zh/nls.workflow.json b/ui/src/i18n/locales/zh/nls.workflow.json index 46058991..31c726f9 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.json +++ b/ui/src/i18n/locales/zh/nls.workflow.json @@ -49,7 +49,7 @@ "workflow.detail.orchestration.action.release.confirm": "确定要发布更改吗?", "workflow.detail.orchestration.action.release.failed.uncompleted": "流程编排未完成,请检查是否有节点未配置", "workflow.detail.orchestration.action.run": "执行", - "workflow.detail.orchestration.action.run.confirm": "你有尚未发布的更改。你确定要以最近一次发布的版本继续执行吗?", + "workflow.detail.orchestration.action.run.confirm": "你有尚未发布的更改。确定要以最近一次发布的版本继续执行吗?", "workflow.detail.orchestration.action.run.prompt": "执行中……请稍后查看执行历史", "workflow.detail.runs.tab": "执行历史" } diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index b6291e06..9ea8c7dc 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -7,7 +7,7 @@ "workflow_node.action.rename_branch": "重命名", "workflow_node.action.remove_branch": "删除分支", - "workflow_node.unsaved_changes.confirm": "你有尚未保存的更改。你确定要关闭面板吗?", + "workflow_node.unsaved_changes.confirm": "你有尚未保存的更改。确定要关闭面板吗?", "workflow_node.start.label": "开始", "workflow_node.start.form.trigger.label": "触发方式", diff --git a/ui/src/pages/accesses/AccessList.tsx b/ui/src/pages/accesses/AccessList.tsx index ba7d59d8..6fa03647 100644 --- a/ui/src/pages/accesses/AccessList.tsx +++ b/ui/src/pages/accesses/AccessList.tsx @@ -130,7 +130,7 @@ const AccessList = () => { }); }, []); - const { loading } = useRequest( + const { loading, run: refreshTableData } = useRequest( () => { const startIndex = (page - 1) * pageSize; const endIndex = startIndex + pageSize; @@ -157,6 +157,7 @@ const AccessList = () => { // TODO: 有关联数据的不允许被删除 try { await deleteAccess(data); + refreshTableData(); } catch (err) { console.error(err); notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) }); diff --git a/ui/src/pages/certificates/CertificateList.tsx b/ui/src/pages/certificates/CertificateList.tsx index 7ee33b7c..a78c9326 100644 --- a/ui/src/pages/certificates/CertificateList.tsx +++ b/ui/src/pages/certificates/CertificateList.tsx @@ -4,13 +4,13 @@ import { useNavigate, useSearchParams } from "react-router-dom"; import { DeleteOutlined as DeleteOutlinedIcon, SelectOutlined as SelectOutlinedIcon } from "@ant-design/icons"; import { PageHeader } from "@ant-design/pro-components"; import { useRequest } from "ahooks"; -import { Button, Divider, Empty, Menu, type MenuProps, Radio, Space, Table, type TableProps, Tooltip, Typography, notification, theme } from "antd"; +import { Button, Divider, Empty, Menu, type MenuProps, Modal, Radio, Space, Table, type TableProps, Tooltip, Typography, notification, theme } from "antd"; import dayjs from "dayjs"; import { ClientResponseError } from "pocketbase"; import CertificateDetailDrawer from "@/components/certificate/CertificateDetailDrawer"; import { CERTIFICATE_SOURCES, type CertificateModel } from "@/domain/certificate"; -import { type ListCertificateRequest, list as listCertificate } from "@/repository/certificate"; +import { type ListCertificateRequest, list as listCertificate, remove as removeCertificate } from "@/repository/certificate"; import { getErrMsg } from "@/utils/error"; const CertificateList = () => { @@ -21,6 +21,7 @@ const CertificateList = () => { const { token: themeToken } = theme.useToken(); + const [modalApi, ModalContextHolder] = Modal.useModal(); const [notificationApi, NotificationContextHolder] = notification.useNotification(); const tableColumns: TableProps["columns"] = [ @@ -169,14 +170,7 @@ const CertificateList = () => { /> - diff --git a/ui/src/pages/workflows/WorkflowDetail.tsx b/ui/src/pages/workflows/WorkflowDetail.tsx index 826703b3..f2f46398 100644 --- a/ui/src/pages/workflows/WorkflowDetail.tsx +++ b/ui/src/pages/workflows/WorkflowDetail.tsx @@ -109,7 +109,7 @@ const WorkflowDetail = () => { content: t("workflow.action.delete.confirm"), onOk: async () => { try { - const resp: boolean = await removeWorkflow(workflow); + const resp = await removeWorkflow(workflow); if (resp) { navigate("/workflows", { replace: true }); } diff --git a/ui/src/pages/workflows/WorkflowList.tsx b/ui/src/pages/workflows/WorkflowList.tsx index fa3f9154..30975917 100644 --- a/ui/src/pages/workflows/WorkflowList.tsx +++ b/ui/src/pages/workflows/WorkflowList.tsx @@ -240,7 +240,7 @@ const WorkflowList = () => { const [page, setPage] = useState(() => parseInt(+searchParams.get("page")! + "") || 1); const [pageSize, setPageSize] = useState(() => parseInt(+searchParams.get("perPage")! + "") || 10); - const { loading } = useRequest( + const { loading, run: refreshTableData } = useRequest( () => { return listWorkflow({ page: page, @@ -302,9 +302,10 @@ const WorkflowList = () => { content: t("workflow.action.delete.confirm"), onOk: async () => { try { - const resp: boolean = await removeWorkflow(workflow); + const resp = await removeWorkflow(workflow); if (resp) { setTableData((prev) => prev.filter((item) => item.id !== workflow.id)); + refreshTableData(); } } catch (err) { console.error(err); diff --git a/ui/src/repository/access.ts b/ui/src/repository/access.ts index a29b33d8..02d9827b 100644 --- a/ui/src/repository/access.ts +++ b/ui/src/repository/access.ts @@ -30,4 +30,5 @@ export const remove = async (record: MaybeModelRecordWithId) => { if ("provider" in record && record.provider === "pdns") record.provider = "powerdns"; await getPocketBase().collection(COLLECTION_NAME).update(record.id!, record); + return true; }; diff --git a/ui/src/repository/certificate.ts b/ui/src/repository/certificate.ts index 0654dc28..64ae9edb 100644 --- a/ui/src/repository/certificate.ts +++ b/ui/src/repository/certificate.ts @@ -42,4 +42,5 @@ export const remove = async (record: MaybeModelRecordWithId) = record = { ...record, deleted: dayjs.utc().format("YYYY-MM-DD HH:mm:ss") }; await getPocketBase().collection(COLLECTION_NAME).update(record.id!, record); + return true; };