diff --git a/packages/core/pipeline/src/service/email.ts b/packages/core/pipeline/src/service/email.ts index a427ef718..7b533139a 100644 --- a/packages/core/pipeline/src/service/email.ts +++ b/packages/core/pipeline/src/service/email.ts @@ -9,7 +9,8 @@ export type EmailSend = { export type EmailSendByTemplateReq = { type: string; data: any; - email: { receivers: string[]; attachments?: any[] }; + receivers: string[]; + attachments?: any[]; }; export interface IEmailService { diff --git a/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx b/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx index 100cb5bb5..e4641dc80 100644 --- a/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx +++ b/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx @@ -145,6 +145,9 @@ export default function ({ crudExpose, context: { selectedRowKeys } }: CreateCru }, }, }, + search: { + col: { span: 3 }, + }, form: { afterSubmit({ form, res, mode }) { if (mode === "add") { @@ -262,6 +265,7 @@ export default function ({ crudExpose, context: { selectedRowKeys } }: CreateCru type: "number", search: { show: true, + col: { span: 3 }, }, column: { width: 100, @@ -277,6 +281,7 @@ export default function ({ crudExpose, context: { selectedRowKeys } }: CreateCru show: computed(() => { return userStore.isAdmin && settingStore.sysPublic.managerOtherUserPipeline; }), + col: { span: 3 }, }, form: { show: false, @@ -297,6 +302,7 @@ export default function ({ crudExpose, context: { selectedRowKeys } }: CreateCru component: { name: "a-input", }, + col: { span: 3 }, }, form: { rules: [{ required: true, message: t("certd.fields.required") }], diff --git a/packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts b/packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts index ca98051e7..5f143bf1b 100644 --- a/packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts +++ b/packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts @@ -33,7 +33,20 @@ export class PipelineController extends CrudController { async page(@Body(ALL) body) { const isAdmin = await this.authService.isAdmin(this.ctx); const publicSettings = await this.sysSettingsService.getPublicSettings(); - if (!(publicSettings.managerOtherUserPipeline && isAdmin)) { + + let onlyOther = false + if(isAdmin){ + if(publicSettings.managerOtherUserPipeline){ + //管理员管理 其他用户 + if( body.query.userId === -1){ + //如果只查询其他用户 + onlyOther = true; + delete body.query.userId; + } + }else{ + body.query.userId = this.getUserId(); + } + }else{ body.query.userId = this.getUserId(); } @@ -44,6 +57,9 @@ export class PipelineController extends CrudController { if (title) { qb.andWhere('(title like :title or content like :content)', { title: `%${title}%`, content: `%${title}%` }); } + if(onlyOther){ + qb.andWhere('user_id != :userId', { userId: this.getUserId() }); + } }; if (!body.sort || !body.sort?.prop) { body.sort = { prop: 'order', asc: false }; @@ -142,26 +158,36 @@ export class PipelineController extends CrudController { @Post('/batchDelete', { summary: Constants.per.authOnly }) async batchDelete(@Body('ids') ids: number[]) { - await this.service.batchDelete(ids, this.getUserId()); + const isAdmin = await this.authService.isAdmin(this.ctx); + const userId = isAdmin ? undefined : this.getUserId() ; + await this.service.batchDelete(ids, userId); return this.ok({}); } + + @Post('/batchUpdateGroup', { summary: Constants.per.authOnly }) async batchUpdateGroup(@Body('ids') ids: number[], @Body('groupId') groupId: number) { - await this.service.batchUpdateGroup(ids, groupId, this.getUserId()); + const isAdmin = await this.authService.isAdmin(this.ctx); + const userId = isAdmin ? undefined : this.getUserId() ; + await this.service.batchUpdateGroup(ids, groupId, userId); return this.ok({}); } @Post('/batchUpdateTrigger', { summary: Constants.per.authOnly }) async batchUpdateTrigger(@Body('ids') ids: number[], @Body('trigger') trigger: any) { - await this.service.batchUpdateTrigger(ids, trigger, this.getUserId()); + const isAdmin = await this.authService.isAdmin(this.ctx); + const userId = isAdmin ? undefined : this.getUserId() ; + await this.service.batchUpdateTrigger(ids, trigger, userId); return this.ok({}); } @Post('/batchUpdateNotification', { summary: Constants.per.authOnly }) async batchUpdateNotification(@Body('ids') ids: number[], @Body('notification') notification: any) { - await this.service.batchUpdateNotifications(ids, notification, this.getUserId()); + const isAdmin = await this.authService.isAdmin(this.ctx); + const userId = isAdmin ? undefined : this.getUserId() ; + await this.service.batchUpdateNotifications(ids, notification, userId); return this.ok({}); } diff --git a/packages/ui/certd-server/src/modules/basic/service/code-service.ts b/packages/ui/certd-server/src/modules/basic/service/code-service.ts index f8c6b21f7..78ccc84d0 100644 --- a/packages/ui/certd-server/src/modules/basic/service/code-service.ts +++ b/packages/ui/certd-server/src/modules/basic/service/code-service.ts @@ -108,9 +108,7 @@ export class CodeService { await this.emailService.sendByTemplate({ type: templateData.notificationType, data: templateData, - email:{ - receivers: [email], - }, + receivers: [email], }); const key = this.buildEmailCodeKey(email,opts?.verificationType); 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 aa0f18903..200ec35d6 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 @@ -123,9 +123,7 @@ export class EmailService implements IEmailService { content: '测试邮件,from certd', url:"https://certd.handfree.work", }, - email: { - receivers: [receiver], - }, + receivers: [receiver], }); } @@ -186,8 +184,9 @@ export class EmailService implements IEmailService { content = await addon.buildDefaultContent({ data: req.data }) } return await this.send({ - ...req.email, - ...content + ...content, + receivers: req.receivers, + attachments: req.attachments, }) } } diff --git a/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts b/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts index 85b959305..f2544a408 100644 --- a/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts +++ b/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts @@ -777,17 +777,29 @@ export class PipelineService extends BaseService { } async batchDelete(ids: number[], userId: number) { + if (!isPlus()) { + throw new NeedVIPException("此功能需要升级专业版"); + } for (const id of ids) { - await this.checkUserId(id, userId); + if (userId) { + await this.checkUserId(id, userId); + } await this.delete(id); } } async batchUpdateGroup(ids: number[], groupId: number, userId: any) { + if (!isPlus()) { + throw new NeedVIPException("此功能需要升级专业版"); + } + const query :any = {} + if(userId && userId>0){ + query.userId = userId; + } await this.repository.update( { id: In(ids), - userId + ...query }, { groupId } ); @@ -795,11 +807,17 @@ export class PipelineService extends BaseService { async batchUpdateTrigger(ids: number[], trigger: any, userId: any) { - + if (!isPlus()) { + throw new NeedVIPException("此功能需要升级专业版"); + } + const query :any = {} + if(userId && userId>0){ + query.userId = userId; + } const list = await this.find({ where: { id: In(ids), - userId + ...query } }); @@ -822,11 +840,17 @@ export class PipelineService extends BaseService { } async batchUpdateNotifications(ids: number[], notification: Notification, userId: any) { - + if (!isPlus()) { + throw new NeedVIPException("此功能需要升级专业版"); + } + const query :any = {} + if(userId && userId>0){ + query.userId = userId; + } const list = await this.find({ where: { id: In(ids), - userId + ...query } }); diff --git a/packages/ui/certd-server/src/plugins/plugin-notification/email/index.ts b/packages/ui/certd-server/src/plugins/plugin-notification/email/index.ts index 5bb54518c..bb7e7a71e 100644 --- a/packages/ui/certd-server/src/plugins/plugin-notification/email/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-notification/email/index.ts @@ -34,7 +34,7 @@ export class EmailNotification extends BaseNotification { await this.ctx.emailService.sendByTemplate({ type: body.notificationType, data: templateData, - email: emailSend + ...emailSend }) // await this.ctx.emailService.send({ 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 index 8e06e558e..eabbd39a6 100644 --- 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 @@ -1,5 +1,5 @@ -import {AbstractTaskPlugin, FileItem, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput} from '@certd/pipeline'; -import {CertInfo, CertReader} from "@certd/plugin-cert"; +import { AbstractTaskPlugin, FileItem, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline'; +import { CertInfo, CertReader } from "@certd/plugin-cert"; import dayjs from "dayjs"; import { get } from 'lodash-es'; @@ -9,7 +9,7 @@ import { get } from 'lodash-es'; icon: 'ion:mail-outline', desc: '通过邮件发送证书', group: pluginGroups.other.key, - showRunStrategy:false, + showRunStrategy: false, default: { strategy: { runStrategy: RunStrategy.SkipWhenSucceed, @@ -45,7 +45,7 @@ export class DeployCertToMailPlugin extends AbstractTaskPlugin { component: { name: 'EmailSelector', vModel: 'value', - mode:"tags", + mode: "tags", }, required: true, }) @@ -78,40 +78,40 @@ export class DeployCertToMailPlugin extends AbstractTaskPlugin { */ - @TaskInput({ - title: '邮件标题', - component: { - name: 'a-input', - vModel: 'value', - placeholder:`证书申请成功【$\{mainDomain}】`, - }, - helper: '请输入邮件标题否则将使用默认标题\n模板变量:主域名=$\{mainDomain}、全部域名=$\{domains}、过期时间=$\{expiresTime}、备注=$\{remark}、证书PEM=$\{crt}、证书私钥=$\{key}、中间证书/CA证书=$\{ic}', - required: false, - }) - title!: string; +// @TaskInput({ +// title: '邮件标题', +// component: { +// name: 'a-input', +// vModel: 'value', +// placeholder: `证书申请成功【$\{mainDomain}】`, +// }, +// helper: '请输入邮件标题否则将使用默认标题\n模板变量:主域名=$\{mainDomain}、全部域名=$\{domains}、过期时间=$\{expiresTime}、备注=$\{remark}、证书PEM=$\{crt}、证书私钥=$\{key}、中间证书/CA证书=$\{ic}', +// required: false, +// }) +// title!: string; - @TaskInput({ - title: '邮件模版', - component: { - name: 'a-textarea', - vModel: 'value', - autosize: { - minRows: 6, - maxRows: 10, - }, - placeholder: ` -
-

证书申请成功

-

域名:$\{domains}

-

证书有效期:$\{expiresTime}

-

备注:$\{remark}

-
-`, - }, - helper: `请输入模版内容否则将使用默认模版,模板变量同上`, - required: false, - }) - template!: string; +// @TaskInput({ +// title: '邮件模版', +// component: { +// name: 'a-textarea', +// vModel: 'value', +// autosize: { +// minRows: 6, +// maxRows: 10, +// }, +// placeholder: ` +//
+//

证书申请成功

+//

域名:$\{domains}

+//

证书有效期:$\{expiresTime}

+//

备注:$\{remark}

+//
+// `, +// }, +// helper: `请输入模版内容否则将使用默认模版,模板变量同上`, +// required: false, +// }) +// template!: string; @TaskInput({ title: '备注', @@ -123,7 +123,7 @@ export class DeployCertToMailPlugin extends AbstractTaskPlugin { }) remark!: string; - async onInstance() {} + async onInstance() { } async execute(): Promise { this.logger.info(`开始发送邮件`); @@ -132,41 +132,32 @@ export class DeployCertToMailPlugin extends AbstractTaskPlugin { const domains = certReader.getAllDomains().join(','); - const data = { + const data: any = { mainDomain, domains, expiresTime: dayjs(certReader.expires).format("YYYY-MM-DD HH:mm:ss"), - remark:this.remark ||"", + remark: this.remark || "", crt: this.cert.crt, key: this.cert.key, - ic: this.cert.ic + ic: this.cert.ic, + url: "" } let title = `证书申请成功【${mainDomain}】`; - let html = ` -
-

证书申请成功

-

域名:${domains}

-

证书有效期:${data.expiresTime}

-

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

-
+ let content = `证书申请成功 +域名:${domains} +证书有效期:${data.expiresTime} +备注:${this.remark || ""} `; - - if (this.title) { - const compile = this.compile(this.title); - title = compile(data); - } - if (this.template) { - const compile = this.compile(this.template); - html = compile(data); - } + data.content = content; + data.title = title const file = this.certZip if (!file) { throw new Error('证书压缩文件还未生成,重新运行证书任务'); } - await this.ctx.emailService.send({ - subject:title, - html: html, + await this.ctx.emailService.sendByTemplate({ + type: "common", + data, receivers: this.email, attachments: [ { @@ -178,7 +169,7 @@ export class DeployCertToMailPlugin extends AbstractTaskPlugin { } compile(templateString: string) { - return function(data) { + return function (data) { return templateString.replace(/\${(.*?)}/g, (match, key) => { const value = get(data, key, ''); return String(value); diff --git a/packages/ui/certd-server/src/plugins/plugin-template/email/plugin-common.ts b/packages/ui/certd-server/src/plugins/plugin-template/email/plugin-common.ts index e8515ce4d..0ded6cd96 100644 --- a/packages/ui/certd-server/src/plugins/plugin-template/email/plugin-common.ts +++ b/packages/ui/certd-server/src/plugins/plugin-template/email/plugin-common.ts @@ -29,7 +29,7 @@ export class CommonEmailTemplateProvider extends BaseEmailTemplateProvider imple async buildDefaultContent(req:BuildContentReq) { const defaultTemplate = new CommonEmailTemplateProvider() defaultTemplate.titleTemplate = "${title}" - defaultTemplate.contentTemplate = "${content} \n\n 查看详情:${url}" + defaultTemplate.contentTemplate = "${content} \n\n ${url?'查看详情:'+url:''}" defaultTemplate.formatType = "text" return await defaultTemplate.buildContent(req) } 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 189dcc56a..6265b889d 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 @@ -11,7 +11,7 @@ import {CertApplyPluginNames, CertInfo, CertReader} from "@certd/plugin-cert"; name: 'DeployCertToTencentEO', title: '腾讯云-部署到腾讯云EO', icon: 'svg:icon-tencentcloud', - desc: '腾讯云边缘安全加速平台EdgeOne(EO),必须配置上传证书到腾讯云任务', + desc: '腾讯云边缘安全加速平台EdgeOne(EO)', group: pluginGroups.tencent.key, default: { strategy: { @@ -126,6 +126,7 @@ export class DeployCertToTencentEO extends AbstractTaskPlugin { }, ], }; + this.logger.info('设置腾讯云EO证书参数:', JSON.stringify(params)); await this.doRequest(client, params); }