diff --git a/packages/plugins/plugin-cert/src/plugin/cert-plugin/getter/index.ts b/packages/plugins/plugin-cert/src/plugin/cert-plugin/getter/index.ts new file mode 100644 index 000000000..3b39cc635 --- /dev/null +++ b/packages/plugins/plugin-cert/src/plugin/cert-plugin/getter/index.ts @@ -0,0 +1,149 @@ +import { IsTaskPlugin, PageSearch, pluginGroups, RunStrategy, Step, TaskInput, TaskOutput } from "@certd/pipeline"; +import type { CertInfo } from "../acme.js"; +import { CertReader } from "../cert-reader.js"; +import { CertApplyBasePlugin } from "../base.js"; +import { AliyunAccess, createRemoteSelectInputDefine } from "@certd/plugin-lib"; + +export { CertReader }; +export type { CertInfo }; + +@IsTaskPlugin({ + name: "CertApplyGetFormAliyun", + icon: "ph:certificate", + title: "获取阿里云订阅证书", + group: pluginGroups.cert.key, + desc: "从阿里云拉取订阅模式的商用证书", + default: { + strategy: { + runStrategy: RunStrategy.AlwaysRun, + }, + }, +}) +export class CertApplyGetFormAliyunPlugin extends CertApplyBasePlugin { + @TaskInput({ + title: "Access授权", + helper: "阿里云授权AccessKeyId、AccessKeySecret", + component: { + name: "access-selector", + type: "aliyun", + }, + required: true, + }) + accessId!: string; + + @TaskInput( + createRemoteSelectInputDefine({ + title: "证书订单ID", + helper: "订阅模式的证书订单Id", + typeName: "CertApplyGetFormAliyun", + action: CertApplyGetFormAliyunPlugin.prototype.onGetOrderList.name, + }) + ) + orderId!: number; + + async onInit(): Promise {} + + async doCertApply(): Promise { + const access = await this.getAccess(this.accessId); + const client = await access.getClient("cas.aliyuncs.com"); + const certDetail = await this.getCertDetail(client, this.orderId); + return certDetail; + } + + async getCertDetail(client: any, certId: any) { + const res = await client.doRequest({ + // 接口名称 + // 接口名称 + action: "GetUserCertificateDetail", + // 接口版本 + version: "2020-04-07", + // 接口协议 + protocol: "HTTPS", + // 接口 HTTP 方法 + method: "POST", + authType: "AK", + style: "RPC", + // 接口 PATH + pathname: `/`, + data: { + query: { + CertId: certId, + }, + }, + }); + + const crt = res.Cert; + const key = res.Key; + + return new CertReader({ + crt, + key, + csr: "", + }); + } + + async getCertificateState(client: any, orderId: any) { + const res = await client.doRequest({ + // 接口名称 + action: "DescribeCertificateState", + // 接口版本 + version: "2020-04-07", + // 接口协议 + protocol: "HTTPS", + // 接口 HTTP 方法 + method: "POST", + authType: "AK", + style: "RPC", + // 接口 PATH + pathname: `/`, + data: { + query: { + OrderId: orderId, + }, + }, + }); + + return res.CertId; + } + + async onGetOrderList(req: PageSearch) { + if (!this.accessId) { + throw new Error("请先选择Access授权"); + } + const access = await this.getAccess(this.accessId); + + const client = await access.getClient("cas.aliyuncs.com"); + + const res = await client.doRequest({ + // 接口名称 + action: "ListUserCertificateOrder", + // 接口版本 + version: "2020-04-07", + method: "POST", + authType: "AK", + style: "RPC", + // 接口 PATH + pathname: `/`, + data: { + query: { + Status: "ISSUED", + }, + }, + }); + const list = res?.CertificateOrderList || []; + if (!list || list.length === 0) { + throw new Error("没有找到已签发的证书订单"); + } + + return list.map((item: any) => { + const label = `${item.Domain}<${item.OrderId}>`; + return { + label: label, + value: item.OrderId, + Domain: item.Domain, + }; + }); + } +} + +new CertApplyGetFormAliyunPlugin(); diff --git a/packages/ui/certd-client/src/locales/langs/en-US/certd.ts b/packages/ui/certd-client/src/locales/langs/en-US/certd.ts index b57069f92..1294223d7 100644 --- a/packages/ui/certd-client/src/locales/langs/en-US/certd.ts +++ b/packages/ui/certd-client/src/locales/langs/en-US/certd.ts @@ -220,6 +220,7 @@ export default { selectTitle: "Certificate Apply Plugin", jsAcme: "JS-ACME: Easy to use, powerful features [Recommended]", legoAcme: "Lego-ACME: Based on Lego, supports a wide range of DNS providers, suitable for users familiar with Lego", + aliyunOrder: "Aliyun-Order: Get certificate from Aliyun certificate order", }, pipelineForm: { createTitle: "Create Certificate Pipeline", diff --git a/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts b/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts index 41e7587a0..c7cb5f34c 100644 --- a/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts +++ b/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts @@ -225,6 +225,7 @@ export default { selectTitle: "证书申请插件", jsAcme: "JS-ACME:使用简单方便,功能强大【推荐】", legoAcme: "Lego-ACME:基于Lego实现,支持海量DNS提供商,熟悉LEGO的用户可以使用", + aliyunOrder: "Aliyun-Order:从阿里云证书订单中获取证书更新", }, pipelineForm: { createTitle: "创建证书流水线", diff --git a/packages/ui/certd-client/src/views/certd/pipeline/certd-form/use.tsx b/packages/ui/certd-client/src/views/certd/pipeline/certd-form/use.tsx index 66764cfd6..909d29f62 100644 --- a/packages/ui/certd-client/src/views/certd/pipeline/certd-form/use.tsx +++ b/packages/ui/certd-client/src/views/certd/pipeline/certd-form/use.tsx @@ -163,6 +163,7 @@ export function useCertPipelineCreator() { data: [ { value: "CertApply", label: "JS-ACME" }, { value: "CertApplyLego", label: "Lego-ACME" }, + { value: "CertApplyAliyun", label: "Aliyun-Order" }, ], }), form: { @@ -174,6 +175,7 @@ export function useCertPipelineCreator() {
  • {t("certd.plugin.jsAcme")}
  • {t("certd.plugin.legoAcme")}
  • +
  • {t("certd.plugin.aliyunOrder")}
); }, @@ -201,7 +203,7 @@ export function useCertPipelineCreator() { component: { name: "cron-editor", vModel: "modelValue", - placeholder: "0 0 4 * * *", + placeholder: "0 0 4 * * * (表示凌晨4点执行)", }, helper: t("certd.pipelineForm.triggerCronHelper"), order: 100,