Compare commits

..

103 Commits

Author SHA1 Message Date
xiaojunnuo
f3a24ef6de chore: singleton 2025-12-28 23:46:55 +08:00
xiaojunnuo
1347355cb1 perf: 支持授权给管理员查看和下载用户证书 2025-12-28 23:36:53 +08:00
xiaojunnuo
f847c4a414 chore: 1 2025-12-28 01:05:48 +08:00
xiaojunnuo
776fa924e3 chore: 1 2025-12-28 00:49:41 +08:00
xiaojunnuo
8872466968 perf: 支持从阿里云商用证书订单中获取证书 2025-12-28 00:38:38 +08:00
xiaojunnuo
b620038d98 Merge branch 'v2-dev' of https://github.com/certd/certd into v2-dev 2025-12-27 22:57:31 +08:00
xiaojunnuo
a248367b15 perf: 支持ucloud waf(未测试) 2025-12-27 22:57:26 +08:00
xiaojunnuo
c159ec4a9a Merge branch 'v2-dev' of https://github.com/certd/certd into v2-dev 2025-12-27 15:05:52 +08:00
xiaojunnuo
5359a7670f perf: 优化阿里云esa清理证书时机 2025-12-27 15:05:43 +08:00
xiaojunnuo
7e1c7a6de2 chore: 1 2025-12-27 02:23:29 +08:00
xiaojunnuo
91e19bbdd3 chore: 优化图标 2025-12-27 02:20:01 +08:00
xiaojunnuo
e61daaee2d perf: 支持ucloud,上传到ussl,部署到ucdn 2025-12-27 01:54:47 +08:00
xiaojunnuo
8caab1fd92 perf: aws route53 2025-12-26 23:20:14 +08:00
xiaojunnuo
cd944882c3 perf: 执行队列数量支持设置 2025-12-26 18:17:05 +08:00
xiaojunnuo
888d9591fe perf: 支持执行队列,避免同一时间触发流水线太多导致被限制 2025-12-26 16:30:03 +08:00
xiaojunnuo
833808c5de fix: 修复从模版创建的流水线不会自动执行的bug 2025-12-26 16:29:20 +08:00
xiaojunnuo
d731956b06 fix: 首页最快到期证书,不包含已禁用的流水线 2025-12-26 14:37:03 +08:00
xiaojunnuo
40449ae4de chore: docs 2025-12-26 14:26:27 +08:00
xiaojunnuo
44ad61f004 Merge branch 'v2-dev' of https://github.com/certd/certd into v2-dev 2025-12-26 09:29:37 +08:00
xiaojunnuo
74865d53f8 chore: 修复aws route53 删除record失败的问题 2025-12-26 09:29:29 +08:00
xiaojunnuo
373415261e Merge branch 'v2-dev' of https://github.com/certd/certd into v2-dev 2025-12-25 22:20:59 +08:00
xiaojunnuo
d0f653da9a perf: 批量修改定时时间支持随机时间 2025-12-25 22:20:54 +08:00
xiaojunnuo
cbb8319cfa perf: 支持aws route53 dns 2025-12-25 18:56:27 +08:00
xiaojunnuo
0e467a6024 chore: docs 2025-12-22 16:36:32 +08:00
xiaojunnuo
e505916525 fix: 修复用户删除后,用相同的oauth授权登录报错用户不存在的问题
https://github.com/certd/certd/issues/603
2025-12-19 11:37:22 +08:00
xiaojunnuo
31f09ab117 chore: ip证书文档 2025-12-19 11:30:01 +08:00
xiaojunnuo
09e5e0f9b3 chore: 1 2025-12-19 10:49:10 +08:00
xiaojunnuo
773cada57a perf: ip证书校验方式提示 2025-12-19 10:08:28 +08:00
xiaojunnuo
403947ed6d chore: 开源地址 2025-12-18 19:07:27 +08:00
xiaojunnuo
d9d08a725c perf: 官方开源地址 2025-12-18 19:03:46 +08:00
xiaojunnuo
e2ed75af94 Merge branch 'v2-dev' of https://github.com/certd/certd into v2-dev 2025-12-17 10:02:30 +08:00
xiaojunnuo
dd19afce92 fix: 修复部署到华为obs 报错的bug 2025-12-17 10:02:23 +08:00
xiaojunnuo
5b5deac7d9 perf: 腾讯云EO增加请求参数打印 2025-12-16 23:10:30 +08:00
xiaojunnuo
3f3ee3456e chore: 支持仅查询其他用户的流水线 2025-12-16 22:52:07 +08:00
xiaojunnuo
3e2f2fc02e chore: 批量修改流水线优化 2025-12-16 22:31:06 +08:00
xiaojunnuo
c5a3003cf7 fix: 发送证书到邮箱插件的邮件模版转为使用邮箱配置中的通用模版 2025-12-16 22:07:39 +08:00
xiaojunnuo
4c6dcddf11 Merge branch 'v2-dev' of https://github.com/certd/certd into v2-dev 2025-12-16 10:02:31 +08:00
xiaojunnuo
b314e500cd build: release 2025-12-16 07:43:49 +08:00
xiaojunnuo
b83e6ad13f build: publish 2025-12-16 01:47:46 +08:00
xiaojunnuo
fee401cfdf build: trigger build image 2025-12-16 01:47:35 +08:00
xiaojunnuo
fa14f62198 v1.37.16 2025-12-16 01:46:13 +08:00
xiaojunnuo
5526665494 build: prepare to build 2025-12-16 01:44:10 +08:00
xiaojunnuo
6249af996a build: prepare to build 2025-12-16 01:41:26 +08:00
xiaojunnuo
e51a1b365e build: prepare to build 2025-12-16 01:30:58 +08:00
xiaojunnuo
f53f00d126 chore: 1 2025-12-16 00:39:21 +08:00
xiaojunnuo
ab8fbaf21d chore: 修复清除定时任务未生效的bug 2025-12-16 00:34:32 +08:00
xiaojunnuo
63d8bcf882 perf: 批量设置定时,支持清除定时 2025-12-16 00:21:31 +08:00
xiaojunnuo
e4e16bc6a6 fix: 修复ipv6作为证书域名申请证书校验失败的bug 2025-12-15 23:34:47 +08:00
xiaojunnuo
e4c21c4d5c chore: 模版发邮件 plus 2025-12-15 22:32:25 +08:00
xiaojunnuo
d9e6dbf889 chore: 优化telegram更多保留字符 2025-12-15 22:21:43 +08:00
xiaojunnuo
5f4469e306 fix: telegram 修复消息内存在横杠无法发出的bug 2025-12-15 15:12:07 +08:00
xiaojunnuo
16f6365b18 chore: oidc自动注册时增加邮箱 2025-12-15 00:23:35 +08:00
xiaojunnuo
cdab54bf51 chore: 1 2025-12-15 00:21:42 +08:00
xiaojunnuo
b6fea0c856 perf: oidc支持使用第三方昵称或账号作为certd用户的用户名 2025-12-15 00:19:55 +08:00
xiaojunnuo
6f186932cc perf: 支持彩虹聚合登录 2025-12-15 00:12:27 +08:00
xiaojunnuo
de544ec725 chore: email template优化 2025-12-14 23:19:32 +08:00
xiaojunnuo
a6c0d2c6f1 perf: 支持邮件模版设置 2025-12-14 01:36:20 +08:00
xiaojunnuo
437d956cad chore: email template 2025-12-12 23:39:09 +08:00
xiaojunnuo
43ba0b9da6 docs: 1panel增加应用商店部署方式 2025-12-11 18:14:15 +08:00
xiaojunnuo
fe1e2c3b62 Merge branch 'v2-dev' of https://github.com/certd/certd into v2-dev 2025-12-10 14:17:20 +08:00
xiaojunnuo
bbe7e5f96d chore: 1 2025-12-10 14:15:39 +08:00
xiaojunnuo
2bfad9fc65 fix: 优化西部数据 500 already exists 的问题 2025-12-09 23:33:11 +08:00
xiaojunnuo
9f24c18f7f chore: 优化数据库脚本 2025-12-09 23:28:29 +08:00
xiaojunnuo
a2d1e5ea03 chore: 修复sqlite语句双引号改单引号 2025-12-09 23:11:19 +08:00
xiaojunnuo
b082e4e988 chore: 1 2025-12-09 00:47:08 +08:00
xiaojunnuo
45fbce0c2a perf: 新增数据库迁移doc说明文档,优化datetime字段平滑迁移 2025-12-09 00:45:10 +08:00
xiaojunnuo
ff7006e232 build: release 2025-12-07 01:17:22 +08:00
xiaojunnuo
c68fdef0e4 build: publish 2025-12-07 00:59:50 +08:00
xiaojunnuo
4c60e4edc1 build: trigger build image 2025-12-07 00:59:39 +08:00
xiaojunnuo
f2e4e59f8d v1.37.15 2025-12-07 00:58:12 +08:00
xiaojunnuo
898205b5b1 build: prepare to build 2025-12-07 00:56:13 +08:00
xiaojunnuo
8ec6862861 chore: 升级fs 2025-12-07 00:56:06 +08:00
xiaojunnuo
c3ba6322d8 build: prepare to build 2025-12-07 00:55:38 +08:00
xiaojunnuo
e589828425 build: prepare to build 2025-12-07 00:47:24 +08:00
xiaojunnuo
c909aa161b chore: webhook修改为隐藏变量,避免别人fork后触发我的流水线 2025-12-07 00:18:05 +08:00
xiaojunnuo
5cee7d44f1 perf: 第三方登录支持gitee 2025-12-06 17:25:02 +08:00
xiaojunnuo
973b323a99 docs: 优化教程 2025-12-06 16:24:19 +08:00
xiaojunnuo
d55954a363 perf: 支持k8s apply 2025-12-05 02:05:27 +08:00
xiaojunnuo
adca151e4f perf: 邮件模版安全优化 2025-12-05 00:45:56 +08:00
xiaojunnuo
43513049be perf: 支持部署到中国移动CDN 2025-12-04 00:46:25 +08:00
xiaojunnuo
a5ca41131b fix: oidc 支持nonce 2025-12-03 22:00:35 +08:00
xiaojunnuo
2ea3810980 build: release 2025-12-03 10:09:24 +08:00
xiaojunnuo
c9cb54e8b2 build: release 2025-12-03 07:34:48 +08:00
xiaojunnuo
23dd3db50b build: publish 2025-12-03 01:01:31 +08:00
xiaojunnuo
179c46914d build: trigger build image 2025-12-03 01:01:20 +08:00
xiaojunnuo
ddb18e6c21 v1.37.14 2025-12-03 00:59:54 +08:00
xiaojunnuo
d2e147ba51 build: prepare to build 2025-12-03 00:57:50 +08:00
xiaojunnuo
b63033f846 build: release 2025-12-03 00:57:37 +08:00
xiaojunnuo
677e1101e6 fix: 修复注销登录时,第三方登录注销请求失败的报错 2025-12-03 00:57:17 +08:00
xiaojunnuo
3abc2ccfbb build: 1 2025-12-03 00:48:21 +08:00
xiaojunnuo
827d28f1cd build: publish 2025-12-03 00:41:16 +08:00
xiaojunnuo
59d12a1bbe build: trigger build image 2025-12-03 00:40:59 +08:00
xiaojunnuo
8134172301 v1.37.13 2025-12-03 00:39:32 +08:00
xiaojunnuo
8d983aa561 build: prepare to build 2025-12-03 00:36:47 +08:00
xiaojunnuo
bb3085ef84 perf: 第三方登录允许选择logo 2025-12-03 00:35:17 +08:00
xiaojunnuo
78b1650bdb fix: 修复西部数据返回信息乱码问题 2025-12-02 16:37:26 +08:00
xiaojunnuo
5edc72d475 fix: 修复西部数码使用域名级别的key申请证书失败的问题 2025-12-02 16:11:33 +08:00
xiaojunnuo
1df32c9dfa docs: 阿里云超时配置 2025-12-01 19:10:47 +08:00
xiaojunnuo
bedb1ff7f9 docs: 流水线有效期 2025-12-01 11:48:57 +08:00
xiaojunnuo
fbf12f16b5 perf: 支持OIDC单点登录 2025-12-01 00:40:46 +08:00
xiaojunnuo
22a5f34e1f build: release 2025-11-30 02:53:41 +08:00
xiaojunnuo
e1a8b08619 build: publish 2025-11-30 02:32:23 +08:00
xiaojunnuo
466d30fb74 build: trigger build image 2025-11-30 02:32:06 +08:00
260 changed files with 6084 additions and 943 deletions

View File

@@ -44,7 +44,8 @@ jobs:
- name: deploy-certd-demo - name: deploy-certd-demo
uses: tyrrrz/action-http-request@master uses: tyrrrz/action-http-request@master
with: with:
url: http://flow-openapi.aliyun.com/pipeline/webhook/lzCzlGrLCOHQaTMMt0mG # 通过webhook 触发 certd-demo来部署
url: ${{ secrets.WEBHOOK_CERTD_DEMO }}
method: POST method: POST
headers: | headers: |
Content-Type: application/json Content-Type: application/json

View File

