Compare commits
165 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85f9ef35f6 | ||
|
|
6de220e38a | ||
|
|
0d455d8c2f | ||
|
|
f7b0b44ef6 | ||
|
|
81282a9c88 | ||
|
|
a9b302e38d | ||
|
|
1fe4c367f7 | ||
|
|
2de7583900 | ||
|
|
356703c83e | ||
|
|
1cae709b2b | ||
|
|
46a492248f | ||
|
|
d876ea6711 | ||
|
|
b40b4c3cfd | ||
|
|
44980d6c46 | ||
|
|
442f9647a2 | ||
|
|
a06ef07178 | ||
|
|
0c2ea5da4c | ||
|
|
45814ceb49 | ||
|
|
41f4617e66 | ||
|
|
a463711b03 | ||
|
|
3a147141b1 | ||
|
|
aea1c13bd3 | ||
|
|
9cc4c017ae | ||
|
|
88022747be | ||
|
|
ebb292a2f7 | ||
|
|
818998259d | ||
|
|
36b02c2cec | ||
|
|
e6195ade3e | ||
|
|
231a875bb4 | ||
|
|
378c777a38 | ||
|
|
8ef63916ef | ||
|
|
f32ecdf5f1 | ||
|
|
94739b9b8e | ||
|
|
023db4e04e | ||
|
|
5a4b95f5fe | ||
|
|
b091657b5c | ||
|
|
f7bf5c9328 | ||
|
|
86e521b9aa | ||
|
|
e08cf57b72 | ||
|
|
9e06cb9a83 | ||
|
|
c65e8622b8 | ||
|
|
7795efeb7a | ||
|
|
e725e0020e | ||
|
|
8478ce25f1 | ||
|
|
22cdac6210 | ||
|
|
3422a1a59f | ||
|
|
f807b8cb46 | ||
|
|
e1e510ce1e | ||
|
|
36bc3ff22d | ||
|
|
1db1ffde99 | ||
|
|
7984b625ba | ||
|
|
bb22f062ed | ||
|
|
a3086e6a5b | ||
|
|
1eb9bd34fd | ||
|
|
cff7baaaad | ||
|
|
47af700375 | ||
|
|
eb7f53a1e3 | ||
|
|
d23792fda2 | ||
|
|
b5cbb8e450 | ||
|
|
fc037b4518 | ||
|
|
c04921f42b | ||
|
|
8af3463668 | ||
|
|
094565ccd6 | ||
|
|
07b9769504 | ||
|
|
566b12f5d1 | ||
|
|
a560999d13 | ||
|
|
a818a3d293 | ||
|
|
4d68a174cb | ||
|
|
905219e523 | ||
|
|
c675b87040 | ||
|
|
e2dadfdc40 | ||
|
|
a66f9aa04d | ||
|
|
863e74dd2e | ||
|
|
aebb07c5cc | ||
|
|
677fec0a0b | ||
|
|
61f06faaf5 | ||
|
|
fcf8309c23 | ||
|
|
76b19a4980 | ||
|
|
ed1a9fc7aa | ||
|
|
b71e30755d | ||
|
|
fe196d1b20 | ||
|
|
0b152a3cb8 | ||
|
|
1a0e096ddb | ||
|
|
bf040d4c42 | ||
|
|
3e2101aa5b | ||
|
|
44f11b38e7 | ||
|
|
06f8514bc1 | ||
|
|
d9a9f1c25c | ||
|
|
e77f7244ba | ||
|
|
09779cd1e1 | ||
|
|
11024168db | ||
|
|
304914513e | ||
|
|
03d0efcfc6 | ||
|
|
0c2bdc9146 | ||
|
|
188450b0c0 | ||
|
|
ddf6bbfa46 | ||
|
|
2c7c98a152 | ||
|
|
d31ac75718 | ||
|
|
4b28c659de | ||
|
|
00b937e52a | ||
|
|
68f333fb87 | ||
|
|
085b4d9319 | ||
|
|
b8edd14f39 | ||
|
|
61a19d694b | ||
|
|
aa96859798 | ||
|
|
abf015f485 | ||
|
|
0b9a02afde | ||
|
|
e332ce28f8 | ||
|
|
08e779f9f1 | ||
|
|
a53b6cd28f | ||
|
|
47ebab237b | ||
|
|
5a5af60f97 | ||
|
|
50cc17c7cb | ||
|
|
a1e504c138 | ||
|
|
4cc413047c | ||
|
|
2397097e4d | ||
|
|
c88f959ec9 | ||
|
|
0b2e28b62d | ||
|
|
c7f2ead696 | ||
|
|
b454e02d01 | ||
|
|
47df2ffc3e | ||
|
|
d18e431e2f | ||
|
|
0a147d2db7 | ||
|
|
ccdc933064 | ||
|
|
023f2d4569 | ||
|
|
06a7371d2b | ||
|
|
626f5d3487 | ||
|
|
8cd3b9fe2e | ||
|
|
716c35d52a | ||
|
|
8cc0f3918b | ||
|
|
98b51f0799 | ||
|
|
81d6dad548 | ||
|
|
41bc11cf96 | ||
|
|
721dbe415a | ||
|
|
f5c0b51428 | ||
|
|
892c6ad80c | ||
|
|
a47805e494 | ||
|
|
9dd49054d1 | ||
|
|
f5d1d1a0b7 | ||
|
|
d75fcb7fec | ||
|
|
826be45b6a | ||
|
|
d35d9c17c5 | ||
|
|
f9553e7d44 | ||
|
|
638c9720cf | ||
|
|
08a190882f | ||
|
|
bfa7530a39 | ||
|
|
6c74148c27 | ||
|
|
480cad0fed | ||
|
|
32be489136 | ||
|
|
11801d8e2e | ||
|
|
1b280a2940 | ||
|
|
424890a1e1 | ||
|
|
5f85219495 | ||
|
|
a63d687f1c | ||
|
|
f2d6c3ad83 | ||
|
|
0b6941d5ce | ||
|
|
048696ee93 | ||
|
|
ae51676471 | ||
|
|
27a405fb1d | ||
|
|
e2cf65b591 | ||
|
|
f933fb705c | ||
|
|
918ea59b9a | ||
|
|
b9dab77c8b | ||
|
|
4159534a64 | ||
|
|
d00177a9b6 |
1
.gitignore
vendored
@@ -17,6 +17,7 @@ gen
|
||||
/test/*.private.*
|
||||
|
||||
/*.log
|
||||
nohup.out
|
||||
|
||||
/packages/ui/*/.idea
|
||||
/packages/ui/*/node_modules
|
||||
|
||||
112
CHANGELOG.md
@@ -3,6 +3,118 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.9](https://github.com/certd/certd/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复Farcdn证书有效期错误的问题 ([1fe4c36](https://github.com/certd/certd/commit/1fe4c367f7128de9ba5e3395ae06bc81e63a7d5a))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 不止证书自动化,插件解锁无限可能 ([a9b302e](https://github.com/certd/certd/commit/a9b302e38d3328d75df8b2da3d8b914851e55e9c))
|
||||
* 邮箱支持保存和选择 ([f7b0b44](https://github.com/certd/certd/commit/f7b0b44ef6044bec36510a6f0b06d8dca5bfce49))
|
||||
* 支持github 新版本检查并发布通知 ([356703c](https://github.com/certd/certd/commit/356703c83ea18c6efb8931402e181280d7b7e696))
|
||||
|
||||
## [1.34.8](https://github.com/certd/certd/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 更新 1panel API 版本支持v1/v2设置 ([e6195ad](https://github.com/certd/certd/commit/e6195ade3ec54b138825b8d6738f86eb8afdd720))
|
||||
* 同步更新namesilo接口,修复无法创建和删除dns记录的问题 ([36b02c2](https://github.com/certd/certd/commit/36b02c2cec145c13d4ef29d49aba5b6b4f697df2))
|
||||
* 修复阿里云 esa 证书获取站点列表错误的问题 ([0c2ea5d](https://github.com/certd/certd/commit/0c2ea5da4c836f8a0df132a3f22d399bd9ee1de9))
|
||||
* 修复部署到华为cdn,子账号ak查询不到域名的bug ([ebb292a](https://github.com/certd/certd/commit/ebb292a2f7a425c1bc810f59468beb3f1d5bc3f0))
|
||||
* 修复证书申请任务无法修改dns提供商类型的bug ([8802274](https://github.com/certd/certd/commit/88022747bebe2054223e0241d68d410771405e68))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 关闭腾讯云证书通知提醒 ([231a875](https://github.com/certd/certd/commit/231a875bb481420c39bf76ec9ff4e50954ab9fe4))
|
||||
* 优化站点选择组件,切换选择时不刷新列表 ([3a14714](https://github.com/certd/certd/commit/3a147141b1a5d67c92a5ce88a5313eaa62859e03))
|
||||
* 优化站点ip检查 ([a463711](https://github.com/certd/certd/commit/a463711b03a20120f2a298be15d71ca152d27f21))
|
||||
* 站点监控支持监控IP ([9cc4c01](https://github.com/certd/certd/commit/9cc4c017ae646a18284e732769b82636feda01d3))
|
||||
* 支持批量重新运行 ([8189982](https://github.com/certd/certd/commit/818998259ddc75e722196ac5c365038818539b9b))
|
||||
* farcdn优化 ([a06ef07](https://github.com/certd/certd/commit/a06ef07178ed73c537e21c7d57e5e5144d2c056d))
|
||||
|
||||
## [1.34.7](https://github.com/certd/certd/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化阿里云DCDN插件,支持多选 ([b091657](https://github.com/certd/certd/commit/b091657b5c537acf2442a2bfc345d0a77f5e2c50))
|
||||
* 支持部署到farcdn ([e08cf57](https://github.com/certd/certd/commit/e08cf57b72128998f487ab6469868052fbce0dba))
|
||||
|
||||
## [1.34.6](https://github.com/certd/certd/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复公共插件配置修改不生效的bug,优化系统设置参数注入时机 ([e1e510c](https://github.com/certd/certd/commit/e1e510ce1e37a5ae82478226b6987a83f22d1ecb))
|
||||
* 修复又拍云 CDN 设置证书参数和强制 HTTPS 配置报错的bug ([7984b62](https://github.com/certd/certd/commit/7984b625ba6727132f205db8e25f790bce27b2f7))
|
||||
* 修复lego模式下每次都重新申请证书的bug ([f807b8c](https://github.com/certd/certd/commit/f807b8cb465cc329fa034ecbef94e18ef394f870))
|
||||
* 优化 RunnableError错误信息展示 ([36bc3ff](https://github.com/certd/certd/commit/36bc3ff22da93ba342c3c1103d7ee2bbcecf44f2))
|
||||
* **cert:** 修正证书过期时间计算逻辑 ([a3086e6](https://github.com/certd/certd/commit/a3086e6a5bec8b07f5e1d21a2ca8bd969c75bd5c))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 二次认证页面中,添加动态验证码输入框的焦点控制,提升用户体验 ([bb22f06](https://github.com/certd/certd/commit/bb22f062ed4ab4b5b71938270fe4cc666af6b8e7))
|
||||
* 添加阿里云 ESA证书部署插件 ([1db1ffd](https://github.com/certd/certd/commit/1db1ffde99ac7e4684fa606ebc4c327f829b3a26))
|
||||
* 站点证书监控增加通知设置 ([3422a1a](https://github.com/certd/certd/commit/3422a1a59fd0d2c0f17fa9c7e8988ac527ecfdd9))
|
||||
|
||||
## [1.34.5](https://github.com/certd/certd/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 1panel增加授权测试按钮 ([566b12f](https://github.com/certd/certd/commit/566b12f5d14ce10e8f5cf1807c58f7bf27f0d199))
|
||||
* 优化钉钉通知标题颜色 ([a560999](https://github.com/certd/certd/commit/a560999d13eed18d08dd32ee530166569e3f8746))
|
||||
* 优化飞书通知为卡片模式 ([a818a3d](https://github.com/certd/certd/commit/a818a3d293e22fb46979bc77055c05621a6fed81))
|
||||
* 支持部署到宝塔aaWAF ([094565c](https://github.com/certd/certd/commit/094565ccd619ef671c6c11ce5fb7fd54a7a21d1c))
|
||||
* aaWaf、cdnfly站点选择支持查询 ([8af3463](https://github.com/certd/certd/commit/8af3463668a40b9b99febb02e3b4e0d9d8d719b4))
|
||||
|
||||
## [1.34.4](https://github.com/certd/certd/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复部署flexcdn问题 ([76b19a4](https://github.com/certd/certd/commit/76b19a4980f8edba5238543b82a7811e1003746c))
|
||||
* 修复插件导入的bug ([677fec0](https://github.com/certd/certd/commit/677fec0a0b6fceb4966705e471bbfeeda91610c7))
|
||||
* 修复导入在线插件不生效的bug ([fcf8309](https://github.com/certd/certd/commit/fcf8309c238208281ecb4575b2c3cfe50c11d783))
|
||||
* 修复自建插件保存丢失部署策略的bug ([863e74d](https://github.com/certd/certd/commit/863e74dd2e3912f950ff5025b5ed0070aeb37035))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 调整小助手,仅在登录之后显示 ([aebb07c](https://github.com/certd/certd/commit/aebb07c5cc8b1f233b9d203ff017ac60e6971a85))
|
||||
|
||||
## [1.34.3](https://github.com/certd/certd/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 宝塔插件、1panel 改成完全免费版 ([a53b6cd](https://github.com/certd/certd/commit/a53b6cd28ff2ce5662ada82379ea44a06b179b81))
|
||||
* 添加 FlexCDN 更新证书插件 ([bf040d4](https://github.com/certd/certd/commit/bf040d4c428d29c06fbaca5e29100e0c583b2b0b))
|
||||
* 小助手可以关闭 ([3e2101a](https://github.com/certd/certd/commit/3e2101aa5b56548614102e900d59819ce8c7e97c))
|
||||
* 支持部署到maoyun cdn ([68f333f](https://github.com/certd/certd/commit/68f333fb87ce85eed27436ecb0f76351c0ccb0d1))
|
||||
* 支持AI分析报错 ([aa96859](https://github.com/certd/certd/commit/aa96859798166426e485947a6590464de189de05))
|
||||
|
||||
## [1.34.2](https://github.com/certd/certd/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复部署到又拍云强制https无效的bug ([2397097](https://github.com/certd/certd/commit/2397097e4ddcb6f593210598e8779ffd44ac3f8f))
|
||||
* 修复刷新流水线页面后,日志不自动更新的bug ([0b2e28b](https://github.com/certd/certd/commit/0b2e28b62dd5eb6804c602083e65c87a9d1d72d2))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 集成智能问答机器人 ([9dd4905](https://github.com/certd/certd/commit/9dd49054d18ec436a5029444ca55a38adc682933))
|
||||
* 支持设置网安备案号 ([d18e431](https://github.com/certd/certd/commit/d18e431e2f08e6b37704032c4ea6fbdd8e971442))
|
||||
* http方式支持校验443端口 ([d75fcb7](https://github.com/certd/certd/commit/d75fcb7fec421a9a638eaa27fe9378c84b5e0f19))
|
||||
|
||||
## [1.34.1](https://github.com/certd/certd/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 根据SOA记录判断子域名托管有缺陷,改回手动配置子域名托管记录的方式 ([1b280a2](https://github.com/certd/certd/commit/1b280a2940f9e2d919b0bf23b89cc185be1fa498))
|
||||
* 修复宝塔授权测试按钮显示错误的bug ([048696e](https://github.com/certd/certd/commit/048696ee9386491bb68592fb3a47d1c900bb68bf))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持部署证书到火山dcdn ([5f85219](https://github.com/certd/certd/commit/5f852194953dc1b4e6336770f417507b8f5a33ad))
|
||||
* 支持部署证书到unicloud ([a63d687](https://github.com/certd/certd/commit/a63d687f1c573159f0857693f37602b0e1e44072))
|
||||
|
||||
# [1.34.0](https://github.com/certd/certd/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
50
README.md
@@ -5,28 +5,35 @@ Certd 是一个免费全自动申请和自动部署更新SSL证书的管理系
|
||||
|
||||
关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具
|
||||
|
||||
> 关于证书续期:
|
||||
>* 实际上没有办法不改变证书文件本身情况下直接续期或者续签。
|
||||
>* 我们所说的续期,其实就是按照全套流程重新申请一份新证书,然后重新部署上去。
|
||||
>* 免费证书过期时间90天,以后可能还会缩短,所以自动化部署必不可少
|
||||
|
||||
|
||||
> 流水线数量现已调整为无限制,欢迎大家使用
|
||||
|
||||
## 一、特性
|
||||
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
||||
|
||||
* 全自动申请证书(支持所有注册商注册的域名)
|
||||
* 全自动申请证书(支持所有注册商注册的域名,支持DNS-01、HTTP-01、CNAME代理等多种域名验证方式)
|
||||
* 全自动部署更新证书(目前支持部署到主机、阿里云、腾讯云等70+部署插件)
|
||||
* 支持DNS-01、HTTP-01、CNAME代理等多种域名验证方式
|
||||
* 支持通配符域名/泛域名,支持多个域名打到一个证书上,支持pem、pfx、der、jks等多种证书格式
|
||||
* 邮件通知、webhook通知
|
||||
* 私有化部署,数据保存本地,授权信息加密存储,镜像由Github Actions构建,过程公开透明
|
||||
* 支持SQLite,PostgreSQL、MySQL数据库
|
||||
* 邮件通知、webhook通知、企微、钉钉、飞书、anpush等多种通知方式
|
||||
* 私有化部署,数据保存本地,安装升级非常简单快捷
|
||||
* 镜像由Github Actions构建,过程公开透明
|
||||
* 授权加密,站点隐藏,2FA,密码防爆破等多重安全保障
|
||||
* 支持SQLite,PostgreSQL、MySQL多种数据库
|
||||
* 开放接口支持
|
||||
* 站点证书监控
|
||||
* 多用户管理
|
||||
|
||||
|
||||

|
||||
|
||||
>
|
||||
> 流水线数量现已调整为无限制,欢迎大家使用
|
||||
>
|
||||
|
||||
> 关于证书续期:
|
||||
>* 实际上没有办法不改变证书文件本身情况下直接续期或者续签。
|
||||
>* 我们所说的续期,其实就是按照全套流程重新申请一份新证书,然后重新部署上去。
|
||||
>* 免费证书过期时间90天,以后可能还会缩短,所以自动化部署必不可少
|
||||
|
||||
|
||||
|
||||
## 二、在线体验
|
||||
|
||||
@@ -103,8 +110,7 @@ https://certd.handfree.work/
|
||||
> * 请务必使用web应用防火墙防护本应用,防止XSS、SQL注入等攻击
|
||||
> * 请务必做好服务器本身的安全防护,防止数据库泄露
|
||||
> * 请务必做好数据备份,避免数据丢失
|
||||
|
||||
|
||||
> * [更多安全生产建议点我](https://certd.docmirror.cn/guide/feature/safe/)
|
||||
|
||||
|
||||
## 五、更多帮助
|
||||
@@ -143,14 +149,14 @@ https://afdian.com/a/greper
|
||||
|
||||
专业版特权对比
|
||||
|
||||
| 功能 | 免费版 | 专业版 |
|
||||
|---------|--------------------|-----------------------------|
|
||||
| 免费证书申请 | 免费无限制 | 免费无限制 |
|
||||
| 域名数量 | 无限制 | 无限制 |
|
||||
| 证书流水线条数 | 无限制 | 无限制 |
|
||||
| 站点证书监控 | 限制1条 | 无限制 |
|
||||
| 自动部署插件 | 阿里云CDN、腾讯云、七牛CDN、主机部署等 | 支持群晖、宝塔、1Panel等,持续开发中 |
|
||||
| 通知 | 邮件通知、自定义webhook | 邮件免配置、企微、飞书、anpush、server酱等 |
|
||||
| 功能 | 免费版 | 专业版 |
|
||||
|---------|---------------------------------------|--------------------------------|
|
||||
| 免费证书申请 | 免费无限制 | 免费无限制 |
|
||||
| 域名数量 | 无限制 | 无限制 |
|
||||
| 证书流水线条数 | 无限制 | 无限制 |
|
||||
| 站点证书监控 | 限制1条 | 无限制 |
|
||||
| 自动部署插件 | 阿里云CDN、腾讯云、七牛CDN、主机部署、宝塔、1Panel等大部分插件 | 群晖 |
|
||||
| 通知 | 邮件通知、自定义webhook | 邮件免配置、企微、钉钉、飞书、anpush、server酱等 |
|
||||
|
||||
|
||||
************************
|
||||
|
||||
@@ -1 +1 @@
|
||||
01:58
|
||||
23:14
|
||||
|
||||
@@ -3,6 +3,8 @@ services:
|
||||
certd:
|
||||
# 镜像 # ↓↓↓↓↓ ---- 镜像版本号,建议改成固定版本号,例如:certd:1.29.0
|
||||
image: registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest
|
||||
# image: ghcr.io/certd/certd:latest # --------- 如果 报镜像not found,可以尝试其他镜像源
|
||||
# image: greper/certd:latest
|
||||
container_name: certd # 容器名
|
||||
restart: unless-stopped # 自动重启
|
||||
volumes:
|
||||
@@ -14,7 +16,7 @@ services:
|
||||
- "7001:7001"
|
||||
# ↓↓↓↓ ---------------------------------------------------------- https端口,可以根据实际情况,是否暴露该端口
|
||||
- "7002:7002"
|
||||
#↓↓↓↓ -------------------------------------------------------------- 如果出现getaddrinfo ENOTFOUND错误,可以尝试设置dns
|
||||
#↓↓↓↓ -------------------------------------------------------------- 如果出现getaddrinfo EAI_AGAIN 或 getaddrinfo ENOTFOUND 错误,可以尝试设置dns
|
||||
# dns:
|
||||
# - 223.5.5.5 # 阿里云公共dns
|
||||
# - 223.6.6.6
|
||||
@@ -35,6 +37,8 @@ services:
|
||||
# networks:
|
||||
# - ip6net
|
||||
environment:
|
||||
# ↓↓↓↓ ----------------------------------------------------- 使用上海东八时区
|
||||
# - TZ=Asia/Shanghai
|
||||
# 设置环境变量即可自定义certd配置
|
||||
# 配置项见: packages/ui/certd-server/src/config/config.default.ts
|
||||
# 配置规则: certd_ + 配置项, 点号用_代替
|
||||
|
||||
@@ -88,22 +88,26 @@ export default defineConfig({
|
||||
text: "特性",
|
||||
items: [
|
||||
{text: "CNAME代理校验", link: "/guide/feature/cname/index.md"},
|
||||
{text: "插件列表", link: "/guide/plugins.md"},
|
||||
{text: "多数据库支持", link: "/guide/install/database.md"},
|
||||
{text: "开放接口", link: "/guide/open/index.md"},
|
||||
{
|
||||
text: "站点安全", items: [
|
||||
{text: "安全特性", link: "/guide/feature/safe"},
|
||||
{text: "站点隐藏", link: "/guide/feature/safe/hidden"},
|
||||
{text: "安全生产建议", link: "/guide/feature/safe/suggest"},
|
||||
text: "站点安全", link: "/guide/feature/safe/"
|
||||
},
|
||||
{
|
||||
text: "插件列表", items: [
|
||||
{text: "授权提供商", link: "/guide/plugins/access.md"},
|
||||
{text: "DNS提供商", link: "/guide/plugins/dns-provider.md"},
|
||||
{text: "任务插件", link: "/guide/plugins/deploy.md"},
|
||||
{text: "通知插件", link: "/guide/plugins/notification.md"},
|
||||
]
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "常见问题",
|
||||
items: [
|
||||
{text: "QA", link: "/guide/qa/use.md"},
|
||||
{text: "常见报错处理", link: "/guide/qa/"},
|
||||
{text: "群晖证书部署", link: "/guide/use/synology/"},
|
||||
{text: "腾讯云密钥获取", link: "/guide/use/tencent/"},
|
||||
{text: "连接windows主机", link: "/guide/use/host/windows.md"},
|
||||
@@ -115,8 +119,14 @@ export default defineConfig({
|
||||
{text: "js脚本插件使用", link: "/guide/use/custom-script/index.md"},
|
||||
{text: "邮箱配置", link: "/guide/use/email/index.md"},
|
||||
{text: "IPv6支持", link: "/guide/use/setting/ipv6.md"},
|
||||
{text: "其他插件使用", link: "/deploy/"},
|
||||
{text: "商业版说明", link: "/comm/"},
|
||||
{text: "ESXi", link: "/guide/use/ESXi/index.md"},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "商业版配置", link: "/guide/use/comm/", items: [
|
||||
{text: "支付宝配置", link: "/guide/use/comm/payments/alipay.md"},
|
||||
{text: "微信支付配置", link: "/guide/use/comm/payments/wxpay.md"},
|
||||
{text: "彩虹易支付配置", link: "/guide/use/comm/payments/yizhifu.md"},
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -129,30 +139,9 @@ export default defineConfig({
|
||||
{text: "捐赠", link: "/guide/donate/"},
|
||||
{text: "开源协议", link: "/guide/license/"},
|
||||
{text: "我的其他开源项目", link: "/guide/link/"},
|
||||
|
||||
]
|
||||
}
|
||||
],
|
||||
"/deploy/": [
|
||||
{
|
||||
text: "部署证书插件",
|
||||
items: [
|
||||
{text: "插件说明", link: "/deploy/index.md"},
|
||||
{text: "部署到ESXi", link: "/deploy/ESXi/index.md"},
|
||||
]
|
||||
}
|
||||
],
|
||||
"/comm/": [
|
||||
{
|
||||
text: "商业版",
|
||||
items: [
|
||||
{text: "支付宝配置", link: "/comm/payments/alipay.md"},
|
||||
{text: "微信支付配置", link: "/comm/payments/wxpay.md"},
|
||||
{text: "彩虹易支付配置", link: "/comm/payments/yizhifu.md"},
|
||||
]
|
||||
}
|
||||
]
|
||||
,
|
||||
},
|
||||
|
||||
socialLinks: [
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
# 部署插件说明
|
||||
|
||||
## 待完善
|
||||
|
||||
@@ -3,6 +3,120 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.8](https://github.com/certd/certd/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 更新 1panel API 版本支持v1/v2设置 ([e6195ad](https://github.com/certd/certd/commit/e6195ade3ec54b138825b8d6738f86eb8afdd720))
|
||||
* 同步更新namesilo接口,修复无法创建和删除dns记录的问题 ([36b02c2](https://github.com/certd/certd/commit/36b02c2cec145c13d4ef29d49aba5b6b4f697df2))
|
||||
* 修复阿里云 esa 证书获取站点列表错误的问题 ([0c2ea5d](https://github.com/certd/certd/commit/0c2ea5da4c836f8a0df132a3f22d399bd9ee1de9))
|
||||
* 修复部署到华为cdn,子账号ak查询不到域名的bug ([ebb292a](https://github.com/certd/certd/commit/ebb292a2f7a425c1bc810f59468beb3f1d5bc3f0))
|
||||
* 修复证书申请任务无法修改dns提供商类型的bug ([8802274](https://github.com/certd/certd/commit/88022747bebe2054223e0241d68d410771405e68))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 关闭腾讯云证书通知提醒 ([231a875](https://github.com/certd/certd/commit/231a875bb481420c39bf76ec9ff4e50954ab9fe4))
|
||||
* 优化站点选择组件,切换选择时不刷新列表 ([3a14714](https://github.com/certd/certd/commit/3a147141b1a5d67c92a5ce88a5313eaa62859e03))
|
||||
* 优化站点ip检查 ([a463711](https://github.com/certd/certd/commit/a463711b03a20120f2a298be15d71ca152d27f21))
|
||||
* 站点监控支持监控IP ([9cc4c01](https://github.com/certd/certd/commit/9cc4c017ae646a18284e732769b82636feda01d3))
|
||||
* 支持批量重新运行 ([8189982](https://github.com/certd/certd/commit/818998259ddc75e722196ac5c365038818539b9b))
|
||||
* farcdn优化 ([a06ef07](https://github.com/certd/certd/commit/a06ef07178ed73c537e21c7d57e5e5144d2c056d))
|
||||
|
||||
## [1.34.7](https://github.com/certd/certd/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化阿里云DCDN插件,支持多选 ([b091657](https://github.com/certd/certd/commit/b091657b5c537acf2442a2bfc345d0a77f5e2c50))
|
||||
* 支持部署到farcdn ([e08cf57](https://github.com/certd/certd/commit/e08cf57b72128998f487ab6469868052fbce0dba))
|
||||
|
||||
## [1.34.6](https://github.com/certd/certd/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复公共插件配置修改不生效的bug,优化系统设置参数注入时机 ([e1e510c](https://github.com/certd/certd/commit/e1e510ce1e37a5ae82478226b6987a83f22d1ecb))
|
||||
* 修复又拍云 CDN 设置证书参数和强制 HTTPS 配置报错的bug ([7984b62](https://github.com/certd/certd/commit/7984b625ba6727132f205db8e25f790bce27b2f7))
|
||||
* 修复lego模式下每次都重新申请证书的bug ([f807b8c](https://github.com/certd/certd/commit/f807b8cb465cc329fa034ecbef94e18ef394f870))
|
||||
* 优化 RunnableError错误信息展示 ([36bc3ff](https://github.com/certd/certd/commit/36bc3ff22da93ba342c3c1103d7ee2bbcecf44f2))
|
||||
* **cert:** 修正证书过期时间计算逻辑 ([a3086e6](https://github.com/certd/certd/commit/a3086e6a5bec8b07f5e1d21a2ca8bd969c75bd5c))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 二次认证页面中,添加动态验证码输入框的焦点控制,提升用户体验 ([bb22f06](https://github.com/certd/certd/commit/bb22f062ed4ab4b5b71938270fe4cc666af6b8e7))
|
||||
* 添加阿里云 ESA证书部署插件 ([1db1ffd](https://github.com/certd/certd/commit/1db1ffde99ac7e4684fa606ebc4c327f829b3a26))
|
||||
* 站点证书监控增加通知设置 ([3422a1a](https://github.com/certd/certd/commit/3422a1a59fd0d2c0f17fa9c7e8988ac527ecfdd9))
|
||||
|
||||
## [1.34.5](https://github.com/certd/certd/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 1panel增加授权测试按钮 ([566b12f](https://github.com/certd/certd/commit/566b12f5d14ce10e8f5cf1807c58f7bf27f0d199))
|
||||
* 优化钉钉通知标题颜色 ([a560999](https://github.com/certd/certd/commit/a560999d13eed18d08dd32ee530166569e3f8746))
|
||||
* 优化飞书通知为卡片模式 ([a818a3d](https://github.com/certd/certd/commit/a818a3d293e22fb46979bc77055c05621a6fed81))
|
||||
* 支持部署到宝塔aaWAF ([094565c](https://github.com/certd/certd/commit/094565ccd619ef671c6c11ce5fb7fd54a7a21d1c))
|
||||
* aaWaf、cdnfly站点选择支持查询 ([8af3463](https://github.com/certd/certd/commit/8af3463668a40b9b99febb02e3b4e0d9d8d719b4))
|
||||
|
||||
## [1.34.4](https://github.com/certd/certd/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复部署flexcdn问题 ([76b19a4](https://github.com/certd/certd/commit/76b19a4980f8edba5238543b82a7811e1003746c))
|
||||
* 修复插件导入的bug ([677fec0](https://github.com/certd/certd/commit/677fec0a0b6fceb4966705e471bbfeeda91610c7))
|
||||
* 修复导入在线插件不生效的bug ([fcf8309](https://github.com/certd/certd/commit/fcf8309c238208281ecb4575b2c3cfe50c11d783))
|
||||
* 修复自建插件保存丢失部署策略的bug ([863e74d](https://github.com/certd/certd/commit/863e74dd2e3912f950ff5025b5ed0070aeb37035))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 调整小助手,仅在登录之后显示 ([aebb07c](https://github.com/certd/certd/commit/aebb07c5cc8b1f233b9d203ff017ac60e6971a85))
|
||||
|
||||
## [1.34.3](https://github.com/certd/certd/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 宝塔插件、1panel 改成完全免费版 ([a53b6cd](https://github.com/certd/certd/commit/a53b6cd28ff2ce5662ada82379ea44a06b179b81))
|
||||
* 添加 FlexCDN 更新证书插件 ([bf040d4](https://github.com/certd/certd/commit/bf040d4c428d29c06fbaca5e29100e0c583b2b0b))
|
||||
* 小助手可以关闭 ([3e2101a](https://github.com/certd/certd/commit/3e2101aa5b56548614102e900d59819ce8c7e97c))
|
||||
* 支持部署到maoyun cdn ([68f333f](https://github.com/certd/certd/commit/68f333fb87ce85eed27436ecb0f76351c0ccb0d1))
|
||||
* 支持AI分析报错 ([aa96859](https://github.com/certd/certd/commit/aa96859798166426e485947a6590464de189de05))
|
||||
|
||||
## [1.34.2](https://github.com/certd/certd/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复部署到又拍云强制https无效的bug ([2397097](https://github.com/certd/certd/commit/2397097e4ddcb6f593210598e8779ffd44ac3f8f))
|
||||
* 修复刷新流水线页面后,日志不自动更新的bug ([0b2e28b](https://github.com/certd/certd/commit/0b2e28b62dd5eb6804c602083e65c87a9d1d72d2))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 集成智能问答机器人 ([9dd4905](https://github.com/certd/certd/commit/9dd49054d18ec436a5029444ca55a38adc682933))
|
||||
* 支持设置网安备案号 ([d18e431](https://github.com/certd/certd/commit/d18e431e2f08e6b37704032c4ea6fbdd8e971442))
|
||||
* http方式支持校验443端口 ([d75fcb7](https://github.com/certd/certd/commit/d75fcb7fec421a9a638eaa27fe9378c84b5e0f19))
|
||||
|
||||
## [1.34.1](https://github.com/certd/certd/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 根据SOA记录判断子域名托管有缺陷,改回手动配置子域名托管记录的方式 ([1b280a2](https://github.com/certd/certd/commit/1b280a2940f9e2d919b0bf23b89cc185be1fa498))
|
||||
* 修复宝塔授权测试按钮显示错误的bug ([048696e](https://github.com/certd/certd/commit/048696ee9386491bb68592fb3a47d1c900bb68bf))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持部署证书到火山dcdn ([5f85219](https://github.com/certd/certd/commit/5f852194953dc1b4e6336770f417507b8f5a33ad))
|
||||
* 支持部署证书到unicloud ([a63d687](https://github.com/certd/certd/commit/a63d687f1c573159f0857693f37602b0e1e44072))
|
||||
|
||||
# [1.34.0](https://github.com/certd/certd/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复二次认证登录进入错误账号的bug ([e3930e0](https://github.com/certd/certd/commit/e3930e07172dd7903cb0f6ff26e0e3e828ba3e77))
|
||||
|
||||
### Features
|
||||
|
||||
* 从yaml文件注册插件 ([deb3893](https://github.com/certd/certd/commit/deb38938204b29543f36d3266249958faaaa6b66))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化cdnfly插件,支持自动匹配域名部署 ([afd59e9](https://github.com/certd/certd/commit/afd59e9933b2650f41c5d47684c171b93b962065))
|
||||
|
||||
## [1.33.8](https://github.com/certd/certd/compare/v1.33.7...v1.33.8) (2025-04-26)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
88
docs/guide/development/demo/access.md
Normal file
@@ -0,0 +1,88 @@
|
||||
|
||||
# 授权插件Demo
|
||||
|
||||
```ts
|
||||
import { AccessInput, BaseAccess, IsAccess } from '@certd/pipeline';
|
||||
import { isDev } from '../../utils/env.js';
|
||||
|
||||
/**
|
||||
* 这个注解将注册一个授权配置
|
||||
* 在certd的后台管理系统中,用户可以选择添加此类型的授权
|
||||
*/
|
||||
@IsAccess({
|
||||
name: 'demo',
|
||||
title: '授权插件示例',
|
||||
icon: 'clarity:plugin-line',
|
||||
desc: '',
|
||||
})
|
||||
export class DemoAccess extends BaseAccess {
|
||||
/**
|
||||
* 授权属性配置
|
||||
*/
|
||||
@AccessInput({
|
||||
title: '密钥Id',
|
||||
component: {
|
||||
placeholder: 'demoKeyId',
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
demoKeyId = '';
|
||||
|
||||
/**
|
||||
* 授权属性配置
|
||||
*/
|
||||
@AccessInput({
|
||||
//标题
|
||||
title: '密钥串',
|
||||
component: {
|
||||
//input组件的placeholder
|
||||
placeholder: 'demoKeySecret',
|
||||
},
|
||||
//是否必填
|
||||
required: true,
|
||||
//改属性是否需要加密
|
||||
encrypt: true,
|
||||
})
|
||||
//属性名称
|
||||
demoKeySecret = '';
|
||||
}
|
||||
new DemoAccess();
|
||||
```
|
||||
|
||||
|
||||
# 阿里云授权
|
||||
```ts
|
||||
|
||||
import { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline";
|
||||
|
||||
@IsAccess({
|
||||
name: "aliyun",
|
||||
title: "阿里云授权",
|
||||
desc: "",
|
||||
icon: "ant-design:aliyun-outlined",
|
||||
order: 0,
|
||||
})
|
||||
export class AliyunAccess extends BaseAccess {
|
||||
@AccessInput({
|
||||
title: "accessKeyId",
|
||||
component: {
|
||||
placeholder: "accessKeyId",
|
||||
},
|
||||
helper: "登录阿里云控制台->AccessKey管理页面获取。",
|
||||
required: true,
|
||||
})
|
||||
accessKeyId = "";
|
||||
@AccessInput({
|
||||
title: "accessKeySecret",
|
||||
component: {
|
||||
placeholder: "accessKeySecret",
|
||||
},
|
||||
required: true,
|
||||
encrypt: true,
|
||||
helper: "注意:证书申请需要dns解析权限;其他阿里云插件,需要对应的权限,比如证书上传需要证书管理权限;嫌麻烦就用主账号的全量权限的accessKey",
|
||||
})
|
||||
accessKeySecret = "";
|
||||
}
|
||||
|
||||
new AliyunAccess();
|
||||
```
|
||||
@@ -22,4 +22,6 @@
|
||||

|
||||
|
||||
## 3、忘记解除地址和解除密码怎么办
|
||||
登录服务器,在数据库平级的目录下创建`.unhidden`文件即可`临时解除`站点隐藏
|
||||
登录服务器,在数据库平级的目录下创建`.unhidden`命名的空白文件,即可临时解除站点隐藏
|
||||
临时解除后会自动删除`.unhidden`文件,请尽快设置好新的`解除地址`和`解除密码`,并记住
|
||||
|
||||
|
||||
@@ -1,36 +1,49 @@
|
||||
# 站点安全特性
|
||||
# 安全特性
|
||||
|
||||
Certd 存储了证书以及授权等敏感数据,所以需要严格保障安全。
|
||||
我们非常重视您的数据安全,提供了以下安全特性
|
||||
Certd 存储了证书以及授权等敏感数据,所以需要严格保障安全。
|
||||
我们提供了以下安全特性,以及安全生产建议(请遵照建议进行生产部署以保障数据安全)
|
||||
|
||||
## 1、 授权数据加密存储【默认开启】
|
||||
## 一、站点安全特性
|
||||
|
||||
### 1、 授权数据加密存储【默认开启】
|
||||
* 所有的授权敏感字段会加密后存储
|
||||
* 每个用户独立维护授权数据,连管理员都无权查看
|
||||
|
||||

|
||||
星号部分为加密数据
|
||||
|
||||
## 2、 密码防爆破【默认开启】
|
||||
### 2、 密码防爆破【默认开启】
|
||||
* 登录失败次数过多,账号将被锁定,最高24小时(重启服务可解除锁定)
|
||||
* 用户登录密码加密hash后存储,无法计算出密码明文
|
||||

|
||||
|
||||
## 3、站点隐藏【建议开启】
|
||||
### 3、站点隐藏【建议开启】
|
||||
* 一般来说Certd设置好之后,后续很少需要访问修改。
|
||||
* 所以我们平时可以把站点访问关闭,需要的时候再打开,减少站点被攻击的风险
|
||||
* 请前往 `系统管理->系统设置->安全设置->开启站点隐藏`
|
||||
* [站点隐藏设置说明](./hidden/)
|
||||

|
||||
|
||||
## 4、登录双重验证
|
||||
点击查看 [站点隐藏功能详细使用说明](./hidden/)
|
||||
|
||||
|
||||
### 4、登录双重验证
|
||||
|
||||
支持2FA双重认证
|
||||
|
||||

|
||||
|
||||
## 5、数据库自动备份【建议开启】
|
||||
### 5、数据库自动备份【建议开启】
|
||||
* [自动备份设置说明](../../use/backup/)
|
||||
|
||||
|
||||
## 更多安全生产建议
|
||||
[安全生产建议](./suggest.md)
|
||||
## 二、安全生产建议
|
||||
|
||||
尽管`Cert`本身实现了很多安全特性,但`外部环境的安全`仍需要您来确保。
|
||||
请`务必`遵循如下建议做好安全防护
|
||||
|
||||
* 请`务必`使用`HTTPS协议`访问本应用,避免被中间人攻击
|
||||
* 请`务必`使用`web应用防火墙`防护本应用,防止XSS、SQL注入等攻击
|
||||
* 请`务必`做好`服务器本身`的安全防护,防止数据库泄露
|
||||
* 请`务必`做好[`数据备份`](../../use/backup/),避免数据丢失
|
||||
* 请`务必`修改管理员账号用户名,且建议将admin注册为普通用户,且设置为禁用。
|
||||
* 建议开启[`站点隐藏`](./hidden/)功能
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# 安全生产建议
|
||||
|
||||
尽管`Cert`本身实现了很多安全特性,但`外部环境的安全`仍需要您来确保。
|
||||
请`务必`遵循如下建议做好安全防护
|
||||
|
||||
* 请`务必`使用`HTTPS协议`访问本应用,避免被中间人攻击
|
||||
* 请`务必`使用`web应用防火墙`防护本应用,防止XSS、SQL注入等攻击
|
||||
* 请`务必`做好`服务器本身`的安全防护,防止数据库泄露
|
||||
* 请`务必`做好[`数据备份`](../../use/backup/),避免数据丢失
|
||||
* 建议开启[`站点隐藏`](./hidden/)功能
|
||||
@@ -5,32 +5,28 @@ Certd 是一款开源、免费、全自动申请和部署更新SSL证书的工
|
||||
|
||||
关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具
|
||||
|
||||
## 1、关于证书续期
|
||||
>* 实际上没有办法不改变证书文件本身情况下直接续期或者续签。
|
||||
>* 我们所说的续期,其实就是按照全套流程重新申请一份新证书,然后重新部署上去。
|
||||
>* 免费证书过期时间90天,以后可能还会缩短,所以自动化部署必不可少
|
||||
|
||||
## 一、特性
|
||||
|
||||
## 2、项目特性
|
||||
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
||||
|
||||
* 全自动申请证书(支持所有注册商注册的域名)
|
||||
* 全自动部署更新证书(目前支持部署到主机、部署到阿里云、腾讯云等,目前已支持60+部署插件)
|
||||
* 支持通配符域名/泛域名,支持多个域名打到一个证书上
|
||||
* 邮件通知
|
||||
* 私有化部署,保障数据安全
|
||||
* 支持SQLite、Postgresql、MySQL数据库
|
||||
* 全自动申请证书(支持所有注册商注册的域名,支持DNS-01、HTTP-01、CNAME代理等多种域名验证方式)
|
||||
* 全自动部署更新证书(目前支持部署到主机、阿里云、腾讯云等70+部署插件)
|
||||
* 支持通配符域名/泛域名,支持多个域名打到一个证书上,支持pem、pfx、der、jks等多种证书格式
|
||||
* 邮件通知、webhook通知、企微、钉钉、飞书、anpush等多种通知方式
|
||||
* 私有化部署,数据保存本地,安装升级非常简单快捷
|
||||
* 镜像由Github Actions构建,过程公开透明
|
||||
* 授权加密,站点隐藏,2FA,密码防爆破等多重安全保障
|
||||
* 支持SQLite,PostgreSQL、MySQL多种数据库
|
||||
* 开放接口支持
|
||||
* 站点证书监控
|
||||
* 多用户管理
|
||||
|
||||
|
||||

|
||||
|
||||
## 二、一些说明
|
||||
* 本项目申请证书过程遵循acme协议
|
||||
* 需要验证域名所有权,一般有两种方式
|
||||
* http-01: 在网站根目录下放置一份txt文件
|
||||
* dns-01: 需要给域名添加txt解析记录,通配符域名只能用这种方式(本项目仅支持dns-01)
|
||||
* 证书续期:
|
||||
* 实际上没有办法不改变证书文件本身情况下直接续期或者续签。
|
||||
* 我们所说的续期,其实就是按照全套流程重新申请一份新证书,然后重新部署上去。
|
||||
* 免费证书过期时间90天,以后可能还会缩短,所以自动化部署必不可少
|
||||
* 设置每天自动运行,当证书过期前35天,会自动重新申请证书并部署
|
||||
|
||||
## 三、证书颁发机构对比
|
||||
* Let's Encrypt:申请最简单。
|
||||
* Google: 大厂光环,兼容性好,首次需要翻墙获取EAB。
|
||||
* ZeroSSL: 需要EAB,获取EAB无需翻墙。
|
||||
@@ -1,5 +1,6 @@
|
||||
# 源码部署
|
||||
如果没有`git`和`nodejs`基础,则不推荐
|
||||
如果没有开发基础、没有运维基础、没有`git`和`nodejs`基础,强烈不推荐此方式
|
||||
|
||||
## 一、源码安装
|
||||
|
||||
### 环境要求
|
||||
@@ -42,8 +43,8 @@ git pull
|
||||
kill -9 $(lsof -t -i:7001)
|
||||
# 重新编译启动
|
||||
./start.sh
|
||||
```
|
||||
|
||||
```
|
||||
::: warning
|
||||
升级certd版本前,切记切记先备份一下数据
|
||||
:::
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# 插件列表
|
||||
|
||||

|
||||
|
||||
|
||||
58
docs/guide/plugins/access.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# 授权列表
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **阿里云授权** | |
|
||||
| 2.| **EAB授权** | ZeroSSL证书申请需要EAB授权 |
|
||||
| 3.| **google cloud** | 谷歌云授权 |
|
||||
| 4.| **主机登录授权** | |
|
||||
| 5.| **SFTP授权** | |
|
||||
| 6.| **阿里云OSS授权** | 包含地域和Bucket |
|
||||
| 7.| **FTP授权** | |
|
||||
| 8.| **腾讯云** | |
|
||||
| 9.| **腾讯云COS授权** | 腾讯云对象存储授权,包含地域和存储桶 |
|
||||
| 10.| **七牛云授权** | |
|
||||
| 11.| **七牛OSS授权** | |
|
||||
| 12.| **天翼云授权** | |
|
||||
| 13.| **s3/minio授权** | S3/minio oss授权 |
|
||||
| 14.| **baota授权** | |
|
||||
| 15.| **易盾DCDN授权** | https://user.yiduncdn.com |
|
||||
| 16.| **易盾rcdn授权** | 易盾CDN,每月免费30G,[注册即领](https://rhcdn.yiduncdn.com/register?code=8mn536rrzfbf8) |
|
||||
| 17.| **易发云短信** | sms.yfyidc.cn/ |
|
||||
| 18.| **cdnfly授权** | |
|
||||
| 19.| **群晖登录授权** | |
|
||||
| 20.| **k8s授权** | |
|
||||
| 21.| **1panel授权** | 账号和密码 |
|
||||
| 22.| **百度云授权** | |
|
||||
| 23.| **LeCDN授权** | |
|
||||
| 24.| **白山云授权** | |
|
||||
| 25.| **plesk授权** | |
|
||||
| 26.| **易支付** | |
|
||||
| 27.| **支付宝** | |
|
||||
| 28.| **微信支付** | |
|
||||
| 29.| **长亭雷池授权** | |
|
||||
| 30.| **lucky** | |
|
||||
| 31.| **括彩云cdn授权** | 括彩云CDN,每月免费30G,[注册即领](https://kuocaicdn.com/register?code=8mn536rrzfbf8) |
|
||||
| 32.| **uniCloud** | unicloud授权 |
|
||||
| 33.| **华为云授权** | |
|
||||
| 34.| **西部数码授权** | |
|
||||
| 35.| **多吉云** | |
|
||||
| 36.| **我爱云授权** | 我爱云CDN |
|
||||
| 37.| **CacheFly** | CacheFly |
|
||||
| 38.| **Gcore** | Gcore |
|
||||
| 39.| **亚马逊云aws授权** | |
|
||||
| 40.| **dns.la授权** | |
|
||||
| 41.| **又拍云** | |
|
||||
| 42.| **火山引擎** | |
|
||||
| 43.| **京东云** | |
|
||||
| 44.| **51dns授权** | |
|
||||
|
||||
<style module>
|
||||
table th:first-of-type {
|
||||
width: 65px;
|
||||
}
|
||||
table th:nth-of-type(2) {
|
||||
width: 240px;
|
||||
}
|
||||
</style>
|
||||
|
||||
130
docs/guide/plugins/deploy.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# 任务插件
|
||||
共 `70` 款任务插件
|
||||
## 1. 证书申请
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **证书申请(JS版)** | 免费通配符域名证书申请,支持多个域名打到同一个证书上 |
|
||||
| 2.| **证书申请(Lego)** | 支持海量DNS解析提供商,推荐使用,一样的免费通配符域名证书申请,支持多个域名打到同一个证书上 |
|
||||
| 3.| **商用证书托管** | 手动上传自定义证书后,自动部署(每次证书有更新,都需要手动上传一次) |
|
||||
## 2. 主机
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **FTP-上传证书到FTP** | 将证书上传到FTP服务器 |
|
||||
| 2.| **IIS-部署到IIS站点** | |
|
||||
| 3.| **主机-执行远程主机脚本命令** | 可以执行重启nginx等操作让证书生效 |
|
||||
| 4.| **主机-部署证书到SSH主机** | SFTP上传证书到主机,然后SSH执行部署脚本命令 |
|
||||
## 3. CDN
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **易盾-部署到易盾DCDN** | 主要是防御,http://user.yiduncdn.com/ |
|
||||
| 2.| **易盾-部署到易盾RCDN** | 易盾CDN,每月免费30G,[注册即领](https://rhcdn.yiduncdn.com/register?code=8mn536rrzfbf8) |
|
||||
| 3.| **cdnfly-部署证书到cdnfly** | cdnfly |
|
||||
| 4.| **百度云-部署证书到CDN** | 部署到百度云CDN |
|
||||
| 5.| **LeCDN-更新证书** | |
|
||||
| 6.| **LeCDN-更新证书V2** | 支持新版本LeCDN |
|
||||
| 7.| **白山云-更新证书** | |
|
||||
| 8.| **天翼云-部署证书到CDN** | 部署证书到天翼云CDN和全站加速 |
|
||||
| 9.| **括彩云-部署到括彩云CDN** | 括彩云CDN,每月免费30G,[注册即领](https://kuocaicdn.com/register?code=8mn536rrzfbf8) |
|
||||
| 10.| **多吉云-部署到多吉云CDN** | |
|
||||
| 11.| **我爱云-部署证书到我爱云CDN** | 部署证书到我爱云CDN |
|
||||
| 12.| **CacheFly-部署证书到CacheFly** | 部署证书到 CacheFly |
|
||||
| 13.| **Gcore-部署证书到Gcore** | 仅上传 并不会部署到cdn |
|
||||
| 14.| **Gcore-刷新Gcore证书** | 刷新现有的证书 |
|
||||
| 15.| **又拍云-部署证书到CDN/USS** | 支持又拍云CDN,又拍云云存储USS |
|
||||
## 4. 面板
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **宝塔-面板证书部署** | 部署宝塔面板本身的ssl证书 |
|
||||
| 2.| **宝塔-网站证书部署** | 部署宝塔管理的站点的ssl证书,目前支持网站站点、docker站点等 |
|
||||
| 3.| **群晖-部署证书到群晖面板** | Synology,支持6.x以上版本 |
|
||||
| 4.| **K8S-部署证书到Secret** | 部署证书到k8s的secret |
|
||||
| 5.| **K8S-Ingress 证书部署** | 部署证书到k8s的Ingress |
|
||||
| 6.| **1Panel-部署证书到1Panel** | 更新1Panel的证书 |
|
||||
| 7.| **Plesk-部署Plesk网站证书** | |
|
||||
| 8.| **雷池-更新证书** | 更新长亭雷池WAF的证书 |
|
||||
| 9.| **lucky-更新Lucky证书** | |
|
||||
| 10.| **uniCloud-部署到服务空间** | 部署到服务空间 |
|
||||
| 11.| **威联通-部署证书到威联通** | 部署证书到qnap |
|
||||
## 5. 阿里云
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **阿里云-部署到Ack** | 部署到阿里云Ack集群Ingress等通过Secret管理证书的应用 |
|
||||
| 2.| **阿里云-部署至任意云资源** | 【不建议使用】需要消耗阿里云自动部署次数,支持SLB、LIVE、webHosting、VOD、CR、DCDN、DDoS、CDN、ALB、APIGateway、FC、GA、MSE、NLB、OSS、SAE、WAF等云产品 |
|
||||
| 3.| **阿里云-部署证书至CDN** | 自动部署域名证书至阿里云CDN |
|
||||
| 4.| **阿里云-部署证书至DCDN** | 依赖证书申请前置任务,自动部署域名证书至阿里云DCDN |
|
||||
| 5.| **阿里云-部署证书至OSS** | 自动部署域名证书至阿里云OSS |
|
||||
| 6.| **阿里云-上传证书到阿里云** | 如果不想在阿里云上同一份证书上传多次,可以把此任务作为前置任务,其他阿里云任务证书那一项选择此任务的输出 |
|
||||
| 7.| **阿里云-部署至阿里云WAF** | 部署证书到阿里云WAF |
|
||||
| 8.| **阿里云-部署至ALB(应用负载均衡)** | ALB,更新监听器的默认证书 |
|
||||
| 9.| **阿里云-部署至NLB(网络负载均衡)** | NLB,网络负载均衡,更新监听器的默认证书 |
|
||||
| 10.| **阿里云-部署至SLB(传统负载均衡)** | 部署证书到阿里云SLB(传统负载均衡) |
|
||||
| 11.| **阿里云-部署至阿里云FC(3.0)** | 部署证书到阿里云函数计算(FC3.0),【注意】证书的加密算法必须选择【pkcs1旧版】 |
|
||||
## 6. 华为云
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **华为云-部署证书至CDN** | |
|
||||
## 7. 腾讯云
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **腾讯云-部署证书到任意云资源** | 支持负载均衡、CDN、DDoS、直播、点播、Web应用防火墙、API网关、TEO、容器服务、对象存储、轻应用服务器、云原生微服务、云开发 |
|
||||
| 2.| **腾讯云-部署到CLB** | 暂时只支持单向认证证书,暂时只支持通用负载均衡 |
|
||||
| 3.| **腾讯云-部署到CDN(废弃)** | 已废弃,请使用v2版 |
|
||||
| 4.| **腾讯云-部署到CDN-v2** | 推荐使用 |
|
||||
| 5.| **腾讯云-上传证书到腾讯云** | 上传成功后输出:tencentCertId |
|
||||
| 6.| **腾讯云-部署证书到COS** | 部署到腾讯云COS源站域名证书【注意:很不稳定,需要重试很多次偶尔才能成功一次】 |
|
||||
| 7.| **腾讯云-部署到腾讯云EO** | 腾讯云边缘安全加速平台EO,必须配置上传证书到腾讯云任务 |
|
||||
| 8.| **腾讯云-删除即将过期证书** | 仅删除未使用的证书 |
|
||||
| 9.| **腾讯云-部署到TKE-ingress** | serverless集群请使用K8S部署插件;Qcloud类型需要【上传到腾讯云】作为前置任务;ApiServer未开启外网访问则需要做域名的内网IP映射 |
|
||||
## 8. 火山引擎
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **火山引擎-部署证书至CDN** | 支持网页,文件下载,音视频点播 |
|
||||
| 2.| **火山引擎-部署证书至CLB** | 部署至火山引擎负载均衡 |
|
||||
| 3.| **火山引擎-上传证书至证书中心** | 上传证书至火山引擎证书中心 |
|
||||
| 4.| **火山引擎-部署证书至ALB** | 部署至火山引擎应用负载均衡 |
|
||||
| 5.| **火山引擎-部署证书至Live** | 部署至火山引擎视频直播 |
|
||||
## 9. 京东云
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **京东云-部署证书至CDN** | 京东云内容分发网络 |
|
||||
| 2.| **京东云-更新已有证书** | 更新SSL数字证书中的证书 |
|
||||
| 3.| **京东云-上传新证书** | 上传证书到SSL数字证书中心 |
|
||||
## 10. 七牛云
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **七牛云-部署证书至OSS** | 自动部署域名证书至七牛云KODO,注意是自定义源站域名,不是CDN域名 |
|
||||
| 2.| **七牛云-部署证书至CDN** | 自动部署域名证书至七牛云CDN |
|
||||
## 11. 亚马逊云
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **AWS-部署证书到CloudFront** | 部署证书到 AWS CloudFront |
|
||||
## 12. 其他
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **Demo-测试插件** | |
|
||||
| 2.| **重启 Certd** | 【仅管理员可用】 重启 certd的https服务,用于更新 Certd 的 ssl 证书 |
|
||||
| 3.| **自定义js脚本** | 【仅管理员】运行自定义js脚本执行 |
|
||||
| 4.| **等待** | 等待一段时间 |
|
||||
| 5.| **数据库备份** | 仅支持备份SQLite数据库 |
|
||||
|
||||
<style module>
|
||||
table th:first-of-type {
|
||||
width: 65px;
|
||||
}
|
||||
table th:nth-of-type(2) {
|
||||
width: 240px;
|
||||
}
|
||||
</style>
|
||||
|
||||
22
docs/guide/plugins/dns-provider.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# DNS提供商
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **阿里云** | 阿里云DNS解析提供商 |
|
||||
| 2.| **腾讯云** | 腾讯云域名DNS解析提供者 |
|
||||
| 3.| **华为云** | 华为云DNS解析提供商 |
|
||||
| 4.| **西部数码** | west dns provider |
|
||||
| 5.| **dns.la** | dns.la |
|
||||
| 6.| **火山引擎** | 火山引擎DNS解析提供商 |
|
||||
| 7.| **京东云** | 京东云DNS解析提供商 |
|
||||
| 8.| **51dns** | 51DNS |
|
||||
|
||||
<style module>
|
||||
table th:first-of-type {
|
||||
width: 65px;
|
||||
}
|
||||
table th:nth-of-type(2) {
|
||||
width: 240px;
|
||||
}
|
||||
</style>
|
||||
|
||||
26
docs/guide/plugins/notification.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# 通知插件
|
||||
|
||||
| 序号 | 名称 | 说明 |
|
||||
|-----|-----|-----|
|
||||
| 1.| **企业微信通知** | 企业微信群聊机器人通知 |
|
||||
| 2.| **电子邮件** | 电子邮件通知 |
|
||||
| 3.| **爱语飞飞微信通知(iyuu)** | https://iyuu.cn/ |
|
||||
| 4.| **自定义webhook** | 根据模版自定义http请求 |
|
||||
| 5.| **Server酱ᵀ** | https://sct.ftqq.com/ |
|
||||
| 6.| **Server酱³** | https://doc.sc3.ft07.com/serverchan3 |
|
||||
| 7.| **AnPush** | https://anpush.com |
|
||||
| 8.| **Telegram通知** | Telegram Bot推送通知 |
|
||||
| 9.| **Discord 通知** | Discord 机器人通知 |
|
||||
| 10.| **Slack通知** | Slack消息推送通知 |
|
||||
| 11.| **Bark 通知** | Bark 推送通知插件 |
|
||||
| 12.| **飞书通知** | 飞书群聊webhook通知 |
|
||||
|
||||
<style module>
|
||||
table th:first-of-type {
|
||||
width: 65px;
|
||||
}
|
||||
table th:nth-of-type(2) {
|
||||
width: 240px;
|
||||
}
|
||||
</style>
|
||||
|
||||
BIN
docs/guide/qa/images/baota-net.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
73
docs/guide/qa/index.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# 常见报错解决
|
||||
|
||||
## 1. getaddrinfo ENOTFOUND错误
|
||||
如果出现`getaddrinfo ENOTFOUND`/`getaddrinfo EAI_AGAIN`错误,可以尝试在`docker-compose.yaml`中设置dns
|
||||
```yaml
|
||||
version: '3.3' # 兼容旧版docker-compose
|
||||
services:
|
||||
certd:
|
||||
#↓↓↓↓ ------------ # 如果出现getaddrinfo ENOTFOUND 或 EAI_AGAIN错误,可以尝试设置dns
|
||||
dns:
|
||||
- 223.5.5.5 # 阿里云公共dns
|
||||
- 223.6.6.6
|
||||
# # ↓↓↓↓ ------- # 如果你服务器在腾讯云,可以用这个替换上面阿里云的公共dns
|
||||
# - 119.29.29.29 # 腾讯云公共dns
|
||||
# - 182.254.116.116
|
||||
# # ↓↓↓↓ ------- # 如果你服务器部署在国外,可以用这个替换上面阿里云的公共dns
|
||||
# - 8.8.8.8 # 谷歌公共dns
|
||||
# - 8.8.4.4
|
||||
```
|
||||
|
||||
如果仍然有问题,按如下步骤检查是否能够ping通域名
|
||||
```shell
|
||||
docker exec -it certd /bin/sh
|
||||
ping www.baidu.com
|
||||
ping gg.px.certd.handfree.work
|
||||
ping app.handfree.work
|
||||
```
|
||||
|
||||
如果您是宝塔部署的
|
||||
可以试试将容器网络加入brige网络,看是否解决问题
|
||||

|
||||
|
||||
如果还是不行,请联系我们
|
||||
|
||||
|
||||
## 2. 连接IPv6超时
|
||||
docker-compose 需要放开IPv6网络的配置
|
||||
```yaml
|
||||
services:
|
||||
certd:
|
||||
networks:
|
||||
- ip6net
|
||||
# ↓↓↓↓ -------------------------------------------------------------- 启用ipv6网络,还需要把上面networks的注释放开
|
||||
networks:
|
||||
ip6net:
|
||||
enable_ipv6: true
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 2001:db8::/64
|
||||
|
||||
```
|
||||
|
||||
## 3. SSL_CERT_NOT_MATCH_DOMAIN_ERROR
|
||||
部署证书任务报类似 `SSL_CERT_NOT_MATCH_DOMAIN_ERROR`错误
|
||||
这是由于当前流水线的证书域名与要部署的目标站点的域名不匹配导致的,在申请证书任务中,增加目标站点域名,重新运行流水线即可
|
||||
|
||||
|
||||
## 4. 没有服务器配置文件,请检查是否开启了外网映射!
|
||||
宝塔网站证书部署报错:`Error: 没有服务器配置文件,请检查是否开启了外网映射!`
|
||||
解决方案:先手动在宝塔网站中设置一次证书
|
||||
|
||||
|
||||
## 5. 如何查看容器日志
|
||||
```shell
|
||||
docker logs -f --tail 200 certd
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
14
docs/guide/qa/use.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# 使用问题
|
||||
|
||||
|
||||
## 1. 是否支持IP证书
|
||||
|
||||
因为ACME协议不支持IP证书,所以certd目前也不支持IP证书
|
||||
|
||||
|
||||
## 2. 建议设置多长时间运行一次流水线
|
||||
建议每天运行一次,检查证书过期时间
|
||||
当证书没过期时,自动跳过部署
|
||||
当证书到期前35天(创建流水线时可以修改),将会自动重新申请证书,自动部署
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 165 KiB |
@@ -17,7 +17,9 @@ CERTD_HTTPS_port=7002
|
||||
参考Certd顶部的创建证书流水线教程
|
||||
|
||||
### 2、配置复制到本机任务
|
||||
将证书复制到certd的证书安装位置
|
||||
将证书复制到certd的证书安装位置
|
||||
证书路径:`ssl/cert.crt`
|
||||
私钥路径:`ssl/cert.key`
|
||||
|
||||

|
||||

|
||||
|
||||
BIN
docs/guide/use/pretask/images/pretask1.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
docs/guide/use/pretask/images/pretask2.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
13
docs/guide/use/pretask/index.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# 带输出的前置任务
|
||||
|
||||
前置任务输出可以在后续任务中使用
|
||||
|
||||
比如上传证书到阿里云,会返回阿里云的CertId,之后其他阿里云的部署任务可以选择复用这个证书
|
||||
|
||||
## 复用证书
|
||||
|
||||

|
||||
|
||||
在后续任务中可以选择前置任务的输出
|
||||
|
||||

|
||||
@@ -9,5 +9,5 @@
|
||||
}
|
||||
},
|
||||
"npmClient": "pnpm",
|
||||
"version": "1.34.0"
|
||||
"version": "1.34.9"
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
"init": "lerna run build",
|
||||
"docs:dev": "vitepress dev docs",
|
||||
"docs:build": "vitepress build docs",
|
||||
"docs:preview": "vitepress preview docs"
|
||||
"docs:preview": "vitepress preview docs",
|
||||
"pub": "echo 1"
|
||||
},
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
|
||||
@@ -3,6 +3,46 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.9](https://github.com/publishlab/node-acme-client/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.34.8](https://github.com/publishlab/node-acme-client/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.34.7](https://github.com/publishlab/node-acme-client/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.34.6](https://github.com/publishlab/node-acme-client/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.34.5](https://github.com/publishlab/node-acme-client/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.34.4](https://github.com/publishlab/node-acme-client/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.34.3](https://github.com/publishlab/node-acme-client/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.34.2](https://github.com/publishlab/node-acme-client/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* http方式支持校验443端口 ([d75fcb7](https://github.com/publishlab/node-acme-client/commit/d75fcb7fec421a9a638eaa27fe9378c84b5e0f19))
|
||||
|
||||
## [1.34.1](https://github.com/publishlab/node-acme-client/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 根据SOA记录判断子域名托管有缺陷,改回手动配置子域名托管记录的方式 ([1b280a2](https://github.com/publishlab/node-acme-client/commit/1b280a2940f9e2d919b0bf23b89cc185be1fa498))
|
||||
|
||||
# [1.34.0](https://github.com/publishlab/node-acme-client/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "Simple and unopinionated ACME client",
|
||||
"private": false,
|
||||
"author": "nmorsman",
|
||||
"version": "1.34.0",
|
||||
"version": "1.34.9",
|
||||
"type": "module",
|
||||
"module": "scr/index.js",
|
||||
"main": "src/index.js",
|
||||
@@ -18,7 +18,7 @@
|
||||
"types"
|
||||
],
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.34.0",
|
||||
"@certd/basic": "^1.34.9",
|
||||
"@peculiar/x509": "^1.11.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"axios": "^1.7.2",
|
||||
@@ -51,7 +51,8 @@
|
||||
"lint": "eslint .",
|
||||
"lint-types": "tsd",
|
||||
"prepublishOnly": "npm run build-docs",
|
||||
"test": "mocha -t 60000 \"test/setup.js\" \"test/**/*.spec.js\""
|
||||
"test": "mocha -t 60000 \"test/setup.js\" \"test/**/*.spec.js\"",
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -68,5 +69,5 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||
},
|
||||
"gitHead": "9b420ad33ff4c36fc99d643c18be9ec7e29f220d"
|
||||
"gitHead": "d876ea671137e7a4d99a23bb8a5baed06f119dfb"
|
||||
}
|
||||
|
||||
@@ -234,6 +234,7 @@ export default async (client, userOpts) => {
|
||||
throw new CancelError("用户取消");
|
||||
}
|
||||
|
||||
const waitDnsDiffuseTime = opts.waitDnsDiffuseTime || 30;
|
||||
try {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await runPromisePa(challengePromises);
|
||||
@@ -242,8 +243,8 @@ export default async (client, userOpts) => {
|
||||
await wait(60 * 1000);
|
||||
} else {
|
||||
await runPromisePa(localVerifyTasks, 1000);
|
||||
log("本地校验完成,等待30s")
|
||||
await wait(30 * 1000)
|
||||
log(`本地校验完成,等待${waitDnsDiffuseTime}s`)
|
||||
await wait(waitDnsDiffuseTime * 1000)
|
||||
}
|
||||
|
||||
log("开始向提供商请求挑战验证");
|
||||
|
||||
@@ -24,22 +24,46 @@ const dns = dnsSdk.promises
|
||||
*/
|
||||
|
||||
async function verifyHttpChallenge(authz, challenge, keyAuthorization, suffix = `/.well-known/acme-challenge/${challenge.token}`) {
|
||||
|
||||
async function doQuery(challengeUrl){
|
||||
log(`正在测试请求 ${challengeUrl} `)
|
||||
// const httpsPort = axios.defaults.acmeSettings.httpsChallengePort || 443;
|
||||
// const challengeUrl = `https://${authz.identifier.value}:${httpsPort}${suffix}`;
|
||||
|
||||
/* May redirect to HTTPS with invalid/self-signed cert - https://letsencrypt.org/docs/challenge-types/#http-01-challenge */
|
||||
const httpsAgent = new https.Agent({ rejectUnauthorized: false });
|
||||
|
||||
log(`Sending HTTP query to ${authz.identifier.value}, suffix: ${suffix}, port: ${httpPort}`);
|
||||
let data = ""
|
||||
try{
|
||||
const resp = await axios.get(challengeUrl, { httpsAgent });
|
||||
data = (resp.data || '').replace(/\s+$/, '');
|
||||
}catch (e) {
|
||||
log(`[error] HTTP request error from ${authz.identifier.value}`,e.message);
|
||||
return false
|
||||
}
|
||||
|
||||
if (!data || (data !== keyAuthorization)) {
|
||||
log(`[error] Authorization not found in HTTP response from ${authz.identifier.value}`);
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
const httpPort = axios.defaults.acmeSettings.httpChallengePort || 80;
|
||||
const challengeUrl = `http://${authz.identifier.value}:${httpPort}${suffix}`;
|
||||
|
||||
/* May redirect to HTTPS with invalid/self-signed cert - https://letsencrypt.org/docs/challenge-types/#http-01-challenge */
|
||||
const httpsAgent = new https.Agent({ rejectUnauthorized: false });
|
||||
|
||||
log(`Sending HTTP query to ${authz.identifier.value}, suffix: ${suffix}, port: ${httpPort}`);
|
||||
const resp = await axios.get(challengeUrl, { httpsAgent });
|
||||
const data = (resp.data || '').replace(/\s+$/, '');
|
||||
|
||||
log(`Query successful, HTTP status code: ${resp.status}`);
|
||||
|
||||
if (!data || (data !== keyAuthorization)) {
|
||||
throw new Error(`Authorization not found in HTTP response from ${authz.identifier.value}`);
|
||||
if (!await doQuery(challengeUrl)) {
|
||||
const httpsPort = axios.defaults.acmeSettings.httpsChallengePort || 443;
|
||||
const httpsChallengeUrl = `https://${authz.identifier.value}:${httpsPort}${suffix}`;
|
||||
const res = await doQuery(httpsChallengeUrl)
|
||||
if (!res) {
|
||||
throw new Error(`[error] 验证失败,请检查以上测试url是否可以正常访问`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
log(`Key authorization match for ${challenge.type}/${authz.identifier.value}, ACME challenge verified`);
|
||||
return true;
|
||||
}
|
||||
|
||||
11
packages/core/acme-client/test/soa.spec.mjs
Normal file
@@ -0,0 +1,11 @@
|
||||
import {assert} from 'chai'
|
||||
import {resolveDomainBySoaRecord} from "../src/util.js"
|
||||
describe('dns', () => {
|
||||
it('resolveDomainBySoaRecord', async () => {
|
||||
const resp = await resolveDomainBySoaRecord("a.corp.smartdeer.com")
|
||||
|
||||
assert.equal(resp, "smartdeer.com")
|
||||
|
||||
});
|
||||
|
||||
})
|
||||
@@ -3,6 +3,49 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.9](https://github.com/certd/certd/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.34.8](https://github.com/certd/certd/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.34.7](https://github.com/certd/certd/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.34.6](https://github.com/certd/certd/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.34.5](https://github.com/certd/certd/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持部署到宝塔aaWAF ([094565c](https://github.com/certd/certd/commit/094565ccd619ef671c6c11ce5fb7fd54a7a21d1c))
|
||||
|
||||
## [1.34.4](https://github.com/certd/certd/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复导入在线插件不生效的bug ([fcf8309](https://github.com/certd/certd/commit/fcf8309c238208281ecb4575b2c3cfe50c11d783))
|
||||
* 修复自建插件保存丢失部署策略的bug ([863e74d](https://github.com/certd/certd/commit/863e74dd2e3912f950ff5025b5ed0070aeb37035))
|
||||
|
||||
## [1.34.3](https://github.com/certd/certd/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.34.2](https://github.com/certd/certd/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.34.1](https://github.com/certd/certd/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持部署证书到火山dcdn ([5f85219](https://github.com/certd/certd/commit/5f852194953dc1b4e6336770f417507b8f5a33ad))
|
||||
|
||||
# [1.34.0](https://github.com/certd/certd/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
@@ -1 +1 @@
|
||||
17:24
|
||||
00:54
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/basic",
|
||||
"private": false,
|
||||
"version": "1.34.0",
|
||||
"version": "1.34.9",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -12,7 +12,8 @@
|
||||
"build": "npm run before-build && tsc --skipLibCheck",
|
||||
"dev-build": "npm run build",
|
||||
"preview": "vite preview",
|
||||
"test": "mocha --loader=ts-node/esm"
|
||||
"test": "mocha --loader=ts-node/esm",
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.7.2",
|
||||
@@ -44,5 +45,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "9b420ad33ff4c36fc99d643c18be9ec7e29f220d"
|
||||
"gitHead": "d876ea671137e7a4d99a23bb8a5baed06f119dfb"
|
||||
}
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
export * from './util.request.js';
|
||||
export * from './util.env.js';
|
||||
export * from './util.log.js';
|
||||
export * from './util.file.js';
|
||||
export * from './util.sp.js';
|
||||
export * from './util.promise.js';
|
||||
export * from './util.hash.js';
|
||||
export * from './util.merge.js';
|
||||
export * from './util.cache.js';
|
||||
export * from './util.string.js';
|
||||
export * from './util.lock.js';
|
||||
export * from './util.mitter.js';
|
||||
export * from './util.id.js';
|
||||
export * from './util.domain.js';
|
||||
export * from './util.amount.js';
|
||||
import { stringUtils } from './util.string.js';
|
||||
import sleep from './util.sleep.js';
|
||||
import { http, download } from './util.request.js';
|
||||
export * from "./util.request.js";
|
||||
export * from "./util.env.js";
|
||||
export * from "./util.log.js";
|
||||
export * from "./util.file.js";
|
||||
export * from "./util.sp.js";
|
||||
export * from "./util.promise.js";
|
||||
export * from "./util.hash.js";
|
||||
export * from "./util.merge.js";
|
||||
export * from "./util.cache.js";
|
||||
export * from "./util.string.js";
|
||||
export * from "./util.lock.js";
|
||||
export * from "./util.mitter.js";
|
||||
export * from "./util.id.js";
|
||||
export * from "./util.domain.js";
|
||||
export * from "./util.amount.js";
|
||||
import { stringUtils } from "./util.string.js";
|
||||
import sleep from "./util.sleep.js";
|
||||
import { http, download } from "./util.request.js";
|
||||
|
||||
import { mergeUtils } from './util.merge.js';
|
||||
import { sp } from './util.sp.js';
|
||||
import { hashUtils } from './util.hash.js';
|
||||
import { promises } from './util.promise.js';
|
||||
import { fileUtils } from './util.file.js';
|
||||
import * as _ from 'lodash-es';
|
||||
import { cache } from './util.cache.js';
|
||||
import dayjs from 'dayjs';
|
||||
import { domainUtils } from './util.domain.js';
|
||||
import { optionsUtils } from './util.options.js';
|
||||
import { amountUtils } from './util.amount.js';
|
||||
import { nanoid } from 'nanoid';
|
||||
import * as id from './util.id.js';
|
||||
import { locker } from './util.lock.js';
|
||||
import { mitter } from './util.mitter.js';
|
||||
import { mergeUtils } from "./util.merge.js";
|
||||
import { sp } from "./util.sp.js";
|
||||
import { hashUtils } from "./util.hash.js";
|
||||
import { promises } from "./util.promise.js";
|
||||
import { fileUtils } from "./util.file.js";
|
||||
import * as _ from "lodash-es";
|
||||
import { cache } from "./util.cache.js";
|
||||
import dayjs from "dayjs";
|
||||
import { domainUtils } from "./util.domain.js";
|
||||
import { optionsUtils } from "./util.options.js";
|
||||
import { amountUtils } from "./util.amount.js";
|
||||
import { nanoid } from "nanoid";
|
||||
import * as id from "./util.id.js";
|
||||
import { locker } from "./util.lock.js";
|
||||
import { mitter } from "./util.mitter.js";
|
||||
|
||||
import * as request from './util.request.js';
|
||||
import * as request from "./util.request.js";
|
||||
export const utils = {
|
||||
sleep,
|
||||
http,
|
||||
|
||||
@@ -14,9 +14,13 @@ function hmacSha256(data: string, digest: BinaryToTextEncoding = "base64") {
|
||||
function base64(data: string) {
|
||||
return Buffer.from(data).toString("base64");
|
||||
}
|
||||
function base64Decode(data: string) {
|
||||
return Buffer.from(data, "base64").toString("utf8");
|
||||
}
|
||||
export const hashUtils = {
|
||||
md5,
|
||||
sha256,
|
||||
base64,
|
||||
base64Decode,
|
||||
hmacSha256,
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { domainUtils } from './util.domain.js';
|
||||
import { domainUtils } from "./util.domain.js";
|
||||
|
||||
function groupByDomain(options: any[], inDomains: string[]) {
|
||||
const matched = [];
|
||||
@@ -19,16 +19,16 @@ function groupByDomain(options: any[], inDomains: string[]) {
|
||||
function buildGroupOptions(options: any[], inDomains: string[]) {
|
||||
const grouped = groupByDomain(options, inDomains);
|
||||
const groupOptions = [];
|
||||
groupOptions.push({ value: 'matched', disabled: true, label: '----已匹配----' });
|
||||
groupOptions.push({ value: "matched", disabled: true, label: "----已匹配----" });
|
||||
if (grouped.matched.length === 0) {
|
||||
options.push({ value: '', disabled: true, label: '没有可以匹配的域名' });
|
||||
options.push({ value: "", disabled: true, label: "没有可以匹配的域名" });
|
||||
} else {
|
||||
for (const matched of grouped.matched) {
|
||||
groupOptions.push(matched);
|
||||
}
|
||||
}
|
||||
if (grouped.notMatched.length > 0) {
|
||||
groupOptions.push({ value: 'unmatched', disabled: true, label: '----未匹配----' });
|
||||
groupOptions.push({ value: "unmatched", disabled: true, label: "----未匹配----" });
|
||||
for (const notMatched of grouped.notMatched) {
|
||||
groupOptions.push(notMatched);
|
||||
}
|
||||
|
||||
@@ -91,10 +91,23 @@ export function createAxiosService({ logger }: { logger: Logger }) {
|
||||
// 请求拦截
|
||||
service.interceptors.request.use(
|
||||
(config: any) => {
|
||||
if (config.logParams == null) {
|
||||
config.logParams = false;
|
||||
}
|
||||
if (config.logRes == null) {
|
||||
config.logRes = false;
|
||||
}
|
||||
if (config.logData == null) {
|
||||
config.logData = false;
|
||||
}
|
||||
|
||||
logger.info(`http request:${config.url},method:${config.method}`);
|
||||
if (config.logParams !== false && config.params) {
|
||||
logger.info(`params:${JSON.stringify(config.params)}`);
|
||||
}
|
||||
if (config.logData !== false && config.data) {
|
||||
logger.info(`data:${JSON.stringify(config.data)}`);
|
||||
}
|
||||
if (config.timeout == null) {
|
||||
config.timeout = 15000;
|
||||
}
|
||||
@@ -145,7 +158,8 @@ export function createAxiosService({ logger }: { logger: Logger }) {
|
||||
} else {
|
||||
logger.info("http response status:", response?.status);
|
||||
}
|
||||
if (response?.config?.returnResponse) {
|
||||
|
||||
if (response?.config?.returnOriginRes) {
|
||||
return response;
|
||||
}
|
||||
return response.data;
|
||||
@@ -201,6 +215,10 @@ export function createAxiosService({ logger }: { logger: Logger }) {
|
||||
logger.error("AggregateError", error);
|
||||
}
|
||||
const err = new HttpError(error);
|
||||
if (error.response?.config?.logParams === false) {
|
||||
delete err.request?.params;
|
||||
delete err.request?.data;
|
||||
}
|
||||
return Promise.reject(err);
|
||||
}
|
||||
);
|
||||
@@ -214,8 +232,9 @@ export type HttpRequestConfig<D = any> = {
|
||||
skipCheckRes?: boolean;
|
||||
logParams?: boolean;
|
||||
logRes?: boolean;
|
||||
logData?: boolean;
|
||||
httpProxy?: string;
|
||||
returnResponse?: boolean;
|
||||
returnOriginRes?: boolean;
|
||||
} & AxiosRequestConfig<D>;
|
||||
export type HttpClient = {
|
||||
request<D = any, R = any>(config: HttpRequestConfig<D>): Promise<HttpClientResponse<R>>;
|
||||
|
||||
@@ -3,6 +3,58 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.9](https://github.com/certd/certd/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.34.8](https://github.com/certd/certd/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化站点选择组件,切换选择时不刷新列表 ([3a14714](https://github.com/certd/certd/commit/3a147141b1a5d67c92a5ce88a5313eaa62859e03))
|
||||
* 站点监控支持监控IP ([9cc4c01](https://github.com/certd/certd/commit/9cc4c017ae646a18284e732769b82636feda01d3))
|
||||
* 支持批量重新运行 ([8189982](https://github.com/certd/certd/commit/818998259ddc75e722196ac5c365038818539b9b))
|
||||
|
||||
## [1.34.7](https://github.com/certd/certd/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.34.6](https://github.com/certd/certd/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复公共插件配置修改不生效的bug,优化系统设置参数注入时机 ([e1e510c](https://github.com/certd/certd/commit/e1e510ce1e37a5ae82478226b6987a83f22d1ecb))
|
||||
* 优化 RunnableError错误信息展示 ([36bc3ff](https://github.com/certd/certd/commit/36bc3ff22da93ba342c3c1103d7ee2bbcecf44f2))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 添加阿里云 ESA证书部署插件 ([1db1ffd](https://github.com/certd/certd/commit/1db1ffde99ac7e4684fa606ebc4c327f829b3a26))
|
||||
|
||||
## [1.34.5](https://github.com/certd/certd/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化钉钉通知标题颜色 ([a560999](https://github.com/certd/certd/commit/a560999d13eed18d08dd32ee530166569e3f8746))
|
||||
* 优化飞书通知为卡片模式 ([a818a3d](https://github.com/certd/certd/commit/a818a3d293e22fb46979bc77055c05621a6fed81))
|
||||
|
||||
## [1.34.4](https://github.com/certd/certd/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复导入在线插件不生效的bug ([fcf8309](https://github.com/certd/certd/commit/fcf8309c238208281ecb4575b2c3cfe50c11d783))
|
||||
|
||||
## [1.34.3](https://github.com/certd/certd/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.34.2](https://github.com/certd/certd/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.34.1](https://github.com/certd/certd/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
# [1.34.0](https://github.com/certd/certd/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/pipeline",
|
||||
"private": false,
|
||||
"version": "1.34.0",
|
||||
"version": "1.34.9",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -13,11 +13,12 @@
|
||||
"dev-build": "npm run build",
|
||||
"build3": "rollup -c",
|
||||
"preview": "vite preview",
|
||||
"test": "mocha --loader=ts-node/esm"
|
||||
"test": "mocha --loader=ts-node/esm",
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.34.0",
|
||||
"@certd/plus-core": "^1.34.0",
|
||||
"@certd/basic": "^1.34.9",
|
||||
"@certd/plus-core": "^1.34.9",
|
||||
"dayjs": "^1.11.7",
|
||||
"lodash-es": "^4.17.21",
|
||||
"reflect-metadata": "^0.1.13"
|
||||
@@ -43,5 +44,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "9b420ad33ff4c36fc99d643c18be9ec7e29f220d"
|
||||
"gitHead": "d876ea671137e7a4d99a23bb8a5baed06f119dfb"
|
||||
}
|
||||
|
||||
@@ -2,3 +2,18 @@ import { IContext } from "../core/index.js";
|
||||
|
||||
export type UserContext = IContext;
|
||||
export type PipelineContext = IContext;
|
||||
|
||||
export type PageReq = {
|
||||
offset?: number;
|
||||
limit?: number;
|
||||
searchKey?: string;
|
||||
// sortBy?: string;
|
||||
// sortOrder?: "asc" | "desc";
|
||||
};
|
||||
|
||||
export type PageRes = {
|
||||
offset?: number;
|
||||
limit?: number;
|
||||
total?: string;
|
||||
list: any[];
|
||||
};
|
||||
|
||||
@@ -218,7 +218,7 @@ export class Executor {
|
||||
returnType: ResultType.error,
|
||||
runnable: t,
|
||||
});
|
||||
errorMessage += `任务${t.title}执行失败,错误详情:${e.message};`;
|
||||
errorMessage += `任务${t.title}执行失败,错误详情:${e.message};`;
|
||||
}
|
||||
}
|
||||
if (errorList.length > 0) {
|
||||
@@ -295,6 +295,12 @@ export class Executor {
|
||||
const pluginConfig = await this.options.pluginConfigService.getPluginConfig(pluginName);
|
||||
//从outputContext读取输入参数
|
||||
const input = cloneDeep(step.input);
|
||||
const sysInput = pluginConfig.sysSetting?.input || {};
|
||||
//注入系统设置参数
|
||||
for (const sysInputKey in sysInput) {
|
||||
input[sysInputKey] = sysInput[sysInputKey];
|
||||
}
|
||||
|
||||
Decorator.inject(define.input, instance, input, (item, key) => {
|
||||
if (item.component?.name === "output-selector") {
|
||||
const contextKey = input[key];
|
||||
@@ -314,12 +320,6 @@ export class Executor {
|
||||
}
|
||||
});
|
||||
|
||||
const sysInput = pluginConfig.sysSetting?.input || {};
|
||||
//注入系统设置参数
|
||||
for (const sysInputKey in sysInput) {
|
||||
input[sysInputKey] = sysInput[sysInputKey];
|
||||
}
|
||||
|
||||
const newInputHash = hashUtils.md5(JSON.stringify(input));
|
||||
step.status!.inputHash = newInputHash;
|
||||
//判断是否需要跳过
|
||||
@@ -438,7 +438,7 @@ export class Executor {
|
||||
const runnableError = error as RunnableError;
|
||||
content = `流水线ID:${this.pipeline.id},运行ID:${this.runtime.id}\n\n`;
|
||||
for (const re of runnableError.errors) {
|
||||
content += ` - ${re.runnable.title} 执行失败\n 错误详情:${re.e.message}\n\n`;
|
||||
content += ` - ${re.runnable.title} 执行失败,错误详情:${re.e?.message || re.e?.error?.message}\n\n`;
|
||||
}
|
||||
} else {
|
||||
content = `流水线ID:${this.pipeline.id},运行ID:${this.runtime.id}\n\n${this.currentStatusMap?.currentStep?.title} 执行失败\n\n错误详情:${error.message}`;
|
||||
@@ -489,7 +489,15 @@ export class Executor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param stepId 如果==ALL 清除所有
|
||||
*/
|
||||
clearLastStatus(stepId: string) {
|
||||
if (stepId === "ALL") {
|
||||
this.lastStatusMap.clear();
|
||||
return;
|
||||
}
|
||||
this.lastStatusMap.clearById(stepId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,6 +203,7 @@ export class RunnableCollection {
|
||||
if (runnable?.status) {
|
||||
runnable.status.status = ResultType.none;
|
||||
runnable.status.result = ResultType.none;
|
||||
runnable.status.output = {};
|
||||
runnable.status.inputHash = "";
|
||||
// @ts-ignore
|
||||
runnable.input = {};
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import { Decorator } from "./index.js";
|
||||
|
||||
export type AutowireProp = {
|
||||
name?: string;
|
||||
type?: any;
|
||||
};
|
||||
export const AUTOWIRE_KEY = "pipeline:autowire";
|
||||
|
||||
export function Autowire(props?: AutowireProp): PropertyDecorator {
|
||||
return (target, propertyKey) => {
|
||||
const _type = Reflect.getMetadata("design:type", target, propertyKey);
|
||||
target = Decorator.target(target, propertyKey);
|
||||
props = props || {};
|
||||
props.type = _type;
|
||||
Reflect.defineMetadata(AUTOWIRE_KEY, props || {}, target, propertyKey);
|
||||
};
|
||||
}
|
||||
@@ -1,2 +1 @@
|
||||
export * from "./utils.js";
|
||||
export * from "./common.js";
|
||||
|
||||
@@ -51,10 +51,6 @@ export type PluginDefine = Registrable & {
|
||||
[key: string]: TaskOutputDefine;
|
||||
};
|
||||
|
||||
autowire?: {
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
shortcut?: {
|
||||
[key: string]: {
|
||||
title: string;
|
||||
@@ -231,6 +227,11 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
||||
return name + "_" + dayjs().format("YYYYMMDDHHmmssSSS");
|
||||
}
|
||||
|
||||
buildCertName(domain: string) {
|
||||
domain = domain.replaceAll("*", "_").replaceAll(".", "_");
|
||||
return `${domain}_${dayjs().format("YYYYMMDDHHmmssSSS")}`;
|
||||
}
|
||||
|
||||
async onRequest(req: PluginRequestHandleReq<any>) {
|
||||
if (!req.action) {
|
||||
throw new Error("action is required");
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { pluginRegistry } from "./registry.js";
|
||||
import { PluginDefine, TaskInputDefine, TaskOutputDefine } from "./api.js";
|
||||
import { Decorator } from "../decorator/index.js";
|
||||
import { AUTOWIRE_KEY } from "../decorator/index.js";
|
||||
import "reflect-metadata";
|
||||
import { merge, sortBy } from "lodash-es";
|
||||
// 提供一个唯一 key
|
||||
@@ -12,7 +11,6 @@ export function IsTaskPlugin(define: PluginDefine): ClassDecorator {
|
||||
target = Decorator.target(target);
|
||||
|
||||
const inputs: any = {};
|
||||
const autowires: any = {};
|
||||
const outputs: any = {};
|
||||
const properties = Decorator.getClassProperties(target);
|
||||
for (const property in properties) {
|
||||
@@ -21,11 +19,6 @@ export function IsTaskPlugin(define: PluginDefine): ClassDecorator {
|
||||
inputs[property] = input;
|
||||
}
|
||||
|
||||
const autowire = Reflect.getMetadata(AUTOWIRE_KEY, target, property);
|
||||
if (autowire) {
|
||||
autowires[property] = autowire;
|
||||
}
|
||||
|
||||
const output = Reflect.getMetadata(PLUGIN_OUTPUT_KEY, target, property);
|
||||
if (output) {
|
||||
outputs[property] = output;
|
||||
@@ -57,7 +50,7 @@ export function IsTaskPlugin(define: PluginDefine): ClassDecorator {
|
||||
},
|
||||
};
|
||||
|
||||
define = merge(defaultConfig, define, { input: inputMap, autowire: autowires, output: outputs });
|
||||
define = merge(defaultConfig, define, { input: inputMap, output: outputs });
|
||||
|
||||
Reflect.defineMetadata(PLUGIN_CLASS_KEY, define, target);
|
||||
|
||||
|
||||
@@ -48,6 +48,11 @@ export class Registry<T = any> {
|
||||
logger.info(`注册插件:${this.type}:${key}`);
|
||||
}
|
||||
|
||||
unRegister(key: string) {
|
||||
delete this.storage[key];
|
||||
logger.info(`反注册插件:${this.type}:${key}`);
|
||||
}
|
||||
|
||||
get(name: string): RegistryItem<T> {
|
||||
if (!name) {
|
||||
throw new Error("插件名称不能为空");
|
||||
@@ -65,7 +70,7 @@ export class Registry<T = any> {
|
||||
}
|
||||
|
||||
getDefineList() {
|
||||
const list = [];
|
||||
let list = [];
|
||||
for (const key in this.storage) {
|
||||
const define = this.getDefine(key);
|
||||
if (define) {
|
||||
@@ -78,6 +83,10 @@ export class Registry<T = any> {
|
||||
list.push({ ...define, key });
|
||||
}
|
||||
}
|
||||
|
||||
list = list.sort((a, b) => {
|
||||
return (a.order ?? 10) - (b?.order ?? 10);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,42 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.9](https://github.com/certd/certd/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.34.8](https://github.com/certd/certd/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.34.7](https://github.com/certd/certd/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.34.6](https://github.com/certd/certd/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.34.5](https://github.com/certd/certd/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.34.4](https://github.com/certd/certd/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.34.3](https://github.com/certd/certd/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.34.2](https://github.com/certd/certd/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.34.1](https://github.com/certd/certd/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
# [1.34.0](https://github.com/certd/certd/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-huawei",
|
||||
"private": false,
|
||||
"version": "1.34.0",
|
||||
"version": "1.34.9",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
@@ -10,7 +10,8 @@
|
||||
"before-build": "rimraf dist && rimraf tsconfig.tsbuildinfo && rimraf .rollup.cache",
|
||||
"build": "npm run before-build && rollup -c ",
|
||||
"dev-build": "npm run build",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.7.2",
|
||||
@@ -23,5 +24,5 @@
|
||||
"prettier": "^2.8.8",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"gitHead": "9b420ad33ff4c36fc99d643c18be9ec7e29f220d"
|
||||
"gitHead": "d876ea671137e7a4d99a23bb8a5baed06f119dfb"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,42 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.9](https://github.com/certd/certd/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.34.8](https://github.com/certd/certd/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.34.7](https://github.com/certd/certd/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.34.6](https://github.com/certd/certd/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.34.5](https://github.com/certd/certd/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.34.4](https://github.com/certd/certd/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.34.3](https://github.com/certd/certd/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.34.2](https://github.com/certd/certd/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.34.1](https://github.com/certd/certd/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
# [1.34.0](https://github.com/certd/certd/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-iframe",
|
||||
"private": false,
|
||||
"version": "1.34.0",
|
||||
"version": "1.34.9",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -13,7 +13,8 @@
|
||||
"dev-build": "npm run build",
|
||||
"build3": "rollup -c",
|
||||
"build2": "vue-tsc --noEmit && vite build",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"nanoid": "^4.0.0"
|
||||
@@ -30,5 +31,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "9b420ad33ff4c36fc99d643c18be9ec7e29f220d"
|
||||
"gitHead": "d876ea671137e7a4d99a23bb8a5baed06f119dfb"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,42 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.9](https://github.com/certd/certd/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.34.8](https://github.com/certd/certd/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.34.7](https://github.com/certd/certd/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.34.6](https://github.com/certd/certd/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.34.5](https://github.com/certd/certd/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.34.4](https://github.com/certd/certd/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.34.3](https://github.com/certd/certd/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.34.2](https://github.com/certd/certd/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.34.1](https://github.com/certd/certd/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
# [1.34.0](https://github.com/certd/certd/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/jdcloud",
|
||||
"version": "1.34.0",
|
||||
"version": "1.34.9",
|
||||
"description": "jdcloud openApi sdk",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
@@ -9,7 +9,8 @@
|
||||
"test": "cross-env NODE_CONFIG_DIR=./test/config mocha --recursive --require babel-register",
|
||||
"dev": "babel src --out-dir babel -w",
|
||||
"build": "rollup -c ",
|
||||
"dev-build": "npm run build"
|
||||
"dev-build": "npm run build",
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"author": "",
|
||||
"license": "Apache",
|
||||
@@ -60,5 +61,5 @@
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
"gitHead": "9b420ad33ff4c36fc99d643c18be9ec7e29f220d"
|
||||
"gitHead": "d876ea671137e7a4d99a23bb8a5baed06f119dfb"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,42 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.9](https://github.com/certd/certd/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.34.8](https://github.com/certd/certd/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.34.7](https://github.com/certd/certd/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.34.6](https://github.com/certd/certd/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.34.5](https://github.com/certd/certd/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.34.4](https://github.com/certd/certd/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.34.3](https://github.com/certd/certd/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.34.2](https://github.com/certd/certd/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.34.1](https://github.com/certd/certd/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
# [1.34.0](https://github.com/certd/certd/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-k8s",
|
||||
"private": false,
|
||||
"version": "1.34.0",
|
||||
"version": "1.34.9",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -13,10 +13,11 @@
|
||||
"dev-build": "npm run build",
|
||||
"build3": "rollup -c",
|
||||
"build2": "vue-tsc --noEmit && vite build",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.34.0",
|
||||
"@certd/basic": "^1.34.9",
|
||||
"@kubernetes/client-node": "0.21.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -31,5 +32,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "9b420ad33ff4c36fc99d643c18be9ec7e29f220d"
|
||||
"gitHead": "d876ea671137e7a4d99a23bb8a5baed06f119dfb"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,50 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.9](https://github.com/certd/certd/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 邮箱支持保存和选择 ([f7b0b44](https://github.com/certd/certd/commit/f7b0b44ef6044bec36510a6f0b06d8dca5bfce49))
|
||||
|
||||
## [1.34.8](https://github.com/certd/certd/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
## [1.34.7](https://github.com/certd/certd/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
## [1.34.6](https://github.com/certd/certd/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 站点证书监控增加通知设置 ([3422a1a](https://github.com/certd/certd/commit/3422a1a59fd0d2c0f17fa9c7e8988ac527ecfdd9))
|
||||
|
||||
## [1.34.5](https://github.com/certd/certd/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
## [1.34.4](https://github.com/certd/certd/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
## [1.34.3](https://github.com/certd/certd/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 小助手可以关闭 ([3e2101a](https://github.com/certd/certd/commit/3e2101aa5b56548614102e900d59819ce8c7e97c))
|
||||
|
||||
## [1.34.2](https://github.com/certd/certd/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持设置网安备案号 ([d18e431](https://github.com/certd/certd/commit/d18e431e2f08e6b37704032c4ea6fbdd8e971442))
|
||||
|
||||
## [1.34.1](https://github.com/certd/certd/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
# [1.34.0](https://github.com/certd/certd/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/lib-server",
|
||||
"version": "1.34.0",
|
||||
"version": "1.34.9",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -27,10 +27,10 @@
|
||||
],
|
||||
"license": "AGPL",
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.34.0",
|
||||
"@certd/basic": "^1.34.0",
|
||||
"@certd/pipeline": "^1.34.0",
|
||||
"@certd/plus-core": "^1.34.0",
|
||||
"@certd/acme-client": "^1.34.9",
|
||||
"@certd/basic": "^1.34.9",
|
||||
"@certd/pipeline": "^1.34.9",
|
||||
"@certd/plus-core": "^1.34.9",
|
||||
"@midwayjs/cache": "~3.14.0",
|
||||
"@midwayjs/core": "~3.20.3",
|
||||
"@midwayjs/i18n": "~3.20.3",
|
||||
@@ -61,5 +61,5 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "9b420ad33ff4c36fc99d643c18be9ec7e29f220d"
|
||||
"gitHead": "d876ea671137e7a4d99a23bb8a5baed06f119dfb"
|
||||
}
|
||||
|
||||
@@ -25,7 +25,9 @@ export class SysPublicSettings extends BaseSettings {
|
||||
limitUserPipelineCount = 0;
|
||||
managerOtherUserPipeline = false;
|
||||
icpNo?: string;
|
||||
mpsNo?: string;
|
||||
robots?: boolean = true;
|
||||
aiChatEnabled = true;
|
||||
}
|
||||
|
||||
export class SysPrivateSettings extends BaseSettings {
|
||||
@@ -202,3 +204,5 @@ export class SysSafeSetting extends BaseSettings {
|
||||
autoHiddenTimes: 5,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,11 +3,12 @@ import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { SysSettingsEntity } from '../entity/sys-settings.js';
|
||||
import { BaseSettings, SysInstallInfo, SysPrivateSettings, SysPublicSettings, SysSecret, SysSecretBackup } from './models.js';
|
||||
import * as _ from 'lodash-es';
|
||||
|
||||
import { BaseService } from '../../../basic/index.js';
|
||||
import { cache, logger, setGlobalProxy } from '@certd/basic';
|
||||
import * as dns from 'node:dns';
|
||||
|
||||
import {mergeUtils} from "@certd/basic";
|
||||
const {merge} = mergeUtils;
|
||||
/**
|
||||
* 设置
|
||||
*/
|
||||
@@ -75,7 +76,7 @@ export class SysSettingsService extends BaseService<SysSettingsEntity> {
|
||||
}
|
||||
let newSetting: T = new type();
|
||||
const savedSettings = await this.getSettingByKey(key);
|
||||
newSetting = _.merge(newSetting, savedSettings);
|
||||
newSetting = merge(newSetting, savedSettings);
|
||||
await this.saveSetting(newSetting);
|
||||
cache.set(cacheKey, newSetting);
|
||||
return newSetting;
|
||||
|
||||
@@ -3,6 +3,42 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.9](https://github.com/certd/certd/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.34.8](https://github.com/certd/certd/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.34.7](https://github.com/certd/certd/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.34.6](https://github.com/certd/certd/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.34.5](https://github.com/certd/certd/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.34.4](https://github.com/certd/certd/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.34.3](https://github.com/certd/certd/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.34.2](https://github.com/certd/certd/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.34.1](https://github.com/certd/certd/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
# [1.34.0](https://github.com/certd/certd/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/midway-flyway-js",
|
||||
"version": "1.34.0",
|
||||
"version": "1.34.9",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -46,5 +46,5 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "9b420ad33ff4c36fc99d643c18be9ec7e29f220d"
|
||||
"gitHead": "d876ea671137e7a4d99a23bb8a5baed06f119dfb"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,56 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.9](https://github.com/certd/certd/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 邮箱支持保存和选择 ([f7b0b44](https://github.com/certd/certd/commit/f7b0b44ef6044bec36510a6f0b06d8dca5bfce49))
|
||||
|
||||
## [1.34.8](https://github.com/certd/certd/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复证书申请任务无法修改dns提供商类型的bug ([8802274](https://github.com/certd/certd/commit/88022747bebe2054223e0241d68d410771405e68))
|
||||
|
||||
## [1.34.7](https://github.com/certd/certd/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
## [1.34.6](https://github.com/certd/certd/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复公共插件配置修改不生效的bug,优化系统设置参数注入时机 ([e1e510c](https://github.com/certd/certd/commit/e1e510ce1e37a5ae82478226b6987a83f22d1ecb))
|
||||
* 修复lego模式下每次都重新申请证书的bug ([f807b8c](https://github.com/certd/certd/commit/f807b8cb465cc329fa034ecbef94e18ef394f870))
|
||||
* **cert:** 修正证书过期时间计算逻辑 ([a3086e6](https://github.com/certd/certd/commit/a3086e6a5bec8b07f5e1d21a2ca8bd969c75bd5c))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 添加阿里云 ESA证书部署插件 ([1db1ffd](https://github.com/certd/certd/commit/1db1ffde99ac7e4684fa606ebc4c327f829b3a26))
|
||||
|
||||
## [1.34.5](https://github.com/certd/certd/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
## [1.34.4](https://github.com/certd/certd/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
## [1.34.3](https://github.com/certd/certd/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
## [1.34.2](https://github.com/certd/certd/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
## [1.34.1](https://github.com/certd/certd/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 根据SOA记录判断子域名托管有缺陷,改回手动配置子域名托管记录的方式 ([1b280a2](https://github.com/certd/certd/commit/1b280a2940f9e2d919b0bf23b89cc185be1fa498))
|
||||
|
||||
# [1.34.0](https://github.com/certd/certd/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-cert",
|
||||
"private": false,
|
||||
"version": "1.34.0",
|
||||
"version": "1.34.9",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -12,13 +12,14 @@
|
||||
"dev-build": "npm run build",
|
||||
"build3": "rollup -c",
|
||||
"build2": "vue-tsc --noEmit && vite build",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.34.0",
|
||||
"@certd/basic": "^1.34.0",
|
||||
"@certd/pipeline": "^1.34.0",
|
||||
"@certd/plugin-lib": "^1.34.0",
|
||||
"@certd/acme-client": "^1.34.9",
|
||||
"@certd/basic": "^1.34.9",
|
||||
"@certd/pipeline": "^1.34.9",
|
||||
"@certd/plugin-lib": "^1.34.9",
|
||||
"@google-cloud/publicca": "^1.3.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"jszip": "^3.10.1",
|
||||
@@ -42,5 +43,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "9b420ad33ff4c36fc99d643c18be9ec7e29f220d"
|
||||
"gitHead": "d876ea671137e7a4d99a23bb8a5baed06f119dfb"
|
||||
}
|
||||
|
||||
@@ -4,9 +4,6 @@ import { IAccess, Registrable } from "@certd/pipeline";
|
||||
export type DnsProviderDefine = Registrable & {
|
||||
accessType: string;
|
||||
icon?: string;
|
||||
autowire?: {
|
||||
[key: string]: any;
|
||||
};
|
||||
};
|
||||
|
||||
export type CreateRecordOptions = {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { CreateRecordOptions, DnsProviderContext, DnsProviderDefine, IDnsProvider, RemoveRecordOptions } from "./api.js";
|
||||
import { dnsProviderRegistry } from "./registry.js";
|
||||
import { Decorator } from "@certd/pipeline";
|
||||
import { HttpClient, ILogger } from "@certd/basic";
|
||||
|
||||
export abstract class AbstractDnsProvider<T = any> implements IDnsProvider<T> {
|
||||
@@ -9,6 +8,8 @@ export abstract class AbstractDnsProvider<T = any> implements IDnsProvider<T> {
|
||||
logger!: ILogger;
|
||||
|
||||
usePunyCode(): boolean {
|
||||
//是否使用punycode来添加解析记录
|
||||
//默认都使用原始中文域名来添加
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -39,8 +40,6 @@ export async function createDnsProvider(opts: { dnsProviderType: string; context
|
||||
}
|
||||
// @ts-ignore
|
||||
const dnsProvider: IDnsProvider = new DnsProviderClass();
|
||||
|
||||
Decorator.inject(dnsProviderDefine.autowire, dnsProvider, context);
|
||||
dnsProvider.setCtx(context);
|
||||
await dnsProvider.onInstance();
|
||||
return dnsProvider;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { dnsProviderRegistry } from "./registry.js";
|
||||
import { DnsProviderDefine } from "./api.js";
|
||||
import { Decorator, AUTOWIRE_KEY } from "@certd/pipeline";
|
||||
import { Decorator } from "@certd/pipeline";
|
||||
import * as _ from "lodash-es";
|
||||
|
||||
// 提供一个唯一 key
|
||||
@@ -9,15 +9,6 @@ export const DNS_PROVIDER_CLASS_KEY = "pipeline:dns-provider";
|
||||
export function IsDnsProvider(define: DnsProviderDefine): ClassDecorator {
|
||||
return (target: any) => {
|
||||
target = Decorator.target(target);
|
||||
const autowires: any = {};
|
||||
const properties = Decorator.getClassProperties(target);
|
||||
for (const property in properties) {
|
||||
const autowire = Reflect.getMetadata(AUTOWIRE_KEY, target, property);
|
||||
if (autowire) {
|
||||
autowires[property] = autowire;
|
||||
}
|
||||
}
|
||||
_.merge(define, { autowire: autowires });
|
||||
|
||||
Reflect.defineMetadata(DNS_PROVIDER_CLASS_KEY, define, target);
|
||||
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { IDomainParser, ISubDomainsGetter } from "./api";
|
||||
//@ts-ignore
|
||||
import psl from "psl";
|
||||
import { ILogger, utils, logger as globalLogger } from "@certd/basic";
|
||||
import { resolveDomainBySoaRecord } from "@certd/acme-client";
|
||||
import { logger, utils } from "@certd/basic";
|
||||
|
||||
export class DomainParser implements IDomainParser {
|
||||
subDomainsGetter: ISubDomainsGetter;
|
||||
constructor(subDomainsGetter: ISubDomainsGetter) {
|
||||
logger: ILogger;
|
||||
constructor(subDomainsGetter: ISubDomainsGetter, logger?: ILogger) {
|
||||
this.subDomainsGetter = subDomainsGetter;
|
||||
this.logger = logger || globalLogger;
|
||||
}
|
||||
|
||||
parseDomain(fullDomain: string) {
|
||||
parseDomainByPsl(fullDomain: string) {
|
||||
const parsed = psl.parse(fullDomain) as psl.ParsedDomain;
|
||||
if (parsed.error) {
|
||||
throw new Error(`解析${fullDomain}域名失败:` + JSON.stringify(parsed.error));
|
||||
@@ -19,38 +21,46 @@ export class DomainParser implements IDomainParser {
|
||||
}
|
||||
|
||||
async parse(fullDomain: string) {
|
||||
logger.info(`查找主域名:${fullDomain}`);
|
||||
this.logger.info(`查找主域名:${fullDomain}`);
|
||||
const cacheKey = `domain_parse:${fullDomain}`;
|
||||
const value = utils.cache.get(cacheKey);
|
||||
if (value) {
|
||||
logger.info(`从缓存获取到主域名:${fullDomain}->${value}`);
|
||||
this.logger.info(`从缓存获取到主域名:${fullDomain}->${value}`);
|
||||
return value;
|
||||
}
|
||||
|
||||
const subDomains = await this.subDomainsGetter.getSubDomains();
|
||||
if (subDomains && subDomains.length > 0) {
|
||||
const fullDomainDot = "." + fullDomain;
|
||||
for (const subDomain of subDomains) {
|
||||
if (fullDomainDot.endsWith("." + subDomain)) {
|
||||
//找到子域名托管
|
||||
utils.cache.set(cacheKey, subDomain, {
|
||||
ttl: 60 * 1000,
|
||||
});
|
||||
this.logger.info(`获取到子域名托管域名:${fullDomain}->${subDomain}`);
|
||||
return subDomain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const res = this.parseDomainByPsl(fullDomain);
|
||||
this.logger.info(`从psl获取主域名:${fullDomain}->${res}`);
|
||||
|
||||
let soaManDomain = null;
|
||||
try {
|
||||
const mainDomain = await resolveDomainBySoaRecord(fullDomain);
|
||||
if (mainDomain) {
|
||||
utils.cache.set(cacheKey, mainDomain, {
|
||||
ttl: 2 * 60 * 1000,
|
||||
});
|
||||
logger.info(`获取到主域名:${fullDomain}->${mainDomain}`);
|
||||
return mainDomain;
|
||||
this.logger.info(`从SOA获取到主域名:${fullDomain}->${mainDomain}`);
|
||||
soaManDomain = mainDomain;
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error("从SOA获取主域名失败", e.message);
|
||||
this.logger.error("从SOA获取主域名失败", e.message);
|
||||
}
|
||||
if (soaManDomain && soaManDomain !== res) {
|
||||
this.logger.warn(`SOA获取的主域名(${soaManDomain})和psl获取的主域名(${res})不一致,请确认是否有设置子域名托管`);
|
||||
}
|
||||
|
||||
// const subDomains = await this.subDomainsGetter.getSubDomains();
|
||||
// if (subDomains && subDomains.length > 0) {
|
||||
// for (const subDomain of subDomains) {
|
||||
// if (fullDomain.endsWith(subDomain)) {
|
||||
// //找到子域名托管
|
||||
// return subDomain;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
const res = this.parseDomain(fullDomain);
|
||||
logger.info(`从psl获取主域名:${fullDomain}->${res}`);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ type AcmeServiceOptions = {
|
||||
maxCheckRetryCount?: number;
|
||||
userId: number;
|
||||
domainParser: IDomainParser;
|
||||
waitDnsDiffuseTime?: number;
|
||||
};
|
||||
|
||||
export class AcmeService {
|
||||
@@ -248,7 +249,10 @@ export class AcmeService {
|
||||
fullRecord = cname.fullRecord;
|
||||
}
|
||||
} else {
|
||||
this.logger.error("未找到域名Cname校验计划,使用默认的dnsProvider");
|
||||
this.logger.error(`未找到域名${fullDomain}的CNAME校验计划,请修改证书申请配置`);
|
||||
}
|
||||
if (dnsProvider == null) {
|
||||
throw new Error(`未找到域名${fullDomain}CNAME校验计划的DnsProvider,请修改证书申请配置`);
|
||||
}
|
||||
} else if (domainVerifyPlan.type === "http") {
|
||||
const httpVerifyPlan = domainVerifyPlan.httpVerifyPlan;
|
||||
|
||||
@@ -27,7 +27,8 @@ export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
|
||||
"1、支持多个域名打到一个证书上,例如: foo.com,*.foo.com,*.bar.com\n" +
|
||||
"2、子域名被通配符包含的不要填写,例如:www.foo.com已经被*.foo.com包含,不要填写www.foo.com\n" +
|
||||
"3、泛域名只能通配*号那一级(*.foo.com的证书不能用于xxx.yyy.foo.com、不能用于foo.com)\n" +
|
||||
"4、输入一个,空格之后,再输入下一个",
|
||||
"4、输入一个,空格之后,再输入下一个 \n" +
|
||||
"5、如果您配置了子域托管解析,请先[设置托管子域名](#/certd/pipeline/subDomain)",
|
||||
})
|
||||
domains!: string[];
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ export abstract class CertApplyBasePlugin extends CertApplyBaseConvertPlugin {
|
||||
@TaskInput({
|
||||
title: "邮箱",
|
||||
component: {
|
||||
name: "a-input",
|
||||
name: "email-selector",
|
||||
vModel: "value",
|
||||
},
|
||||
rules: [{ type: "email", message: "请输入正确的邮箱" }],
|
||||
@@ -81,6 +81,10 @@ export abstract class CertApplyBasePlugin extends CertApplyBaseConvertPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
getCheckChangeInputKeys() {
|
||||
//插件哪些字段参与校验是否需要更新
|
||||
return ["domains", "sslProvider", "privateKeyType", "dnsProviderType", "pfxPassword"];
|
||||
}
|
||||
/**
|
||||
* 是否更新证书
|
||||
*/
|
||||
@@ -91,7 +95,7 @@ export abstract class CertApplyBasePlugin extends CertApplyBaseConvertPlugin {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
const checkInputChanges = ["domains", "sslProvider", "privateKeyType", "dnsProviderType", "pfxPassword"];
|
||||
const checkInputChanges = this.getCheckChangeInputKeys();
|
||||
const oldInput = JSON.stringify(pick(this.lastStatus?.input, checkInputChanges));
|
||||
const thisInput = JSON.stringify(pick(this, checkInputChanges));
|
||||
const inputChanged = oldInput !== thisInput;
|
||||
@@ -145,7 +149,8 @@ export abstract class CertApplyBasePlugin extends CertApplyBaseConvertPlugin {
|
||||
throw new Error("过期时间不能为空");
|
||||
}
|
||||
// 检查有效期
|
||||
const leftDays = dayjs(expires).diff(dayjs(), "day");
|
||||
const leftDays = Math.floor((expires - dayjs().valueOf()) / (1000 * 60 * 60 * 24));
|
||||
this.logger.info(`证书剩余天数:${leftDays}`);
|
||||
return {
|
||||
isWillExpire: leftDays <= maxDays,
|
||||
leftDays,
|
||||
|
||||
@@ -93,6 +93,21 @@ export class CertReader {
|
||||
return domains;
|
||||
}
|
||||
|
||||
getAltNames() {
|
||||
const { detail } = this.getCrtDetail();
|
||||
return detail.domains.altNames;
|
||||
}
|
||||
|
||||
static getMainDomain(crt: string) {
|
||||
const { detail } = CertReader.readCertDetail(crt);
|
||||
return detail.domains.commonName;
|
||||
}
|
||||
|
||||
getMainDomain() {
|
||||
const { detail } = this.getCrtDetail();
|
||||
return detail.domains.commonName;
|
||||
}
|
||||
|
||||
saveToFile(type: "crt" | "key" | "pfx" | "der" | "oc" | "one" | "ic" | "jks", filepath?: string) {
|
||||
if (!this.cert[type]) {
|
||||
return;
|
||||
@@ -164,8 +179,14 @@ export class CertReader {
|
||||
buildCertFileName(suffix: string, applyTime: any, prefix = "cert") {
|
||||
const detail = this.getCrtDetail();
|
||||
let domain = detail.detail.domains.commonName;
|
||||
domain = domain.replace(".", "_").replace("*", "_");
|
||||
domain = domain.replaceAll(".", "_").replaceAll("*", "_");
|
||||
const timeStr = dayjs(applyTime).format("YYYYMMDDHHmmss");
|
||||
return `${prefix}_${domain}_${timeStr}.${suffix}`;
|
||||
}
|
||||
|
||||
buildCertName() {
|
||||
let domain = this.getMainDomain();
|
||||
domain = domain.replaceAll("*", "_").replaceAll("*", "_");
|
||||
return `${domain}_${dayjs().format("YYYYMMDDHHmmssSSS")}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,9 +68,9 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
||||
],
|
||||
},
|
||||
required: true,
|
||||
helper: `DNS直接验证:域名是在阿里云/腾讯云/华为云/Cloudflare/NameSilo/西数/火山/dns.la/京东云注册的,选它;
|
||||
CNAME代理验证:支持任何注册商注册的域名,但第一次需要手动添加CNAME记录;
|
||||
HTTP文件验证:不支持泛域名,需要配置网站文件上传`,
|
||||
helper: `1. <b>DNS直接验证</b>:域名dns解析是在阿里云/腾讯云/华为云/CF/NameSilo/西数/火山/dns.la/京东云/51dns的,选它
|
||||
2. <b>CNAME代理验证</b>:支持任何注册商的域名,第一次需要手动添加CNAME记录(建议将DNS服务器修改为阿里云/腾讯云的,然后使用DNS直接验证)
|
||||
3. <b>HTTP文件验证</b>:不支持泛域名,需要配置网站文件上传`,
|
||||
})
|
||||
challengeType!: string;
|
||||
|
||||
@@ -102,11 +102,11 @@ HTTP文件验证:不支持泛域名,需要配置网站文件上传`,
|
||||
return form.challengeType === 'dns'
|
||||
}),
|
||||
component:{
|
||||
on:{
|
||||
selectedChange({form,$event}){
|
||||
form.dnsProviderAccessType = $event.accessType
|
||||
onSelectedChange: ctx.compute(({form})=>{
|
||||
return ($event)=>{
|
||||
form.dnsProviderAccessType = $event.accessType
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
`,
|
||||
@@ -290,6 +290,17 @@ HTTP文件验证:不支持泛域名,需要配置网站文件上传`,
|
||||
})
|
||||
maxCheckRetryCount = 20;
|
||||
|
||||
@TaskInput({
|
||||
title: "等待解析生效时长",
|
||||
value: 30,
|
||||
component: {
|
||||
name: "a-input-number",
|
||||
vModel: "value",
|
||||
},
|
||||
helper: "等待解析生效时长(秒)",
|
||||
})
|
||||
waitDnsDiffuseTime = 30;
|
||||
|
||||
acme!: AcmeService;
|
||||
|
||||
eab!: EabAccess;
|
||||
@@ -309,7 +320,7 @@ HTTP文件验证:不支持泛域名,需要配置网站文件上传`,
|
||||
this.logger.info("当前正在使用 google EAB授权");
|
||||
eab = await this.getAccess(this.eabAccessId);
|
||||
} else if (this.googleCommonEabAccessId) {
|
||||
this.logger.info("当前正在使用 google公共EAB授权");
|
||||
this.logger.info("当前正在使用 google 公共EAB授权");
|
||||
eab = await this.getAccess(this.googleCommonEabAccessId, true);
|
||||
} else {
|
||||
throw new Error("google需要配置EAB授权或服务账号授权");
|
||||
@@ -327,7 +338,7 @@ HTTP文件验证:不支持泛域名,需要配置网站文件上传`,
|
||||
}
|
||||
this.eab = eab;
|
||||
const subDomainsGetter = await this.ctx.serviceGetter.get<ISubDomainsGetter>("subDomainsGetter");
|
||||
const domainParser = new DomainParser(subDomainsGetter);
|
||||
const domainParser = new DomainParser(subDomainsGetter, this.logger);
|
||||
this.acme = new AcmeService({
|
||||
userId: this.ctx.user.id,
|
||||
userContext: this.userContext,
|
||||
@@ -341,6 +352,7 @@ HTTP文件验证:不支持泛域名,需要配置网站文件上传`,
|
||||
signal: this.ctx.signal,
|
||||
maxCheckRetryCount: this.maxCheckRetryCount,
|
||||
domainParser,
|
||||
waitDnsDiffuseTime: this.waitDnsDiffuseTime,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -112,9 +112,12 @@ export class CertApplyLegoPlugin extends CertApplyBasePlugin {
|
||||
})
|
||||
privateKeyType!: PrivateKeyType;
|
||||
|
||||
|
||||
eab?: EabAccess;
|
||||
|
||||
getCheckChangeInputKeys() {
|
||||
return ["domains", "privateKeyType", "dnsType"];
|
||||
}
|
||||
|
||||
async onInstance() {
|
||||
this.accessService = this.ctx.accessService;
|
||||
this.logger = this.ctx.logger;
|
||||
|
||||
27
packages/plugins/plugin-cert/test/cert-plugin.test.mjs
Normal file
@@ -0,0 +1,27 @@
|
||||
import { expect } from "chai";
|
||||
import { CertApplyPlugin } from "../dist/index.js";
|
||||
import dayjs from "dayjs";
|
||||
import { logger } from "@certd/basic";
|
||||
|
||||
describe("test/cert-plugin.ts", () => {
|
||||
const certApplyPlugin = new CertApplyPlugin();
|
||||
certApplyPlugin.logger = logger;
|
||||
it("should throw error when expires is null or undefined", () => {
|
||||
expect(() => {
|
||||
// @ts-ignore
|
||||
certApplyPlugin.isWillExpire(undefined);
|
||||
}).throw("过期时间不能为空");
|
||||
|
||||
expect(() => {
|
||||
// @ts-ignore
|
||||
certApplyPlugin.isWillExpire(null);
|
||||
}).throw("过期时间不能为空");
|
||||
});
|
||||
|
||||
it("isWillExpire", () => {
|
||||
const now = dayjs().add(36, "day") - 10000;
|
||||
const res = certApplyPlugin.isWillExpire(now.valueOf(), 35);
|
||||
console.log(res);
|
||||
expect(res.isWillExpire).eq(true);
|
||||
});
|
||||
});
|
||||
@@ -3,6 +3,59 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.9](https://github.com/certd/certd/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
## [1.34.8](https://github.com/certd/certd/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复阿里云 esa 证书获取站点列表错误的问题 ([0c2ea5d](https://github.com/certd/certd/commit/0c2ea5da4c836f8a0df132a3f22d399bd9ee1de9))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 关闭腾讯云证书通知提醒 ([231a875](https://github.com/certd/certd/commit/231a875bb481420c39bf76ec9ff4e50954ab9fe4))
|
||||
* 优化站点选择组件,切换选择时不刷新列表 ([3a14714](https://github.com/certd/certd/commit/3a147141b1a5d67c92a5ce88a5313eaa62859e03))
|
||||
|
||||
## [1.34.7](https://github.com/certd/certd/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
## [1.34.6](https://github.com/certd/certd/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 添加阿里云 ESA证书部署插件 ([1db1ffd](https://github.com/certd/certd/commit/1db1ffde99ac7e4684fa606ebc4c327f829b3a26))
|
||||
|
||||
## [1.34.5](https://github.com/certd/certd/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* aaWaf、cdnfly站点选择支持查询 ([8af3463](https://github.com/certd/certd/commit/8af3463668a40b9b99febb02e3b4e0d9d8d719b4))
|
||||
|
||||
## [1.34.4](https://github.com/certd/certd/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
## [1.34.3](https://github.com/certd/certd/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持部署到maoyun cdn ([68f333f](https://github.com/certd/certd/commit/68f333fb87ce85eed27436ecb0f76351c0ccb0d1))
|
||||
|
||||
## [1.34.2](https://github.com/certd/certd/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* http方式支持校验443端口 ([d75fcb7](https://github.com/certd/certd/commit/d75fcb7fec421a9a638eaa27fe9378c84b5e0f19))
|
||||
|
||||
## [1.34.1](https://github.com/certd/certd/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持部署证书到火山dcdn ([5f85219](https://github.com/certd/certd/commit/5f852194953dc1b4e6336770f417507b8f5a33ad))
|
||||
|
||||
# [1.34.0](https://github.com/certd/certd/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-lib",
|
||||
"private": false,
|
||||
"version": "1.34.0",
|
||||
"version": "1.34.9",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -12,13 +12,16 @@
|
||||
"dev-build": "npm run build",
|
||||
"build3": "rollup -c",
|
||||
"build2": "vue-tsc --noEmit && vite build",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"@alicloud/openapi-client": "^0.4.14",
|
||||
"@alicloud/pop-core": "^1.7.10",
|
||||
"@alicloud/tea-util": "^1.4.10",
|
||||
"@aws-sdk/client-s3": "^3.787.0",
|
||||
"@certd/basic": "^1.34.0",
|
||||
"@certd/pipeline": "^1.34.0",
|
||||
"@certd/basic": "^1.34.9",
|
||||
"@certd/pipeline": "^1.34.9",
|
||||
"@kubernetes/client-node": "0.21.0",
|
||||
"ali-oss": "^6.22.0",
|
||||
"basic-ftp": "^5.0.5",
|
||||
@@ -49,5 +52,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "9b420ad33ff4c36fc99d643c18be9ec7e29f220d"
|
||||
"gitHead": "d876ea671137e7a4d99a23bb8a5baed06f119dfb"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,90 @@
|
||||
import { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline";
|
||||
import { ILogger } from "@certd/basic";
|
||||
|
||||
export type AliyunClientV2Req = {
|
||||
action: string;
|
||||
version: string;
|
||||
protocol?: "HTTPS";
|
||||
// 接口 HTTP 方法
|
||||
method?: "GET" | "POST";
|
||||
authType?: "AK";
|
||||
style?: "RPC";
|
||||
// 接口 PATH
|
||||
pathname?: `/`;
|
||||
|
||||
data?: any;
|
||||
};
|
||||
export class AliyunClientV2 {
|
||||
access: AliyunAccess;
|
||||
logger: ILogger;
|
||||
endpoint: string;
|
||||
|
||||
client: any;
|
||||
constructor(opts: { access: AliyunAccess; logger: ILogger; endpoint: string }) {
|
||||
this.access = opts.access;
|
||||
this.logger = opts.logger;
|
||||
this.endpoint = opts.endpoint;
|
||||
}
|
||||
|
||||
async getClient() {
|
||||
if (this.client) {
|
||||
return this.client;
|
||||
}
|
||||
const $OpenApi = await import("@alicloud/openapi-client");
|
||||
// const Credential = await import("@alicloud/credentials");
|
||||
// //@ts-ignore
|
||||
// const credential = new Credential.default.default({
|
||||
//
|
||||
// type: "access_key",
|
||||
// });
|
||||
const config = new $OpenApi.Config({
|
||||
accessKeyId: this.access.accessKeyId,
|
||||
accessKeySecret: this.access.accessKeySecret,
|
||||
});
|
||||
// Endpoint 请参考 https://api.aliyun.com/product/FC
|
||||
// config.endpoint = `esa.${this.regionId}.aliyuncs.com`;
|
||||
config.endpoint = this.endpoint;
|
||||
//@ts-ignore
|
||||
this.client = new $OpenApi.default.default(config);
|
||||
return this.client;
|
||||
}
|
||||
|
||||
async doRequest(req: AliyunClientV2Req) {
|
||||
const client = await this.getClient();
|
||||
|
||||
const $OpenApi = await import("@alicloud/openapi-client");
|
||||
const $Util = await import("@alicloud/tea-util");
|
||||
|
||||
const params = new $OpenApi.Params({
|
||||
// 接口名称
|
||||
action: req.action,
|
||||
// 接口版本
|
||||
version: req.version,
|
||||
// 接口协议
|
||||
protocol: "HTTPS",
|
||||
// 接口 HTTP 方法
|
||||
method: req.method ?? "POST",
|
||||
authType: "AK",
|
||||
style: "RPC",
|
||||
// 接口 PATH
|
||||
pathname: `/`,
|
||||
// 接口请求体内容格式
|
||||
reqBodyType: "json",
|
||||
// 接口响应体内容格式
|
||||
bodyType: "json",
|
||||
});
|
||||
|
||||
const runtime = new $Util.RuntimeOptions({});
|
||||
const request = new $OpenApi.OpenApiRequest(req.data);
|
||||
// 复制代码运行请自行打印 API 的返回值
|
||||
// 返回值实际为 Map 类型,可从 Map 中获得三类数据:响应体 body、响应头 headers、HTTP 返回的状态码 statusCode。
|
||||
const res = await client.callApi(params, request, runtime);
|
||||
/**
|
||||
* res?.body?.
|
||||
*/
|
||||
return res?.body;
|
||||
}
|
||||
}
|
||||
|
||||
@IsAccess({
|
||||
name: "aliyun",
|
||||
@@ -27,6 +113,14 @@ export class AliyunAccess extends BaseAccess {
|
||||
helper: "注意:证书申请需要dns解析权限;其他阿里云插件,需要对应的权限,比如证书上传需要证书管理权限;嫌麻烦就用主账号的全量权限的accessKey",
|
||||
})
|
||||
accessKeySecret = "";
|
||||
|
||||
getClient(endpoint: string) {
|
||||
return new AliyunClientV2({
|
||||
access: this,
|
||||
logger: this.ctx.logger,
|
||||
endpoint: endpoint,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
new AliyunAccess();
|
||||
|
||||
@@ -52,9 +52,11 @@ export class AliossClient {
|
||||
}
|
||||
}
|
||||
|
||||
async uploadFile(filePath: string, content: Buffer | string) {
|
||||
async uploadFile(filePath: string, content: Buffer | string, timeout = 1000 * 60 * 60) {
|
||||
await this.init();
|
||||
return await this.client.put(filePath, content);
|
||||
return await this.client.put(filePath, content, {
|
||||
timeout,
|
||||
});
|
||||
}
|
||||
|
||||
async removeFile(filePath: string) {
|
||||
@@ -62,9 +64,11 @@ export class AliossClient {
|
||||
return await this.client.delete(filePath);
|
||||
}
|
||||
|
||||
async downloadFile(key: string, savePath: string) {
|
||||
async downloadFile(key: string, savePath: string, timeout = 1000 * 60 * 60) {
|
||||
await this.init();
|
||||
return await this.client.get(key, savePath);
|
||||
return await this.client.get(key, savePath, {
|
||||
timeout,
|
||||
});
|
||||
}
|
||||
|
||||
async listDir(dirKey: string) {
|
||||
|
||||
@@ -83,7 +83,7 @@ export class AliyunSslClient {
|
||||
method: "POST",
|
||||
};
|
||||
|
||||
this.opts.logger.info("开始上传证书");
|
||||
this.opts.logger.info(`开始上传证书:${req.name}`);
|
||||
const ret: any = await client.request("UploadUserCertificate", params, requestOption);
|
||||
this.checkRet(ret);
|
||||
this.opts.logger.info("证书上传成功:aliyunCertId=", ret.CertId);
|
||||
|
||||
@@ -1,82 +1 @@
|
||||
import { merge } from "lodash-es";
|
||||
|
||||
export function createCertDomainGetterInputDefine(opts?: { certInputKey?: string; props?: any }) {
|
||||
const certInputKey = opts?.certInputKey || "cert";
|
||||
return merge(
|
||||
{
|
||||
title: "当前证书域名",
|
||||
component: {
|
||||
name: "cert-domains-getter",
|
||||
},
|
||||
mergeScript: `
|
||||
return {
|
||||
component:{
|
||||
inputKey: ctx.compute(({form})=>{
|
||||
return form.${certInputKey}
|
||||
}),
|
||||
}
|
||||
}
|
||||
`,
|
||||
required: true,
|
||||
},
|
||||
opts?.props
|
||||
);
|
||||
}
|
||||
|
||||
export function createRemoteSelectInputDefine(opts?: {
|
||||
title: string;
|
||||
certDomainsInputKey?: string;
|
||||
accessIdInputKey?: string;
|
||||
typeName?: string;
|
||||
action: string;
|
||||
type?: string;
|
||||
watches?: string[];
|
||||
helper?: string;
|
||||
formItem?: any;
|
||||
mode?: string;
|
||||
multi?: boolean;
|
||||
required?: boolean;
|
||||
rules?: any;
|
||||
}) {
|
||||
const title = opts?.title || "请选择";
|
||||
const certDomainsInputKey = opts?.certDomainsInputKey || "certDomains";
|
||||
const accessIdInputKey = opts?.accessIdInputKey || "accessId";
|
||||
const typeName = opts?.typeName;
|
||||
const action = opts?.action;
|
||||
const type = opts?.type || "plugin";
|
||||
const watches = opts?.watches || [];
|
||||
const helper = opts?.helper || "请选择";
|
||||
let mode = "tags";
|
||||
if (opts.multi === false) {
|
||||
mode = undefined;
|
||||
} else {
|
||||
mode = opts?.mode ?? "tags";
|
||||
}
|
||||
|
||||
const item = {
|
||||
title,
|
||||
component: {
|
||||
name: "remote-select",
|
||||
vModel: "value",
|
||||
mode,
|
||||
type,
|
||||
typeName,
|
||||
action,
|
||||
watches: [certDomainsInputKey, accessIdInputKey, ...watches],
|
||||
},
|
||||
rules: opts?.rules,
|
||||
required: opts.required ?? true,
|
||||
mergeScript: `
|
||||
return {
|
||||
component:{
|
||||
form: ctx.compute(({form})=>{
|
||||
return form
|
||||
})
|
||||
},
|
||||
}
|
||||
`,
|
||||
helper,
|
||||
};
|
||||
|
||||
return merge(item, opts?.formItem);
|
||||
}
|
||||
export * from "./util.js";
|
||||
|
||||
93
packages/plugins/plugin-lib/src/common/util.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { merge } from "lodash-es";
|
||||
|
||||
export function createCertDomainGetterInputDefine(opts?: { certInputKey?: string; props?: any }) {
|
||||
const certInputKey = opts?.certInputKey || "cert";
|
||||
return merge(
|
||||
{
|
||||
title: "当前证书域名",
|
||||
component: {
|
||||
name: "cert-domains-getter",
|
||||
},
|
||||
mergeScript: `
|
||||
return {
|
||||
component:{
|
||||
inputKey: ctx.compute(({form})=>{
|
||||
return form.${certInputKey}
|
||||
}),
|
||||
}
|
||||
}
|
||||
`,
|
||||
required: true,
|
||||
},
|
||||
opts?.props
|
||||
);
|
||||
}
|
||||
|
||||
export function createRemoteSelectInputDefine(opts?: {
|
||||
title: string;
|
||||
certDomainsInputKey?: string;
|
||||
accessIdInputKey?: string;
|
||||
typeName?: string;
|
||||
action: string;
|
||||
type?: string;
|
||||
watches?: string[];
|
||||
helper?: string;
|
||||
formItem?: any;
|
||||
mode?: string;
|
||||
multi?: boolean;
|
||||
required?: boolean;
|
||||
rules?: any;
|
||||
mergeScript?: string;
|
||||
search?: boolean;
|
||||
pager?: boolean;
|
||||
component?: any;
|
||||
}) {
|
||||
const title = opts?.title || "请选择";
|
||||
const certDomainsInputKey = opts?.certDomainsInputKey || "certDomains";
|
||||
const accessIdInputKey = opts?.accessIdInputKey || "accessId";
|
||||
const typeName = opts?.typeName;
|
||||
const action = opts?.action;
|
||||
const type = opts?.type || "plugin";
|
||||
const watches = opts?.watches || [];
|
||||
const helper = opts?.helper || "请选择";
|
||||
const search = opts?.search ?? false;
|
||||
const pager = opts?.pager ?? false;
|
||||
let mode = "tags";
|
||||
if (opts.multi === false) {
|
||||
mode = undefined;
|
||||
} else {
|
||||
mode = opts?.mode ?? "tags";
|
||||
}
|
||||
|
||||
const item = {
|
||||
title,
|
||||
component: {
|
||||
name: "remote-select",
|
||||
vModel: "value",
|
||||
mode,
|
||||
type,
|
||||
typeName,
|
||||
action,
|
||||
search,
|
||||
pager,
|
||||
watches: [certDomainsInputKey, accessIdInputKey, ...watches],
|
||||
...opts.component,
|
||||
},
|
||||
rules: opts?.rules,
|
||||
required: opts.required ?? true,
|
||||
mergeScript:
|
||||
opts.mergeScript ??
|
||||
`
|
||||
return {
|
||||
component:{
|
||||
form: ctx.compute(({form})=>{
|
||||
return form
|
||||
})
|
||||
},
|
||||
}
|
||||
`,
|
||||
helper,
|
||||
};
|
||||
|
||||
return merge(item, opts?.formItem);
|
||||
}
|
||||
@@ -24,7 +24,7 @@ export class FtpAccess extends BaseAccess {
|
||||
host!: string;
|
||||
|
||||
@AccessInput({
|
||||
title: "host",
|
||||
title: "端口",
|
||||
value: 21,
|
||||
component: {
|
||||
placeholder: "21",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { HttpClient, ILogger, utils } from "@certd/basic";
|
||||
import { HttpClient, ILogger, safePromise, utils } from "@certd/basic";
|
||||
import { QiniuAccess } from "../access.js";
|
||||
import fs from "fs";
|
||||
|
||||
@@ -77,7 +77,7 @@ export class QiniuClient {
|
||||
const http = new HttpClient({ timeout: 10000, middlewares: [auth] });
|
||||
console.log("http", http);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
return safePromise((resolve, reject) => {
|
||||
try {
|
||||
http.get({
|
||||
url: opts.url,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// @ts-ignore
|
||||
import path from "path";
|
||||
import { isArray } from "lodash-es";
|
||||
import { ILogger } from "@certd/basic";
|
||||
import { ILogger, safePromise } from "@certd/basic";
|
||||
import { SshAccess } from "./ssh-access.js";
|
||||
|
||||
import fs from "fs";
|
||||
@@ -70,7 +70,7 @@ export class AsyncSsh2Client {
|
||||
const ssh2 = await import("ssh2");
|
||||
const ssh2Constants = await import("ssh2/lib/protocol/constants.js");
|
||||
const { SUPPORTED_KEX, SUPPORTED_SERVER_HOST_KEY, SUPPORTED_CIPHER, SUPPORTED_MAC } = ssh2Constants.default;
|
||||
return new Promise((resolve, reject) => {
|
||||
return safePromise((resolve, reject) => {
|
||||
try {
|
||||
const conn = new ssh2.default.Client();
|
||||
conn
|
||||
@@ -108,7 +108,7 @@ export class AsyncSsh2Client {
|
||||
});
|
||||
}
|
||||
async getSftp() {
|
||||
return new Promise((resolve, reject) => {
|
||||
return safePromise((resolve, reject) => {
|
||||
this.logger.info("获取sftp");
|
||||
this.conn.sftp((err: any, sftp: any) => {
|
||||
if (err) {
|
||||
@@ -122,7 +122,7 @@ export class AsyncSsh2Client {
|
||||
|
||||
async fastPut(options: { sftp: any; localPath: string; remotePath: string; opts?: { mode?: string } }) {
|
||||
const { sftp, localPath, remotePath, opts } = options;
|
||||
return new Promise((resolve, reject) => {
|
||||
return safePromise((resolve, reject) => {
|
||||
this.logger.info(`开始上传:${localPath} => ${remotePath}`);
|
||||
sftp.fastPut(localPath, remotePath, { ...(opts ?? {}) }, (err: Error) => {
|
||||
if (err) {
|
||||
@@ -138,7 +138,7 @@ export class AsyncSsh2Client {
|
||||
|
||||
async listDir(options: { sftp: any; remotePath: string }) {
|
||||
const { sftp, remotePath } = options;
|
||||
return new Promise((resolve, reject) => {
|
||||
return safePromise((resolve, reject) => {
|
||||
this.logger.info(`listDir:${remotePath}`);
|
||||
sftp.readdir(remotePath, (err: Error, list: any) => {
|
||||
if (err) {
|
||||
@@ -152,7 +152,7 @@ export class AsyncSsh2Client {
|
||||
|
||||
async unlink(options: { sftp: any; remotePath: string }) {
|
||||
const { sftp, remotePath } = options;
|
||||
return new Promise((resolve, reject) => {
|
||||
return safePromise((resolve, reject) => {
|
||||
this.logger.info(`开始删除远程文件:${remotePath}`);
|
||||
sftp.unlink(remotePath, (err: Error) => {
|
||||
if (err) {
|
||||
@@ -182,7 +182,7 @@ export class AsyncSsh2Client {
|
||||
// script += "\r\nexit\r\n";
|
||||
// //保证windows下正常退出
|
||||
// }
|
||||
return new Promise((resolve, reject) => {
|
||||
return safePromise((resolve, reject) => {
|
||||
this.logger.info(`执行命令:[${this.connConf.host}][exec]: \n` + script);
|
||||
// pty 伪终端,window下的输出会带上conhost.exe之类的多余的字符串,影响返回结果判断
|
||||
// linux下 当使用keyboard-interactive 登录时,需要pty
|
||||
@@ -232,7 +232,7 @@ export class AsyncSsh2Client {
|
||||
async shell(script: string | string[]): Promise<string> {
|
||||
const stripAnsiModule = await import("strip-ansi");
|
||||
const stripAnsi = stripAnsiModule.default;
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
return safePromise<any>((resolve, reject) => {
|
||||
this.logger.info(`执行shell脚本:[${this.connConf.host}][shell]: ` + script);
|
||||
this.conn.shell((err: Error, stream: any) => {
|
||||
if (err) {
|
||||
@@ -299,7 +299,7 @@ export class AsyncSsh2Client {
|
||||
}
|
||||
|
||||
async download(param: { remotePath: string; savePath: string; sftp: any }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return safePromise((resolve, reject) => {
|
||||
const { remotePath, savePath, sftp } = param;
|
||||
sftp.fastGet(
|
||||
remotePath,
|
||||
@@ -385,44 +385,40 @@ export class SshClient {
|
||||
|
||||
async scpUpload(options: { conn: any; localPath: string; remotePath: string; opts?: { mode?: string } }) {
|
||||
const { conn, localPath, remotePath } = options;
|
||||
return new Promise((resolve, reject) => {
|
||||
return safePromise((resolve, reject) => {
|
||||
// 关键步骤:构造 SCP 命令
|
||||
try {
|
||||
this.logger.info(`开始上传:${localPath} => ${remotePath}`);
|
||||
conn.conn.exec(
|
||||
`scp -t ${remotePath}`, // -t 表示目标模式
|
||||
(err, stream) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
try {
|
||||
// 准备 SCP 协议头
|
||||
const fileStats = fs.statSync(localPath);
|
||||
const fileName = path.basename(localPath);
|
||||
|
||||
// SCP 协议格式:C[权限] [文件大小] [文件名]\n
|
||||
stream.write(`C0644 ${fileStats.size} ${fileName}\n`);
|
||||
|
||||
// 通过管道传输文件
|
||||
fs.createReadStream(localPath)
|
||||
.on("error", e => {
|
||||
this.logger.info("read stream error", e);
|
||||
reject(e);
|
||||
})
|
||||
.pipe(stream)
|
||||
.on("finish", async () => {
|
||||
this.logger.info(`上传完成:${localPath} => ${remotePath}`);
|
||||
resolve(true);
|
||||
})
|
||||
.on("error", reject);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
this.logger.info(`开始上传:${localPath} => ${remotePath}`);
|
||||
conn.conn.exec(
|
||||
`scp -t ${remotePath}`, // -t 表示目标模式
|
||||
(err, stream) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
try {
|
||||
// 准备 SCP 协议头
|
||||
const fileStats = fs.statSync(localPath);
|
||||
const fileName = path.basename(localPath);
|
||||
|
||||
// SCP 协议格式:C[权限] [文件大小] [文件名]\n
|
||||
stream.write(`C0644 ${fileStats.size} ${fileName}\n`);
|
||||
|
||||
// 通过管道传输文件
|
||||
fs.createReadStream(localPath)
|
||||
.on("error", e => {
|
||||
this.logger.info("read stream error", e);
|
||||
reject(e);
|
||||
})
|
||||
.pipe(stream)
|
||||
.on("finish", async () => {
|
||||
this.logger.info(`上传完成:${localPath} => ${remotePath}`);
|
||||
resolve(true);
|
||||
})
|
||||
.on("error", reject);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { TencentAccess } from "../access.js";
|
||||
import { ILogger } from "@certd/basic";
|
||||
import { ILogger, safePromise } from "@certd/basic";
|
||||
import fs from "fs";
|
||||
|
||||
export class TencentCosClient {
|
||||
@@ -26,7 +26,7 @@ export class TencentCosClient {
|
||||
|
||||
async uploadFile(key: string, file: Buffer | string) {
|
||||
const cos = await this.getCosClient();
|
||||
return new Promise((resolve, reject) => {
|
||||
return safePromise((resolve, reject) => {
|
||||
let readableStream = file as any;
|
||||
if (typeof file === "string") {
|
||||
readableStream = fs.createReadStream(file);
|
||||
@@ -54,7 +54,7 @@ export class TencentCosClient {
|
||||
|
||||
async removeFile(key: string) {
|
||||
const cos = await this.getCosClient();
|
||||
return new Promise((resolve, reject) => {
|
||||
return safePromise((resolve, reject) => {
|
||||
cos.deleteObject(
|
||||
{
|
||||
Bucket: this.bucket,
|
||||
@@ -75,7 +75,7 @@ export class TencentCosClient {
|
||||
async downloadFile(key: string, savePath: string) {
|
||||
const cos = await this.getCosClient();
|
||||
const writeStream = fs.createWriteStream(savePath);
|
||||
return new Promise((resolve, reject) => {
|
||||
return safePromise((resolve, reject) => {
|
||||
cos.getObject(
|
||||
{
|
||||
Bucket: this.bucket,
|
||||
@@ -96,7 +96,7 @@ export class TencentCosClient {
|
||||
|
||||
async listDir(dirKey: string) {
|
||||
const cos = await this.getCosClient();
|
||||
return new Promise((resolve, reject) => {
|
||||
return safePromise((resolve, reject) => {
|
||||
cos.getBucket(
|
||||
{
|
||||
Bucket: this.bucket,
|
||||
|
||||
@@ -49,10 +49,23 @@ export class TencentSslClient {
|
||||
};
|
||||
const ret = await client.UploadCertificate(params);
|
||||
this.checkRet(ret);
|
||||
this.logger.info("证书上传成功:tencentCertId=", ret.CertificateId);
|
||||
this.logger.info(`证书[${opts.certName}]上传成功:tencentCertId=`, ret.CertificateId);
|
||||
await this.switchCertNotify([ret.CertificateId], true);
|
||||
return ret.CertificateId;
|
||||
}
|
||||
|
||||
async switchCertNotify(certIds: string[], disabled: boolean) {
|
||||
const client = await this.getSslClient();
|
||||
const params = {
|
||||
CertificateIds: certIds,
|
||||
SwitchStatus: disabled ? 1 : 0, //1是忽略通知,0是不忽略
|
||||
};
|
||||
const ret = await client.ModifyCertificatesExpiringNotificationSwitch(params);
|
||||
this.checkRet(ret);
|
||||
this.logger.info(`关闭证书${certIds}过期通知成功`);
|
||||
return ret.RequestId;
|
||||
}
|
||||
|
||||
async deployCertificateInstance(params: any) {
|
||||
const client = await this.getSslClient();
|
||||
const res = await client.DeployCertificateInstance(params);
|
||||
|
||||
@@ -3,6 +3,88 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.9](https://github.com/certd/certd/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 邮箱支持保存和选择 ([f7b0b44](https://github.com/certd/certd/commit/f7b0b44ef6044bec36510a6f0b06d8dca5bfce49))
|
||||
* 支持github 新版本检查并发布通知 ([356703c](https://github.com/certd/certd/commit/356703c83ea18c6efb8931402e181280d7b7e696))
|
||||
|
||||
## [1.34.8](https://github.com/certd/certd/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复证书申请任务无法修改dns提供商类型的bug ([8802274](https://github.com/certd/certd/commit/88022747bebe2054223e0241d68d410771405e68))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化站点选择组件,切换选择时不刷新列表 ([3a14714](https://github.com/certd/certd/commit/3a147141b1a5d67c92a5ce88a5313eaa62859e03))
|
||||
* 优化站点ip检查 ([a463711](https://github.com/certd/certd/commit/a463711b03a20120f2a298be15d71ca152d27f21))
|
||||
* 站点监控支持监控IP ([9cc4c01](https://github.com/certd/certd/commit/9cc4c017ae646a18284e732769b82636feda01d3))
|
||||
* 支持批量重新运行 ([8189982](https://github.com/certd/certd/commit/818998259ddc75e722196ac5c365038818539b9b))
|
||||
|
||||
## [1.34.7](https://github.com/certd/certd/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/ui-client
|
||||
|
||||
## [1.34.6](https://github.com/certd/certd/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复又拍云 CDN 设置证书参数和强制 HTTPS 配置报错的bug ([7984b62](https://github.com/certd/certd/commit/7984b625ba6727132f205db8e25f790bce27b2f7))
|
||||
* **cert:** 修正证书过期时间计算逻辑 ([a3086e6](https://github.com/certd/certd/commit/a3086e6a5bec8b07f5e1d21a2ca8bd969c75bd5c))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 二次认证页面中,添加动态验证码输入框的焦点控制,提升用户体验 ([bb22f06](https://github.com/certd/certd/commit/bb22f062ed4ab4b5b71938270fe4cc666af6b8e7))
|
||||
* 站点证书监控增加通知设置 ([3422a1a](https://github.com/certd/certd/commit/3422a1a59fd0d2c0f17fa9c7e8988ac527ecfdd9))
|
||||
|
||||
## [1.34.5](https://github.com/certd/certd/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* aaWaf、cdnfly站点选择支持查询 ([8af3463](https://github.com/certd/certd/commit/8af3463668a40b9b99febb02e3b4e0d9d8d719b4))
|
||||
|
||||
## [1.34.4](https://github.com/certd/certd/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复插件导入的bug ([677fec0](https://github.com/certd/certd/commit/677fec0a0b6fceb4966705e471bbfeeda91610c7))
|
||||
* 修复自建插件保存丢失部署策略的bug ([863e74d](https://github.com/certd/certd/commit/863e74dd2e3912f950ff5025b5ed0070aeb37035))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 调整小助手,仅在登录之后显示 ([aebb07c](https://github.com/certd/certd/commit/aebb07c5cc8b1f233b9d203ff017ac60e6971a85))
|
||||
|
||||
## [1.34.3](https://github.com/certd/certd/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 小助手可以关闭 ([3e2101a](https://github.com/certd/certd/commit/3e2101aa5b56548614102e900d59819ce8c7e97c))
|
||||
* 支持AI分析报错 ([aa96859](https://github.com/certd/certd/commit/aa96859798166426e485947a6590464de189de05))
|
||||
|
||||
## [1.34.2](https://github.com/certd/certd/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复刷新流水线页面后,日志不自动更新的bug ([0b2e28b](https://github.com/certd/certd/commit/0b2e28b62dd5eb6804c602083e65c87a9d1d72d2))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 集成智能问答机器人 ([9dd4905](https://github.com/certd/certd/commit/9dd49054d18ec436a5029444ca55a38adc682933))
|
||||
* 支持设置网安备案号 ([d18e431](https://github.com/certd/certd/commit/d18e431e2f08e6b37704032c4ea6fbdd8e971442))
|
||||
|
||||
## [1.34.1](https://github.com/certd/certd/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 根据SOA记录判断子域名托管有缺陷,改回手动配置子域名托管记录的方式 ([1b280a2](https://github.com/certd/certd/commit/1b280a2940f9e2d919b0bf23b89cc185be1fa498))
|
||||
* 修复宝塔授权测试按钮显示错误的bug ([048696e](https://github.com/certd/certd/commit/048696ee9386491bb68592fb3a47d1c900bb68bf))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持部署证书到火山dcdn ([5f85219](https://github.com/certd/certd/commit/5f852194953dc1b4e6336770f417507b8f5a33ad))
|
||||
|
||||
# [1.34.0](https://github.com/certd/certd/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-client",
|
||||
"version": "1.34.0",
|
||||
"version": "1.34.9",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
@@ -19,7 +19,8 @@
|
||||
"upgrade": "yarn upgrade-interactive --latest",
|
||||
"tsc": "vue-tsc --noEmit --skipLibCheck",
|
||||
"circle:check": "pnpm dependency-cruise --validate --output-type err-html -f dependency-report.html src",
|
||||
"afterPubPush": "git add . && git commit -m \"build: publish success\" && git push"
|
||||
"afterPubPush": "git add . && git commit -m \"build: publish success\" && git push",
|
||||
"pub": "echo 1"
|
||||
},
|
||||
"author": "greper",
|
||||
"license": "AGPL-3.0",
|
||||
@@ -101,8 +102,8 @@
|
||||
"zod-defaults": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/lib-iframe": "^1.34.0",
|
||||
"@certd/pipeline": "^1.34.0",
|
||||
"@certd/lib-iframe": "^1.34.9",
|
||||
"@certd/pipeline": "^1.34.9",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/chai": "^4.3.12",
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<script lang="ts" setup>
|
||||
import zhCN from "ant-design-vue/es/locale/zh_CN";
|
||||
import enUS from "ant-design-vue/es/locale/en_US";
|
||||
import { computed, provide, ref } from "vue";
|
||||
import { computed, onMounted, provide, ref } from "vue";
|
||||
import "dayjs/locale/zh-cn";
|
||||
import "dayjs/locale/en";
|
||||
import dayjs from "dayjs";
|
||||
@@ -19,7 +19,9 @@ import { useAntdDesignTokens } from "/@/vben/hooks";
|
||||
import { theme } from "ant-design-vue";
|
||||
import AConfigProvider from "ant-design-vue/es/config-provider";
|
||||
import { Modal } from "ant-design-vue";
|
||||
|
||||
import MaxKBChat from "/@/components/ai/index.vue";
|
||||
import { util } from "/@/utils";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
defineOptions({
|
||||
name: "App",
|
||||
});
|
||||
@@ -46,6 +48,7 @@ localeChanged("zh-cn");
|
||||
provide("fn:router.reload", reload);
|
||||
provide("fn:locale.changed", localeChanged);
|
||||
|
||||
|
||||
const { isDark } = usePreferences();
|
||||
const { tokens } = useAntdDesignTokens();
|
||||
|
||||
@@ -69,4 +72,6 @@ const tokenTheme = computed(() => {
|
||||
// pageStore.init();
|
||||
// const settingStore = useSettingStore();
|
||||
// settingStore.init();
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
@@ -36,7 +36,7 @@ function createService() {
|
||||
return response;
|
||||
}
|
||||
//@ts-ignore
|
||||
if (response.config.returnResponse) {
|
||||
if (response.config.returnOriginRes) {
|
||||
return response;
|
||||
}
|
||||
// dataAxios 是 axios 返回数据中的 data
|
||||
@@ -69,12 +69,10 @@ function createService() {
|
||||
const err = new CodeError(errorMessage, dataAxios.code, dataAxios.data);
|
||||
// @ts-ignore
|
||||
response.config.onError(err);
|
||||
return;
|
||||
}
|
||||
//@ts-ignore
|
||||
const showErrorNotify = response?.config?.showErrorNotify;
|
||||
errorCreate(`${errorMessage}: ${response.config.url}`, showErrorNotify, dataAxios);
|
||||
return dataAxios;
|
||||
}
|
||||
},
|
||||
error => {
|
||||
@@ -142,7 +140,7 @@ function createRequestFunction(service: any) {
|
||||
headers: {
|
||||
"Content-Type": get(config, "headers.Content-Type", "application/json"),
|
||||
},
|
||||
timeout: 20000,
|
||||
timeout: 30000,
|
||||
baseURL: env.API,
|
||||
data: {},
|
||||
};
|
||||
|
||||