perf: EAB授权支持绑定邮箱,支持公共EAB设置

pull/213/head
xiaojunnuo 2024-10-14 03:17:10 +08:00
parent e8b617b80c
commit 07043aff0c
32 changed files with 374 additions and 57 deletions

View File

@ -217,6 +217,8 @@ export class Executor {
const instance: ITaskPlugin = new plugin.target();
// @ts-ignore
const define: PluginDefine = plugin.define;
const pluginName = define.name;
const pluginConfig = await this.options.pluginConfigService.getPluginConfig(pluginName);
//从outputContext读取输入参数
const input = cloneDeep(step.input);
Decorator.inject(define.input, instance, input, (item, key) => {
@ -238,6 +240,12 @@ export class Executor {
}
});
const sysInput = pluginConfig.sysSetting?.input || {};
//注入系统设置参数
for (const sysInputKey in sysInput) {
input[sysInputKey] = sysInput[sysInputKey];
}
const newInputHash = hashUtils.md5(JSON.stringify(input));
step.status!.inputHash = newInputHash;
//判断是否需要跳过

View File

@ -26,7 +26,10 @@ export type TaskOutputDefine = {
type?: string;
};
export type TaskInputDefine = FormItemProps;
export type TaskInputDefine = {
required?: boolean;
isSys?: boolean;
} & FormItemProps;
export type PluginDefine = Registrable & {
default?: any;

View File

@ -2,11 +2,11 @@ export type PluginConfig = {
name: string;
disabled: boolean;
sysSetting: {
[key: string]: any;
input: Record<string, any>;
};
};
//插件配置服务
export type IPluginConfigService = {
getPluginConfig: (pluginName: string) => Promise<any>;
getPluginConfig: (pluginName: string) => Promise<PluginConfig>;
};

View File

@ -167,7 +167,7 @@ export abstract class BaseService<T> {
index++;
});
if (index > 0) {
qb.where(whereSql, query);
qb.andWhere(whereSql, query);
}
}
//自定义query

View File

@ -26,6 +26,16 @@ export class EabAccess extends BaseAccess {
encrypt: true,
})
hmacKey = "";
@AccessInput({
title: "email",
component: {
placeholder: "绑定一个邮箱",
},
helper: "Google EAB 申请证书绑定邮箱后不能更换否则会导致EAB失效",
required: false,
})
email = "";
}
new EabAccess();

View File

