From 9166a579301a60750f0b72b6a42b0c8d730695fd Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Wed, 4 Feb 2026 17:01:08 +0800 Subject: [PATCH 01/19] =?UTF-8?q?perf:=20=E5=BD=93=E5=9F=9F=E5=90=8D?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E4=B8=AD=E6=B2=A1=E6=9C=89=E5=9F=9F=E5=90=8D?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E5=88=9B=E5=BB=BA=E6=B5=81=E6=B0=B4=E7=BA=BF?= =?UTF-8?q?=E6=97=B6=E4=B8=8D=E5=B1=95=E5=BC=80=E5=9F=9F=E5=90=8D=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E6=A1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugins/common/domain-selector.vue | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/ui/certd-client/src/components/plugins/common/domain-selector.vue b/packages/ui/certd-client/src/components/plugins/common/domain-selector.vue index 7a331e0be..d6fdbf598 100644 --- a/packages/ui/certd-client/src/components/plugins/common/domain-selector.vue +++ b/packages/ui/certd-client/src/components/plugins/common/domain-selector.vue @@ -9,6 +9,7 @@ :options="optionsRef" :value="value" v-bind="attrs" + :open="openProp" @click="onClick" @update:value="emit('update:value', $event)" > @@ -56,11 +57,11 @@ diff --git a/packages/ui/certd-client/src/components/plugins/common/params-show.vue b/packages/ui/certd-client/src/components/plugins/common/params-show.vue index d84cd616c..085e8804c 100644 --- a/packages/ui/certd-client/src/components/plugins/common/params-show.vue +++ b/packages/ui/certd-client/src/components/plugins/common/params-show.vue @@ -1,8 +1,8 @@ diff --git a/packages/ui/certd-client/src/style/common.less b/packages/ui/certd-client/src/style/common.less index edbeb7fe3..5d83d6d5f 100644 --- a/packages/ui/certd-client/src/style/common.less +++ b/packages/ui/certd-client/src/style/common.less @@ -476,4 +476,10 @@ h6 { .fs-icon{ margin-right: 5px; } +} + + +.hidden-important { + display: none !important; + visibility: hidden !important; } \ No newline at end of file From 1d8d5251ae397477eeb2959b782270bb773db312 Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Thu, 5 Feb 2026 11:29:10 +0800 Subject: [PATCH 16/19] =?UTF-8?q?chore:=20domain-selector=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/plugins/common/domain-selector.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui/certd-client/src/components/plugins/common/domain-selector.vue b/packages/ui/certd-client/src/components/plugins/common/domain-selector.vue index c7a17b7bc..6cdc9a665 100644 --- a/packages/ui/certd-client/src/components/plugins/common/domain-selector.vue +++ b/packages/ui/certd-client/src/components/plugins/common/domain-selector.vue @@ -94,7 +94,7 @@ const attrs = useAttrs(); const hasOptions: Ref = ref(null); const popupClassName = computed(() => { - if (hasOptions.value == null) { + if (!hasOptions.value) { return "hidden-important"; } return ""; From 5ea4f46de7ae403a7a16e9488dc1d9c7523d019a Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Thu, 5 Feb 2026 11:39:06 +0800 Subject: [PATCH 17/19] =?UTF-8?q?perf:=20=20eab=E4=BB=8E=E6=9B=B4=E5=A4=9A?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E4=B8=AD=E6=8C=AA=E5=88=B0=E5=A4=96=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/plugins/plugin-cert/src/index.ts | 2 +- .../src/components/plugins/common/domain-selector.vue | 1 + .../src/plugins/plugin-cert/plugin/cert-plugin/apply.ts | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/plugins/plugin-cert/src/index.ts b/packages/plugins/plugin-cert/src/index.ts index 4f136a13d..63eccd8df 100644 --- a/packages/plugins/plugin-cert/src/index.ts +++ b/packages/plugins/plugin-cert/src/index.ts @@ -1 +1 @@ -export * from "@certd/plugin-lib"; \ No newline at end of file +export * from "@certd/plugin-lib"; diff --git a/packages/ui/certd-client/src/components/plugins/common/domain-selector.vue b/packages/ui/certd-client/src/components/plugins/common/domain-selector.vue index 6cdc9a665..589156f41 100644 --- a/packages/ui/certd-client/src/components/plugins/common/domain-selector.vue +++ b/packages/ui/certd-client/src/components/plugins/common/domain-selector.vue @@ -154,6 +154,7 @@ const getOptions = async () => { optionsRef.value = options; if (hasOptions.value == null) { + //初始设置一次 if (options.length > 0) { hasOptions.value = true; } else { diff --git a/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/apply.ts b/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/apply.ts index 562d3bb1e..c4e38e1f7 100644 --- a/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/apply.ts +++ b/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/apply.ts @@ -264,7 +264,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin { name: "access-selector", type: "eab", }, - maybeNeed: true, + maybeNeed: false, required: false, helper: "需要提供EAB授权" + @@ -291,7 +291,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin { name: "access-selector", type: "google", }, - maybeNeed: true, + maybeNeed: false, required: false, helper: "google服务账号授权与EAB授权选填其中一个,[服务账号授权获取方法](https://certd.docmirror.cn/guide/use/google/)\n服务账号授权需要配置代理或者服务器本身在海外", mergeScript: ` From 4d86fb319b81dbf6fa6485982105725b1b066593 Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Thu, 5 Feb 2026 12:22:55 +0800 Subject: [PATCH 18/19] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96zerossl?= =?UTF-8?q?=E7=94=B3=E8=AF=B7=E8=AF=81=E4=B9=A6=E7=A8=B3=E5=AE=9A=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/acme-client/src/client.js | 2 +- .../src/modules/pipeline/service/pipeline-service.ts | 6 ++++++ .../src/plugins/plugin-cert/plugin/cert-plugin/acme.ts | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/core/acme-client/src/client.js b/packages/core/acme-client/src/client.js index 4a9cd25e2..f66ec7a11 100644 --- a/packages/core/acme-client/src/client.js +++ b/packages/core/acme-client/src/client.js @@ -600,7 +600,7 @@ class AcmeClient { throw new Error(`[${d}] Unexpected item status: ${resp.data.status}`); }; - this.log(`[${d}] Waiting for valid status (等待valid状态): ${item.url}`, this.backoffOpts); + this.log(`[${d}] Waiting for valid status (等待valid状态): ${item.url}`, JSON.stringify(this.backoffOpts)); return util.retry(verifyFn, this.backoffOpts); } diff --git a/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts b/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts index a2957f8fd..0e8d3f2c2 100644 --- a/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts +++ b/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts @@ -113,6 +113,9 @@ export class PipelineService extends BaseService { async add(bean: PipelineEntity) { bean.status = ResultType.none; + if (bean.order == null) { + bean.order = 0; + } await this.save(bean); return bean; } @@ -243,6 +246,9 @@ export class PipelineService extends BaseService { if (!bean.status) { bean.status = ResultType.none; } + if (bean.order == null) { + bean.order = 0; + } if (!isUpdate) { //如果是添加,先保存一下,获取到id,更新pipeline.id await this.addOrUpdate(bean); diff --git a/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/acme.ts b/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/acme.ts index 7ae463124..80b6502cf 100644 --- a/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/acme.ts +++ b/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/acme.ts @@ -147,7 +147,7 @@ export class AcmeService { externalAccountBinding: this.eab, backoffAttempts: this.options.maxCheckRetryCount || 20, backoffMin: 5000, - backoffMax: 10000, + backoffMax: 400000, urlMapping, signal: this.options.signal, logger: this.logger, From beb7a4c99277262bb9681c5594cfcd3e36c52074 Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Thu, 5 Feb 2026 16:14:05 +0800 Subject: [PATCH 19/19] =?UTF-8?q?perf:=20=E7=AC=AC=E4=B8=89=E6=96=B9?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=94=AF=E6=8C=81Microsoft?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin-cert/plugin/cert-plugin/acme.ts | 2 +- .../src/plugins/plugin-oauth/index.ts | 3 +- .../plugin-oauth/oauth2/plugin-microsoft.ts | 122 ++++++++++++++++++ 3 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 packages/ui/certd-server/src/plugins/plugin-oauth/oauth2/plugin-microsoft.ts diff --git a/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/acme.ts b/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/acme.ts index 80b6502cf..6bdb7cf51 100644 --- a/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/acme.ts +++ b/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/acme.ts @@ -147,7 +147,7 @@ export class AcmeService { externalAccountBinding: this.eab, backoffAttempts: this.options.maxCheckRetryCount || 20, backoffMin: 5000, - backoffMax: 400000, + backoffMax: 1000*1000, urlMapping, signal: this.options.signal, logger: this.logger, diff --git a/packages/ui/certd-server/src/plugins/plugin-oauth/index.ts b/packages/ui/certd-server/src/plugins/plugin-oauth/index.ts index 3a43d4351..37157bcd7 100644 --- a/packages/ui/certd-server/src/plugins/plugin-oauth/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-oauth/index.ts @@ -4,4 +4,5 @@ export * from './wx/plugin-wx.js' export * from './oauth2/plugin-gitee.js' export * from './oauth2/plugin-clogin.js' export * from './oauth2/plugin-github.js' -export * from './oauth2/plugin-google.js' \ No newline at end of file +export * from './oauth2/plugin-google.js' +export * from './oauth2/plugin-microsoft.js' \ No newline at end of file diff --git a/packages/ui/certd-server/src/plugins/plugin-oauth/oauth2/plugin-microsoft.ts b/packages/ui/certd-server/src/plugins/plugin-oauth/oauth2/plugin-microsoft.ts new file mode 100644 index 000000000..e42b9b6c1 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-oauth/oauth2/plugin-microsoft.ts @@ -0,0 +1,122 @@ +import { AddonInput, BaseAddon, IsAddon } from "@certd/lib-server"; +import { BuildLoginUrlReq, BuildLogoutUrlReq, IOauthProvider, OnCallbackReq } from "../api.js"; + +@IsAddon({ + addonType: "oauth", + name: 'microsoft', + title: 'Microsoft认证', + desc: 'Microsoft OAuth2登录', + icon:"simple-icons:microsoft", + showTest: false, +}) +export class MicrosoftOauthProvider extends BaseAddon implements IOauthProvider { + + @AddonInput({ + title: "ClientId", + helper: "[Azure Portal](https://portal.azure.com/)创建应用后获取", + required: true, + }) + clientId = ""; + + @AddonInput({ + title: "ClientSecretKey", + component: { + placeholder: "ClientSecretKey / appSecretKey", + }, + required: true, + }) + clientSecretKey = ""; + + @AddonInput({ + title: "TenantId", + helper: "租户ID,留空使用/common端点(需要应用配置为多租户)", + component: { + placeholder: "common 或 租户ID", + }, + value: "common", + required: false, + }) + tenantId = "common"; + + async buildLoginUrl(params: BuildLoginUrlReq) { + + let scope = "openid profile email User.Read" // Scope of the access request + let state:any = { + forType: params.forType || 'login', + } + state = this.ctx.utils.hash.base64(JSON.stringify(state)) + + const authorizeEndpoint = `https://login.microsoftonline.com/${this.tenantId}/oauth2/v2.0/authorize` + const redirectUrl = encodeURIComponent(params.redirectUri) + const loginUrl = `${authorizeEndpoint}?client_id=${this.clientId}&redirect_uri=${redirectUrl}&response_type=code&scope=${scope}&state=${state}` + return { + loginUrl, + ticketValue: { + state, + }, + }; + } + + async onCallback(req: OnCallbackReq) { + + const code = req.code || "" + if (!code) { + throw new Error("Missing code parameter"); + } + + const tokenEndpoint = `https://login.microsoftonline.com/${this.tenantId}/oauth2/v2.0/token` + + const uri = new URL(req.currentURL) + const redirectUri = `${uri.origin}${uri.pathname}` + + // 构建 form-urlencoded 格式的数据 + const formData = new URLSearchParams(); + formData.append('client_id', this.clientId); + formData.append('client_secret', this.clientSecretKey); + formData.append('code', code); + formData.append('redirect_uri', redirectUri); + formData.append('grant_type', 'authorization_code'); + + const res = await this.ctx.utils.http.request( { + url: tokenEndpoint, + method: "post", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "application/json" + }, + data: formData.toString() + }) + + const tokens = res + + const userInfoEndpoint = "https://graph.microsoft.com/v1.0/me" + + // 获取用户信息 + const userInfoRes = await this.ctx.utils.http.request( { + url: userInfoEndpoint, + method: "get", + headers: { + "Authorization": `Bearer ${tokens.access_token}`, + "Accept": "application/json" + } + }) + const userInfo = userInfoRes + + return { + token:{ + accessToken: tokens.access_token, + refreshToken: tokens.refresh_token, + expiresIn: tokens.expires_in, + }, + userInfo: { + openId: userInfo.id, + nickName: userInfo.displayName || userInfo.userPrincipalName || "", + avatar: userInfo.avatar || "", + }, + } + }; + + async buildLogoutUrl(params: BuildLogoutUrlReq) { + return {}; + } +} \ No newline at end of file