@@ -121,10 +121,12 @@ jobs:
- name: deploy-certd-doc - name: deploy-certd-doc
uses: tyrrrz/action-http-request@master uses: tyrrrz/action-http-request@master
with: with:
url: http://flow-openapi.aliyun.com/pipeline/webhook/IiSxLDp9aOhgDUxJPytv url: ${{ secrets.WEBHOOK_CERTD_DOC }}
method: POST method: POST
body: | body: |
{} {
"CERTD_VERSION": "1.0.0"
}
headers: | headers: |
Content-Type: application/json Content-Type: application/json
retry-count: 3 retry-count: 3

View File

@@ -9,5 +9,6 @@
"[typescript]": { "[typescript]": {
"editor.defaultFormatter": "vscode.typescript-language-features" "editor.defaultFormatter": "vscode.typescript-language-features"
}, },
"editor.tabSize": 2 "editor.tabSize": 2,
"explorer.autoReveal": false
} }

View File

@@ -3,6 +3,52 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.16](https://github.com/certd/certd/compare/v1.37.15...v1.37.16) (2025-12-15)
### Bug Fixes
* 修复ipv6作为证书域名申请证书校验失败的bug ([e4e16bc](https://github.com/certd/certd/commit/e4e16bc6a65bb082c18ca0590226f0987a47d477))
* 优化西部数据 500 already exists 的问题 ([2bfad9f](https://github.com/certd/certd/commit/2bfad9fc651da208b610abd921fbfb2fbc04203f))
### Performance Improvements
* 批量设置定时,支持清除定时 ([63d8bcf](https://github.com/certd/certd/commit/63d8bcf8823f713365042d3c7aee3cf31d44b044))
* 新增数据库迁移doc说明文档优化datetime字段平滑迁移 ([45fbce0](https://github.com/certd/certd/commit/45fbce0c2af5fb3ead6d3dd12a42f8cc1714262f))
* 支持彩虹聚合登录 ([6f18693](https://github.com/certd/certd/commit/6f186932ccad4becfdc0087c0539f7b2d0069844))
* 支持邮件模版设置 ([a6c0d2c](https://github.com/certd/certd/commit/a6c0d2c6f1fd6b60e6d7af290487c94564fd91ea))
* oidc支持使用第三方昵称或账号作为certd用户的用户名 ([b6fea0c](https://github.com/certd/certd/commit/b6fea0c8562abf912daa7d72958ceb2e93575d31))
## [1.37.15](https://github.com/certd/certd/compare/v1.37.14...v1.37.15) (2025-12-06)
### Bug Fixes
* oidc 支持nonce ([a5ca411](https://github.com/certd/certd/commit/a5ca41131b308b36b17ca359d9709ea8e9b7cee1))
### Performance Improvements
* 第三方登录支持gitee ([5cee7d4](https://github.com/certd/certd/commit/5cee7d44f17bd36972f477bc1f270999da558d05))
* 邮件模版安全优化 ([adca151](https://github.com/certd/certd/commit/adca151e4f07a4c6a2a753bfa48ee0d4d6469fd2))
* 支持部署到中国移动CDN ([4351304](https://github.com/certd/certd/commit/43513049beff407558d2a234415521464165cebc))
* 支持k8s apply ([d55954a](https://github.com/certd/certd/commit/d55954a36391ebe6a9397ff7dcfb710193ac5e34))
## [1.37.14](https://github.com/certd/certd/compare/v1.37.13...v1.37.14) (2025-12-02)
### Bug Fixes
* 修复注销登录时,第三方登录注销请求失败的报错 ([677e110](https://github.com/certd/certd/commit/677e1101e6cf4451abd8a876cc1d0ddd26a10b88))
## [1.37.13](https://github.com/certd/certd/compare/v1.37.12...v1.37.13) (2025-12-02)
### Bug Fixes
* 修复西部数据返回信息乱码问题 ([78b1650](https://github.com/certd/certd/commit/78b1650bdb071c858b3f90d53a700d11ee6de328))
* 修复西部数码使用域名级别的key申请证书失败的问题 ([5edc72d](https://github.com/certd/certd/commit/5edc72d47550b8e3364dabda70a41cce75d87956))
### Performance Improvements
* 第三方登录允许选择logo ([bb3085e](https://github.com/certd/certd/commit/bb3085ef84201ccd2dc632ba8c5097cb00258be4))
* 支持OIDC单点登录 ([fbf12f1](https://github.com/certd/certd/commit/fbf12f16b5eaa7676fd41923587bf6bd2595adba))
## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29) ## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29)
### Bug Fixes ### Bug Fixes

View File

@@ -17,6 +17,13 @@ Certd® 是一个免费的全自动证书管理系统,让你的网站证书永
> 流水线数量现已调整为无限制,欢迎大家使用 > 流水线数量现已调整为无限制,欢迎大家使用
|官方开源地址: | |
| ---- | ---- |
| [Github](https://github.com/certd/certd)| ![](https://img.shields.io/github/stars/certd/certd?logo=github) |
| [Gitee](https://gitee.com/certd/certd) | ![](https://gitee.com/certd/certd/badge/star.svg?theme=dark) |
| [AtomGit](https://atomgit.com/certd/certd) |![](https://atomgit.com/certd/certd/star/badge.svg) |
## 一、特性 ## 一、特性
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。 本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。

View File

@@ -13,6 +13,15 @@ Certd® is a free, fully automated certificate management system that ensures yo
> The number of pipelines is now unlimited. Welcome to use it. > The number of pipelines is now unlimited. Welcome to use it.
Official Open Source Address:
[Github](https://github.com/certd/certd) ![](https://img.shields.io/github/stars/certd/certd?logo=github)
[Gitee](https://gitee.com/certd/certd) ![](https://gitee.com/certd/certd/badge/star.svg?theme=dark)
[AtomGit](https://atomgit.com/certd/certd) ![](https://atomgit.com/certd/certd/star/badge.svg)
## 1. Features ## 1. Features
This project not only supports automated certificate application but also automated certificate deployment and updates, ensuring your certificates never expire. This project not only supports automated certificate application but also automated certificate deployment and updates, ensuring your certificates never expire.

View File

@@ -121,6 +121,8 @@ export default defineConfig({
{text: "ESXi", link: "/guide/use/ESXi/index.md"}, {text: "ESXi", link: "/guide/use/ESXi/index.md"},
{text: "宝塔动态IP白名单", link: "/guide/use/baota/white_list.md"}, {text: "宝塔动态IP白名单", link: "/guide/use/baota/white_list.md"},
{text: "子域名托管", link: "/guide/use/cert/subdomain.md"}, {text: "子域名托管", link: "/guide/use/cert/subdomain.md"},
{text: "流水线有效期", link: "/guide/use/pipeline/valid.md"},
{text: "IP证书申请", link: "/guide/use/cert/ip.md"},
] ]
}, },
{ {

View File

@@ -3,6 +3,63 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.16](https://github.com/certd/certd/compare/v1.37.15...v1.37.16) (2025-12-15)
### Bug Fixes
* 修复ipv6作为证书域名申请证书校验失败的bug ([e4e16bc](https://github.com/certd/certd/commit/e4e16bc6a65bb082c18ca0590226f0987a47d477))
* 优化西部数据 500 already exists 的问题 ([2bfad9f](https://github.com/certd/certd/commit/2bfad9fc651da208b610abd921fbfb2fbc04203f))
### Performance Improvements
* 批量设置定时,支持清除定时 ([63d8bcf](https://github.com/certd/certd/commit/63d8bcf8823f713365042d3c7aee3cf31d44b044))
* 新增数据库迁移doc说明文档优化datetime字段平滑迁移 ([45fbce0](https://github.com/certd/certd/commit/45fbce0c2af5fb3ead6d3dd12a42f8cc1714262f))
* 支持彩虹聚合登录 ([6f18693](https://github.com/certd/certd/commit/6f186932ccad4becfdc0087c0539f7b2d0069844))
* 支持邮件模版设置 ([a6c0d2c](https://github.com/certd/certd/commit/a6c0d2c6f1fd6b60e6d7af290487c94564fd91ea))
* oidc支持使用第三方昵称或账号作为certd用户的用户名 ([b6fea0c](https://github.com/certd/certd/commit/b6fea0c8562abf912daa7d72958ceb2e93575d31))
## [1.37.15](https://github.com/certd/certd/compare/v1.37.14...v1.37.15) (2025-12-06)
### Bug Fixes
* oidc 支持nonce ([a5ca411](https://github.com/certd/certd/commit/a5ca41131b308b36b17ca359d9709ea8e9b7cee1))
### Performance Improvements
* 第三方登录支持gitee ([5cee7d4](https://github.com/certd/certd/commit/5cee7d44f17bd36972f477bc1f270999da558d05))
* 邮件模版安全优化 ([adca151](https://github.com/certd/certd/commit/adca151e4f07a4c6a2a753bfa48ee0d4d6469fd2))
* 支持部署到中国移动CDN ([4351304](https://github.com/certd/certd/commit/43513049beff407558d2a234415521464165cebc))
* 支持k8s apply ([d55954a](https://github.com/certd/certd/commit/d55954a36391ebe6a9397ff7dcfb710193ac5e34))
## [1.37.14](https://github.com/certd/certd/compare/v1.37.13...v1.37.14) (2025-12-02)
### Bug Fixes
* 修复注销登录时,第三方登录注销请求失败的报错 ([677e110](https://github.com/certd/certd/commit/677e1101e6cf4451abd8a876cc1d0ddd26a10b88))
## [1.37.13](https://github.com/certd/certd/compare/v1.37.12...v1.37.13) (2025-12-02)
### Bug Fixes
* 修复西部数据返回信息乱码问题 ([78b1650](https://github.com/certd/certd/commit/78b1650bdb071c858b3f90d53a700d11ee6de328))
* 修复西部数码使用域名级别的key申请证书失败的问题 ([5edc72d](https://github.com/certd/certd/commit/5edc72d47550b8e3364dabda70a41cce75d87956))
### Performance Improvements
* 第三方登录允许选择logo ([bb3085e](https://github.com/certd/certd/commit/bb3085ef84201ccd2dc632ba8c5097cb00258be4))
* 支持OIDC单点登录 ([fbf12f1](https://github.com/certd/certd/commit/fbf12f16b5eaa7676fd41923587bf6bd2595adba))
## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29)
### Bug Fixes
* 修复waf tls版本号小写 ([0adcc6a](https://github.com/certd/certd/commit/0adcc6a8d194469be0c26940ed4837fb34929b68))
### Performance Improvements
* 支持微信扫码登录 ([73325aa](https://github.com/certd/certd/commit/73325aaefb0e750a22aaac40929e7bf3f5864996))
* 支持证书颁发机构 LiteSSL ([6be7591](https://github.com/certd/certd/commit/6be75913324e2828d9016eb307ff2d0abbbb2191))
## [1.37.11](https://github.com/certd/certd/compare/v1.37.10...v1.37.11) (2025-11-28) ## [1.37.11](https://github.com/certd/certd/compare/v1.37.10...v1.37.11) (2025-11-28)
### Bug Fixes ### Bug Fixes

View File

@@ -6,6 +6,13 @@ Certd 是一款开源、免费、全自动申请和部署更新SSL证书的工
关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具 关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具
| 官方开源地址: | |
| ---- | ---- |
| [Github](https://github.com/certd/certd)| ![](https://img.shields.io/github/stars/certd/certd?logo=github) |
| [Gitee](https://gitee.com/certd/certd) | ![](https://gitee.com/certd/certd/badge/star.svg?theme=dark) |
| [AtomGit](https://atomgit.com/certd/certd) |![](https://atomgit.com/certd/certd/star/badge.svg) |
![首页](../images/start/home.png) ![首页](../images/start/home.png)
## 1、关于证书续期 ## 1、关于证书续期

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -7,7 +7,36 @@ https://1panel.cn/docs/installation/online_installation/
## 二、部署certd ## 二、部署certd
有两种安装方式
### 1. 应用商店方式安装【推荐】
#### 1.1 安装
打开`1Panel->应用商店`,更新远程应用,搜索`certd`,点击安装
![](./images/store-1.png)
![](./images/store-2.png)
#### 1.2 访问测试:
http://ip:7001
https://ip:7002
默认账号密码
admin/123456
登录后请及时修改密码
#### 1.3 备份
![](./images/store-3.png)
#### 1.4 恢复
安装新Certd后点击导入备份按钮选择上面备份的文件即可
### 2. docker-compose方式安装
#### 2.1 安装
1. 打开`docker-compose.yaml`,整个内容复制下来 1. 打开`docker-compose.yaml`,整个内容复制下来
https://gitee.com/certd/certd/raw/v2/docker/run/docker-compose.yaml https://gitee.com/certd/certd/raw/v2/docker/run/docker-compose.yaml
@@ -22,7 +51,7 @@ https://1panel.cn/docs/installation/online_installation/
> 默认使用sqlite数据库数据保存在`/data/certd`目录下,您可以手动备份该目录 > 默认使用sqlite数据库数据保存在`/data/certd`目录下,您可以手动备份该目录
> certd还支持`mysql`和`postgresql`数据库,[点我了解如何切换其他数据库](../database) > certd还支持`mysql`和`postgresql`数据库,[点我了解如何切换其他数据库](../database)
3. 访问测试 #### 2.2 访问测试
http://ip:7001 http://ip:7001
https://ip:7002 https://ip:7002
@@ -30,7 +59,7 @@ https://ip:7002
admin/123456 admin/123456
登录后请及时修改密码 登录后请及时修改密码
## 三、升级 #### 2.3 升级
1. 找到容器,点击更多->升级 1. 找到容器,点击更多->升级
![](./images/upgrade-1.png) ![](./images/upgrade-1.png)
@@ -39,11 +68,11 @@ admin/123456
![img.png](./images/upgrade-2.png) ![img.png](./images/upgrade-2.png)
## 四、数据备份 #### 2.4 备份
> 默认数据保存在`/data/certd`目录下,可以手动备份 > 默认数据保存在`/data/certd`目录下,可以手动备份
> 建议配置一条 [数据库备份流水线](../../use/backup/),自动备份 > 建议配置一条 [数据库备份流水线](../../use/backup/),自动备份
## 五、备份恢复 #### 2.5 恢复
将备份的`db.sqlite`及同目录下的其他文件一起覆盖到原来的位置重启certd即可 将备份的`db.sqlite`及同目录下的其他文件一起覆盖到原来的位置重启certd即可

View File

@@ -65,9 +65,54 @@ docker-compose up -d
## 二、从旧版的sqlite切换数据库 ## 二、从旧版的sqlite切换数据库
1. 先将`旧certd`升级到最新版 `建议备份sqlite数据库` 从旧版`sqlite`迁移到`mysql``postgresql`数据库
2. 按照上面全新安装方式部署一套`新的certd` `注意新旧版本的certd要一致`
3. 使用数据库工具将数据从sqlite导入到mysql或postgresql `注意flyway_history数据表不要导入`
4. 重启新certd
5. 确认没有问题之后删除旧版certd
下面以 `SQLite``MySQL` 为例进行演示
![db-0.png](images/db-0.png)
#### 0.前提条件:
1. SQLite版Certd站点已经`升级到最新版` `建议备份sqlite数据库`
2. `全新安装`MySQL版本Certd`确保是全新的,因为里面的数据会被清空覆盖`
3. 两套Certd站点版本一致
#### 1. 安装DBeaver工具
[https://dbeaver.io/download/](https://dbeaver.io/download/)
![db-1.png](images/db-1.png)
#### 2. 连接到sqlite数据库
![db-2.png](images/db-sqlite-1.png)
![db-3.png](images/db-sqlite-2.png)
#### 3. 连接到mysql或postgresql数据库
![db-4.png](images/db-mysql-1.png)
![db-5.png](images/db-mysql-2.png)
#### 4. 开始同步数据
选择mysql数据库选择所有的表`flyway_history除外`),右键导入数据
> 切记flyway_history数据表不要导入
![db-6.png](images/db-sync-1.jpg)
![db-7.png](images/db-sync-2.png)
![db-8.png](images/db-sync-3.png)
下一步、下一步,直到数据加载设置,勾选`在加载前截断目标表`此选项很重要并且会清空mysql certd数据库中的数据
![db-7.png](images/db-sync-4.png)
#### 5. 导入完成
![db-9.png](images/db-success.png)
#### 6. 重启MySQL版本Certd
访问MySQL版本测试数据已成功迁移
确认没有问题之后删除旧版certd

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

View File

@@ -40,31 +40,33 @@
| 36.| **括彩云cdn授权** | 括彩云CDN每月免费30G[注册即领](https://kuocaicdn.com/register?code=8mn536rrzfbf8) | | 36.| **括彩云cdn授权** | 括彩云CDN每月免费30G[注册即领](https://kuocaicdn.com/register?code=8mn536rrzfbf8) |
| 37.| **uniCloud** | unicloud授权 | | 37.| **uniCloud** | unicloud授权 |
| 38.| **猫云授权** | | | 38.| **猫云授权** | |
| 39.| **西部数码授权** | | | 39.| **授权插件示例** | |
| 40.| **多吉云** | | | 40.| **西部数码授权** | |
| 41.| **我爱云授权** | 我爱云CDN | | 41.| **多吉云** | |
| 42.| **CacheFly** | CacheFly | | 42.| **我爱云授权** | 我爱云CDN |
| 43.| **Gcore** | Gcore | | 43.| **CacheFly** | CacheFly |
| 44.| **亚马逊云aws授权** | | | 44.| **Gcore** | Gcore |
| 45.| **亚马逊云科技(国区)授权** | | | 45.| **亚马逊云aws授权** | |
| 46.| **dns.la授权** | | | 46.| **亚马逊云科技(国区)授权** | |
| 47.| **又拍云** | | | 47.| **dns.la授权** | |
| 48.| **51dns授权** | | | 48.| **又拍云** | |
| 49.| **FlexCDN授权** | | | 49.| **51dns授权** | |
| 50.| **farcdn授权** | | | 50.| **FlexCDN授权** | |
| 51.| **cloudflare授权** | | | 51.| **farcdn授权** | |
| 52.| **Github授权** | | | 52.| **cloudflare授权** | |
| 53.| **namesilo授权** | | | 53.| **Github授权** | |
| 54.| **proxmox** | | | 54.| **namesilo授权** | |
| 55.| **网宿授权** | | | 55.| **proxmox** | |
| 56.| **金山云授权** | | | 56.| **网宿授权** | |
| 57.| **APISIX授权** | | | 57.| **金山云授权** | |
| 58.| **Dokploy授权** | | | 58.| **APISIX授权** | |
| 59.| **godaddy授权** | | | 59.| **Dokploy授权** | |
| 60.| **新网授权** | | | 60.| **godaddy授权** | |
| 61.| **新网授权(代理方式)** | | | 61.| **新网授权** | |
| 62.| **新网互联授权** | 仅支持代理账号ip需要加入白名单 | | 62.| **新网授权(代理方式)** | |
| 63.| **雨云授权** | https://app.rainyun.com/ | | 63.| **新网互联授权** | 仅支持代理账号ip需要加入白名单 |
| 64.| **中国移动CND授权** | |
| 65.| **雨云授权** | https://app.rainyun.com/ |
<style module> <style module>
table th:first-of-type { table th:first-of-type {

View File

@@ -1,5 +1,5 @@
# 任务插件 # 任务插件
`103` 款任务插件 `105` 款任务插件
## 1. 证书申请 ## 1. 证书申请
| 序号 | 名称 | 说明 | | 序号 | 名称 | 说明 |
@@ -42,6 +42,7 @@
| 19.| **网宿-更新证书** | 网宿证书自动更新 | | 19.| **网宿-更新证书** | 网宿证书自动更新 |
| 20.| **金山云-更新CDN证书** | 金山云自动更新CDN证书 | | 20.| **金山云-更新CDN证书** | 金山云自动更新CDN证书 |
| 21.| **APISIX-更新证书** | 自动更新APISIX证书 | | 21.| **APISIX-更新证书** | 自动更新APISIX证书 |
| 22.| **中国移动-部署证书到CDN** | 中国移动自动部署证书到CDN |
## 4. 面板 ## 4. 面板
| 序号 | 名称 | 说明 | | 序号 | 名称 | 说明 |
@@ -54,15 +55,16 @@
| 6.| **群晖-部署证书到群晖面板** | Synology支持6.x以上版本 | | 6.| **群晖-部署证书到群晖面板** | Synology支持6.x以上版本 |
| 7.| **K8S-部署证书到Secret** | 部署证书到k8s的secret | | 7.| **K8S-部署证书到Secret** | 部署证书到k8s的secret |
| 8.| **K8S-Ingress 证书部署** | 部署证书到k8s的Ingress | | 8.| **K8S-Ingress 证书部署** | 部署证书到k8s的Ingress |
| 9.| **1Panel-部署证书到1Panel** | 更新1Panel的证书 | | 9.| **K8S-Apply自定义yaml** | apply自定义yaml到k8s |
| 10.| **Plesk-部署Plesk网站证书** | | | 10.| **1Panel-部署证书到1Panel** | 更新1Panel的证书 |
| 11.| **雷池-更新证书** | 更新长亭雷池WAF的证书 | | 11.| **Plesk-部署Plesk网站证书** | |
| 12.| **lucky-更新Lucky证书** | | | 12.| **雷池-更新证书** | 更新长亭雷池WAF的证书 |
| 13.| **uniCloud-部署到服务空间** | 部署到服务空间 | | 13.| **lucky-更新Lucky证书** | |
| 14.| **威联通-部署证书到威联通** | 部署证书到qnap | | 14.| **uniCloud-部署到服务空间** | 部署到服务空间 |
| 15.| **飞牛NAS-部署证书** | | | 15.| **威联通-部署证书到威联通** | 部署证书到qnap |
| 16.| **Proxmox-上传证书到Proxmox** | | | 16.| **飞牛NAS-部署证书** | |
| 17.| **Dokploy-部署server证书** | 自动更新Dokploy server证书 | | 17.| **Proxmox-上传证书到Proxmox** | |
| 18.| **Dokploy-部署server证书** | 自动更新Dokploy server证书 |
## 5. 阿里云 ## 5. 阿里云
| 序号 | 名称 | 说明 | | 序号 | 名称 | 说明 |

View File

@@ -17,8 +17,9 @@
| 13.| **cloudflare** | cloudflare dns provider | | 13.| **cloudflare** | cloudflare dns provider |
| 14.| **namesilo** | namesilo dns provider | | 14.| **namesilo** | namesilo dns provider |
| 15.| **godaddy** | GoDaddy | | 15.| **godaddy** | GoDaddy |
| 16.| **51dns** | 51DNS | | 16.| **Dns提供商Demo** | dns provider示例 |
| 17.| **新网互联** | 新网互联 | | 17.| **51dns** | 51DNS |
| 18.| **新网互联** | 新网互联 |
<style module> <style module>
table th:first-of-type { table th:first-of-type {

View File

@@ -43,4 +43,12 @@ service:
certd_koa_hostname: 0.0.0.0 certd_koa_hostname: 0.0.0.0
``` ```
## 6. DNS记录问题
1. DNS 不要设置CAA记录删除即可
2. DNSSEC相关报错DNSSEC管理中删除即可
3. DNS 有其他平台申请过的_acme-challenge记录删除即可

View File

@@ -5,8 +5,10 @@
配置环境变量 配置环境变量
```shell ```shell
ALIYUN_CLIENT_CONNECT_TIMEOUT=10000 # 连接超时,单位毫秒 # docker-compose.yaml
ALIYUN_CLIENT_READ_TIMEOUT=10000 #读取数据超时,单位毫秒 environment:
- ALIYUN_CLIENT_CONNECT_TIMEOUT=16000 # 连接超时,单位毫秒
- ALIYUN_CLIENT_READ_TIMEOUT=16000 #读取数据超时,单位毫秒
``` ```

View File

@@ -17,7 +17,7 @@
> 如果出现过: 100.25.1.5 100.25.4.8 > 如果出现过: 100.25.1.5 100.25.4.8
> >
> 可以尝试配置 100.25.*.5 > 可以尝试配置 100.25.*.*
## 二、nginx代理方案 ## 二、nginx代理方案

View File

@@ -1,10 +0,0 @@
# 证书申请失败情况
## DNS记录问题
1. DNS 不要设置CAA记录删除即可
2. DNSSEC相关报错DNSSEC管理中删除即可
3. DNS 有其他平台申请过的_acme-challenge记录删除即可

11
docs/guide/use/cert/ip.md Normal file
View File

@@ -0,0 +1,11 @@
# IP证书申请
certd已支持IP证书申请
> 注意IP证书有效期只有7天。
## 申请方式
相比普通的域名证书申请方式区别在于:
1. 域名栏填写IP
2. 校验方式选择HTTP只能HTTP
3. 证书颁发机构选择默认的Let's Encrypt
4. 过期更新天数改成2天

View File

@@ -7,13 +7,14 @@
services: services:
certd: certd:
environment: # 环境变量 environment: # 环境变量
- certd_system_resetAdminPasswd=false - certd_system_resetAdminPasswd=true
``` ```
## 2. 重启容器 ## 2. 重启容器
```shell ```shell
docker compose up -d docker compose up -d
docker logs -f --tail 500 certd docker logs -f --tail 500 certd
# 观察日志当日志中输出“重置1号管理员用户密码完成”,即可操作下一步 # 观察日志当日志中输出“重置1号管理员用户密码完成”即可操作下一步
# 这里会打印1号管理员记录的用户名如果你修改过管理员用户名请注意查看此条日志
``` ```
## 3. 恢复环境变量 ## 3. 恢复环境变量
修改docker-compose.yaml`certd_system_resetAdminPasswd`改回`false` 修改docker-compose.yaml`certd_system_resetAdminPasswd`改回`false`
@@ -23,4 +24,6 @@ docker logs -f --tail 500 certd
docker compose up -d docker compose up -d
``` ```
## 5. 默认密码登录 ## 5. 默认密码登录
使用`admin/123456`登录系统,请及时修改管理员密码 使用`原管理员账号/123456`登录系统,请及时修改管理员密码
> 默认管理员账号: admin
> 如果忘记管理员账号,请查看修改密码时的启动日志,会打印管理员账号名

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -0,0 +1,17 @@
# 流水线有效期功能
可以为流水线设置有效期,超过有效期后,流水线将停止运行
## 1. 打开有效期开关
![setting.png](images/setting.png)
## 2. 设置有效期
![valid.png](images/edit.png)
![valid.png](images/edit2.png)
## 3. 设置完成
该流水线将在有效期结束后停止运行
![valid.png](images/show.png)

View File

@@ -9,5 +9,5 @@
} }
}, },
"npmClient": "pnpm", "npmClient": "pnpm",
"version": "1.37.12" "version": "1.37.16"
} }

View File

@@ -17,8 +17,8 @@
"start:server": "cd ./packages/ui/certd-server && npm start", "start:server": "cd ./packages/ui/certd-server && npm start",
"devb": "lerna run dev-build", "devb": "lerna run dev-build",
"i-all": "lerna link && lerna exec npm install ", "i-all": "lerna link && lerna exec npm install ",
"publish": "npm run prepublishOnly2 && lerna publish --force-publish=pro/plus-core --conventional-commits --create-release github && npm run afterpublishOnly && npm run commitAll", "publish": "npm run prepublishOnly2 && lerna publish --force-publish=pro/plus-core --conventional-commits --create-release github && npm run afterpublishOnly ",
"afterpublishOnly": "npm run plugin-doc-gen && npm run copylogs && time /t >trigger/build.trigger && git add ./trigger/build.trigger && git commit -m \"build: trigger build image\" && TIMEOUT /T 10 && git push", "afterpublishOnly": "npm run plugin-doc-gen && npm run copylogs && time /t >trigger/build.trigger && git add ./trigger/build.trigger && git commit -m \"build: trigger build image\" && TIMEOUT /T 10 && npm run commitAll",
"transform-sql": "cd ./packages/ui/certd-server/db/ && node --experimental-json-modules transform.js", "transform-sql": "cd ./packages/ui/certd-server/db/ && node --experimental-json-modules transform.js",
"plugin-doc-gen": "cd ./packages/ui/certd-server/ && npm run export-md", "plugin-doc-gen": "cd ./packages/ui/certd-server/ && npm run export-md",
"commitAll": "git add . && git commit -m \"build: publish\" && git push && npm run commitPro", "commitAll": "git add . && git commit -m \"build: publish\" && git push && npm run commitPro",

View File

@@ -3,6 +3,24 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.16](https://github.com/publishlab/node-acme-client/compare/v1.37.15...v1.37.16) (2025-12-15)
### Bug Fixes
* 修复ipv6作为证书域名申请证书校验失败的bug ([e4e16bc](https://github.com/publishlab/node-acme-client/commit/e4e16bc6a65bb082c18ca0590226f0987a47d477))
## [1.37.15](https://github.com/publishlab/node-acme-client/compare/v1.37.14...v1.37.15) (2025-12-06)
**Note:** Version bump only for package @certd/acme-client
## [1.37.14](https://github.com/publishlab/node-acme-client/compare/v1.37.13...v1.37.14) (2025-12-02)
**Note:** Version bump only for package @certd/acme-client
## [1.37.13](https://github.com/publishlab/node-acme-client/compare/v1.37.12...v1.37.13) (2025-12-02)
**Note:** Version bump only for package @certd/acme-client
## [1.37.12](https://github.com/publishlab/node-acme-client/compare/v1.37.11...v1.37.12) (2025-11-29) ## [1.37.12](https://github.com/publishlab/node-acme-client/compare/v1.37.11...v1.37.12) (2025-11-29)
### Performance Improvements ### Performance Improvements

View File

@@ -3,7 +3,7 @@
"description": "Simple and unopinionated ACME client", "description": "Simple and unopinionated ACME client",
"private": false, "private": false,
"author": "nmorsman", "author": "nmorsman",
"version": "1.37.12", "version": "1.37.16",
"type": "module", "type": "module",
"module": "scr/index.js", "module": "scr/index.js",
"main": "src/index.js", "main": "src/index.js",
@@ -18,7 +18,7 @@
"types" "types"
], ],
"dependencies": { "dependencies": {
"@certd/basic": "^1.37.12", "@certd/basic": "^1.37.16",
"@peculiar/x509": "^1.11.0", "@peculiar/x509": "^1.11.0",
"asn1js": "^3.0.5", "asn1js": "^3.0.5",
"axios": "^1.7.2", "axios": "^1.7.2",
@@ -70,5 +70,5 @@
"bugs": { "bugs": {
"url": "https://github.com/publishlab/node-acme-client/issues" "url": "https://github.com/publishlab/node-acme-client/issues"
}, },
"gitHead": "9acac86ed58616fef31ec4d63021bb221429a425" "gitHead": "fa14f6219810ddbfcf1dde7b69963ee8a36c80c4"
} }

View File

@@ -247,7 +247,7 @@ async function getAuthoritativeDnsResolver(recordName, logger = log) {
try { try {
/* Resolve root domain by SOA */ /* Resolve root domain by SOA */
const domain = await resolveDomainBySoaRecord(recordNam,logger); const domain = await resolveDomainBySoaRecord(recordName,logger);
/* Resolve authoritative NS addresses */ /* Resolve authoritative NS addresses */
logger(`获取到权威NS服务器name: ${domain}`); logger(`获取到权威NS服务器name: ${domain}`);

View File

@@ -8,7 +8,7 @@ import {log as defaultLog} from './logger.js'
import axios from './axios.js' import axios from './axios.js'
import * as util from './util.js' import * as util from './util.js'
import {isAlpnCertificateAuthorizationValid} from './crypto/index.js' import {isAlpnCertificateAuthorizationValid} from './crypto/index.js'
import {utils} from '@certd/basic'
const dns = dnsSdk.promises const dns = dnsSdk.promises
@@ -60,11 +60,15 @@ async function verifyHttpChallenge(authz, challenge, keyAuthorization, suffix =
} }
const httpPort = axios.defaults.acmeSettings.httpChallengePort || 80; const httpPort = axios.defaults.acmeSettings.httpChallengePort || 80;
const challengeUrl = `http://${authz.identifier.value}:${httpPort}${suffix}`; let host = authz.identifier.value;
if(utils.domain.isIpv6(host)){
host = `[${host}]`;
}
const challengeUrl = `http://${host}:${httpPort}${suffix}`;
if (!await doQuery(challengeUrl)) { if (!await doQuery(challengeUrl)) {
const httpsPort = axios.defaults.acmeSettings.httpsChallengePort || 443; const httpsPort = axios.defaults.acmeSettings.httpsChallengePort || 443;
const httpsChallengeUrl = `https://${authz.identifier.value}:${httpsPort}${suffix}`; const httpsChallengeUrl = `https://${host}:${httpsPort}${suffix}`;
const res = await doQuery(httpsChallengeUrl) const res = await doQuery(httpsChallengeUrl)
if (!res) { if (!res) {
throw new Error(`[error] 验证失败请检查以上测试url是否可以正常访问`); throw new Error(`[error] 验证失败请检查以上测试url是否可以正常访问`);

View File

@@ -26,3 +26,4 @@ dist-ssr
test/user.secret.* test/user.secret.*
test/**/*.js test/**/*.js
src/**/*.spec.ts src/**/*.spec.ts
test.mjs

View File

@@ -3,6 +3,24 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.16](https://github.com/certd/certd/compare/v1.37.15...v1.37.16) (2025-12-15)
### Bug Fixes
* 修复ipv6作为证书域名申请证书校验失败的bug ([e4e16bc](https://github.com/certd/certd/commit/e4e16bc6a65bb082c18ca0590226f0987a47d477))
## [1.37.15](https://github.com/certd/certd/compare/v1.37.14...v1.37.15) (2025-12-06)
**Note:** Version bump only for package @certd/basic
## [1.37.14](https://github.com/certd/certd/compare/v1.37.13...v1.37.14) (2025-12-02)
**Note:** Version bump only for package @certd/basic
## [1.37.13](https://github.com/certd/certd/compare/v1.37.12...v1.37.13) (2025-12-02)
**Note:** Version bump only for package @certd/basic
## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29) ## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29)
**Note:** Version bump only for package @certd/basic **Note:** Version bump only for package @certd/basic

View File

@@ -1 +1 @@
02:28 01:44

View File

@@ -1,7 +1,7 @@
{ {
"name": "@certd/basic", "name": "@certd/basic",
"private": false, "private": false,
"version": "1.37.12", "version": "1.37.16",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
@@ -47,5 +47,5 @@
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "9acac86ed58616fef31ec4d63021bb221429a425" "gitHead": "fa14f6219810ddbfcf1dde7b69963ee8a36c80c4"
} }

View File

@@ -58,7 +58,7 @@ function isIpv6(d: string) {
if (!d) { if (!d) {
return false; return false;
} }
const isIPv6Regex = /^([\da-f]{1,4}:){2,7}[\da-f]{1,4}$/i; const isIPv6Regex = /^([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{1,4}$|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4})$/gm;
return isIPv6Regex.test(d); return isIPv6Regex.test(d);
} }

View File

@@ -1,4 +1,4 @@
export function isDev() { export function isDev() {
const nodeEnv = process.env.NODE_ENV || ''; const nodeEnv = process.env.NODE_ENV || 'dev';
return nodeEnv === 'development' || nodeEnv.includes('local') || nodeEnv.startsWith('dev'); return nodeEnv === 'development' || nodeEnv.includes('local') || nodeEnv.startsWith('dev');
} }

View File

@@ -1,14 +1,18 @@
import { random } from "lodash-es"; // import { random } from "lodash-es";
import { locker } from "./dist/utils/util.lock.js"; // import { locker } from "./dist/utils/util.lock.js";
async function testLocker() { // async function testLocker() {
for (let i = 0; i < 10; i++) { // for (let i = 0; i < 10; i++) {
await locker.execute("test", async () => { // await locker.execute("test", async () => {
console.log("test", i); // console.log("test", i);
await new Promise(resolve => setTimeout(resolve, Math.random() * 1000)); // await new Promise(resolve => setTimeout(resolve, Math.random() * 1000));
throw new Error("test error"); // throw new Error("test error");
}); // });
} // }
} // }
await testLocker(); // await testLocker();
import { domainUtils } from "./dist/utils/util.domain.js";
console.log(domainUtils.isIpv6("::0:0:0:FFFF:129.144.52.38"));

View File

@@ -3,6 +3,24 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.16](https://github.com/certd/certd/compare/v1.37.15...v1.37.16) (2025-12-15)
### Performance Improvements
* 支持邮件模版设置 ([a6c0d2c](https://github.com/certd/certd/commit/a6c0d2c6f1fd6b60e6d7af290487c94564fd91ea))
## [1.37.15](https://github.com/certd/certd/compare/v1.37.14...v1.37.15) (2025-12-06)
**Note:** Version bump only for package @certd/pipeline
## [1.37.14](https://github.com/certd/certd/compare/v1.37.13...v1.37.14) (2025-12-02)
**Note:** Version bump only for package @certd/pipeline
## [1.37.13](https://github.com/certd/certd/compare/v1.37.12...v1.37.13) (2025-12-02)
**Note:** Version bump only for package @certd/pipeline
## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29) ## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29)
**Note:** Version bump only for package @certd/pipeline **Note:** Version bump only for package @certd/pipeline

View File

@@ -1,7 +1,7 @@
{ {
"name": "@certd/pipeline", "name": "@certd/pipeline",
"private": false, "private": false,
"version": "1.37.12", "version": "1.37.16",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
@@ -18,8 +18,8 @@
"compile": "tsc --skipLibCheck --watch" "compile": "tsc --skipLibCheck --watch"
}, },
"dependencies": { "dependencies": {
"@certd/basic": "^1.37.12", "@certd/basic": "^1.37.16",
"@certd/plus-core": "^1.37.12", "@certd/plus-core": "^1.37.16",
"dayjs": "^1.11.7", "dayjs": "^1.11.7",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"reflect-metadata": "^0.1.13" "reflect-metadata": "^0.1.13"
@@ -45,5 +45,5 @@
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "9acac86ed58616fef31ec4d63021bb221429a425" "gitHead": "fa14f6219810ddbfcf1dde7b69963ee8a36c80c4"
} }

View File

@@ -423,31 +423,46 @@ export class Executor {
let subject = ""; let subject = "";
let content = ""; let content = "";
const errorMessage = error?.message; const errorMessage = error?.message;
const templateData: any = {
pipelineId: this.pipeline.id,
historyId: this.runtime.id,
pipelineTitle: this.pipeline.title,
};
let pipelineResult = "";
let errors = "";
if (when === "start") { if (when === "start") {
subject = `开始执行,${this.pipeline.title}${this.pipeline.id}`; pipelineResult = "开始执行";
subject = `${pipelineResult}${this.pipeline.title}${this.pipeline.id}`;
content = `流水线ID:${this.pipeline.id}运行ID:${this.runtime.id}`; content = `流水线ID:${this.pipeline.id}运行ID:${this.runtime.id}`;
} else if (when === "success") { } else if (when === "success") {
subject = `执行成功,${this.pipeline.title}${this.pipeline.id}`; pipelineResult = "执行成功";
subject = `${pipelineResult}${this.pipeline.title}${this.pipeline.id}`;
content = `流水线ID:${this.pipeline.id}运行ID:${this.runtime.id}`; content = `流水线ID:${this.pipeline.id}运行ID:${this.runtime.id}`;
} else if (when === "turnToSuccess") { } else if (when === "turnToSuccess") {
subject = `执行成功(失败转成功)${this.pipeline.title}${this.pipeline.id}`; pipelineResult = "执行成功(失败转成功)";
subject = `${pipelineResult}${this.pipeline.title}${this.pipeline.id}`;
content = `流水线ID:${this.pipeline.id}运行ID:${this.runtime.id}`; content = `流水线ID:${this.pipeline.id}运行ID:${this.runtime.id}`;
} else if (when === "error") { } else if (when === "error") {
subject = `执行失败,${this.pipeline.title}${this.pipeline.id}`; pipelineResult = "执行失败";
subject = `${pipelineResult}${this.pipeline.title}${this.pipeline.id}`;
if (error instanceof RunnableError) { if (error instanceof RunnableError) {
const runnableError = error as RunnableError; const runnableError = error as RunnableError;
content = `流水线ID:${this.pipeline.id}运行ID:${this.runtime.id}\n\n`; content = `流水线ID:${this.pipeline.id}运行ID:${this.runtime.id}\n\n`;
for (const re of runnableError.errors) { for (const re of runnableError.errors) {
content += ` - ${re.runnable.title} 执行失败,错误详情:${re.e?.message || re.e?.error?.message}\n\n`; errors += ` - ${re.runnable.title} 执行失败,错误详情:${re.e?.message || re.e?.error?.message}\n\n`;
} }
content += errors;
} else { } else {
errors = error.message;
content = `流水线ID:${this.pipeline.id}运行ID:${this.runtime.id}\n\n${this.currentStatusMap?.currentStep?.title} 执行失败\n\n错误详情:${error.message}`; content = `流水线ID:${this.pipeline.id}运行ID:${this.runtime.id}\n\n${this.currentStatusMap?.currentStep?.title} 执行失败\n\n错误详情:${error.message}`;
} }
} else { } else {
return; return;
} }
templateData.errors = errors;
templateData.pipelineResult = pipelineResult;
for (const notification of this.pipeline.notifications) { for (const notification of this.pipeline.notifications) {
if (!notification.when.includes(when)) { if (!notification.when.includes(when)) {
continue; continue;
@@ -455,9 +470,9 @@ export class Executor {
if (notification.type === "email" && notification.options?.receivers) { if (notification.type === "email" && notification.options?.receivers) {
try { try {
await this.options.emailService?.send({ await this.options.emailService?.sendByTemplate({
subject, type: "pipelineResult",
content, data: templateData,
receivers: notification.options?.receivers, receivers: notification.options?.receivers,
}); });
} catch (e) { } catch (e) {
@@ -472,15 +487,15 @@ export class Executor {
useEmail: false, useEmail: false,
logger: this.logger, logger: this.logger,
body: { body: {
notificationType: "pipelineResult",
title: subject, title: subject,
content, content,
userId: this.pipeline.userId, userId: this.pipeline.userId,
pipeline: this.pipeline, pipeline: this.pipeline,
result: this.lastRuntime?.pipeline?.status, result: this.lastRuntime?.pipeline?.status,
pipelineId: this.pipeline.id,
historyId: this.runtime.id,
errorMessage, errorMessage,
url, url,
...templateData,
}, },
}); });
} catch (e) { } catch (e) {

View File

@@ -15,6 +15,11 @@ export type NotificationBody = {
historyId?: number; historyId?: number;
errorMessage?: string; errorMessage?: string;
url?: string; url?: string;
notificationType?: string;
attachments?: any[];
pipelineResult?: string;
pipelineTitle?: string;
errors?: string;
}; };
export type NotificationRequestHandleReqInput<T = any> = { export type NotificationRequestHandleReqInput<T = any> = {

View File

@@ -185,6 +185,8 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
if (res == null) { if (res == null) {
throw new Error("授权不存在,可能已被删除,请前往任务配置里面重新选择授权"); throw new Error("授权不存在,可能已被删除,请前往任务配置里面重新选择授权");
} }
res.ctx.logger = this.logger;
res.ctx.http = this.http;
// @ts-ignore // @ts-ignore
if (this.logger?.addSecret) { if (this.logger?.addSecret) {
// 隐藏加密信息,不在日志中输出 // 隐藏加密信息,不在日志中输出

View File

@@ -27,6 +27,7 @@ export const pluginGroups = {
tencent: new PluginGroup("tencent", "腾讯云", 4, "svg:icon-tencentcloud"), tencent: new PluginGroup("tencent", "腾讯云", 4, "svg:icon-tencentcloud"),
volcengine: new PluginGroup("volcengine", "火山引擎", 4, "svg:icon-volcengine"), volcengine: new PluginGroup("volcengine", "火山引擎", 4, "svg:icon-volcengine"),
jdcloud: new PluginGroup("jdcloud", "京东云", 4, "svg:icon-jdcloud"), jdcloud: new PluginGroup("jdcloud", "京东云", 4, "svg:icon-jdcloud"),
ucloud: new PluginGroup("ucloud", "UCloud", 4, "svg:icon-ucloud"),
baidu: new PluginGroup("baidu", "百度云", 4, "ant-design:baidu-outlined"), baidu: new PluginGroup("baidu", "百度云", 4, "ant-design:baidu-outlined"),
qiniu: new PluginGroup("qiniu", "七牛云", 5, "svg:icon-qiniuyun"), qiniu: new PluginGroup("qiniu", "七牛云", 5, "svg:icon-qiniuyun"),
aws: new PluginGroup("aws", "亚马逊云", 6, "svg:icon-aws"), aws: new PluginGroup("aws", "亚马逊云", 6, "svg:icon-aws"),

View File

@@ -6,6 +6,14 @@ export type EmailSend = {
html?: string; html?: string;
}; };
export type EmailSendByTemplateReq = {
type: string;
data: any;
receivers: string[];
attachments?: any[];
};
export interface IEmailService { export interface IEmailService {
send(email: EmailSend): Promise<void>; send(email: EmailSend): Promise<void>;
sendByTemplate(req: EmailSendByTemplateReq): Promise<void>;
} }

View File

@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.16](https://github.com/certd/certd/compare/v1.37.15...v1.37.16) (2025-12-15)
**Note:** Version bump only for package @certd/lib-huawei
## [1.37.15](https://github.com/certd/certd/compare/v1.37.14...v1.37.15) (2025-12-06)
**Note:** Version bump only for package @certd/lib-huawei
## [1.37.14](https://github.com/certd/certd/compare/v1.37.13...v1.37.14) (2025-12-02)
**Note:** Version bump only for package @certd/lib-huawei
## [1.37.13](https://github.com/certd/certd/compare/v1.37.12...v1.37.13) (2025-12-02)
**Note:** Version bump only for package @certd/lib-huawei
## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29) ## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29)
**Note:** Version bump only for package @certd/lib-huawei **Note:** Version bump only for package @certd/lib-huawei

View File

@@ -1,7 +1,7 @@
{ {
"name": "@certd/lib-huawei", "name": "@certd/lib-huawei",
"private": false, "private": false,
"version": "1.37.12", "version": "1.37.16",
"main": "./dist/bundle.js", "main": "./dist/bundle.js",
"module": "./dist/bundle.js", "module": "./dist/bundle.js",
"types": "./dist/d/index.d.ts", "types": "./dist/d/index.d.ts",
@@ -24,5 +24,5 @@
"prettier": "^2.8.8", "prettier": "^2.8.8",
"tslib": "^2.8.1" "tslib": "^2.8.1"
}, },
"gitHead": "9acac86ed58616fef31ec4d63021bb221429a425" "gitHead": "fa14f6219810ddbfcf1dde7b69963ee8a36c80c4"
} }

View File

@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.16](https://github.com/certd/certd/compare/v1.37.15...v1.37.16) (2025-12-15)
**Note:** Version bump only for package @certd/lib-iframe
## [1.37.15](https://github.com/certd/certd/compare/v1.37.14...v1.37.15) (2025-12-06)
**Note:** Version bump only for package @certd/lib-iframe
## [1.37.14](https://github.com/certd/certd/compare/v1.37.13...v1.37.14) (2025-12-02)
**Note:** Version bump only for package @certd/lib-iframe
## [1.37.13](https://github.com/certd/certd/compare/v1.37.12...v1.37.13) (2025-12-02)
**Note:** Version bump only for package @certd/lib-iframe
## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29) ## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29)
**Note:** Version bump only for package @certd/lib-iframe **Note:** Version bump only for package @certd/lib-iframe

View File

@@ -1,7 +1,7 @@
{ {
"name": "@certd/lib-iframe", "name": "@certd/lib-iframe",
"private": false, "private": false,
"version": "1.37.12", "version": "1.37.16",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
@@ -31,5 +31,5 @@
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "9acac86ed58616fef31ec4d63021bb221429a425" "gitHead": "fa14f6219810ddbfcf1dde7b69963ee8a36c80c4"
} }

View File

@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.16](https://github.com/certd/certd/compare/v1.37.15...v1.37.16) (2025-12-15)
**Note:** Version bump only for package @certd/jdcloud
## [1.37.15](https://github.com/certd/certd/compare/v1.37.14...v1.37.15) (2025-12-06)
**Note:** Version bump only for package @certd/jdcloud
## [1.37.14](https://github.com/certd/certd/compare/v1.37.13...v1.37.14) (2025-12-02)
**Note:** Version bump only for package @certd/jdcloud
## [1.37.13](https://github.com/certd/certd/compare/v1.37.12...v1.37.13) (2025-12-02)
**Note:** Version bump only for package @certd/jdcloud
## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29) ## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29)
**Note:** Version bump only for package @certd/jdcloud **Note:** Version bump only for package @certd/jdcloud

View File

@@ -1,6 +1,6 @@
{ {
"name": "@certd/jdcloud", "name": "@certd/jdcloud",
"version": "1.37.12", "version": "1.37.16",
"description": "jdcloud openApi sdk", "description": "jdcloud openApi sdk",
"main": "./dist/bundle.js", "main": "./dist/bundle.js",
"module": "./dist/bundle.js", "module": "./dist/bundle.js",
@@ -56,5 +56,5 @@
"fetch" "fetch"
] ]
}, },
"gitHead": "9acac86ed58616fef31ec4d63021bb221429a425" "gitHead": "fa14f6219810ddbfcf1dde7b69963ee8a36c80c4"
} }

View File

@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.16](https://github.com/certd/certd/compare/v1.37.15...v1.37.16) (2025-12-15)
**Note:** Version bump only for package @certd/lib-k8s
## [1.37.15](https://github.com/certd/certd/compare/v1.37.14...v1.37.15) (2025-12-06)
### Performance Improvements
* 邮件模版安全优化 ([adca151](https://github.com/certd/certd/commit/adca151e4f07a4c6a2a753bfa48ee0d4d6469fd2))
* 支持k8s apply ([d55954a](https://github.com/certd/certd/commit/d55954a36391ebe6a9397ff7dcfb710193ac5e34))
## [1.37.14](https://github.com/certd/certd/compare/v1.37.13...v1.37.14) (2025-12-02)
**Note:** Version bump only for package @certd/lib-k8s
## [1.37.13](https://github.com/certd/certd/compare/v1.37.12...v1.37.13) (2025-12-02)
**Note:** Version bump only for package @certd/lib-k8s
## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29) ## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29)
**Note:** Version bump only for package @certd/lib-k8s **Note:** Version bump only for package @certd/lib-k8s

View File

@@ -1,7 +1,7 @@
{ {
"name": "@certd/lib-k8s", "name": "@certd/lib-k8s",
"private": false, "private": false,
"version": "1.37.12", "version": "1.37.16",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
@@ -17,7 +17,7 @@
"pub": "npm publish" "pub": "npm publish"
}, },
"dependencies": { "dependencies": {
"@certd/basic": "^1.37.12", "@certd/basic": "^1.37.16",
"@kubernetes/client-node": "0.21.0" "@kubernetes/client-node": "0.21.0"
}, },
"devDependencies": { "devDependencies": {
@@ -32,5 +32,5 @@
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "9acac86ed58616fef31ec4d63021bb221429a425" "gitHead": "fa14f6219810ddbfcf1dde7b69963ee8a36c80c4"
} }

View File

@@ -1,4 +1,4 @@
import { CoreV1Api, KubeConfig, NetworkingV1Api, V1Ingress, V1Secret } from "@kubernetes/client-node"; import { CoreV1Api, KubeConfig, NetworkingV1Api, V1Ingress, V1Secret, KubernetesObjectApi, loadYaml, KubernetesObject } from "@kubernetes/client-node";
import dns from "dns"; import dns from "dns";
import { ILogger } from "@certd/basic"; import { ILogger } from "@certd/basic";
import { merge } from "lodash-es"; import { merge } from "lodash-es";
@@ -27,6 +27,11 @@ export class K8sClient {
} }
init() { init() {
const kubeconfig = this.getKubeConfig();
this.client = kubeconfig.makeApiClient(CoreV1Api);
}
getKubeConfig() {
const kubeconfig = new KubeConfig(); const kubeconfig = new KubeConfig();
kubeconfig.loadFromString(this.kubeConfigStr); kubeconfig.loadFromString(this.kubeConfigStr);
this.kubeconfig = kubeconfig; this.kubeconfig = kubeconfig;
@@ -41,16 +46,35 @@ export class K8sClient {
} catch (e) { } catch (e) {
this.logger.warn("skipTLSVerify error", e); this.logger.warn("skipTLSVerify error", e);
} }
return kubeconfig;
}
this.client = kubeconfig.makeApiClient(CoreV1Api); getKubeClient() {
const kc = this.getKubeConfig();
const client = KubernetesObjectApi.makeApiClient(kc);
return client;
}
// const reqOpts = { kubeconfig, request: {} } as any; async apply(manifest: string) {
// if (this.lookup) { const yml = loadYaml<KubernetesObject>(manifest);
// reqOpts.request.lookup = this.lookup; const client = this.getKubeClient();
// } try {
// await client.create(yml);
// const backend = new Request(reqOpts); } catch (e) {
// this.client = new Client({ backend, version: '1.13' }); this.logger.error("apply error", e.response?.body);
if (e.response?.body?.reason === "AlreadyExists") {
//patch
this.logger.info("patch existing resource: ", yml.metadata?.name);
const existing = await client.read(yml as any);
if (!yml.metadata) {
yml.metadata = {};
}
yml.metadata.resourceVersion = existing.body.metadata.resourceVersion;
await client.patch(yml);
return;
}
throw e;
}
} }
/** /**
@@ -168,6 +192,7 @@ export class K8sClient {
const oldIngress = await client.readNamespacedIngress(ingressName, namespace); const oldIngress = await client.readNamespacedIngress(ingressName, namespace);
const newIngress = merge(oldIngress.body, opts.body); const newIngress = merge(oldIngress.body, opts.body);
const res = await client.replaceNamespacedIngress(ingressName, namespace, newIngress); const res = await client.replaceNamespacedIngress(ingressName, namespace, newIngress);
this.logger.info("ingress patched", opts.body); this.logger.info("ingress patched", opts.body);
return res; return res;
} }

View File

@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.16](https://github.com/certd/certd/compare/v1.37.15...v1.37.16) (2025-12-15)
### Bug Fixes
* 修复ipv6作为证书域名申请证书校验失败的bug ([e4e16bc](https://github.com/certd/certd/commit/e4e16bc6a65bb082c18ca0590226f0987a47d477))
### Performance Improvements
* 支持邮件模版设置 ([a6c0d2c](https://github.com/certd/certd/commit/a6c0d2c6f1fd6b60e6d7af290487c94564fd91ea))
## [1.37.15](https://github.com/certd/certd/compare/v1.37.14...v1.37.15) (2025-12-06)
**Note:** Version bump only for package @certd/lib-server
## [1.37.14](https://github.com/certd/certd/compare/v1.37.13...v1.37.14) (2025-12-02)
**Note:** Version bump only for package @certd/lib-server
## [1.37.13](https://github.com/certd/certd/compare/v1.37.12...v1.37.13) (2025-12-02)
### Performance Improvements
* 第三方登录允许选择logo ([bb3085e](https://github.com/certd/certd/commit/bb3085ef84201ccd2dc632ba8c5097cb00258be4))
## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29) ## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29)
**Note:** Version bump only for package @certd/lib-server **Note:** Version bump only for package @certd/lib-server

View File

@@ -1,6 +1,6 @@
{ {
"name": "@certd/lib-server", "name": "@certd/lib-server",
"version": "1.37.12", "version": "1.37.16",
"description": "midway with flyway, sql upgrade way ", "description": "midway with flyway, sql upgrade way ",
"private": false, "private": false,
"type": "module", "type": "module",
@@ -28,11 +28,11 @@
], ],
"license": "AGPL", "license": "AGPL",
"dependencies": { "dependencies": {
"@certd/acme-client": "^1.37.12", "@certd/acme-client": "^1.37.16",
"@certd/basic": "^1.37.12", "@certd/basic": "^1.37.16",
"@certd/pipeline": "^1.37.12", "@certd/pipeline": "^1.37.16",
"@certd/plugin-lib": "^1.37.12", "@certd/plugin-lib": "^1.37.16",
"@certd/plus-core": "^1.37.12", "@certd/plus-core": "^1.37.16",
"@midwayjs/cache": "3.14.0", "@midwayjs/cache": "3.14.0",
"@midwayjs/core": "3.20.11", "@midwayjs/core": "3.20.11",
"@midwayjs/i18n": "3.20.13", "@midwayjs/i18n": "3.20.13",
@@ -64,5 +64,5 @@
"typeorm": "^0.3.11", "typeorm": "^0.3.11",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "9acac86ed58616fef31ec4d63021bb221429a425" "gitHead": "fa14f6219810ddbfcf1dde7b69963ee8a36c80c4"
} }

View File

@@ -2,3 +2,4 @@ export * from './service/plus-service.js';
export * from './service/file-service.js'; export * from './service/file-service.js';
export * from './service/encryptor.js'; export * from './service/encryptor.js';
export * from './service/ocr-service.js'; export * from './service/ocr-service.js';
export * from './service/executor-queue.js';

View File

@@ -0,0 +1,79 @@
import { logger } from "@certd/basic";
export type TaskItem = {
task: ()=>Promise<void>;
}
export class UserTaskQueue{
userId: number;
pendingQueue: TaskItem[] = [];
runningQueue: TaskItem[] = [];
getMaxRunningCount: ()=>number ;
constructor(req: { userId: number ,getMaxRunningCount: ()=>number }) {
this.userId = req.userId;
this.getMaxRunningCount = req.getMaxRunningCount ;
}
addTask(task: TaskItem) {
this.pendingQueue.push(task);
this.runTask();
}
runTask() {
logger.info(`[user_${this.userId}]当前运行队列:${this.runningQueue.length}, 等待队列:${this.pendingQueue.length},最大运行队列:${this.getMaxRunningCount()}`);
if (this.runningQueue.length >= this.getMaxRunningCount()) {
return;
}
if (this.pendingQueue.length === 0) {
return;
}
const task = this.pendingQueue.shift();
if (!task) {
return;
}
// 执行任务
this.runningQueue.push(task);
const call = async ()=>{
try{
await task.task();
}finally{
// 任务执行完成,从运行队列中移除
const index = this.runningQueue.indexOf(task);
if (index > -1) {
this.runningQueue.splice(index, 1);
}
// 继续执行下一个任务
this.runTask();
}
}
logger.info(`[user_${this.userId}]执行任务,当前运行队列:${this.runningQueue.length}, 等待队列:${this.pendingQueue.length}`);
call()
}
}
export class ExecutorQueue{
queues: Record<number, UserTaskQueue> = {};
maxRunningCount: number = 8;
setMaxRunningCount(count: number) {
this.maxRunningCount = count;
}
getUserQueue(userId: number) {
const userQueue = this.queues[userId];
if (!userQueue) {
this.queues[userId] = new UserTaskQueue({ userId, getMaxRunningCount: ()=>this.maxRunningCount });
}
return this.queues[userId];
}
addTask(userId: number, task: TaskItem) {
const userQueue = this.getUserQueue(userId);
userQueue.addTask(task);
}
}
export const executorQueue = new ExecutorQueue();

View File

@@ -14,7 +14,7 @@ export const uploadTmpFileCacheKey = 'tmpfile_key_';
/** /**
*/ */
@Provide() @Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true }) @Scope(ScopeEnum.Singleton, { allowDowngrade: true })
export class FileService { export class FileService {
async saveFile(userId: number, tmpCacheKey: any, permission: 'public' | 'private') { async saveFile(userId: number, tmpCacheKey: any, permission: 'public' | 'private') {
if (tmpCacheKey.startsWith(`/${permission}`)) { if (tmpCacheKey.startsWith(`/${permission}`)) {

View File

@@ -5,7 +5,7 @@ import { IOcrService } from "@certd/plugin-lib";
/** /**
*/ */
@Provide("ocrService") @Provide("ocrService")
@Scope(ScopeEnum.Request, { allowDowngrade: true }) @Scope(ScopeEnum.Singleton, { allowDowngrade: true })
export class OcrService implements IOcrService { export class OcrService implements IOcrService {
@Inject() @Inject()
plusService: PlusService; plusService: PlusService;

View File

@@ -5,7 +5,7 @@ import { SysInstallInfo, SysLicenseInfo, SysSettingsService } from '../../settin
import { merge } from 'lodash-es'; import { merge } from 'lodash-es';
import fs from 'fs'; import fs from 'fs';
@Provide("plusService") @Provide("plusService")
@Scope(ScopeEnum.Request, { allowDowngrade: true }) @Scope(ScopeEnum.Singleton, { allowDowngrade: true })
export class PlusService { export class PlusService {
@Inject() @Inject()
sysSettingsService: SysSettingsService; sysSettingsService: SysSettingsService;

View File

@@ -43,12 +43,16 @@ export class SysPublicSettings extends BaseSettings {
//流水线是否启用有效期 //流水线是否启用有效期
pipelineValidTimeEnabled?: boolean = false; pipelineValidTimeEnabled?: boolean = false;
//证书域名添加到监控 //证书域名添加到监控
certDomainAddToMonitorEnabled?: boolean = false; certDomainAddToMonitorEnabled?: boolean = false;
// 固定证书有效期天数0表示不固定 // 固定证书有效期天数0表示不固定
fixedCertExpireDays?: number; fixedCertExpireDays?: number;
//默认到期前更新天数
defaultCertRenewDays?: number;
// 第三方OAuth配置 // 第三方OAuth配置
oauthEnabled?: boolean = false; oauthEnabled?: boolean = false;
oauthProviders: Record<string, { oauthProviders: Record<string, {
@@ -73,6 +77,8 @@ export class SysPrivateSettings extends BaseSettings {
httpRequestTimeout?: number = 30; httpRequestTimeout?: number = 30;
pipelineMaxRunningCount?: number;
sms?: { sms?: {
type?: string; type?: string;
config?: any; config?: any;
@@ -108,6 +114,11 @@ export class SysLicenseInfo extends BaseSettings {
license?: string; license?: string;
} }
export type EmailTemplate = {
addonId?: number;
}
export class SysEmailConf extends BaseSettings { export class SysEmailConf extends BaseSettings {
static __title__ = '邮箱配置'; static __title__ = '邮箱配置';
static __key__ = 'sys.email'; static __key__ = 'sys.email';
@@ -126,6 +137,13 @@ export class SysEmailConf extends BaseSettings {
}; };
sender: string; sender: string;
usePlus?: boolean; usePlus?: boolean;
templates:{
registerCode?: EmailTemplate,
forgotPassword?: EmailTemplate,
pipelineResult?: EmailTemplate,
common?: EmailTemplate,
}
} }
export class SysSiteInfo extends BaseSettings { export class SysSiteInfo extends BaseSettings {

View File

@@ -8,6 +8,7 @@ import { BaseService } from '../../../basic/index.js';
import { cache, logger, setGlobalProxy } from '@certd/basic'; import { cache, logger, setGlobalProxy } from '@certd/basic';
import * as dns from 'node:dns'; import * as dns from 'node:dns';
import {mergeUtils} from "@certd/basic"; import {mergeUtils} from "@certd/basic";
import { executorQueue } from '../../basic/service/executor-queue.js';
const {merge} = mergeUtils; const {merge} = mergeUtils;
/** /**
* 设置 * 设置
@@ -140,6 +141,10 @@ export class SysSettingsService extends BaseService<SysSettingsEntity> {
if (bean.dnsResultOrder) { if (bean.dnsResultOrder) {
dns.setDefaultResultOrder(bean.dnsResultOrder as any); dns.setDefaultResultOrder(bean.dnsResultOrder as any);
} }
if (bean.pipelineMaxRunningCount){
executorQueue.setMaxRunningCount(bean.pipelineMaxRunningCount);
}
} }
async updateByKey(key: string, setting: any) { async updateByKey(key: string, setting: any) {

View File

@@ -10,7 +10,7 @@ import {EncryptService} from './encrypt-service.js';
* 授权 * 授权
*/ */
@Provide() @Provide()
@Scope(ScopeEnum.Request, {allowDowngrade: true}) @Scope(ScopeEnum.Singleton, { allowDowngrade: true })
export class AccessService extends BaseService<AccessEntity> { export class AccessService extends BaseService<AccessEntity> {
@InjectEntityModel(AccessEntity) @InjectEntityModel(AccessEntity)
repository: Repository<AccessEntity>; repository: Repository<AccessEntity>;

View File

@@ -65,6 +65,7 @@ export abstract class BaseAddon implements IAddon {
http!: HttpClient; http!: HttpClient;
logger!: ILogger; logger!: ILogger;
title!: string;

View File

@@ -9,7 +9,7 @@ import { AddonEntity } from "../entity/addon.js";
* Addon * Addon
*/ */
@Provide() @Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true }) @Scope(ScopeEnum.Singleton, { allowDowngrade: true })
export class AddonService extends BaseService<AddonEntity> { export class AddonService extends BaseService<AddonEntity> {
@InjectEntityModel(AddonEntity) @InjectEntityModel(AddonEntity)
repository: Repository<AddonEntity>; repository: Repository<AddonEntity>;

View File

@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.16](https://github.com/certd/certd/compare/v1.37.15...v1.37.16) (2025-12-15)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.37.15](https://github.com/certd/certd/compare/v1.37.14...v1.37.15) (2025-12-06)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.37.14](https://github.com/certd/certd/compare/v1.37.13...v1.37.14) (2025-12-02)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.37.13](https://github.com/certd/certd/compare/v1.37.12...v1.37.13) (2025-12-02)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29) ## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29)
**Note:** Version bump only for package @certd/midway-flyway-js **Note:** Version bump only for package @certd/midway-flyway-js

View File

@@ -1,6 +1,6 @@
{ {
"name": "@certd/midway-flyway-js", "name": "@certd/midway-flyway-js",
"version": "1.37.12", "version": "1.37.16",
"description": "midway with flyway, sql upgrade way ", "description": "midway with flyway, sql upgrade way ",
"private": false, "private": false,
"type": "module", "type": "module",
@@ -46,5 +46,5 @@
"typeorm": "^0.3.11", "typeorm": "^0.3.11",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "9acac86ed58616fef31ec4d63021bb221429a425" "gitHead": "fa14f6219810ddbfcf1dde7b69963ee8a36c80c4"
} }

View File

@@ -3,6 +3,28 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.16](https://github.com/certd/certd/compare/v1.37.15...v1.37.16) (2025-12-15)
### Bug Fixes
* 修复ipv6作为证书域名申请证书校验失败的bug ([e4e16bc](https://github.com/certd/certd/commit/e4e16bc6a65bb082c18ca0590226f0987a47d477))
### Performance Improvements
* 支持邮件模版设置 ([a6c0d2c](https://github.com/certd/certd/commit/a6c0d2c6f1fd6b60e6d7af290487c94564fd91ea))
## [1.37.15](https://github.com/certd/certd/compare/v1.37.14...v1.37.15) (2025-12-06)
**Note:** Version bump only for package @certd/plugin-cert
## [1.37.14](https://github.com/certd/certd/compare/v1.37.13...v1.37.14) (2025-12-02)
**Note:** Version bump only for package @certd/plugin-cert
## [1.37.13](https://github.com/certd/certd/compare/v1.37.12...v1.37.13) (2025-12-02)
**Note:** Version bump only for package @certd/plugin-cert
## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29) ## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29)
### Performance Improvements ### Performance Improvements

View File

@@ -1,7 +1,7 @@
{ {
"name": "@certd/plugin-cert", "name": "@certd/plugin-cert",
"private": false, "private": false,
"version": "1.37.12", "version": "1.37.16",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@@ -17,10 +17,10 @@
"compile": "tsc --skipLibCheck --watch" "compile": "tsc --skipLibCheck --watch"
}, },
"dependencies": { "dependencies": {
"@certd/acme-client": "^1.37.12", "@certd/acme-client": "^1.37.16",
"@certd/basic": "^1.37.12", "@certd/basic": "^1.37.16",
"@certd/pipeline": "^1.37.12", "@certd/pipeline": "^1.37.16",
"@certd/plugin-lib": "^1.37.12", "@certd/plugin-lib": "^1.37.16",
"@google-cloud/publicca": "^1.3.0", "@google-cloud/publicca": "^1.3.0",
"dayjs": "^1.11.7", "dayjs": "^1.11.7",
"jszip": "^3.10.1", "jszip": "^3.10.1",
@@ -43,5 +43,5 @@
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "9acac86ed58616fef31ec4d63021bb221429a425" "gitHead": "fa14f6219810ddbfcf1dde7b69963ee8a36c80c4"
} }

View File

@@ -21,6 +21,11 @@ export class DomainParser implements IDomainParser {
} }
async parse(fullDomain: string) { async parse(fullDomain: string) {
//如果是ip
if (utils.domain.isIp(fullDomain)) {
return fullDomain;
}
this.logger.info(`查找主域名:${fullDomain}`); this.logger.info(`查找主域名:${fullDomain}`);
const cacheKey = `domain_parse:${fullDomain}`; const cacheKey = `domain_parse:${fullDomain}`;
const value = utils.cache.get(cacheKey); const value = utils.cache.get(cacheKey);

View File

@@ -233,13 +233,22 @@ export class AcmeService {
// const origDomain = punycode.toUnicode(domain); // const origDomain = punycode.toUnicode(domain);
const origFullDomain = punycode.toUnicode(fullDomain); const origFullDomain = punycode.toUnicode(fullDomain);
const isIp = utils.domain.isIp(origFullDomain);
function checkIpChallenge(type: string) {
if (isIp) {
throw new Error(`IP证书不支持${type}校验方式请选择HTTP方式校验`);
}
}
if (providers.domainsVerifyPlan) { if (providers.domainsVerifyPlan) {
//按照计划执行 //按照计划执行
const domainVerifyPlan = providers.domainsVerifyPlan[origFullDomain]; const domainVerifyPlan = providers.domainsVerifyPlan[origFullDomain];
if (domainVerifyPlan) { if (domainVerifyPlan) {
if (domainVerifyPlan.type === "dns") { if (domainVerifyPlan.type === "dns") {
checkIpChallenge("dns");
dnsProvider = domainVerifyPlan.dnsProvider; dnsProvider = domainVerifyPlan.dnsProvider;
} else if (domainVerifyPlan.type === "cname") { } else if (domainVerifyPlan.type === "cname") {
checkIpChallenge("cname");
const cname: CnameVerifyPlan = domainVerifyPlan.cnameVerifyPlan; const cname: CnameVerifyPlan = domainVerifyPlan.cnameVerifyPlan;
if (cname) { if (cname) {
dnsProvider = cname.dnsProvider; dnsProvider = cname.dnsProvider;
@@ -274,6 +283,7 @@ export class AcmeService {
} }
const dnsChallenge = getChallenge("dns-01"); const dnsChallenge = getChallenge("dns-01");
checkIpChallenge("dns");
return await doDnsVerify(dnsChallenge, fullRecord, dnsProvider); return await doDnsVerify(dnsChallenge, fullRecord, dnsProvider);
} }

View File

@@ -20,7 +20,7 @@ export abstract class CertApplyBasePlugin extends CertApplyBaseConvertPlugin {
@TaskInput({ @TaskInput({
title: "更新天数", title: "更新天数",
value: 35, value: 18,
component: { component: {
name: "a-input-number", name: "a-input-number",
vModel: "value", vModel: "value",
@@ -154,6 +154,7 @@ export abstract class CertApplyBasePlugin extends CertApplyBaseConvertPlugin {
title: `证书申请成功【${this.pipeline.title}`, title: `证书申请成功【${this.pipeline.title}`,
content: `域名:${this.domains.join(",")}`, content: `域名:${this.domains.join(",")}`,
url: url, url: url,
notificationType: "certApplySuccess",
}; };
try { try {
await this.ctx.notificationService.send({ await this.ctx.notificationService.send({

View File

@@ -0,0 +1,165 @@
import { IsTaskPlugin, PageSearch, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { AliyunAccess, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import type { CertInfo } from "../acme.js";
import { CertApplyBasePlugin } from "../base.js";
import { CertReader } from "../cert-reader.js";
import dayjs from "dayjs";
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",
component: {
name: "RemoteAutoComplete",
vModel: "value",
},
action: CertApplyGetFormAliyunPlugin.prototype.onGetOrderList.name,
})
)
orderId!: string;
async onInit(): Promise<void> {}
async doCertApply(): Promise<CertReader> {
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await access.getClient("cas.aliyuncs.com");
this.logger.info(`开始获取证书,orderId:${this.orderId}`);
let orderId: any = this.orderId;
if (!orderId) {
throw new Error("请先输入证书订单ID");
}
if (typeof orderId !== "string") {
orderId = parseInt(orderId);
}
const certState = await this.getCertificateState(client, orderId);
this.logger.info(`获取到证书Id:${JSON.stringify(certState.CertId)}`);
const certDetail = await this.getCertDetail(client, certState.CertId);
this.logger.info(`获取到证书:${certDetail.getAllDomains()}, 过期时间:${dayjs(certDetail.expires).format("YYYY-MM-DD HH:mm:ss")}`);
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): Promise<{ CertId: string; Type: string; Domain: string }> {
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;
}
async onGetOrderList(req: PageSearch) {
if (!this.accessId) {
throw new Error("请先选择Access授权");
}
const access = await this.getAccess<AliyunAccess>(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();

View File

@@ -93,7 +93,7 @@ const preferredChainMergeScript = (() => {
desc: "免费通配符域名证书申请,支持多个域名打到同一个证书上", desc: "免费通配符域名证书申请,支持多个域名打到同一个证书上",
default: { default: {
input: { input: {
renewDays: 35, renewDays: 18,
forceUpdate: false, forceUpdate: false,
}, },
strategy: { strategy: {
@@ -111,7 +111,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
options: [ options: [
{ value: "dns", label: "DNS直接验证" }, { value: "dns", label: "DNS直接验证" },
{ value: "cname", label: "CNAME代理验证" }, { value: "cname", label: "CNAME代理验证" },
{ value: "http", label: "HTTP文件验证" }, { value: "http", label: "HTTP文件验证IP证书只能选它" },
{ value: "dnses", label: "多DNS提供商" }, { value: "dnses", label: "多DNS提供商" },
{ value: "auto", label: "自动匹配" }, { value: "auto", label: "自动匹配" },
], ],
@@ -119,7 +119,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
required: true, required: true,
helper: `1. <b>DNS直接验证</b>当域名dns解析已被本系统支持时即下方DNS解析服务商选项中可选推荐选择此方式 helper: `1. <b>DNS直接验证</b>当域名dns解析已被本系统支持时即下方DNS解析服务商选项中可选推荐选择此方式
2. <b>CNAME代理验证</b>:支持任何注册商的域名,第一次需要手动添加[CNAME记录](#/certd/cname/record)如果经常申请失败建议将DNS服务器修改为阿里云/腾讯云的然后使用DNS直接验证 2. <b>CNAME代理验证</b>:支持任何注册商的域名,第一次需要手动添加[CNAME记录](#/certd/cname/record)如果经常申请失败建议将DNS服务器修改为阿里云/腾讯云的然后使用DNS直接验证
3. <b>HTTP文件验证</b>:不支持泛域名,需要配置网站文件上传 3. <b>HTTP文件验证</b>:不支持泛域名,需要配置网站文件上传IP证书必须选它
4. <b>多DNS提供商</b>每个域名可以选择独立的DNS提供商 4. <b>多DNS提供商</b>每个域名可以选择独立的DNS提供商
5. <b>自动匹配</b>:此处无需选择校验方式,需要在[域名管理](#/certd/cert/domain)中提前配置好校验方式 5. <b>自动匹配</b>:此处无需选择校验方式,需要在[域名管理](#/certd/cert/domain)中提前配置好校验方式
`, `,
@@ -133,12 +133,12 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
name: "icon-select", name: "icon-select",
vModel: "value", vModel: "value",
options: [ options: [
{ value: "letsencrypt", label: "Let's Encrypt免费新手推荐", icon: "simple-icons:letsencrypt" }, { value: "letsencrypt", label: "Let's Encrypt免费新手推荐支持IP证书", icon: "simple-icons:letsencrypt" },
{ value: "google", label: "Google免费", icon: "flat-color-icons:google" }, { value: "google", label: "Google免费", icon: "flat-color-icons:google" },
{ value: "zerossl", label: "ZeroSSL免费", icon: "emojione:digit-zero" }, { value: "zerossl", label: "ZeroSSL免费", icon: "emojione:digit-zero" },
{ value: "litessl", label: "litessl免费", icon: "roentgen:free" }, { value: "litessl", label: "litessl免费", icon: "roentgen:free" },
{ value: "sslcom", label: "SSL.com仅主域名和www免费", icon: "la:expeditedssl" }, { value: "sslcom", label: "SSL.com仅主域名和www免费", icon: "la:expeditedssl" },
{ value: "letsencrypt_staging", label: "Let's Encrypt测试环境IP证书", icon: "simple-icons:letsencrypt" }, { value: "letsencrypt_staging", label: "Let's Encrypt测试环境仅供测试", icon: "simple-icons:letsencrypt" },
], ],
}, },
helper: "Let's Encrypt申请最简单\nGoogle大厂光环兼容性好仅首次需要翻墙获取EAB授权\nZeroSSL需要EAB授权无需翻墙\nSSL.com仅主域名和www免费,必须设置CAA记录", helper: "Let's Encrypt申请最简单\nGoogle大厂光环兼容性好仅首次需要翻墙获取EAB授权\nZeroSSL需要EAB授权无需翻墙\nSSL.com仅主域名和www免费,必须设置CAA记录",
@@ -220,7 +220,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
if(form.challengeType === 'cname' ){ if(form.challengeType === 'cname' ){
return '请按照上面的提示给要申请证书的域名添加CNAME记录添加后点击验证验证成功后不要删除记录申请和续期证书会一直用它' return '请按照上面的提示给要申请证书的域名添加CNAME记录添加后点击验证验证成功后不要删除记录申请和续期证书会一直用它'
}else if (form.challengeType === 'http'){ }else if (form.challengeType === 'http'){
return '请按照上面的提示,给每个域名设置文件上传配置,证书申请过程中会上传校验文件到网站根目录下' return '请按照上面的提示,给每个域名设置文件上传配置,证书申请过程中会上传校验文件到网站根目录的.well-known/acme-challenge/目录下'
}else if (form.challengeType === 'http'){ }else if (form.challengeType === 'http'){
return '给每个域名单独配置dns提供商' return '给每个域名单独配置dns提供商'
} }

View File

@@ -3,4 +3,5 @@ export { EVENT_CERT_APPLY_SUCCESS } from "./cert-plugin/base-convert.js";
export * from "./cert-plugin/index.js"; export * from "./cert-plugin/index.js";
export * from "./cert-plugin/lego/index.js"; export * from "./cert-plugin/lego/index.js";
export * from "./cert-plugin/custom/index.js"; export * from "./cert-plugin/custom/index.js";
export * from "./cert-plugin/getter/aliyun.js";
export const CertApplyPluginNames = [":cert:"]; export const CertApplyPluginNames = [":cert:"];

View File

@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.16](https://github.com/certd/certd/compare/v1.37.15...v1.37.16) (2025-12-15)
**Note:** Version bump only for package @certd/plugin-lib
## [1.37.15](https://github.com/certd/certd/compare/v1.37.14...v1.37.15) (2025-12-06)
**Note:** Version bump only for package @certd/plugin-lib
## [1.37.14](https://github.com/certd/certd/compare/v1.37.13...v1.37.14) (2025-12-02)
**Note:** Version bump only for package @certd/plugin-lib
## [1.37.13](https://github.com/certd/certd/compare/v1.37.12...v1.37.13) (2025-12-02)
**Note:** Version bump only for package @certd/plugin-lib
## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29) ## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29)
**Note:** Version bump only for package @certd/plugin-lib **Note:** Version bump only for package @certd/plugin-lib

View File

@@ -1,7 +1,7 @@
{ {
"name": "@certd/plugin-lib", "name": "@certd/plugin-lib",
"private": false, "private": false,
"version": "1.37.12", "version": "1.37.16",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@@ -22,8 +22,8 @@
"@alicloud/pop-core": "^1.7.10", "@alicloud/pop-core": "^1.7.10",
"@alicloud/tea-util": "^1.4.10", "@alicloud/tea-util": "^1.4.10",
"@aws-sdk/client-s3": "^3.787.0", "@aws-sdk/client-s3": "^3.787.0",
"@certd/basic": "^1.37.12", "@certd/basic": "^1.37.16",
"@certd/pipeline": "^1.37.12", "@certd/pipeline": "^1.37.16",
"@kubernetes/client-node": "0.21.0", "@kubernetes/client-node": "0.21.0",
"ali-oss": "^6.22.0", "ali-oss": "^6.22.0",
"basic-ftp": "^5.0.5", "basic-ftp": "^5.0.5",
@@ -53,5 +53,5 @@
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "9acac86ed58616fef31ec4d63021bb221429a425" "gitHead": "fa14f6219810ddbfcf1dde7b69963ee8a36c80c4"
} }

View File

@@ -3,6 +3,37 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.16](https://github.com/certd/certd/compare/v1.37.15...v1.37.16) (2025-12-15)
### Bug Fixes
* 修复ipv6作为证书域名申请证书校验失败的bug ([e4e16bc](https://github.com/certd/certd/commit/e4e16bc6a65bb082c18ca0590226f0987a47d477))
### Performance Improvements
* 批量设置定时,支持清除定时 ([63d8bcf](https://github.com/certd/certd/commit/63d8bcf8823f713365042d3c7aee3cf31d44b044))
* 支持彩虹聚合登录 ([6f18693](https://github.com/certd/certd/commit/6f186932ccad4becfdc0087c0539f7b2d0069844))
* 支持邮件模版设置 ([a6c0d2c](https://github.com/certd/certd/commit/a6c0d2c6f1fd6b60e6d7af290487c94564fd91ea))
## [1.37.15](https://github.com/certd/certd/compare/v1.37.14...v1.37.15) (2025-12-06)
### Performance Improvements
* 第三方登录支持gitee ([5cee7d4](https://github.com/certd/certd/commit/5cee7d44f17bd36972f477bc1f270999da558d05))
## [1.37.14](https://github.com/certd/certd/compare/v1.37.13...v1.37.14) (2025-12-02)
### Bug Fixes
* 修复注销登录时,第三方登录注销请求失败的报错 ([677e110](https://github.com/certd/certd/commit/677e1101e6cf4451abd8a876cc1d0ddd26a10b88))
## [1.37.13](https://github.com/certd/certd/compare/v1.37.12...v1.37.13) (2025-12-02)
### Performance Improvements
* 第三方登录允许选择logo ([bb3085e](https://github.com/certd/certd/commit/bb3085ef84201ccd2dc632ba8c5097cb00258be4))
* 支持OIDC单点登录 ([fbf12f1](https://github.com/certd/certd/commit/fbf12f16b5eaa7676fd41923587bf6bd2595adba))
## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29) ## [1.37.12](https://github.com/certd/certd/compare/v1.37.11...v1.37.12) (2025-11-29)
### Performance Improvements ### Performance Improvements

View File

@@ -1,6 +1,6 @@
{ {
"name": "@certd/ui-client", "name": "@certd/ui-client",
"version": "1.37.12", "version": "1.37.16",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite --open", "dev": "vite --open",
@@ -33,11 +33,11 @@
"@aws-sdk/s3-request-presigner": "^3.535.0", "@aws-sdk/s3-request-presigner": "^3.535.0",
"@certd/vue-js-cron-light": "^4.0.14", "@certd/vue-js-cron-light": "^4.0.14",
"@ctrl/tinycolor": "^4.1.0", "@ctrl/tinycolor": "^4.1.0",
"@fast-crud/editor-code": "^1.27.4", "@fast-crud/editor-code": "^1.27.7",
"@fast-crud/fast-crud": "^1.27.4", "@fast-crud/fast-crud": "^1.27.7",
"@fast-crud/fast-extends": "^1.27.4", "@fast-crud/fast-extends": "^1.27.7",
"@fast-crud/ui-antdv4": "^1.27.4", "@fast-crud/ui-antdv4": "^1.27.7",
"@fast-crud/ui-interface": "^1.27.4", "@fast-crud/ui-interface": "^1.27.7",
"@iconify/tailwind": "^1.2.0", "@iconify/tailwind": "^1.2.0",
"@iconify/vue": "^4.1.1", "@iconify/vue": "^4.1.1",
"@manypkg/get-packages": "^2.2.2", "@manypkg/get-packages": "^2.2.2",
@@ -106,8 +106,8 @@
"zod-defaults": "^0.1.3" "zod-defaults": "^0.1.3"
}, },
"devDependencies": { "devDependencies": {
"@certd/lib-iframe": "^1.37.12", "@certd/lib-iframe": "^1.37.16",
"@certd/pipeline": "^1.37.12", "@certd/pipeline": "^1.37.16",
"@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-node-resolve": "^15.2.3",
"@types/chai": "^4.3.12", "@types/chai": "^4.3.12",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -55,15 +55,39 @@
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib"> <li class="dib">
<span class="icon iconfont">&#xe8fb;</span> <span class="icon iconfont">&#xe60a;</span>
<div class="name">social-foursquare</div> <div class="name">飞牛</div>
<div class="code-name">&amp;#xe8fb;</div> <div class="code-name">&amp;#xe60a;</div>
</li> </li>
<li class="dib"> <li class="dib">
<span class="icon iconfont">&#xe65a;</span> <span class="icon iconfont">&#xe8ad;</span>
<div class="name">ksyun-logo</div> <div class="name">金山云logo</div>
<div class="code-name">&amp;#xe65a;</div> <div class="code-name">&amp;#xe8ad;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe989;</span>
<div class="name">中国移动</div>
<div class="code-name">&amp;#xe989;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe643;</span>
<div class="name">xinnet</div>
<div class="code-name">&amp;#xe643;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe717;</span>
<div class="name">ucloud</div>
<div class="code-name">&amp;#xe717;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe8fb;</span>
<div class="name">social-foursquare</div>
<div class="code-name">&amp;#xe8fb;</div>
</li> </li>
<li class="dib"> <li class="dib">
@@ -228,7 +252,7 @@
<pre><code class="language-css" <pre><code class="language-css"
>@font-face { >@font-face {
font-family: 'iconfont'; font-family: 'iconfont';
src: url('iconfont.svg?t=1754884110189#iconfont') format('svg'); src: url('iconfont.svg?t=1766772710945#iconfont') format('svg');
} }
</code></pre> </code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3> <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -255,23 +279,59 @@
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib"> <li class="dib">
<span class="icon iconfont icon-four"></span> <span class="icon iconfont icon-fnos"></span>
<div class="name"> <div class="name">
social-foursquare 飞牛
</div> </div>
<div class="code-name">.icon-four <div class="code-name">.icon-fnos
</div> </div>
</li> </li>
<li class="dib"> <li class="dib">
<span class="icon iconfont icon-ksyun"></span> <span class="icon iconfont icon-ksyun"></span>
<div class="name"> <div class="name">
ksyun-logo 金山云logo
</div> </div>
<div class="code-name">.icon-ksyun <div class="code-name">.icon-ksyun
</div> </div>
</li> </li>
<li class="dib">
<span class="icon iconfont icon-cmcc"></span>
<div class="name">
中国移动
</div>
<div class="code-name">.icon-cmcc
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-xinnet"></span>
<div class="name">
xinnet
</div>
<div class="code-name">.icon-xinnet
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-ucloud"></span>
<div class="name">
ucloud
</div>
<div class="code-name">.icon-ucloud
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-four"></span>
<div class="name">
social-foursquare
</div>
<div class="code-name">.icon-four
</div>
</li>
<li class="dib"> <li class="dib">
<span class="icon iconfont icon-rainyun"></span> <span class="icon iconfont icon-rainyun"></span>
<div class="name"> <div class="name">
@@ -517,20 +577,52 @@
<li class="dib"> <li class="dib">
<svg class="icon svg-icon" aria-hidden="true"> <svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-four"></use> <use xlink:href="#icon-fnos"></use>
</svg> </svg>
<div class="name">social-foursquare</div> <div class="name">飞牛</div>
<div class="code-name">#icon-four</div> <div class="code-name">#icon-fnos</div>
</li> </li>
<li class="dib"> <li class="dib">
<svg class="icon svg-icon" aria-hidden="true"> <svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-ksyun"></use> <use xlink:href="#icon-ksyun"></use>
</svg> </svg>
<div class="name">ksyun-logo</div> <div class="name">金山云logo</div>
<div class="code-name">#icon-ksyun</div> <div class="code-name">#icon-ksyun</div>
</li> </li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-cmcc"></use>
</svg>
<div class="name">中国移动</div>
<div class="code-name">#icon-cmcc</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-xinnet"></use>
</svg>
<div class="name">xinnet</div>
<div class="code-name">#icon-xinnet</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-ucloud"></use>
</svg>
<div class="name">ucloud</div>
<div class="code-name">#icon-ucloud</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-four"></use>
</svg>
<div class="name">social-foursquare</div>
<div class="code-name">#icon-four</div>
</li>
<li class="dib"> <li class="dib">
<svg class="icon svg-icon" aria-hidden="true"> <svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-rainyun"></use> <use xlink:href="#icon-rainyun"></use>

View File

@@ -1,6 +1,6 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 4688792 */ font-family: "iconfont"; /* Project id 4688792 */
src: url('iconfont.svg?t=1754884110189#iconfont') format('svg'); src: url('iconfont.svg?t=1766772710945#iconfont') format('svg');
} }
.iconfont { .iconfont {
@@ -11,12 +11,28 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-four:before { .icon-fnos:before {
content: "\e8fb"; content: "\e60a";
} }
.icon-ksyun:before { .icon-ksyun:before {
content: "\e65a"; content: "\e8ad";
}
.icon-cmcc:before {
content: "\e989";
}
.icon-xinnet:before {
content: "\e643";
}
.icon-ucloud:before {
content: "\e717";
}
.icon-four:before {
content: "\e8fb";
} }
.icon-rainyun:before { .icon-rainyun:before {

File diff suppressed because one or more lines are too long

View File

@@ -5,6 +5,41 @@
"css_prefix_text": "icon-", "css_prefix_text": "icon-",
"description": "", "description": "",
"glyphs": [ "glyphs": [
{
"icon_id": "45984300",
"name": "飞牛",
"font_class": "fnos",
"unicode": "e60a",
"unicode_decimal": 58890
},
{
"icon_id": "21785199",
"name": "金山云logo",
"font_class": "ksyun",
"unicode": "e8ad",
"unicode_decimal": 59565
},
{
"icon_id": "17262195",
"name": "中国移动",
"font_class": "cmcc",
"unicode": "e989",
"unicode_decimal": 59785
},
{
"icon_id": "3445787",
"name": "xinnet",
"font_class": "xinnet",
"unicode": "e643",
"unicode_decimal": 58947
},
{
"icon_id": "41854093",
"name": "ucloud",
"font_class": "ucloud",
"unicode": "e717",
"unicode_decimal": 59159
},
{ {
"icon_id": "544964", "icon_id": "544964",
"name": "social-foursquare", "name": "social-foursquare",
@@ -12,13 +47,6 @@
"unicode": "e8fb", "unicode": "e8fb",
"unicode_decimal": 59643 "unicode_decimal": 59643
}, },
{
"icon_id": "8567079",
"name": "ksyun-logo",
"font_class": "ksyun",
"unicode": "e65a",
"unicode_decimal": 58970
},
{ {
"icon_id": "42174864", "icon_id": "42174864",
"name": "雨-copy", "name": "雨-copy",

Some files were not shown because too many files have changed in this diff Show More