@ -6,6 +6,7 @@ import { createDnsProvider, DnsProviderContext, IDnsProvider } from "../../dns-p
import { CertReader } from "./cert-reader.js";
import { CertApplyBasePlugin } from "./base.js";
import { GoogleClient } from "../../libs/google.js";
import { EabAccess } from "../../access";
export type { CertInfo };
export * from "./cert-reader.js";
@ -138,6 +139,13 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
})
sslProvider!: SSLProvider;
@TaskInput({
title: "Google公共EAB授权",
isSys: true,
show: false,
})
googleCommonEabAccessId!: number;
@TaskInput({
title: "EAB授权",
component: {
@ -151,7 +159,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
mergeScript: `
return {
show: ctx.compute(({form})=>{
return form.sslProvider === 'zerossl' || form.sslProvider === 'google'
return form.sslProvider === 'zerossl' || (form.sslProvider === 'google' && !form.googleCommonEabAccessId)
})
}
`,
@ -171,7 +179,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
mergeScript: `
return {
show: ctx.compute(({form})=>{
return form.sslProvider === 'google'
return form.sslProvider === 'google' && !form.googleCommonEabAccessId
})
}
`,
@ -233,10 +241,12 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
acme!: AcmeService;
eab!: EabAccess;
async onInit() {
let eab: any = null;
let eab: EabAccess = null;
if (this.sslProvider === "google") {
const eabAccessId = this.eabAccessId || this.googleCommonEabAccessId;
if (this.googleAccessId) {
this.logger.info("您正在使用google服务账号授权");
const googleAccess = await this.ctx.accessService.getById(this.googleAccessId);
@ -245,9 +255,9 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
logger: this.logger,
});
eab = await googleClient.getEab();
} else if (this.eabAccessId) {
} else if (eabAccessId) {
this.logger.info("您正在使用google EAB授权");
eab = await this.ctx.accessService.getById(this.eabAccessId);
eab = await this.ctx.accessService.getById(eabAccessId);
} else {
this.logger.error("google需要配置EAB授权或服务账号授权");
return;
@ -260,7 +270,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
return;
}
}
this.eab = eab;
this.acme = new AcmeService({
userContext: this.userContext,
logger: this.logger,
@ -276,7 +286,10 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
}
async doCertApply() {
const email = this["email"];
let email = this.email;
if (this.eab && this.eab.email) {
email = this.eab.email;
}
const domains = this["domains"];
const csrInfo = _.merge(

View File

@ -96,6 +96,20 @@ export const sysResources = [
permission: "sys:settings:view"
}
},
{
title: "证书插件配置",
name: "SysPluginConfig",
path: "/sys/plugin/config",
component: "/sys/plugin/config.vue",
meta: {
show: () => {
const settingStore = useSettingStore();
return settingStore.isComm;
},
icon: "ion:extension-puzzle-outline",
permission: "sys:settings:view"
}
},
{
title: "账号绑定",
name: "AccountBind",

View File

@ -222,3 +222,8 @@ h1, h2, h3, h4, h5, h6 {
/* right: 0; */
}
}
.settings-form {
width: 800px;
margin: 20px;
}

View File

@ -1,11 +1,11 @@
// @ts-ignore
import { ref } from "vue";
import { getCommonColumnDefine } from "/@/views/certd/access/common";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { crudBinding } = crudExpose;
const { props, ctx } = context;
const { props, ctx, api } = context;
const lastResRef = ref();
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await context.api.GetList(query);
@ -108,6 +108,33 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
width: 200
}
},
from: {
title: "级别",
type: "dict-select",
dict: dict({
data: [
{ label: "系统", value: "sys" },
{ label: "用户", value: "user" }
]
}),
search: {
show: false
},
form: {
show: false
},
column: {
width: 100,
align: "center",
component: {
color: "auto"
},
order: 10
},
valueBuilder: ({ row, key, value }) => {
row[key] = row.userId > 0 ? "user" : "sys";
}
},
...commonColumnsDefine
}
}

View File

@ -25,7 +25,7 @@ export default defineComponent({
},
emits: ["update:modelValue"],
setup(props, ctx) {
const api = createAccessApi(props.from === "sys" ? "/sys/access" : "/pi/access");
const api = createAccessApi(props.from);
const context: any = { props, ctx, api };
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });

View File

