diff --git a/packages/core/pipeline/src/service/email.ts b/packages/core/pipeline/src/service/email.ts index 871a185b..dd3b6561 100644 --- a/packages/core/pipeline/src/service/email.ts +++ b/packages/core/pipeline/src/service/email.ts @@ -1,7 +1,9 @@ export type EmailSend = { subject: string; - content: string; receivers: string[]; + content?: string; + attachments?: any[]; + html?: string; }; export interface IEmailService { diff --git a/packages/plugins/plugin-cert/src/plugin/cert-plugin/base-convert.ts b/packages/plugins/plugin-cert/src/plugin/cert-plugin/base-convert.ts index 48381706..00f1614a 100644 --- a/packages/plugins/plugin-cert/src/plugin/cert-plugin/base-convert.ts +++ b/packages/plugins/plugin-cert/src/plugin/cert-plugin/base-convert.ts @@ -1,4 +1,4 @@ -import { AbstractTaskPlugin, IContext, Step, TaskInput, TaskOutput } from "@certd/pipeline"; +import { AbstractTaskPlugin, FileItem, IContext, Step, TaskInput, TaskOutput } from "@certd/pipeline"; import dayjs from "dayjs"; import type { CertInfo } from "./acme.js"; import { CertReader } from "./cert-reader.js"; @@ -71,6 +71,12 @@ export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin { }) cert?: CertInfo; + @TaskOutput({ + title: "域名证书压缩文件", + type: "certZip", + }) + certZip?: FileItem; + async onInstance() { this.userContext = this.ctx.userContext; this.lastStatus = this.ctx.lastStatus as Step; @@ -131,6 +137,7 @@ export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin { } else { this.extendsFiles(); } + this.certZip = this._result.files[0]; } async zipCert(cert: CertInfo, filename: string) { diff --git a/packages/ui/certd-server/src/modules/basic/service/email-service.ts b/packages/ui/certd-server/src/modules/basic/service/email-service.ts index 25b19644..6159600a 100644 --- a/packages/ui/certd-server/src/modules/basic/service/email-service.ts +++ b/packages/ui/certd-server/src/modules/basic/service/email-service.ts @@ -98,6 +98,8 @@ export class EmailService implements IEmailService { to: email.receivers.join(', '), // list of receivers subject: subject, text: email.content, + html: email.html, + attachments: email.attachments, }; await transporter.sendMail(mailOptions); } diff --git a/packages/ui/certd-server/src/plugins/plugin-other/plugins/index.ts b/packages/ui/certd-server/src/plugins/plugin-other/plugins/index.ts index 25488992..c12c34da 100644 --- a/packages/ui/certd-server/src/plugins/plugin-other/plugins/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-other/plugins/index.ts @@ -2,3 +2,4 @@ export * from './plugin-restart.js'; export * from './plugin-script.js'; export * from './plugin-wait.js'; export * from './plugin-db-backup.js'; +export * from './plugin-deploy-to-mail.js'; diff --git a/packages/ui/certd-server/src/plugins/plugin-other/plugins/plugin-deploy-to-mail.ts b/packages/ui/certd-server/src/plugins/plugin-other/plugins/plugin-deploy-to-mail.ts new file mode 100644 index 00000000..73a2a85a --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-other/plugins/plugin-deploy-to-mail.ts @@ -0,0 +1,98 @@ +import {AbstractTaskPlugin, FileItem, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput} from '@certd/pipeline'; +import {CertInfo, CertReader} from "@certd/plugin-cert"; +import dayjs from "dayjs"; + +@IsTaskPlugin({ + name: 'DeployCertToMailPlugin', + title: '邮件发送证书', + icon: 'ri:rest-time-line', + desc: '通过邮件发送证书', + group: pluginGroups.other.key, + showRunStrategy:false, + default: { + strategy: { + runStrategy: RunStrategy.SkipWhenSucceed, + }, + }, +}) +export class DeployCertToMailPlugin extends AbstractTaskPlugin { + + @TaskInput({ + title: '域名证书', + helper: '请选择前置任务输出的域名证书', + component: { + name: 'output-selector', + from: [":cert:"], + }, + required: true, + }) + cert!: CertInfo; + + @TaskInput({ + title: '证书压缩文件', + helper: '请选择前置任务输出的域名证书压缩文件', + component: { + name: 'output-selector', + from: [":certZip:"], + }, + required: true, + }) + certZip!: FileItem; + + @TaskInput({ + title: '接收邮箱', + component: { + name: 'EmailSelector', + vModel: 'value', + mode:"tags", + }, + required: true, + }) + email!: string[]; + + @TaskInput({ + title: '备注', + component: { + name: 'a-input', + vModel: 'value', + }, + required: false, + }) + remark!: string; + + async onInstance() {} + async execute(): Promise { + + this.logger.info(`开始发送邮件`); + const certReader = new CertReader(this.cert) + const mainDomain = certReader.getMainDomain(); + const domains = certReader.getAllDomains().join(','); + const title = `证书申请成功【${mainDomain}】`; + const html = ` +
+

证书申请成功

+

域名:${domains}

+

证书有效期:${dayjs(certReader.expires).format("YYYY-MM-DD HH:mm:ss")}

+

备注:${this.remark||""}

+
+ `; + const file = this.certZip + if (!file) { + throw new Error('证书压缩文件还未生成,重新运行证书任务'); + } + await this.ctx.emailService.send({ + subject:title, + html: html, + receivers: this.email, + attachments: [ + { + filename: file.filename, + path: file.path, + }, + ], + }) + + + } +} +new DeployCertToMailPlugin(); diff --git a/packages/ui/certd-server/src/plugins/plugin-tencent/plugin/deploy-to-eo/index.ts b/packages/ui/certd-server/src/plugins/plugin-tencent/plugin/deploy-to-eo/index.ts index ab4b16f7..df3c1074 100644 --- a/packages/ui/certd-server/src/plugins/plugin-tencent/plugin/deploy-to-eo/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-tencent/plugin/deploy-to-eo/index.ts @@ -5,7 +5,7 @@ import { TencentAccess } from "@certd/plugin-lib"; name: 'DeployCertToTencentEO', title: '腾讯云-部署到腾讯云EO', icon: 'svg:icon-tencentcloud', - desc: '腾讯云边缘安全加速平台EO,必须配置上传证书到腾讯云任务', + desc: '腾讯云边缘安全加速平台EdgeOne(EO),必须配置上传证书到腾讯云任务', group: pluginGroups.tencent.key, default: { strategy: {