diff --git a/packages/core/pipeline/src/core/executor.ts b/packages/core/pipeline/src/core/executor.ts index 0aa47b894..cf29d8d46 100644 --- a/packages/core/pipeline/src/core/executor.ts +++ b/packages/core/pipeline/src/core/executor.ts @@ -11,6 +11,7 @@ import { ICnameProxyService, IEmailService, IPluginConfigService, IUrlService } import { FileStore } from "./file-store.js"; import { cloneDeep, forEach, merge } from "lodash-es"; import { INotificationService } from "../notification/index.js"; +import { taskEmitterCreate } from "../service/emit.js"; export type SysInfo = { //系统标题 @@ -342,6 +343,10 @@ export class Executor { signal: this.abort.signal, utils, user: this.options.user, + emitter: taskEmitterCreate({ + step, + pipeline: this.pipeline, + }), }; instance.setCtx(taskCtx); diff --git a/packages/core/pipeline/src/plugin/api.ts b/packages/core/pipeline/src/plugin/api.ts index d2590422a..45b6bc727 100644 --- a/packages/core/pipeline/src/plugin/api.ts +++ b/packages/core/pipeline/src/plugin/api.ts @@ -7,9 +7,10 @@ import { CancelError, IContext, RunHistory, RunnableCollection } from "../core/i import { HttpRequestConfig, ILogger, logger, utils } from "@certd/basic"; import { HttpClient } from "@certd/basic"; import dayjs from "dayjs"; -import { IPluginConfigService } from "../service/config"; +import { IPluginConfigService } from "../service/config.js"; import { upperFirst } from "lodash-es"; -import { INotificationService } from "../notification"; +import { INotificationService } from "../notification/index.js"; +import { TaskEmitter } from "../service/emit.js"; export type PluginRequestHandleReq = { typeName: string; @@ -111,6 +112,8 @@ export type TaskInstanceContext = { utils: typeof utils; //用户信息 user: UserInfo; + + emitter: TaskEmitter; }; export abstract class AbstractTaskPlugin implements ITaskPlugin { diff --git a/packages/core/pipeline/src/service/emit.ts b/packages/core/pipeline/src/service/emit.ts new file mode 100644 index 000000000..70c027fb3 --- /dev/null +++ b/packages/core/pipeline/src/service/emit.ts @@ -0,0 +1,68 @@ +import { logger } from "@certd/basic"; +import { Pipeline, Runnable } from "../dt"; + +export type PipelineEventListener = (...args: any[]) => Promise; +export type PipelineEvent = { + pipeline: Pipeline; + step: Runnable; + event: T; +}; +export class PipelineEmitter { + events: Record; + constructor() { + this.events = {}; + } + on(event: string, listener: PipelineEventListener) { + if (!this.events[event]) { + this.events[event] = []; + } + this.events[event].push(listener); + } + async emit(name: string, event: PipelineEvent) { + const listeners = this.events[name]; + if (listeners) { + for (const listener of listeners) { + try { + await listener(event); + } catch (e) { + logger.error(`事件<${name}>监听器执行失败:`, e); + } + } + } + } + off(event: string, listener: PipelineEventListener) { + if (this.events[event]) { + this.events[event] = this.events[event].filter((l) => l !== listener); + } + } + once(event: string, listener: PipelineEventListener) { + const onceListener = async (...args: any[]) => { + this.off(event, onceListener); + await listener(...args); + }; + this.on(event, onceListener); + } +} + +export const pipelineEmitter = new PipelineEmitter(); + +export type TaskEmitterCreateReq = { + step: Runnable; + pipeline: Pipeline; +}; + +export type TaskEmitter = { + emit: (name: string, event: T) => Promise; +}; + +export function taskEmitterCreate(req: TaskEmitterCreateReq) { + return { + emit: async (name: string, event: T) => { + await pipelineEmitter.emit(name, { + pipeline: req.pipeline, + step: req.step, + event, + }); + }, + } as TaskEmitter; +} diff --git a/packages/core/pipeline/src/service/index.ts b/packages/core/pipeline/src/service/index.ts index 71a48726e..71be97520 100644 --- a/packages/core/pipeline/src/service/index.ts +++ b/packages/core/pipeline/src/service/index.ts @@ -2,3 +2,4 @@ export * from "./email.js"; export * from "./cname.js"; export * from "./config.js"; export * from "./url.js"; +export * from "./emit.js"; diff --git a/packages/libs/lib-server/src/basic/constants.ts b/packages/libs/lib-server/src/basic/constants.ts index aba37e772..74aa2ac93 100644 --- a/packages/libs/lib-server/src/basic/constants.ts +++ b/packages/libs/lib-server/src/basic/constants.ts @@ -12,6 +12,8 @@ export const Constants = { authOnly: '_authOnly_', //仅需要登录 loginOnly: '_authOnly_', + + open: '_open_', }, res: { serverError(message: string) { @@ -68,5 +70,33 @@ export const Constants = { code: 10001, message: '对不起,预览环境不允许修改此数据', }, + openKeyError: { + code: 20000, + message: 'ApiToken错误', + }, + openKeySignError: { + code: 20001, + message: 'ApiToken签名错误', + }, + openKeyExpiresError: { + code: 20002, + message: 'ApiToken时间戳错误', + }, + openKeySignTypeError: { + code: 20003, + message: 'ApiToken签名类型不支持', + }, + openParamError: { + code: 20010, + message: '请求参数错误', + }, + openCertNotFound: { + code: 20011, + message: '证书不存在', + }, + openCertNotReady: { + code: 20012, + message: '证书还未生成', + }, }, }; diff --git a/packages/libs/lib-server/src/basic/exception/auth-exception.ts b/packages/libs/lib-server/src/basic/exception/auth-exception.ts index 2b027177a..65a255915 100644 --- a/packages/libs/lib-server/src/basic/exception/auth-exception.ts +++ b/packages/libs/lib-server/src/basic/exception/auth-exception.ts @@ -5,10 +5,6 @@ import { BaseException } from './base-exception.js'; */ export class AuthException extends BaseException { constructor(message) { - super( - 'AuthException', - Constants.res.auth.code, - message ? message : Constants.res.auth.message - ); + super('AuthException', Constants.res.auth.code, message ? message : Constants.res.auth.message); } } diff --git a/packages/libs/lib-server/src/basic/exception/base-exception.ts b/packages/libs/lib-server/src/basic/exception/base-exception.ts index a4e89604b..c74b41672 100644 --- a/packages/libs/lib-server/src/basic/exception/base-exception.ts +++ b/packages/libs/lib-server/src/basic/exception/base-exception.ts @@ -2,10 +2,10 @@ * 异常基类 */ export class BaseException extends Error { - status: number; + code: number; constructor(name, code, message) { super(message); this.name = name; - this.status = code; + this.code = code; } } diff --git a/packages/libs/lib-server/src/basic/exception/common-exception.ts b/packages/libs/lib-server/src/basic/exception/common-exception.ts index c9f980684..1873d545f 100644 --- a/packages/libs/lib-server/src/basic/exception/common-exception.ts +++ b/packages/libs/lib-server/src/basic/exception/common-exception.ts @@ -8,3 +8,9 @@ export class CommonException extends BaseException { super('CommonException', Constants.res.error.code, message ? message : Constants.res.error.message); } } + +export class CodeException extends BaseException { + constructor(res: { code: number; message: string }) { + super('CodeException', res.code, res.message); + } +} diff --git a/packages/libs/lib-server/src/basic/result.ts b/packages/libs/lib-server/src/basic/result.ts index ea1022444..e5909a330 100644 --- a/packages/libs/lib-server/src/basic/result.ts +++ b/packages/libs/lib-server/src/basic/result.ts @@ -9,7 +9,7 @@ export class Result { } static error(code = 1, msg) { - return new Result(code, msg, null); + return new Result(code, msg); } static success(msg, data?) { diff --git a/packages/libs/lib-server/src/system/basic/index.ts b/packages/libs/lib-server/src/system/basic/index.ts index 859303a56..920e96115 100644 --- a/packages/libs/lib-server/src/system/basic/index.ts +++ b/packages/libs/lib-server/src/system/basic/index.ts @@ -1,2 +1,3 @@ export * from './service/plus-service.js'; export * from './service/file-service.js'; +export * from './service/encryptor.js'; diff --git a/packages/libs/lib-server/src/system/basic/service/encryptor.ts b/packages/libs/lib-server/src/system/basic/service/encryptor.ts new file mode 100644 index 000000000..2c8252a73 --- /dev/null +++ b/packages/libs/lib-server/src/system/basic/service/encryptor.ts @@ -0,0 +1,29 @@ +import crypto from 'crypto'; + +export class Encryptor { + secretKey: Buffer; + constructor(encryptSecret: string, encoding: BufferEncoding = 'base64') { + this.secretKey = Buffer.from(encryptSecret, encoding); + } + // 加密函数 + encrypt(text: string) { + const iv = crypto.randomBytes(16); // 初始化向量 + // const secretKey = crypto.randomBytes(32); + // const key = Buffer.from(secretKey); + const cipher = crypto.createCipheriv('aes-256-cbc', this.secretKey, iv); + let encrypted = cipher.update(text); + encrypted = Buffer.concat([encrypted, cipher.final()]); + return iv.toString('hex') + ':' + encrypted.toString('hex'); + } + + // 解密函数 + decrypt(encryptedText: string) { + const textParts = encryptedText.split(':'); + const iv = Buffer.from(textParts.shift(), 'hex'); + const encrypted = Buffer.from(textParts.join(':'), 'hex'); + const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(this.secretKey), iv); + let decrypted = decipher.update(encrypted); + decrypted = Buffer.concat([decrypted, decipher.final()]); + return decrypted.toString(); + } +} diff --git a/packages/libs/lib-server/src/user/access/service/encrypt-service.ts b/packages/libs/lib-server/src/user/access/service/encrypt-service.ts index 409984dfb..950b5723b 100644 --- a/packages/libs/lib-server/src/user/access/service/encrypt-service.ts +++ b/packages/libs/lib-server/src/user/access/service/encrypt-service.ts @@ -1,6 +1,5 @@ import { Init, Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core'; -import crypto from 'crypto'; -import { SysSecret, SysSettingsService } from '../../../system/index.js'; +import { Encryptor, SysSecret, SysSettingsService } from '../../../system/index.js'; /** * 授权 @@ -8,7 +7,7 @@ import { SysSecret, SysSettingsService } from '../../../system/index.js'; @Provide() @Scope(ScopeEnum.Singleton) export class EncryptService { - secretKey: Buffer; + encryptor: Encryptor; @Inject() sysSettingService: SysSettingsService; @@ -16,28 +15,16 @@ export class EncryptService { @Init() async init() { const secret: SysSecret = await this.sysSettingService.getSecret(); - this.secretKey = Buffer.from(secret.encryptSecret, 'base64'); + this.encryptor = new Encryptor(secret.encryptSecret); } // 加密函数 encrypt(text: string) { - const iv = crypto.randomBytes(16); // 初始化向量 - // const secretKey = crypto.randomBytes(32); - // const key = Buffer.from(secretKey); - const cipher = crypto.createCipheriv('aes-256-cbc', this.secretKey, iv); - let encrypted = cipher.update(text); - encrypted = Buffer.concat([encrypted, cipher.final()]); - return iv.toString('hex') + ':' + encrypted.toString('hex'); + return this.encryptor.encrypt(text); } // 解密函数 decrypt(encryptedText: string) { - const textParts = encryptedText.split(':'); - const iv = Buffer.from(textParts.shift(), 'hex'); - const encrypted = Buffer.from(textParts.join(':'), 'hex'); - const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(this.secretKey), iv); - let decrypted = decipher.update(encrypted); - decrypted = Buffer.concat([decrypted, decipher.final()]); - return decrypted.toString(); + return this.encryptor.decrypt(encryptedText); } } diff --git a/packages/plugins/plugin-cert/src/plugin/cert-plugin/base.ts b/packages/plugins/plugin-cert/src/plugin/cert-plugin/base.ts index 1820d973e..eb7b7561b 100644 --- a/packages/plugins/plugin-cert/src/plugin/cert-plugin/base.ts +++ b/packages/plugins/plugin-cert/src/plugin/cert-plugin/base.ts @@ -1,4 +1,4 @@ -import { AbstractTaskPlugin, IContext, NotificationBody, Step, TaskInput, TaskOutput } from "@certd/pipeline"; +import { AbstractTaskPlugin, IContext, NotificationBody, Step, TaskEmitter, TaskInput, TaskOutput } from "@certd/pipeline"; import dayjs from "dayjs"; import type { CertInfo } from "./acme.js"; import { CertReader } from "./cert-reader.js"; @@ -6,8 +6,11 @@ import JSZip from "jszip"; import { CertConverter } from "./convert.js"; import { pick } from "lodash-es"; -export { CertReader }; -export type { CertInfo }; +export const EVENT_CERT_APPLY_SUCCESS = "CertApply.success"; + +export async function emitCertApplySuccess(emitter: TaskEmitter, cert: CertReader) { + await emitter.emit(EVENT_CERT_APPLY_SUCCESS, cert); +} export abstract class CertApplyBasePlugin extends AbstractTaskPlugin { @TaskInput({ @@ -119,7 +122,7 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin { abstract onInit(): Promise; - abstract doCertApply(): Promise; + abstract doCertApply(): Promise; async execute(): Promise { const oldCert = await this.condition(); @@ -130,6 +133,8 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin { const cert = await this.doCertApply(); if (cert != null) { await this.output(cert, true); + + await emitCertApplySuccess(this.ctx.emitter, cert); //清空后续任务的状态,让后续任务能够重新执行 this.clearLastStatus(); @@ -234,28 +239,10 @@ cert.jks:jks格式证书文件,java服务器使用 // return null; // } - let inputChanged = false; - //判断域名有没有变更 - /** - * "renewDays": 35, - * "certApplyPlugin": "CertApply", - * "sslProvider": "letsencrypt", - * "privateKeyType": "rsa_2048_pkcs1", - * "dnsProviderType": "aliyun", - * "domains": [ - * "*.handsfree.work" - * ], - * "email": "xiaojunnuo@qq.com", - * "dnsProviderAccess": 3, - * "useProxy": false, - * "skipLocalVerify": false, - * "successNotify": true, - * "pfxPassword": "123456" - */ const checkInputChanges = ["domains", "sslProvider", "privateKeyType", "dnsProviderType", "pfxPassword"]; const oldInput = JSON.stringify(pick(this.lastStatus?.input, checkInputChanges)); const thisInput = JSON.stringify(pick(this, checkInputChanges)); - inputChanged = oldInput !== thisInput; + const inputChanged = oldInput !== thisInput; this.logger.info(`旧参数:${oldInput}`); this.logger.info(`新参数:${thisInput}`); diff --git a/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts b/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts index 24a410ba4..2fae4ad7d 100644 --- a/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts +++ b/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts @@ -2,7 +2,7 @@ import { CertInfo } from "./acme.js"; import fs from "fs"; import os from "os"; import path from "path"; -import { crypto } from "@certd/acme-client"; +import { CertificateInfo, crypto } from "@certd/acme-client"; import { ILogger } from "@certd/basic"; import dayjs from "dayjs"; @@ -21,37 +21,22 @@ export type CertReaderHandle = (ctx: CertReaderHandleContext) => Promise; export type HandleOpts = { logger: ILogger; handle: CertReaderHandle }; export class CertReader { cert: CertInfo; - oc: string; //仅证书,非fullchain证书 - crt: string; - key: string; - csr: string; - ic: string; //中间证书 - one: string; //crt + key 合成一个pem文件 - detail: any; + detail: CertificateInfo; expires: number; constructor(certInfo: CertInfo) { this.cert = certInfo; - this.crt = certInfo.crt; - this.key = certInfo.key; - this.csr = certInfo.csr; - this.ic = certInfo.ic; - if (!this.ic) { - this.ic = this.getIc(); - this.cert.ic = this.ic; + if (!certInfo.ic) { + this.cert.ic = this.getIc(); } - this.oc = certInfo.oc; - if (!this.oc) { - this.oc = this.getOc(); - this.cert.oc = this.oc; + if (!certInfo.oc) { + this.cert.oc = this.getOc(); } - this.one = certInfo.one; - if (!this.one) { - this.one = this.crt + "\n" + this.key; - this.cert.one = this.one; + if (!certInfo.one) { + this.cert.one = this.cert.crt + "\n" + this.cert.key; } const { detail, expires } = this.getCrtDetail(this.cert.crt); @@ -62,13 +47,13 @@ export class CertReader { getIc() { //中间证书ic, 就是crt的第一个 -----END CERTIFICATE----- 之后的内容 const endStr = "-----END CERTIFICATE-----"; - const firstBlockEndIndex = this.crt.indexOf(endStr); + const firstBlockEndIndex = this.cert.crt.indexOf(endStr); const start = firstBlockEndIndex + endStr.length + 1; - if (this.crt.length <= start) { + if (this.cert.crt.length <= start) { return ""; } - const ic = this.crt.substring(start); + const ic = this.cert.crt.substring(start); if (ic == null) { return ""; } @@ -78,7 +63,7 @@ export class CertReader { getOc() { //原始证书 就是crt的第一个 -----END CERTIFICATE----- 之前的内容 const endStr = "-----END CERTIFICATE-----"; - const arr = this.crt.split(endStr); + const arr = this.cert.crt.split(endStr); return arr[0] + endStr; } diff --git a/packages/plugins/plugin-cert/src/plugin/cert-plugin/index.ts b/packages/plugins/plugin-cert/src/plugin/cert-plugin/index.ts index 551e59894..990213dd4 100644 --- a/packages/plugins/plugin-cert/src/plugin/cert-plugin/index.ts +++ b/packages/plugins/plugin-cert/src/plugin/cert-plugin/index.ts @@ -10,7 +10,7 @@ import { CertApplyBasePlugin } from "./base.js"; import { GoogleClient } from "../../libs/google.js"; import { EabAccess } from "../../access"; import { httpChallengeUploaderFactory } from "./uploads/factory.js"; - +export * from "./base.js"; export type { CertInfo }; export * from "./cert-reader.js"; export type CnameRecordInput = { diff --git a/packages/ui/certd-client/src/router/source/modules/certd.ts b/packages/ui/certd-client/src/router/source/modules/certd.ts index 190d76a83..1855fe51b 100644 --- a/packages/ui/certd-client/src/router/source/modules/certd.ts +++ b/packages/ui/certd-client/src/router/source/modules/certd.ts @@ -40,6 +40,17 @@ export const certdResources = [ cache: true } }, + { + title: "证书仓库", + name: "CertStore", + path: "/certd/monitor/cert", + component: "/certd/monitor/cert/index.vue", + meta: { + icon: "ion:shield-checkmark-outline", + auth: true, + isMenu: true + } + }, { title: "站点证书监控", name: "SiteCertMonitor", @@ -80,21 +91,6 @@ export const certdResources = [ auth: true } }, - { - title: "证书仓库", - name: "CertStore", - path: "/certd/monitor/cert", - component: "/certd/monitor/cert/index.vue", - meta: { - show: () => { - const settingStore = useSettingStore(); - return settingStore.isPlus; - }, - icon: "ion:shield-checkmark-outline", - auth: true, - isMenu: false - } - }, { title: "授权管理", name: "AccessManager", @@ -106,6 +102,17 @@ export const certdResources = [ cache: true } }, + { + title: "OpenKey", + name: "OpenKey", + path: "/certd/open/openkey", + component: "/certd/open/openkey/index.vue", + meta: { + icon: "ion:disc-outline", + auth: true, + cache: true + } + }, { title: "通知设置", name: "NotificationManager", diff --git a/packages/ui/certd-client/src/views/certd/monitor/cert/crud.tsx b/packages/ui/certd-client/src/views/certd/monitor/cert/crud.tsx index 5ad919d9d..1a35f60e2 100644 --- a/packages/ui/certd-client/src/views/certd/monitor/cert/crud.tsx +++ b/packages/ui/certd-client/src/views/certd/monitor/cert/crud.tsx @@ -2,6 +2,7 @@ import { useI18n } from "vue-i18n"; import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud"; import { pipelineGroupApi } from "./api"; +import dayjs from "dayjs"; export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { const { t } = useI18n(); @@ -78,23 +79,23 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat show: false } }, - domain: { - title: "主域名", - search: { - show: true - }, - type: "text", - form: { - show: false - }, - column: { - width: 180, - sorter: true, - component: { - name: "fs-values-format" - } - } - }, + // domain: { + // title: "主域名", + // search: { + // show: true + // }, + // type: "text", + // form: { + // show: false + // }, + // column: { + // width: 180, + // sorter: true, + // component: { + // name: "fs-values-format" + // } + // } + // }, domains: { title: "全部域名", search: { @@ -105,10 +106,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat rules: [{ required: true, message: "请输入域名" }] }, column: { - width: 350, + width: 450, sorter: true, component: { - name: "fs-values-format" + name: "fs-values-format", + color: "auto" } } }, @@ -124,17 +126,40 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat show: false } }, - "pipeline.title": { - title: "已关联流水线", - search: { show: false }, - type: "link", + expiresTime: { + title: "过期时间", + search: { + show: true + }, + type: "date", form: { show: false }, column: { - width: 250, sorter: true, - component: {} + cellRender({ value }) { + if (!value) { + return "-"; + } + const expireDate = dayjs(value).format("YYYY-MM-DD"); + const leftDays = dayjs(value).diff(dayjs(), "day"); + const color = leftDays < 20 ? "red" : "#389e0d"; + const percent = (leftDays / 90) * 100; + return `${leftDays}天`} />; + } + } + }, + certProvider: { + title: "证书颁发机构", + search: { + show: true + }, + type: "text", + form: { + show: false + }, + column: { + width: 200 } }, applyTime: { @@ -150,42 +175,17 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat sorter: true } }, - expiresTime: { - title: "过期时间", - search: { - show: true - }, - type: "date", + "pipeline.title": { + title: "已关联流水线", + search: { show: false }, + type: "link", form: { show: false }, column: { - sorter: true - } - }, - fromType: { - title: "来源", - search: { - show: true - }, - type: "text", - form: { show: false }, - column: { - width: 100, - sorter: true - } - }, - certProvider: { - title: "证书颁发机构", - search: { - show: true - }, - type: "text", - form: { - show: false - }, - column: { - width: 400 + width: 350, + sorter: true, + component: {} } } } diff --git a/packages/ui/certd-client/src/views/certd/monitor/cert/index.vue b/packages/ui/certd-client/src/views/certd/monitor/cert/index.vue index 9c890e1a8..7a4a9e345 100644 --- a/packages/ui/certd-client/src/views/certd/monitor/cert/index.vue +++ b/packages/ui/certd-client/src/views/certd/monitor/cert/index.vue @@ -3,7 +3,7 @@ diff --git a/packages/ui/certd-client/src/views/certd/open/openkey/api.ts b/packages/ui/certd-client/src/views/certd/open/openkey/api.ts new file mode 100644 index 000000000..6dac377f2 --- /dev/null +++ b/packages/ui/certd-client/src/views/certd/open/openkey/api.ts @@ -0,0 +1,55 @@ +import { request } from "/src/api/service"; + +export function createApi() { + const apiPrefix = "/open/key"; + return { + async GetList(query: any) { + return await request({ + url: apiPrefix + "/page", + method: "post", + data: query + }); + }, + + async AddObj(obj: any) { + return await request({ + url: apiPrefix + "/add", + method: "post", + data: obj + }); + }, + + async UpdateObj(obj: any) { + return await request({ + url: apiPrefix + "/update", + method: "post", + data: obj + }); + }, + + async DelObj(id: number) { + return await request({ + url: apiPrefix + "/delete", + method: "post", + params: { id } + }); + }, + + async GetObj(id: number) { + return await request({ + url: apiPrefix + "/info", + method: "post", + params: { id } + }); + }, + async GetApiToken(id: number) { + return await request({ + url: apiPrefix + "/getApiToken", + method: "post", + data: { id } + }); + } + }; +} + +export const pipelineGroupApi = createApi(); diff --git a/packages/ui/certd-client/src/views/certd/open/openkey/crud.tsx b/packages/ui/certd-client/src/views/certd/open/openkey/crud.tsx new file mode 100644 index 000000000..e18ed809a --- /dev/null +++ b/packages/ui/certd-client/src/views/certd/open/openkey/crud.tsx @@ -0,0 +1,165 @@ +// @ts-ignore +import { useI18n } from "vue-i18n"; +import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud"; +import { pipelineGroupApi } from "./api"; +import dayjs from "dayjs"; +import { Modal } from "ant-design-vue"; +import CertView from "/@/views/certd/pipeline/cert-view.vue"; +import { useModal } from "/@/use/use-modal"; + +export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { + const { t } = useI18n(); + const api = pipelineGroupApi; + const pageRequest = async (query: UserPageQuery): Promise => { + return await api.GetList(query); + }; + const editRequest = async (req: EditReq) => { + const { form, row } = req; + form.id = row.id; + const res = await api.UpdateObj(form); + return res; + }; + const delRequest = async (req: DelReq) => { + const { row } = req; + return await api.DelObj(row.id); + }; + + const addRequest = async (req: AddReq) => { + const { form } = req; + const res = await api.AddObj(form); + return res; + }; + const model = useModal(); + return { + crudOptions: { + request: { + pageRequest, + addRequest, + editRequest, + delRequest + }, + search: { + show: false + }, + form: { + labelCol: { + //固定label宽度 + span: null, + style: { + width: "100px" + } + }, + col: { + span: 22 + }, + wrapper: { + width: 600 + } + }, + actionbar: { + buttons: { + add: { + text: "生成新的Key", + click() { + Modal.confirm({ + title: "确认", + content: "确定要生成新的Key?", + async onOk() { + await api.AddObj({}); + await crudExpose.doRefresh(); + } + }); + } + } + } + }, + rowHandle: { + width: 300, + fixed: "right", + buttons: { + view: { show: true }, + copy: { show: false }, + edit: { show: false }, + remove: { show: true }, + gen: { + text: "测试ApiToken", + async click({ row }) { + const apiToken = await api.GetApiToken(row.id); + + model.success({ + title: "ApiToken", + maskClosable: true, + okText: "确定", + width: 600, + content: () => { + return ( +
+
测试ApiKey如下,您可以在3分钟内使用它进行开放接口请求测试
+
+ +
+
+ ); + } + }); + } + } + } + }, + columns: { + id: { + title: "ID", + key: "id", + type: "number", + search: { + show: false + }, + column: { + width: 100, + editable: { + disabled: true + } + }, + form: { + show: false + } + }, + keyId: { + title: "KeyId", + search: { + show: false + }, + form: { + show: false + }, + type: "text", + column: { + width: 200, + sorter: true + } + }, + keySecret: { + title: "KeySecret", + type: "text", + form: { + show: false + }, + column: { + width: 550, + sorter: true + } + }, + createTime: { + title: "创建时间", + type: "datetime", + search: { + show: false + }, + form: { + show: false + } + } + } + } + }; +} diff --git a/packages/ui/certd-client/src/views/certd/open/openkey/index.vue b/packages/ui/certd-client/src/views/certd/open/openkey/index.vue new file mode 100644 index 000000000..2f5097ac5 --- /dev/null +++ b/packages/ui/certd-client/src/views/certd/open/openkey/index.vue @@ -0,0 +1,27 @@ + + + diff --git a/packages/ui/certd-server/db/migration/v10020__open.sql b/packages/ui/certd-server/db/migration/v10020__open.sql new file mode 100644 index 000000000..b83121151 --- /dev/null +++ b/packages/ui/certd-server/db/migration/v10020__open.sql @@ -0,0 +1,15 @@ +CREATE TABLE "cd_open_key" +( + "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "user_id" integer, + "key_id" varchar(50), + "key_secret" varchar(100), + "disabled" boolean NOT NULL DEFAULT (false), + "create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), + "update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP) +); + + + +CREATE INDEX "index_open_key_user_id" ON "cd_open_key" ("user_id"); +CREATE INDEX "index_open_key_key_id" ON "cd_open_key" ("key_id"); diff --git a/packages/ui/certd-server/src/configuration.ts b/packages/ui/certd-server/src/configuration.ts index 75044d360..e854055ff 100644 --- a/packages/ui/certd-server/src/configuration.ts +++ b/packages/ui/certd-server/src/configuration.ts @@ -19,7 +19,6 @@ import * as libServer from '@certd/lib-server'; import * as commercial from '@certd/commercial-core'; import * as upload from '@midwayjs/upload'; import { setLogger } from '@certd/acme-client'; - process.on('uncaughtException', error => { console.error('未捕获的异常:', error); // 在这里可以添加日志记录、发送错误通知等操作 diff --git a/packages/ui/certd-server/src/controller/openapi/base-open-controller.ts b/packages/ui/certd-server/src/controller/openapi/base-open-controller.ts new file mode 100644 index 000000000..ad141256e --- /dev/null +++ b/packages/ui/certd-server/src/controller/openapi/base-open-controller.ts @@ -0,0 +1,15 @@ +import { BaseController, Encryptor } from '@certd/lib-server'; +import { OpenKey } from '../../modules/open/service/open-key-service.js'; + +export class BaseOpenController extends BaseController { + ok(res: any) { + const openKey: OpenKey = this.ctx.openKey; + if (openKey.encrypt) { + const data = JSON.stringify(res); + const encryptor = new Encryptor(openKey.keySecret, 'hex'); + const encrypted = encryptor.encrypt(data); + return this.ok(encrypted); + } + return super.ok(res); + } +} diff --git a/packages/ui/certd-server/src/controller/openapi/v1/cert-controller.ts b/packages/ui/certd-server/src/controller/openapi/v1/cert-controller.ts new file mode 100644 index 000000000..0b02fabde --- /dev/null +++ b/packages/ui/certd-server/src/controller/openapi/v1/cert-controller.ts @@ -0,0 +1,39 @@ +import { ALL, Body, Controller, Get, Inject, Post, Provide, Query } from '@midwayjs/core'; +import { CodeException, Constants, EncryptService } from '@certd/lib-server'; +import { CertInfoService } from '../../../modules/monitor/service/cert-info-service.js'; +import { CertInfo } from '@certd/plugin-cert'; +import { OpenKey } from '../../../modules/open/service/open-key-service.js'; +import { BaseOpenController } from '../base-open-controller.js'; + +export type CertGetReq = { + domains?: string; + certId: number; +}; + +/** + */ +@Provide() +@Controller('/api/v1/cert') +export class OpenCertController extends BaseOpenController { + @Inject() + certInfoService: CertInfoService; + @Inject() + encryptService: EncryptService; + + @Get('/get', { summary: Constants.per.open }) + @Post('/get', { summary: Constants.per.open }) + async get(@Body(ALL) bean: CertGetReq, @Query(ALL) query: CertGetReq) { + const openKey: OpenKey = this.ctx.openKey; + const userId = openKey.userId; + if (!userId) { + throw new CodeException(Constants.res.openKeyError); + } + + const res: CertInfo = await this.certInfoService.getCertInfo({ + userId, + domains: bean.domains || query.domains, + certId: bean.certId || query.certId, + }); + return this.ok(res); + } +} diff --git a/packages/ui/certd-server/src/controller/sys/access/access-controller.ts b/packages/ui/certd-server/src/controller/sys/access/access-controller.ts index e4c9c5b42..d9a9590af 100644 --- a/packages/ui/certd-server/src/controller/sys/access/access-controller.ts +++ b/packages/ui/certd-server/src/controller/sys/access/access-controller.ts @@ -1,6 +1,6 @@ import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; import { AccessService, Constants } from '@certd/lib-server'; -import { AccessController } from '../../pipeline/access-controller.js'; +import { AccessController } from '../../user/pipeline/access-controller.js'; import { checkComm } from '@certd/plus-core'; /** diff --git a/packages/ui/certd-server/src/controller/basic/app-controller.ts b/packages/ui/certd-server/src/controller/user/basic/app-controller.ts similarity index 100% rename from packages/ui/certd-server/src/controller/basic/app-controller.ts rename to packages/ui/certd-server/src/controller/user/basic/app-controller.ts diff --git a/packages/ui/certd-server/src/controller/basic/code-controller.ts b/packages/ui/certd-server/src/controller/user/basic/code-controller.ts similarity index 92% rename from packages/ui/certd-server/src/controller/basic/code-controller.ts rename to packages/ui/certd-server/src/controller/user/basic/code-controller.ts index 09a90009d..48d163a3b 100644 --- a/packages/ui/certd-server/src/controller/basic/code-controller.ts +++ b/packages/ui/certd-server/src/controller/user/basic/code-controller.ts @@ -1,8 +1,8 @@ import { Rule, RuleType } from '@midwayjs/validate'; import { ALL, Body, Controller, Get, Inject, Post, Provide, Query } from '@midwayjs/core'; import { BaseController, Constants } from '@certd/lib-server'; -import { CodeService } from '../../modules/basic/service/code-service.js'; -import { EmailService } from '../../modules/basic/service/email-service.js'; +import { CodeService } from '../../../modules/basic/service/code-service.js'; +import { EmailService } from '../../../modules/basic/service/email-service.js'; export class SmsCodeReq { @Rule(RuleType.string().required()) diff --git a/packages/ui/certd-server/src/controller/basic/email-controller.ts b/packages/ui/certd-server/src/controller/user/basic/email-controller.ts similarity index 87% rename from packages/ui/certd-server/src/controller/basic/email-controller.ts rename to packages/ui/certd-server/src/controller/user/basic/email-controller.ts index 684c0456f..543090c73 100644 --- a/packages/ui/certd-server/src/controller/basic/email-controller.ts +++ b/packages/ui/certd-server/src/controller/user/basic/email-controller.ts @@ -1,6 +1,6 @@ import { Body, Controller, Inject, Post, Provide } from '@midwayjs/core'; import { BaseController } from '@certd/lib-server'; -import { EmailService } from '../../modules/basic/service/email-service.js'; +import { EmailService } from '../../../modules/basic/service/email-service.js'; import { Constants } from '@certd/lib-server'; /** diff --git a/packages/ui/certd-server/src/controller/basic/file-controller.ts b/packages/ui/certd-server/src/controller/user/basic/file-controller.ts similarity index 100% rename from packages/ui/certd-server/src/controller/basic/file-controller.ts rename to packages/ui/certd-server/src/controller/user/basic/file-controller.ts diff --git a/packages/ui/certd-server/src/controller/basic/home-controller.ts b/packages/ui/certd-server/src/controller/user/basic/home-controller.ts similarity index 100% rename from packages/ui/certd-server/src/controller/basic/home-controller.ts rename to packages/ui/certd-server/src/controller/user/basic/home-controller.ts diff --git a/packages/ui/certd-server/src/controller/basic/settings-controller.ts b/packages/ui/certd-server/src/controller/user/basic/settings-controller.ts similarity index 100% rename from packages/ui/certd-server/src/controller/basic/settings-controller.ts rename to packages/ui/certd-server/src/controller/user/basic/settings-controller.ts diff --git a/packages/ui/certd-server/src/controller/cname/cname-provider-controller.ts b/packages/ui/certd-server/src/controller/user/cname/cname-provider-controller.ts similarity index 78% rename from packages/ui/certd-server/src/controller/cname/cname-provider-controller.ts rename to packages/ui/certd-server/src/controller/user/cname/cname-provider-controller.ts index 919f0fc0d..044713c79 100644 --- a/packages/ui/certd-server/src/controller/cname/cname-provider-controller.ts +++ b/packages/ui/certd-server/src/controller/user/cname/cname-provider-controller.ts @@ -1,7 +1,7 @@ import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core'; import { BaseController, Constants } from '@certd/lib-server'; -import { CnameRecordService } from '../../modules/cname/service/cname-record-service.js'; -import { CnameProviderService } from '../../modules/cname/service/cname-provider-service.js'; +import { CnameRecordService } from '../../../modules/cname/service/cname-record-service.js'; +import { CnameProviderService } from '../../../modules/cname/service/cname-provider-service.js'; /** * 授权 diff --git a/packages/ui/certd-server/src/controller/cname/cname-record-controller.ts b/packages/ui/certd-server/src/controller/user/cname/cname-record-controller.ts similarity index 96% rename from packages/ui/certd-server/src/controller/cname/cname-record-controller.ts rename to packages/ui/certd-server/src/controller/user/cname/cname-record-controller.ts index db6982201..438fa42ae 100644 --- a/packages/ui/certd-server/src/controller/cname/cname-record-controller.ts +++ b/packages/ui/certd-server/src/controller/user/cname/cname-record-controller.ts @@ -1,6 +1,6 @@ import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; import { Constants, CrudController } from '@certd/lib-server'; -import { CnameRecordService } from '../../modules/cname/service/cname-record-service.js'; +import { CnameRecordService } from '../../../modules/cname/service/cname-record-service.js'; /** * 授权 diff --git a/packages/ui/certd-server/src/controller/dashboard/statistic-controller.ts b/packages/ui/certd-server/src/controller/user/dashboard/statistic-controller.ts similarity index 79% rename from packages/ui/certd-server/src/controller/dashboard/statistic-controller.ts rename to packages/ui/certd-server/src/controller/user/dashboard/statistic-controller.ts index 1b68e7495..91aacfd0a 100644 --- a/packages/ui/certd-server/src/controller/dashboard/statistic-controller.ts +++ b/packages/ui/certd-server/src/controller/user/dashboard/statistic-controller.ts @@ -1,9 +1,9 @@ import { Controller, Inject, Post, Provide } from '@midwayjs/core'; import { BaseController, Constants } from '@certd/lib-server'; -import { UserService } from '../../modules/sys/authority/service/user-service.js'; -import { RoleService } from '../../modules/sys/authority/service/role-service.js'; -import { PipelineService } from '../../modules/pipeline/service/pipeline-service.js'; -import { HistoryService } from '../../modules/pipeline/service/history-service.js'; +import { UserService } from '../../../modules/sys/authority/service/user-service.js'; +import { RoleService } from '../../../modules/sys/authority/service/role-service.js'; +import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js'; +import { HistoryService } from '../../../modules/pipeline/service/history-service.js'; export type ChartItem = { name: string; diff --git a/packages/ui/certd-server/src/controller/login/login-controller.ts b/packages/ui/certd-server/src/controller/user/login/login-controller.ts similarity index 90% rename from packages/ui/certd-server/src/controller/login/login-controller.ts rename to packages/ui/certd-server/src/controller/user/login/login-controller.ts index 26f484fe4..8e9a26639 100644 --- a/packages/ui/certd-server/src/controller/login/login-controller.ts +++ b/packages/ui/certd-server/src/controller/user/login/login-controller.ts @@ -1,7 +1,7 @@ import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core'; -import { LoginService } from '../../modules/login/service/login-service.js'; +import { LoginService } from '../../../modules/login/service/login-service.js'; import { BaseController, Constants, SysPublicSettings, SysSettingsService } from '@certd/lib-server'; -import { CodeService } from '../../modules/basic/service/code-service.js'; +import { CodeService } from '../../../modules/basic/service/code-service.js'; import { checkComm } from '@certd/plus-core'; /** diff --git a/packages/ui/certd-server/src/controller/login/register-controller.ts b/packages/ui/certd-server/src/controller/user/login/register-controller.ts similarity index 93% rename from packages/ui/certd-server/src/controller/login/register-controller.ts rename to packages/ui/certd-server/src/controller/user/login/register-controller.ts index fc5da5ebe..c8d45c2d1 100644 --- a/packages/ui/certd-server/src/controller/login/register-controller.ts +++ b/packages/ui/certd-server/src/controller/user/login/register-controller.ts @@ -1,7 +1,7 @@ import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core'; import { BaseController, Constants, SysSettingsService } from '@certd/lib-server'; -import { RegisterType, UserService } from '../../modules/sys/authority/service/user-service.js'; -import { CodeService } from '../../modules/basic/service/code-service.js'; +import { RegisterType, UserService } from '../../../modules/sys/authority/service/user-service.js'; +import { CodeService } from '../../../modules/basic/service/code-service.js'; import { checkComm, checkPlus } from '@certd/plus-core'; export type RegisterReq = { diff --git a/packages/ui/certd-server/src/controller/mine/mine-controller.ts b/packages/ui/certd-server/src/controller/user/mine/mine-controller.ts similarity index 85% rename from packages/ui/certd-server/src/controller/mine/mine-controller.ts rename to packages/ui/certd-server/src/controller/user/mine/mine-controller.ts index e3b16f2d7..a3949c590 100644 --- a/packages/ui/certd-server/src/controller/mine/mine-controller.ts +++ b/packages/ui/certd-server/src/controller/user/mine/mine-controller.ts @@ -1,7 +1,7 @@ import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core'; import { BaseController, Constants } from '@certd/lib-server'; -import { UserService } from '../../modules/sys/authority/service/user-service.js'; -import { RoleService } from '../../modules/sys/authority/service/role-service.js'; +import { UserService } from '../../../modules/sys/authority/service/user-service.js'; +import { RoleService } from '../../../modules/sys/authority/service/role-service.js'; /** */ diff --git a/packages/ui/certd-server/src/controller/mine/user-settings-controller.ts b/packages/ui/certd-server/src/controller/user/mine/user-settings-controller.ts similarity index 91% rename from packages/ui/certd-server/src/controller/mine/user-settings-controller.ts rename to packages/ui/certd-server/src/controller/user/mine/user-settings-controller.ts index 982d4d4af..b4a53bdcc 100644 --- a/packages/ui/certd-server/src/controller/mine/user-settings-controller.ts +++ b/packages/ui/certd-server/src/controller/user/mine/user-settings-controller.ts @@ -1,8 +1,8 @@ import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; import { CrudController } from '@certd/lib-server'; import { Constants } from '@certd/lib-server'; -import { UserSettingsService } from '../../modules/mine/service/user-settings-service.js'; -import { UserSettingsEntity } from '../../modules/mine/entity/user-settings.js'; +import { UserSettingsService } from '../../../modules/mine/service/user-settings-service.js'; +import { UserSettingsEntity } from '../../../modules/mine/entity/user-settings.js'; /** */ diff --git a/packages/ui/certd-server/src/controller/monitor/cert-info-controller.ts b/packages/ui/certd-server/src/controller/user/monitor/cert-info-controller.ts similarity index 90% rename from packages/ui/certd-server/src/controller/monitor/cert-info-controller.ts rename to packages/ui/certd-server/src/controller/user/monitor/cert-info-controller.ts index 420e5dbf6..49355cd7b 100644 --- a/packages/ui/certd-server/src/controller/monitor/cert-info-controller.ts +++ b/packages/ui/certd-server/src/controller/user/monitor/cert-info-controller.ts @@ -1,8 +1,8 @@ import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; import { Constants, CrudController } from '@certd/lib-server'; -import { AuthService } from '../../modules/sys/authority/service/auth-service.js'; -import { CertInfoService } from '../../modules/monitor/index.js'; -import { PipelineService } from '../../modules/pipeline/service/pipeline-service.js'; +import { AuthService } from '../../../modules/sys/authority/service/auth-service.js'; +import { CertInfoService } from '../../../modules/monitor/index.js'; +import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js'; /** */ diff --git a/packages/ui/certd-server/src/controller/monitor/site-info-controller.ts b/packages/ui/certd-server/src/controller/user/monitor/site-info-controller.ts similarity index 92% rename from packages/ui/certd-server/src/controller/monitor/site-info-controller.ts rename to packages/ui/certd-server/src/controller/user/monitor/site-info-controller.ts index f1c7e96f4..16ad1922d 100644 --- a/packages/ui/certd-server/src/controller/monitor/site-info-controller.ts +++ b/packages/ui/certd-server/src/controller/user/monitor/site-info-controller.ts @@ -1,7 +1,7 @@ import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; import { Constants, CrudController } from '@certd/lib-server'; -import { AuthService } from '../../modules/sys/authority/service/auth-service.js'; -import { SiteInfoService } from '../../modules/monitor/index.js'; +import { AuthService } from '../../../modules/sys/authority/service/auth-service.js'; +import { SiteInfoService } from '../../../modules/monitor/service/site-info-service.js'; /** */ diff --git a/packages/ui/certd-server/src/controller/user/open/open-key-controller.ts b/packages/ui/certd-server/src/controller/user/open/open-key-controller.ts new file mode 100644 index 000000000..49702ffe2 --- /dev/null +++ b/packages/ui/certd-server/src/controller/user/open/open-key-controller.ts @@ -0,0 +1,72 @@ +import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; +import { Constants, CrudController } from '@certd/lib-server'; +import { AuthService } from '../../../modules/sys/authority/service/auth-service.js'; +import { OpenKeyService } from '../../../modules/open/service/open-key-service.js'; + +/** + */ +@Provide() +@Controller('/api/open/key') +export class OpenKeyController extends CrudController { + @Inject() + service: OpenKeyService; + @Inject() + authService: AuthService; + + getService(): OpenKeyService { + return this.service; + } + + @Post('/page', { summary: Constants.per.authOnly }) + async page(@Body(ALL) body: any) { + body.query = body.query ?? {}; + body.query.userId = this.getUserId(); + const res = await this.service.page({ + query: body.query, + page: body.page, + sort: body.sort, + }); + return this.ok(res); + } + + @Post('/list', { summary: Constants.per.authOnly }) + async list(@Body(ALL) body: any) { + body.query = body.query ?? {}; + body.query.userId = this.getUserId(); + return await super.list(body); + } + + @Post('/add', { summary: Constants.per.authOnly }) + async add() { + const bean: any = {}; + bean.userId = this.getUserId(); + const res = await this.service.add(bean); + return this.ok(res); + } + + @Post('/update', { summary: Constants.per.authOnly }) + async update(@Body(ALL) bean) { + await this.service.checkUserId(bean.id, this.getUserId()); + delete bean.userId; + await this.service.update(bean); + return this.ok(); + } + @Post('/info', { summary: Constants.per.authOnly }) + async info(@Query('id') id: number) { + await this.service.checkUserId(id, this.getUserId()); + return await super.info(id); + } + + @Post('/delete', { summary: Constants.per.authOnly }) + async delete(@Query('id') id: number) { + await this.service.checkUserId(id, this.getUserId()); + return await super.delete(id); + } + + @Post('/getApiToken', { summary: Constants.per.authOnly }) + async getApiToken(@Query('id') id: number) { + await this.service.checkUserId(id, this.getUserId()); + const token = await this.service.getApiToken(id); + return this.ok(token); + } +} diff --git a/packages/ui/certd-server/src/controller/pipeline/access-controller.ts b/packages/ui/certd-server/src/controller/user/pipeline/access-controller.ts similarity index 97% rename from packages/ui/certd-server/src/controller/pipeline/access-controller.ts rename to packages/ui/certd-server/src/controller/user/pipeline/access-controller.ts index ce2ff6617..8f965fe25 100644 --- a/packages/ui/certd-server/src/controller/pipeline/access-controller.ts +++ b/packages/ui/certd-server/src/controller/user/pipeline/access-controller.ts @@ -1,7 +1,7 @@ import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; import { Constants, CrudController } from '@certd/lib-server'; import { AccessService } from '@certd/lib-server'; -import { AuthService } from '../../modules/sys/authority/service/auth-service.js'; +import { AuthService } from '../../../modules/sys/authority/service/auth-service.js'; import { AccessDefine } from '@certd/pipeline'; /** diff --git a/packages/ui/certd-server/src/controller/pipeline/cert-controller.ts b/packages/ui/certd-server/src/controller/user/pipeline/cert-controller.ts similarity index 78% rename from packages/ui/certd-server/src/controller/pipeline/cert-controller.ts rename to packages/ui/certd-server/src/controller/user/pipeline/cert-controller.ts index 2196eef8d..7cc6c1f87 100644 --- a/packages/ui/certd-server/src/controller/pipeline/cert-controller.ts +++ b/packages/ui/certd-server/src/controller/user/pipeline/cert-controller.ts @@ -1,7 +1,7 @@ import { Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; -import { PipelineService } from '../../modules/pipeline/service/pipeline-service.js'; +import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js'; import { BaseController, Constants } from '@certd/lib-server'; -import { StorageService } from '../../modules/pipeline/service/storage-service.js'; +import { StorageService } from '../../../modules/pipeline/service/storage-service.js'; @Provide() @Controller('/api/pi/cert') diff --git a/packages/ui/certd-server/src/controller/pipeline/dns-provider-controller.ts b/packages/ui/certd-server/src/controller/user/pipeline/dns-provider-controller.ts similarity index 90% rename from packages/ui/certd-server/src/controller/pipeline/dns-provider-controller.ts rename to packages/ui/certd-server/src/controller/user/pipeline/dns-provider-controller.ts index 4d4963375..0c871fa59 100644 --- a/packages/ui/certd-server/src/controller/pipeline/dns-provider-controller.ts +++ b/packages/ui/certd-server/src/controller/user/pipeline/dns-provider-controller.ts @@ -1,5 +1,5 @@ import { ALL, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; -import { DnsProviderService } from '../../modules/pipeline/service/dns-provider-service.js'; +import { DnsProviderService } from '../../../modules/pipeline/service/dns-provider-service.js'; import { BaseController } from '@certd/lib-server'; import { Constants } from '@certd/lib-server'; diff --git a/packages/ui/certd-server/src/controller/pipeline/handle-controller.ts b/packages/ui/certd-server/src/controller/user/pipeline/handle-controller.ts similarity index 95% rename from packages/ui/certd-server/src/controller/pipeline/handle-controller.ts rename to packages/ui/certd-server/src/controller/user/pipeline/handle-controller.ts index 6bbd31e6e..3d7422a5f 100644 --- a/packages/ui/certd-server/src/controller/pipeline/handle-controller.ts +++ b/packages/ui/certd-server/src/controller/user/pipeline/handle-controller.ts @@ -11,9 +11,9 @@ import { TaskInstanceContext, } from '@certd/pipeline'; import { AccessService, AccessGetter } from '@certd/lib-server'; -import { EmailService } from '../../modules/basic/service/email-service.js'; +import { EmailService } from '../../../modules/basic/service/email-service.js'; import { http, HttpRequestConfig, logger, mergeUtils, utils } from '@certd/basic'; -import { NotificationService } from '../../modules/pipeline/service/notification-service.js'; +import { NotificationService } from '../../../modules/pipeline/service/notification-service.js'; @Provide() @Controller('/api/pi/handle') diff --git a/packages/ui/certd-server/src/controller/pipeline/history-controller.ts b/packages/ui/certd-server/src/controller/user/pipeline/history-controller.ts similarity index 91% rename from packages/ui/certd-server/src/controller/pipeline/history-controller.ts rename to packages/ui/certd-server/src/controller/user/pipeline/history-controller.ts index c2393a8e3..8643cc805 100644 --- a/packages/ui/certd-server/src/controller/pipeline/history-controller.ts +++ b/packages/ui/certd-server/src/controller/user/pipeline/history-controller.ts @@ -1,14 +1,14 @@ import { ALL, Body, Controller, Get, Inject, Post, Provide, Query } from '@midwayjs/core'; import { CommonException, Constants, CrudController, PermissionException } from '@certd/lib-server'; -import { PipelineEntity } from '../../modules/pipeline/entity/pipeline.js'; -import { HistoryService } from '../../modules/pipeline/service/history-service.js'; -import { HistoryLogService } from '../../modules/pipeline/service/history-log-service.js'; -import { HistoryEntity } from '../../modules/pipeline/entity/history.js'; -import { HistoryLogEntity } from '../../modules/pipeline/entity/history-log.js'; -import { PipelineService } from '../../modules/pipeline/service/pipeline-service.js'; +import { PipelineEntity } from '../../../modules/pipeline/entity/pipeline.js'; +import { HistoryService } from '../../../modules/pipeline/service/history-service.js'; +import { HistoryLogService } from '../../../modules/pipeline/service/history-log-service.js'; +import { HistoryEntity } from '../../../modules/pipeline/entity/history.js'; +import { HistoryLogEntity } from '../../../modules/pipeline/entity/history-log.js'; +import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js'; import * as fs from 'fs'; import { logger } from '@certd/basic'; -import { AuthService } from '../../modules/sys/authority/service/auth-service.js'; +import { AuthService } from '../../../modules/sys/authority/service/auth-service.js'; import { SysSettingsService } from '@certd/lib-server'; import { In } from 'typeorm'; diff --git a/packages/ui/certd-server/src/controller/pipeline/notification-controller.ts b/packages/ui/certd-server/src/controller/user/pipeline/notification-controller.ts similarity index 96% rename from packages/ui/certd-server/src/controller/pipeline/notification-controller.ts rename to packages/ui/certd-server/src/controller/user/pipeline/notification-controller.ts index 77dba97ee..97b28e3dd 100644 --- a/packages/ui/certd-server/src/controller/pipeline/notification-controller.ts +++ b/packages/ui/certd-server/src/controller/user/pipeline/notification-controller.ts @@ -1,7 +1,7 @@ import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; import { Constants, CrudController, ValidateException } from '@certd/lib-server'; -import { NotificationService } from '../../modules/pipeline/service/notification-service.js'; -import { AuthService } from '../../modules/sys/authority/service/auth-service.js'; +import { NotificationService } from '../../../modules/pipeline/service/notification-service.js'; +import { AuthService } from '../../../modules/sys/authority/service/auth-service.js'; import { NotificationDefine } from '@certd/pipeline'; import { checkPlus } from '@certd/plus-core'; diff --git a/packages/ui/certd-server/src/controller/pipeline/pipeline-controller.ts b/packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts similarity index 91% rename from packages/ui/certd-server/src/controller/pipeline/pipeline-controller.ts rename to packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts index 3c4ad067a..f0a877c63 100644 --- a/packages/ui/certd-server/src/controller/pipeline/pipeline-controller.ts +++ b/packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts @@ -1,9 +1,9 @@ import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; import { Constants, CrudController, SysSettingsService } from '@certd/lib-server'; -import { PipelineService } from '../../modules/pipeline/service/pipeline-service.js'; -import { PipelineEntity } from '../../modules/pipeline/entity/pipeline.js'; -import { HistoryService } from '../../modules/pipeline/service/history-service.js'; -import { AuthService } from '../../modules/sys/authority/service/auth-service.js'; +import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js'; +import { PipelineEntity } from '../../../modules/pipeline/entity/pipeline.js'; +import { HistoryService } from '../../../modules/pipeline/service/history-service.js'; +import { AuthService } from '../../../modules/sys/authority/service/auth-service.js'; /** * 证书 diff --git a/packages/ui/certd-server/src/controller/pipeline/pipeline-group-controller.ts b/packages/ui/certd-server/src/controller/user/pipeline/pipeline-group-controller.ts similarity index 91% rename from packages/ui/certd-server/src/controller/pipeline/pipeline-group-controller.ts rename to packages/ui/certd-server/src/controller/user/pipeline/pipeline-group-controller.ts index c26cf77ee..dad21359d 100644 --- a/packages/ui/certd-server/src/controller/pipeline/pipeline-group-controller.ts +++ b/packages/ui/certd-server/src/controller/user/pipeline/pipeline-group-controller.ts @@ -1,7 +1,7 @@ import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; import { Constants, CrudController } from '@certd/lib-server'; -import { AuthService } from '../../modules/sys/authority/service/auth-service.js'; -import { PipelineGroupService } from '../../modules/pipeline/service/pipeline-group-service.js'; +import { AuthService } from '../../../modules/sys/authority/service/auth-service.js'; +import { PipelineGroupService } from '../../../modules/pipeline/service/pipeline-group-service.js'; /** * 通知 diff --git a/packages/ui/certd-server/src/controller/pipeline/plugin-controller.ts b/packages/ui/certd-server/src/controller/user/pipeline/plugin-controller.ts similarity index 87% rename from packages/ui/certd-server/src/controller/pipeline/plugin-controller.ts rename to packages/ui/certd-server/src/controller/user/pipeline/plugin-controller.ts index 8703675df..5e5f4f324 100644 --- a/packages/ui/certd-server/src/controller/pipeline/plugin-controller.ts +++ b/packages/ui/certd-server/src/controller/user/pipeline/plugin-controller.ts @@ -1,7 +1,7 @@ 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'; +import { PluginService } from '../../../modules/plugin/service/plugin-service.js'; +import { PluginConfigService } from '../../../modules/plugin/service/plugin-config-service.js'; /** * 插件 diff --git a/packages/ui/certd-server/src/middleware/authority.ts b/packages/ui/certd-server/src/middleware/authority.ts index 850f01081..fcd61f067 100644 --- a/packages/ui/certd-server/src/middleware/authority.ts +++ b/packages/ui/certd-server/src/middleware/authority.ts @@ -1,11 +1,11 @@ import { Init, Inject, MidwayWebRouterService, Provide, Scope, ScopeEnum } from '@midwayjs/core'; import { IMidwayKoaContext, IWebMiddleware, NextFunction } from '@midwayjs/koa'; import jwt from 'jsonwebtoken'; -import { Constants } from '@certd/lib-server'; +import { Constants, SysPrivateSettings, SysSettingsService } from '@certd/lib-server'; import { logger } from '@certd/basic'; import { AuthService } from '../modules/sys/authority/service/auth-service.js'; -import { SysSettingsService } from '@certd/lib-server'; -import { SysPrivateSettings } from '@certd/lib-server'; +import { Next } from 'koa'; +import { OpenKeyService } from '../modules/open/service/open-key-service.js'; /** * 权限校验 @@ -18,6 +18,8 @@ export class AuthorityMiddleware implements IWebMiddleware { @Inject() authService: AuthService; @Inject() + openKeyService: OpenKeyService; + @Inject() sysSettingsService: SysSettingsService; secret: string; @@ -48,6 +50,10 @@ export class AuthorityMiddleware implements IWebMiddleware { return; } + if (permission === Constants.per.open) { + return this.doOpenHandler(ctx, next); + } + let token = ctx.get('Authorization') || ''; token = token.replace('Bearer ', '').trim(); if (!token) { @@ -79,4 +85,20 @@ export class AuthorityMiddleware implements IWebMiddleware { await next(); }; } + + async doOpenHandler(ctx: IMidwayKoaContext, next: Next) { + //开放接口 + const openKey = ctx.get('x-api-token') || ''; + if (!openKey) { + ctx.status = 401; + ctx.body = Constants.res.auth; + return; + } + + //校验 openKey + const openKeyRes = await this.openKeyService.verifyOpenKey(openKey); + ctx.user = { id: openKeyRes.userId }; + ctx.openKey = openKeyRes; + await next(); + } } diff --git a/packages/ui/certd-server/src/modules/auto/auto-e-pipeline-emitter-register.ts b/packages/ui/certd-server/src/modules/auto/auto-e-pipeline-emitter-register.ts new file mode 100644 index 000000000..67068ea8e --- /dev/null +++ b/packages/ui/certd-server/src/modules/auto/auto-e-pipeline-emitter-register.ts @@ -0,0 +1,22 @@ +import { Autoload, Init, Inject, Scope, ScopeEnum } from '@midwayjs/core'; +import { CertInfoService } from '../monitor/index.js'; +import { pipelineEmitter } from '@certd/pipeline'; +import { CertReader, EVENT_CERT_APPLY_SUCCESS } from '@certd/plugin-cert'; +import { PipelineEvent } from '@certd/pipeline/dist/service/emit.js'; + +@Autoload() +@Scope(ScopeEnum.Request, { allowDowngrade: true }) +export class AutoEPipelineEmitterRegister { + @Inject() + certInfoService: CertInfoService; + + @Init() + async init() { + await this.onCertApplySuccess(); + } + async onCertApplySuccess() { + pipelineEmitter.on(EVENT_CERT_APPLY_SUCCESS, async (event: PipelineEvent) => { + await this.certInfoService.updateCert(event.pipeline.id, event.event); + }); + } +} 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 65a9daaac..a7f5122ac 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 @@ -1,4 +1,4 @@ -import { Inject, Provide } from '@midwayjs/core'; +import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core'; import { cache, isDev, randomNumber } from '@certd/basic'; import { SysSettingsService, SysSiteInfo } from '@certd/lib-server'; import { SmsServiceFactory } from '../sms/factory.js'; @@ -13,6 +13,7 @@ import { isComm } from '@certd/plus-core'; /** */ @Provide() +@Scope(ScopeEnum.Request, { allowDowngrade: true }) export class CodeService { @Inject() sysSettingsService: SysSettingsService; diff --git a/packages/ui/certd-server/src/modules/login/service/login-service.ts b/packages/ui/certd-server/src/modules/login/service/login-service.ts index f16eea3ce..88df4f1c2 100644 --- a/packages/ui/certd-server/src/modules/login/service/login-service.ts +++ b/packages/ui/certd-server/src/modules/login/service/login-service.ts @@ -1,4 +1,4 @@ -import { Config, Inject, Provide } from '@midwayjs/core'; +import { Config, Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core'; import { UserService } from '../../sys/authority/service/user-service.js'; import jwt from 'jsonwebtoken'; import { CommonException } from '@certd/lib-server'; @@ -14,6 +14,7 @@ import { CodeService } from '../../basic/service/code-service.js'; * 系统用户 */ @Provide() +@Scope(ScopeEnum.Request, { allowDowngrade: true }) export class LoginService { @Inject() userService: UserService; diff --git a/packages/ui/certd-server/src/modules/monitor/entity/cert-info.ts b/packages/ui/certd-server/src/modules/monitor/entity/cert-info.ts index 623d8b006..f16ca87dc 100644 --- a/packages/ui/certd-server/src/modules/monitor/entity/cert-info.ts +++ b/packages/ui/certd-server/src/modules/monitor/entity/cert-info.ts @@ -22,7 +22,7 @@ export class CertInfoEntity { pipelineId: number; @Column({ name: 'apply_time', comment: '申请时间' }) - applyTime: string; + applyTime: number; @Column({ name: 'from_type', comment: '来源' }) fromType: string; diff --git a/packages/ui/certd-server/src/modules/monitor/index.ts b/packages/ui/certd-server/src/modules/monitor/index.ts index 2e836e704..9dd8939de 100644 --- a/packages/ui/certd-server/src/modules/monitor/index.ts +++ b/packages/ui/certd-server/src/modules/monitor/index.ts @@ -1,5 +1,5 @@ -export * from "./entity/site-info.js"; -export * from "./entity/cert-info.js"; +export * from './entity/site-info.js'; +export * from './entity/cert-info.js'; -export * from "./service/cert-info-service.js"; -export * from "./service/site-info-service.js"; +export * from './service/cert-info-service.js'; +export * from './service/site-info-service.js'; diff --git a/packages/ui/certd-server/src/modules/monitor/service/cert-info-service.ts b/packages/ui/certd-server/src/modules/monitor/service/cert-info-service.ts index b58c62a11..13b919f4a 100644 --- a/packages/ui/certd-server/src/modules/monitor/service/cert-info-service.ts +++ b/packages/ui/certd-server/src/modules/monitor/service/cert-info-service.ts @@ -1,10 +1,13 @@ -import { Provide } from '@midwayjs/core'; -import { BaseService, PageReq } from '@certd/lib-server'; +import { Provide, Scope, ScopeEnum } from '@midwayjs/core'; +import { BaseService, CodeException, Constants, PageReq } from '@certd/lib-server'; import { InjectEntityModel } from '@midwayjs/typeorm'; import { Repository } from 'typeorm'; import { CertInfoEntity } from '../entity/cert-info.js'; +import { utils } from '@certd/basic'; +import { CertInfo, CertReader } from '@certd/plugin-cert'; @Provide() +@Scope(ScopeEnum.Request, { allowDowngrade: true }) export class CertInfoService extends BaseService { @InjectEntityModel(CertInfoEntity) repository: Repository; @@ -68,4 +71,81 @@ export class CertInfoService extends BaseService { pipelineId: id, }); } + + async getCertInfo(params: { domains?: string; certId?: number; userId: number }) { + const { domains, certId, userId } = params; + if (certId) { + return await this.getCertInfoById({ id: certId, userId }); + } + return await this.getCertInfoByDomains({ + domains, + userId, + }); + } + + private async getCertInfoByDomains(params: { domains: string; userId: number }) { + const { domains, userId } = params; + if (!domains) { + throw new CodeException(Constants.res.openCertNotFound); + } + const domainArr = domains.split(','); + + const list = await this.find({ + select: { + id: true, + domains: true, + }, + where: { + userId, + }, + }); + //遍历查找 + const matched = list.find(item => { + const itemDomains = item.domains.split(','); + return utils.domain.match(domainArr, itemDomains); + }); + if (!matched) { + throw new CodeException(Constants.res.openCertNotFound); + } + + return await this.getCertInfoById({ id: matched.id, userId: userId }); + } + + async getCertInfoById(req: { id: number; userId: number }) { + const entity = await this.info(req.id); + if (!entity || entity.userId !== req.userId) { + throw new CodeException(Constants.res.openCertNotFound); + } + + if (!entity.certInfo) { + throw new CodeException(Constants.res.openCertNotReady); + } + const certInfo = JSON.parse(entity.certInfo) as CertInfo; + const certReader = new CertReader(certInfo); + return certReader.toCertInfo(); + } + + async updateCert(pipelineId: number, certReader: CertReader) { + const found = await this.repository.findOne({ + where: { + pipelineId, + }, + }); + if (!found) { + return; + } + const bean = new CertInfoEntity(); + bean.id = found.id; + const certInfo = certReader.toCertInfo(); + bean.certInfo = JSON.stringify(certInfo); + bean.applyTime = new Date().getTime(); + const domains = certReader.detail.domains.altNames; + bean.domains = domains.join(','); + bean.domain = domains[0]; + bean.domainCount = domains.length; + bean.expiresTime = certReader.expires; + bean.certProvider = certReader.detail.issuer.commonName; + + await this.addOrUpdate(bean); + } } diff --git a/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts b/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts index bc897249c..06f6533a8 100644 --- a/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts +++ b/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts @@ -1,4 +1,4 @@ -import { Inject, Provide } from '@midwayjs/core'; +import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core'; import { BaseService, NeedSuiteException, NeedVIPException, SysSettingsService } from '@certd/lib-server'; import { InjectEntityModel } from '@midwayjs/typeorm'; import { Repository } from 'typeorm'; @@ -12,6 +12,7 @@ import { isComm, isPlus } from '@certd/plus-core'; import { UserSuiteService } from '@certd/commercial-core'; @Provide() +@Scope(ScopeEnum.Request, { allowDowngrade: true }) export class SiteInfoService extends BaseService { @InjectEntityModel(SiteInfoEntity) repository: Repository; diff --git a/packages/ui/certd-server/src/modules/open/entity/open-key.ts b/packages/ui/certd-server/src/modules/open/entity/open-key.ts new file mode 100644 index 000000000..fbc988d23 --- /dev/null +++ b/packages/ui/certd-server/src/modules/open/entity/open-key.ts @@ -0,0 +1,22 @@ +import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; + +@Entity('cd_open_key') +export class OpenKeyEntity { + @PrimaryGeneratedColumn() + id: number; + + @Column({ name: 'user_id', comment: '用户id' }) + userId: number; + + @Column({ name: 'key_id', comment: 'keyId' }) + keyId: string; + + @Column({ name: 'key_secret', comment: 'keySecret' }) + keySecret: string; + + @Column({ name: 'create_time', comment: '创建时间', default: () => 'CURRENT_TIMESTAMP' }) + createTime: Date; + + @Column({ name: 'update_time', comment: '修改时间', default: () => 'CURRENT_TIMESTAMP' }) + updateTime: Date; +} diff --git a/packages/ui/certd-server/src/modules/open/service/open-key-service.ts b/packages/ui/certd-server/src/modules/open/service/open-key-service.ts new file mode 100644 index 000000000..d894e661b --- /dev/null +++ b/packages/ui/certd-server/src/modules/open/service/open-key-service.ts @@ -0,0 +1,106 @@ +import { Provide, Scope, ScopeEnum } from '@midwayjs/core'; +import { BaseService, Constants, CodeException, PageReq } from '@certd/lib-server'; +import { InjectEntityModel } from '@midwayjs/typeorm'; +import { Repository } from 'typeorm'; +import { OpenKeyEntity } from '../entity/open-key.js'; +import { utils } from '@certd/basic'; +import crypto from 'crypto'; +import dayjs from 'dayjs'; + +export type OpenKey = { + userId: number; + keyId: string; + keySecret: string; + encrypt: boolean; +}; +@Provide() +@Scope(ScopeEnum.Request, { allowDowngrade: true }) +export class OpenKeyService extends BaseService { + @InjectEntityModel(OpenKeyEntity) + repository: Repository; + + //@ts-ignore + getRepository() { + return this.repository; + } + + async page(pageReq: PageReq) { + return await super.page(pageReq); + } + + async add(bean: OpenKeyEntity) { + return await this.generate(bean.userId); + } + + async generate(userId: number) { + const keyId = utils.id.simpleNanoId(18) + '_key'; + const secretKey = crypto.randomBytes(32); + const keySecret = Buffer.from(secretKey).toString('hex'); + const entity = new OpenKeyEntity(); + entity.userId = userId; + entity.keyId = keyId; + entity.keySecret = keySecret; + await this.repository.save(entity); + return entity; + } + + async getByKeyId(keyId: string) { + return this.repository.findOne({ where: { keyId } }); + } + + async verifyOpenKey(openKey: string): Promise { + // openkey 组成,content = base64({keyId,t,encrypt,signType}) ,sign = md5({keyId,t,encrypt,signType}secret) , key = content.sign + const [content, sign] = openKey.split('.'); + const contentJson = Buffer.from(content, 'base64').toString(); + const { keyId, t, encrypt, signType } = JSON.parse(contentJson); + // 正负不超过3分钟 ,timestamps单位为秒 + if (Math.abs(Number(t) - Math.floor(Date.now() / 1000)) > 180) { + throw new CodeException(Constants.res.openKeyExpiresError); + } + + const entity = await this.getByKeyId(keyId); + if (!entity) { + throw new Error('openKey不存在'); + } + const secret = entity.keySecret; + let computedSign = ''; + if (signType === 'md5') { + computedSign = utils.hash.md5(contentJson + secret); + } else if (signType === 'sha256') { + computedSign = utils.hash.sha256(contentJson + secret); + } else { + throw new CodeException(Constants.res.openKeySignTypeError); + } + if (Buffer.from(computedSign).toString('base64') !== sign) { + throw new CodeException(Constants.res.openKeySignError); + } + + if (!entity.userId) { + throw new CodeException(Constants.res.openKeyError); + } + + return { + userId: entity.userId, + keyId: entity.keyId, + keySecret: entity.keySecret, + encrypt: encrypt, + }; + } + + async getApiToken(id: number) { + const entity = await this.repository.findOne({ where: { id } }); + if (!entity) { + throw new Error('id不存在'); + } + const { keyId, keySecret } = entity; + const openKey = { + keyId, + t: dayjs().unix(), + encrypt: false, + signType: 'md5', + }; + const content = JSON.stringify(openKey); + const sign = utils.hash.md5(content + keySecret); + return Buffer.from(content).toString('base64') + '.' + Buffer.from(sign).toString('base64'); + } +} diff --git a/packages/ui/certd-server/src/plugins/plugin-doge/plugins/deploy-to-cdn/index.ts b/packages/ui/certd-server/src/plugins/plugin-doge/plugins/deploy-to-cdn/index.ts index f3e371c60..0901646b2 100644 --- a/packages/ui/certd-server/src/plugins/plugin-doge/plugins/deploy-to-cdn/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-doge/plugins/deploy-to-cdn/index.ts @@ -1,5 +1,5 @@ import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline'; -import { CertInfo, CertReader } from '@certd/plugin-cert'; +import { CertInfo } from '@certd/plugin-cert'; import { DogeClient } from '../../lib/index.js'; import dayjs from 'dayjs'; @@ -68,11 +68,10 @@ export class DogeCloudDeployToCDNPlugin extends AbstractTaskPlugin { } async updateCert() { - const certReader = new CertReader(this.cert); const data = await this.dogeClient.request('/cdn/cert/upload.json', { note: 'certd-' + dayjs().format('YYYYMMDDHHmmss'), - cert: certReader.crt, - private: certReader.key, + cert: this.cert.crt, + private: this.cert.key, }); return data.id; }