@ -9,7 +9,7 @@
<a-form-item-rest v-if="chooseForm.show">
<a-modal v-model:open="chooseForm.show" title="选择授权提供者" width="900px" @ok="chooseForm.ok">
<div style="height: 400px; position: relative">
<cert-access-modal v-model="selectedId" :type="type"></cert-access-modal>
<cert-access-modal v-model="selectedId" :type="type" :from="from"></cert-access-modal>
</div>
</a-modal>
</a-form-item-rest>
@ -48,7 +48,7 @@ export default defineComponent({
},
emits: ["update:modelValue"],
setup(props, ctx) {
const api = createAccessApi(props.from === "sys" ? "/sys/access" : "/pi/access");
const api = createAccessApi(props.from);
const target = ref({});
const selectedId = ref();

View File

@ -1,6 +1,7 @@
import { request } from "/src/api/service";
export function createAccessApi(apiPrefix = "/pi/access") {
export function createAccessApi(from = "user") {
const apiPrefix = from === "sys" ? "/sys/access" : "/pi/access";
return {
async GetList(query: any) {
return await request({

View File

@ -19,7 +19,7 @@ import { createAccessApi } from "/@/views/certd/access/api";
export default defineComponent({
name: "AccessManager",
setup() {
const api = createAccessApi("/pi/access");
const api = createAccessApi("user");
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api } });
//

View File

@ -1,5 +1,6 @@
import { request } from "/src/api/service";
import _ from "lodash-es";
import { PluginConfigBean, PluginSysSetting } from "/@/views/sys/plugin/api";
const apiPrefix = "/pi/plugin";
const defaultInputDefine = {
@ -54,3 +55,11 @@ export async function GetGroups(query: any) {
initPlugins(plugins);
return groups;
}
export async function GetPluginConfig(req: { id?: number; name: string; type: string }): Promise<PluginConfigBean> {
return await request({
url: apiPrefix + "/config",
method: "post",
data: req
});
}

View File

@ -1,10 +1,10 @@
import { compute, CreateCrudOptionsRet, dict } from "@fast-crud/fast-crud";
import { PluginGroup } from "@certd/pipeline";
import { useReference } from "/@/use/use-refrence";
import _ from "lodash-es";
import _, { merge } from "lodash-es";
import { useUserStore } from "/@/store/modules/user";
import { useSettingStore } from "/@/store/modules/settings";
import * as api from "../api.plugin";
export default function (certPluginGroup: PluginGroup, formWrapperRef: any): CreateCrudOptionsRet {
const inputs: any = {};
const userStore = useUserStore();
@ -46,7 +46,7 @@ export default function (certPluginGroup: PluginGroup, formWrapperRef: any): Cre
crudOptions: {
form: {
wrapper: {
width: "1150px",
width: 1350,
saveRemind: false,
title: "创建证书申请流水线"
}
@ -73,6 +73,19 @@ export default function (certPluginGroup: PluginGroup, formWrapperRef: any): Cre
</ul>
);
}
},
valueChange: {
handle: async ({ form, value }) => {
debugger;
const config = await api.GetPluginConfig({
name: value,
type: "builtIn"
});
if (config.sysSetting?.input) {
merge(form, config.sysSetting.input);
}
},
immediate: true
}
}
},

View File

@ -116,7 +116,7 @@ import { useUserStore } from "/@/store/modules/user";
import { compute, useCompute } from "@fast-crud/fast-crud";
import { useReference } from "/@/use/use-refrence";
import { useSettingStore } from "/@/store/modules/settings";
import * as pluginApi from "../../../api.plugin";
export default {
name: "PiStepForm",
// eslint-disable-next-line vue/no-unused-components
@ -163,7 +163,7 @@ export default {
console.log("currentStepTypeChanged:", currentStep.value);
};
const stepTypeSave = () => {
const stepTypeSave = async () => {
currentStep.value._isAdd = false;
if (currentStep.value.type == null) {
message.warn("请先选择类型");
@ -171,7 +171,7 @@ export default {
}
// stepinput
changeCurrentPlugin(currentStep.value);
await changeCurrentPlugin(currentStep.value);
//
_.merge(currentStep.value, { input: {}, strategy: { runStrategy: 0 } }, currentPlugin.value.default, currentStep.value);
@ -229,7 +229,7 @@ export default {
const currentPlugin = doComputed(() => {
return currentPluginDefine.value;
}, getContext);
const changeCurrentPlugin = (step: any) => {
const changeCurrentPlugin = async (step: any) => {
const stepType = step.type;
step.type = stepType;
step._isAdd = false;
@ -255,6 +255,14 @@ export default {
currentStep.value.input[key] = column.default ?? column.value;
}
}
//
debugger;
const pluginSysConfig = await pluginApi.GetPluginConfig({ name: pluginDefine.name, type: "builtIn" });
if (pluginSysConfig.sysSetting?.input) {
for (const key in pluginSysConfig.sysSetting?.input) {
currentStep.value.input[key] = pluginSysConfig.sysSetting?.input[key];
}
}
console.log("currentStepTypeChanged:", currentStep.value);
console.log("currentStepPlugin:", currentPlugin.value);

View File

@ -20,7 +20,7 @@ export type PluginGroup = {
};
export type PluginDefine = {
key: string;
name: string;
title: string;
desc?: string;
input: {

View File

@ -58,10 +58,43 @@ export async function DeleteBatch(ids: any[]) {
});
}
export async function SetDisabled(bean: { id?: number; name?: string; type?: string; disabled: boolean }) {
export async function SetDisabled(data: { id?: number; name?: string; type?: string; disabled: boolean }) {
return await request({
url: apiPrefix + "/setDisabled",
method: "post",
data: bean
data: data
});
}
export type PluginConfigBean = {
name: string;
disabled: boolean;
sysSetting: {
input?: Record<string, any>;
};
};
export type CertApplyPluginSysInput = {
googleCommonEabAccessId: number;
};
export type PluginSysSetting<T> = {
input?: T;
};
export type CommPluginConfig = {
CertApply?: PluginSysSetting<CertApplyPluginSysInput>;
};
export async function GetCommPluginConfigs(): Promise<CommPluginConfig> {
return await request({
url: apiPrefix + "/getCommPluginConfigs",
method: "post"
});
}
export async function SaveCommPluginConfigs(data: CommPluginConfig): Promise<void> {
return await request({
url: apiPrefix + "/saveCommPluginConfigs",
method: "post",
data
});
}

View File

@ -0,0 +1,62 @@
<template>
<fs-page class="page-plugin-config">
<template #header>
<div class="title">证书插件配置</div>
</template>
<div class="sys-plugin-config settings-form">
<a-form :model="formState" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }" autocomplete="off" @finish="onFinish" @finish-failed="onFinishFailed">
<a-form-item label="公共Google EAB授权" :name="['CertApply', 'input', 'googleCommonEabAccessId']">
<access-selector v-model:model-value="formState.CertApply.input.googleCommonEabAccessId" type="eab" from="sys"></access-selector>
<div class="helper">设置公共Google EAB授权给用户使用避免用户自己去翻墙获取Google EAB授权</div>
</a-form-item>
<a-form-item :wrapper-col="{ offset: 8, span: 16 }">
<a-button :loading="saveLoading" type="primary" html-type="submit">保存</a-button>
</a-form-item>
</a-form>
</div>
</fs-page>
</template>
<script lang="ts" setup>
import AccessSelector from "/@/views/certd/access/access-selector/index.vue";
import { reactive, ref } from "vue";
import { CommPluginConfig, GetCommPluginConfigs, SaveCommPluginConfigs } from "/@/views/sys/plugin/api";
import { merge } from "lodash-es";
import { notification } from "ant-design-vue";
defineOptions({
name: "SysPluginConfig"
});
const formState = reactive<Partial<CommPluginConfig>>({
CertApply: {
input: {}
}
});
async function loadForm() {
const res = await GetCommPluginConfigs();
merge(formState, res);
}
loadForm();
const saveLoading = ref(false);
const onFinish = async (form: any) => {
try {
saveLoading.value = true;
await SaveCommPluginConfigs(form);
notification.success({
message: "保存成功"
});
} finally {
saveLoading.value = false;
}
};
const onFinishFailed = (errorInfo: any) => {
console.log("Failed:", errorInfo);
};
</script>
<style lang="less"></style>

View File

@ -3,7 +3,7 @@
<template #header>
<div class="title">系统设置</div>
</template>
<div class="sys-settings-form">
<div class="sys-settings-form settings-form">
<a-form
:model="formState"
name="basic"

View File

@ -8,7 +8,7 @@ CREATE TABLE "pi_plugin"
"group" varchar(100),
"version" varchar(100),
"setting" text,
"sysSetting" text,
"sys_setting" text,
"content" text,
"type" varchar(100) NOT NULL,
"disabled" boolean NOT NULL,

View File

@ -24,7 +24,7 @@ export class CnameRecordController extends CrudController<CnameRecordService> {
const bq = qb => {
if (domain) {
qb.where('domain like :domain', { domain: `%${domain}%` });
qb.andWhere('domain like :domain', { domain: `%${domain}%` });
}
};

View File

@ -21,7 +21,7 @@ export class AccessController extends CrudController<AccessService> {
body.query = body.query ?? {};
delete body.query.userId;
const buildQuery = qb => {
qb.where('user_id = :userId', { userId: this.getUserId() });
qb.andWhere('user_id = :userId', { userId: this.getUserId() });
};
const res = await this.service.page({
query: body.query,

View File

@ -51,7 +51,7 @@ export class HistoryController extends CrudController<HistoryService> {
const pipelines = await this.pipelineService.list({
query: pipelineQuery,
buildQuery: qb => {
qb.where('title like :title', { title: `%${pipelineTitle}%` });
qb.andWhere('title like :title', { title: `%${pipelineTitle}%` });
},
});
pipelineIds = pipelines.map(p => p.id);
@ -59,7 +59,7 @@ export class HistoryController extends CrudController<HistoryService> {
const buildQuery = qb => {
if (pipelineIds) {
qb.where({
qb.andWhere({
pipelineId: In(pipelineIds),
});
}

View File

@ -37,7 +37,7 @@ export class PipelineController extends CrudController<PipelineService> {
const buildQuery = qb => {
if (title) {
qb.where('title like :title', { title: `%${title}%` });
qb.andWhere('title like :title', { title: `%${title}%` });
}
};
if (!body.sort || !body.sort?.prop) {

View File

@ -1,6 +1,7 @@
import { ALL, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
import { BaseController, Constants } from '@certd/lib-server';
import { PluginService } from '../../modules/plugin/service/plugin-service.js';
import { PluginConfigService } from '../../modules/plugin/service/plugin-config-service.js';
/**
*
@ -11,6 +12,9 @@ export class PluginController extends BaseController {
@Inject()
service: PluginService;
@Inject()
pluginConfigService: PluginConfigService;
@Post('/list', { summary: Constants.per.authOnly })
async list(@Query(ALL) query: any) {
query.userId = this.getUserId();
@ -24,4 +28,10 @@ export class PluginController extends BaseController {
const group = await this.service.getEnabledBuildInGroup();
return this.ok(group);
}
@Post('/config', { summary: Constants.per.authOnly })
async config(@Body(ALL) body: { id?: number; name?: string; type: string }) {
const config = await this.pluginConfigService.getPluginConfig(body);
return this.ok(config);
}
}

View File

@ -3,6 +3,7 @@ import { merge } from 'lodash-es';
import { CrudController } from '@certd/lib-server';
import { PluginService } from '../../../modules/plugin/service/plugin-service.js';
import { checkComm } from '@certd/pipeline';
import { CommPluginConfig, PluginConfigService } from '../../../modules/plugin/service/plugin-config-service.js';
/**
*
@ -13,6 +14,9 @@ export class PluginController extends CrudController<PluginService> {
@Inject()
service: PluginService;
@Inject()
pluginConfigService: PluginConfigService;
getService() {
checkComm();
return this.service;
@ -65,4 +69,15 @@ export class PluginController extends CrudController<PluginService> {
await this.service.setDisabled(body);
return this.ok();
}
@Post('/getCommPluginConfigs', { summary: 'sys:settings:edit' })
async getCommPluginConfigs() {
const res = await this.pluginConfigService.getCommPluginConfig();
return this.ok(res);
}
@Post('/saveCommPluginConfigs', { summary: 'sys:settings:edit' })
async saveCommPluginConfigs(@Body(ALL) body: CommPluginConfig) {
const res = await this.pluginConfigService.saveCommPluginConfig(body);
return this.ok(res);
}
}

View File

@ -1,10 +1,10 @@
import { Config, Inject, Provide, Scope, ScopeEnum, sleep } from '@midwayjs/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { In, Repository } from 'typeorm';
import { BaseService, PageReq } from '@certd/lib-server';
import { BaseService, NeedVIPException, PageReq } from '@certd/lib-server';
import { PipelineEntity } from '../entity/pipeline.js';
import { PipelineDetail } from '../entity/vo/pipeline-detail.js';
import { Executor, isPlus, Pipeline, ResultType, RunHistory, UserInfo } from '@certd/pipeline';
import { Executor, isPlus, logger, Pipeline, ResultType, RunHistory, UserInfo } from '@certd/pipeline';
import { AccessService } from './access-service.js';
import { DbStorage } from './db-storage.js';
import { StorageService } from './storage-service.js';
@ -13,14 +13,12 @@ import { HistoryService } from './history-service.js';
import { HistoryEntity } from '../entity/history.js';
import { HistoryLogEntity } from '../entity/history-log.js';
import { HistoryLogService } from './history-log-service.js';
import { logger } from '@certd/pipeline';
import { EmailService } from '../../basic/service/email-service.js';
import { NeedVIPException } from '@certd/lib-server';
import { UserService } from '../../sys/authority/service/user-service.js';
import { AccessGetter } from './access-getter.js';
import { CnameRecordService } from '../../cname/service/cname-record-service.js';
import { CnameProxyService } from './cname-proxy-service.js';
import { PluginConfigService } from './plugin-config-service.js';
import { PluginConfigGetter } from '../../plugin/service/plugin-config-getter.js';
const runningTasks: Map<string | number, Executor> = new Map();
const freeCount = 10;
@ -47,7 +45,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
historyLogService: HistoryLogService;
@Inject()
pluginConfigService: PluginConfigService;
pluginConfigGetter: PluginConfigGetter;
@Inject()
userService: UserService;
@ -360,7 +358,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
onChanged,
accessService: accessGetter,
cnameProxyService,
pluginConfigService: this.pluginConfigService,
pluginConfigService: this.pluginConfigGetter,
storage: new DbStorage(userId, this.storageService),
emailService: this.emailService,
fileRootDir: this.certdConfig.fileRootDir,

View File

@ -1,13 +0,0 @@
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { IPluginConfigService } from '@certd/pipeline';
/**
*
*/
@Provide()
@Scope(ScopeEnum.Singleton)
export class PluginConfigService implements IPluginConfigService {
getPluginConfig(pluginName: string) {
return Promise.resolve({});
}
}

View File

@ -23,7 +23,7 @@ export class PluginEntity {
@Column({ comment: '配置', length: 40960 })
setting: string;
@Column({ comment: '系统配置', length: 40960 })
@Column({ name: 'sys_setting', comment: '系统配置', length: 40960 })
sysSetting: string;
@Column({ comment: '脚本', length: 40960 })

View File

@ -0,0 +1,22 @@
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { IPluginConfigService, PluginConfig } from '@certd/pipeline';
import { PluginConfigService } from './plugin-config-service.js';
@Provide()
@Scope(ScopeEnum.Singleton)
export class PluginConfigGetter implements IPluginConfigService {
@Inject()
pluginConfigService: PluginConfigService;
async getPluginConfig(pluginName: string): Promise<PluginConfig> {
const res = await this.pluginConfigService.getPluginConfig({
name: pluginName,
type: 'builtIn',
});
return {
name: res.name,
disabled: res.disabled,
sysSetting: res.sysSetting,
};
}
}

View File

@ -0,0 +1,79 @@
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { PluginService } from './plugin-service.js';
export type PluginConfig = {
name: string;
disabled: boolean;
sysSetting: {
input?: Record<string, any>;
};
};
export type CommPluginConfig = {
CertApply?: PluginConfig;
};
export type PluginFindReq = {
id?: number;
name?: string;
type: string;
};
@Provide()
@Scope(ScopeEnum.Singleton)
export class PluginConfigService {
@Inject()
pluginService: PluginService;
async getCommPluginConfig() {
const configs: CommPluginConfig = {};
configs.CertApply = await this.getPluginConfig({
name: 'CertApply',
type: 'builtIn',
});
return configs;
}
async saveCommPluginConfig(body: CommPluginConfig) {
const certApplyConfig = body.CertApply;
const CertApply = await this.pluginService.getRepository().findOne({
where: { name: 'CertApply' },
});
if (!CertApply) {
await this.pluginService.add({
name: 'CertApply',
sysSetting: JSON.stringify(certApplyConfig),
type: 'builtIn',
disabled: false,
});
} else {
await this.pluginService.getRepository().update({ name: 'CertApply' }, { sysSetting: JSON.stringify(certApplyConfig) });
}
}
async get(req: PluginFindReq) {
if (!req.name && !req.id) {
throw new Error('plugin s name or id is required');
}
return await this.pluginService.getRepository().findOne({
where: {
id: req.id,
name: req.name,
type: req.type,
},
});
}
async getPluginConfig(req: PluginFindReq) {
const plugin = await this.get(req);
let sysSetting: any = {};
if (plugin && plugin.sysSetting) {
sysSetting = JSON.parse(plugin.sysSetting);
}
return {
name: plugin.name,
disabled: plugin.disabled,
sysSetting,
};
}
}