mirror of https://github.com/certd/certd
perf: 支持邮箱发送证书
parent
9864792bbf
commit
95332d5db9
|
@ -1,7 +1,9 @@
|
||||||
export type EmailSend = {
|
export type EmailSend = {
|
||||||
subject: string;
|
subject: string;
|
||||||
content: string;
|
|
||||||
receivers: string[];
|
receivers: string[];
|
||||||
|
content?: string;
|
||||||
|
attachments?: any[];
|
||||||
|
html?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IEmailService {
|
export interface IEmailService {
|
||||||
|
|
|
@ -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 dayjs from "dayjs";
|
||||||
import type { CertInfo } from "./acme.js";
|
import type { CertInfo } from "./acme.js";
|
||||||
import { CertReader } from "./cert-reader.js";
|
import { CertReader } from "./cert-reader.js";
|
||||||
|
@ -71,6 +71,12 @@ export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
|
||||||
})
|
})
|
||||||
cert?: CertInfo;
|
cert?: CertInfo;
|
||||||
|
|
||||||
|
@TaskOutput({
|
||||||
|
title: "域名证书压缩文件",
|
||||||
|
type: "certZip",
|
||||||
|
})
|
||||||
|
certZip?: FileItem;
|
||||||
|
|
||||||
async onInstance() {
|
async onInstance() {
|
||||||
this.userContext = this.ctx.userContext;
|
this.userContext = this.ctx.userContext;
|
||||||
this.lastStatus = this.ctx.lastStatus as Step;
|
this.lastStatus = this.ctx.lastStatus as Step;
|
||||||
|
@ -131,6 +137,7 @@ export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
|
||||||
} else {
|
} else {
|
||||||
this.extendsFiles();
|
this.extendsFiles();
|
||||||
}
|
}
|
||||||
|
this.certZip = this._result.files[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
async zipCert(cert: CertInfo, filename: string) {
|
async zipCert(cert: CertInfo, filename: string) {
|
||||||
|
|
|
@ -98,6 +98,8 @@ export class EmailService implements IEmailService {
|
||||||
to: email.receivers.join(', '), // list of receivers
|
to: email.receivers.join(', '), // list of receivers
|
||||||
subject: subject,
|
subject: subject,
|
||||||
text: email.content,
|
text: email.content,
|
||||||
|
html: email.html,
|
||||||
|
attachments: email.attachments,
|
||||||
};
|
};
|
||||||
await transporter.sendMail(mailOptions);
|
await transporter.sendMail(mailOptions);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,3 +2,4 @@ export * from './plugin-restart.js';
|
||||||
export * from './plugin-script.js';
|
export * from './plugin-script.js';
|
||||||
export * from './plugin-wait.js';
|
export * from './plugin-wait.js';
|
||||||
export * from './plugin-db-backup.js';
|
export * from './plugin-db-backup.js';
|
||||||
|
export * from './plugin-deploy-to-mail.js';
|
||||||
|
|
|
@ -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<void> {
|
||||||
|
|
||||||
|
this.logger.info(`开始发送邮件`);
|
||||||
|
const certReader = new CertReader(this.cert)
|
||||||
|
const mainDomain = certReader.getMainDomain();
|
||||||
|
const domains = certReader.getAllDomains().join(',');
|
||||||
|
const title = `证书申请成功【${mainDomain}】`;
|
||||||
|
const html = `
|
||||||
|
<div>
|
||||||
|
<p>证书申请成功</p>
|
||||||
|
<p>域名:${domains}</p>
|
||||||
|
<p>证书有效期:${dayjs(certReader.expires).format("YYYY-MM-DD HH:mm:ss")}</p>
|
||||||
|
<p>备注:${this.remark||""}</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
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();
|
|
@ -5,7 +5,7 @@ import { TencentAccess } from "@certd/plugin-lib";
|
||||||
name: 'DeployCertToTencentEO',
|
name: 'DeployCertToTencentEO',
|
||||||
title: '腾讯云-部署到腾讯云EO',
|
title: '腾讯云-部署到腾讯云EO',
|
||||||
icon: 'svg:icon-tencentcloud',
|
icon: 'svg:icon-tencentcloud',
|
||||||
desc: '腾讯云边缘安全加速平台EO,必须配置上传证书到腾讯云任务',
|
desc: '腾讯云边缘安全加速平台EdgeOne(EO),必须配置上传证书到腾讯云任务',
|
||||||
group: pluginGroups.tencent.key,
|
group: pluginGroups.tencent.key,
|
||||||
default: {
|
default: {
|
||||||
strategy: {
|
strategy: {
|
||||||
|
|
Loading…
Reference in New Issue