Compare commits

...

82 Commits

Author SHA1 Message Date
xiaojunnuo
26f2c9fea2 v1.30.4 2025-02-14 14:58:54 +08:00
xiaojunnuo
290cc0d1bb build: prepare to build 2025-02-14 14:56:19 +08:00
xiaojunnuo
78044c062e fix: 适配最新版1panel密码编码方式 2025-02-14 14:55:15 +08:00
xiaojunnuo
3a2f653229 build: publish 2025-02-14 01:49:16 +08:00
xiaojunnuo
bbe22e6f36 build: trigger build image 2025-02-14 01:48:53 +08:00
xiaojunnuo
d4474ff0fb v1.30.3 2025-02-14 01:46:30 +08:00
xiaojunnuo
c7979f1be5 build: prepare to build 2025-02-14 01:44:45 +08:00
xiaojunnuo
ada0b7106e fix: 修复新版本1panel密码需要加密,无法登录的问题 2025-02-14 01:43:52 +08:00
xiaojunnuo
c3a5542935 fix: 修复腾讯云CLB多域名同证书部署报错的bug
https://github.com/certd/certd/issues/314
2025-02-14 00:42:25 +08:00
xiaojunnuo
287c3688fd build: publish 2025-02-09 16:12:21 +08:00
xiaojunnuo
3948b3993f build: trigger build image 2025-02-09 16:12:04 +08:00
xiaojunnuo
bcacafeb84 v1.30.2 2025-02-09 16:09:40 +08:00
xiaojunnuo
2193ddfabe build: prepare to build 2025-02-09 16:07:13 +08:00
xiaojunnuo
29ae0b7dca build: prepare to build 2025-02-09 16:06:03 +08:00
xiaojunnuo
904837df12 chore: 2025-02-09 16:05:36 +08:00
xiaojunnuo
00c2da444f fix: 修复cloudflare删除解析记录报错的bug 2025-02-09 15:50:08 +08:00
xiaojunnuo
13d0dde9f4 chore: 2025-02-08 22:21:45 +08:00
xiaojunnuo
548f2a960c chore: 增加切换数据库文档 2025-02-08 22:16:27 +08:00
xiaojunnuo
71803f891d chore: 2025-01-24 20:02:11 +08:00
xiaojunnuo
75a38d95f3 perf: 上传自定义证书 2025-01-24 18:04:17 +08:00
xiaojunnuo
c89686a2fd fix: 当前置任务被删除时进行校验 2025-01-24 16:35:40 +08:00
xiaojunnuo
398323533a chore: 2025-01-22 15:43:37 +08:00
xiaojunnuo
a773872cf3 chore: 2025-01-22 15:35:46 +08:00
xiaojunnuo
2eb0d55f92 build: publish 2025-01-20 23:40:07 +08:00
xiaojunnuo
54bd1ad0fa build: trigger build image 2025-01-20 23:39:49 +08:00
xiaojunnuo
089825d360 v1.30.1 2025-01-20 23:37:28 +08:00
xiaojunnuo
333629caff build: prepare to build 2025-01-20 23:35:50 +08:00
xiaojunnuo
d715cd1129 chore: 2025-01-20 23:30:54 +08:00
xiaojunnuo
15d6eaf553 perf: http方式校验,选择sftp时,支持修改文件访问权限比如777 2025-01-20 23:29:03 +08:00
xiaojunnuo
ae5dfc3bee fix: 修复tg消息内容中存在.和*就会发送失败的bug 2025-01-20 18:45:07 +08:00
xiaojunnuo
6ab83b662a fix: 修复部署到阿里云ALB、NLB插件加载混乱的bug 2025-01-20 18:18:16 +08:00
xiaojunnuo
52ae6902d2 perf: 创建流水线时,默认成功时也发送通知 2025-01-20 16:20:14 +08:00
xiaojunnuo
c30adb2671 chore: 2025-01-20 11:55:13 +08:00
xiaojunnuo
e95d29f446 fix: 修复腾讯clb重复执行会报错的bug 2025-01-20 11:53:52 +08:00
xiaojunnuo
c20bb38b06 build: publish 2025-01-20 00:39:15 +08:00
xiaojunnuo
d0213d275d build: trigger build image 2025-01-20 00:38:54 +08:00
xiaojunnuo
9a78dad576 v1.30.0 2025-01-20 00:36:25 +08:00
xiaojunnuo
880f1aeb66 build: prepare to build 2025-01-20 00:34:48 +08:00
xiaojunnuo
e764eabd97 chore: 2025-01-20 00:34:33 +08:00
xiaojunnuo
235f9cf854 build: prepare to build 2025-01-20 00:30:50 +08:00
xiaojunnuo
d10795ecd9 perf: 支持部署证书到proxmox 2025-01-20 00:29:59 +08:00
xiaojunnuo
a7e45dace0 chore: 2025-01-19 23:27:39 +08:00
xiaojunnuo
7e482f798c fix: 修复查看任务日志偶发性无法自动滚动底部的bug 2025-01-19 23:13:30 +08:00
xiaojunnuo
c085bac5d8 perf: 支持部署到阿里云NLB、SLB 2025-01-19 22:55:46 +08:00
xiaojunnuo
653940a0ca perf: 支持部署到阿里云ALB 2025-01-19 15:31:37 +08:00
xiaojunnuo
417d37b199 perf: 支持部署到腾讯云直播 2025-01-19 14:12:16 +08:00
xiaojunnuo
3b2107a4f1 chore: 2025-01-19 01:21:58 +08:00
xiaojunnuo
7f6d03c02a chore: 2025-01-19 01:07:20 +08:00
xiaojunnuo
5fc07d4dd4 chore: 2025-01-19 00:40:43 +08:00
xiaojunnuo
3fb9524cbd Merge remote-tracking branch 'origin/v2-dev' into v2-dev 2025-01-19 00:37:26 +08:00
xiaojunnuo
e79703e49b chore: 2025-01-19 00:33:34 +08:00
xiaojunnuo
b829bd1341 Merge remote-tracking branch 'origin/v2-dev' into v2-dev 2025-01-16 11:49:38 +08:00
xiaojunnuo
8cbab7525a pref: 优化重置管理员密码后打印出用户名,避免忘记用户名的情况 2025-01-16 11:49:09 +08:00
xiaojunnuo
93b37a89c9 chore: 2025-01-15 23:13:17 +08:00
xiaojunnuo
87620b9072 chore: 2025-01-15 22:58:11 +08:00
xiaojunnuo
6877b865a7 chore: 2025-01-15 01:26:39 +08:00
xiaojunnuo
d6b3142a02 chore: 2025-01-15 01:26:23 +08:00
xiaojunnuo
14cdb54212 Merge remote-tracking branch 'origin/v2-dev' into v2-dev 2025-01-15 01:06:16 +08:00
xiaojunnuo
91e7f45a1c perf: 证书仓库 2025-01-15 01:05:34 +08:00
xiaojunnuo
709105120c Merge remote-tracking branch 'origin/v2-dev' into v2-dev 2025-01-14 15:09:16 +08:00
xiaojunnuo
865f26d75c fix: 修复namesilo ttl太短的问题 2025-01-14 14:47:03 +08:00
xiaojunnuo
52a4fd3318 feat: 支持open api接口,根据域名获取证书 2025-01-14 00:54:30 +08:00
xiaojunnuo
c6c269f9e4 chore: 2025-01-12 21:49:17 +08:00
xiaojunnuo
2a8eeaf240 build: publish 2025-01-07 23:19:36 +08:00
xiaojunnuo
f7dcff5113 build: trigger build image 2025-01-07 23:19:12 +08:00
xiaojunnuo
98a81385a6 v1.29.5 2025-01-07 23:16:46 +08:00
xiaojunnuo
7bdc277b58 build: prepare to build 2025-01-07 23:14:55 +08:00
xiaojunnuo
f57116d2be fix: 修复复制到本机插件,pfx格式复制时报错的bug 2025-01-07 23:13:44 +08:00
xiaojunnuo
85c99f7f80 fix: 修复授权管理,点击了查看原文按钮后,无法修改值的bug 2025-01-07 11:00:04 +08:00
xiaojunnuo
75081ceac3 build: publish 2025-01-07 00:02:42 +08:00
xiaojunnuo
65da3ca298 build: trigger build image 2025-01-07 00:02:21 +08:00
xiaojunnuo
94509c64b9 v1.29.4 2025-01-06 23:59:56 +08:00
xiaojunnuo
4f36d94726 build: prepare to build 2025-01-06 23:56:50 +08:00
xiaojunnuo
05c284b999 docs: 文档 2025-01-06 23:55:41 +08:00
xiaojunnuo
635b042690 perf: 优化腾讯云CLB插件,支持非sni情况,sni情况支持填写多个域名 2025-01-06 23:47:08 +08:00
xiaojunnuo
1cb4a539cc fix: 修复站点监控域名校验无法通过的bug 2025-01-06 23:08:16 +08:00
xiaojunnuo
46b87250b2 Merge remote-tracking branch 'origin/v2-dev' into v2-dev 2025-01-06 22:12:42 +08:00
xiaojunnuo
1a05355e54 docs: payments文档 2025-01-06 22:11:07 +08:00
xiaojunnuo
c81c17d17b chore: 2025-01-06 15:32:14 +08:00
xiaojunnuo
7b4f8d31e8 chore: db transform text改成longtext 2025-01-06 09:39:44 +08:00
xiaojunnuo
5cef28c5bd build: publish 2025-01-05 01:14:01 +08:00
xiaojunnuo
6e68da7936 build: trigger build image 2025-01-05 01:13:39 +08:00
153 changed files with 3453 additions and 465 deletions

View File

@@ -3,6 +3,79 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
### Bug Fixes
* 适配最新版1panel密码编码方式 ([78044c0](https://github.com/certd/certd/commit/78044c062e20cdd04f08baef9fb6745bf25eddcf))
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
### Bug Fixes
* 修复腾讯云CLB多域名同证书部署报错的bug ([c3a5542](https://github.com/certd/certd/commit/c3a55429357e78f4b78c9592d3e5897db2d4d549))
* 修复新版本1panel密码需要加密无法登录的问题 ([ada0b71](https://github.com/certd/certd/commit/ada0b7106e97e551783829e4e719f76793a7123d))
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
### Bug Fixes
* 当前置任务被删除时进行校验 ([c89686a](https://github.com/certd/certd/commit/c89686a2fda251484930f0ae715417b618c21690))
* 修复cloudflare删除解析记录报错的bug ([00c2da4](https://github.com/certd/certd/commit/00c2da444f84adb89f3f1226d03294d7c6e3e4f1))
### Performance Improvements
* 上传自定义证书 ([75a38d9](https://github.com/certd/certd/commit/75a38d95f305b4271d9106babe7cffc1c89ae8f3))
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
### Bug Fixes
* 修复部署到阿里云ALB、NLB插件加载混乱的bug ([6ab83b6](https://github.com/certd/certd/commit/6ab83b662a2c5e715b9cb7eb1244de2ebb7f47b0))
* 修复腾讯clb重复执行会报错的bug ([e95d29f](https://github.com/certd/certd/commit/e95d29f446d06eced315a3087fc9e105a30b20bd))
* 修复tg消息内容中存在.和*就会发送失败的bug ([ae5dfc3](https://github.com/certd/certd/commit/ae5dfc3bee950267123ae2fbd1c11e7ce36626ea))
### Performance Improvements
* 创建流水线时,默认成功时也发送通知 ([52ae690](https://github.com/certd/certd/commit/52ae6902d203ca56e0312692b50c55cb6ddd3e39))
* http方式校验选择sftp时支持修改文件访问权限比如777 ([15d6eaf](https://github.com/certd/certd/commit/15d6eaf5532ed25acd4f8d58c429353a2f44206c))
# [1.30.0](https://github.com/certd/certd/compare/v1.29.5...v1.30.0) (2025-01-19)
### Bug Fixes
* 修复查看任务日志偶发性无法自动滚动底部的bug ([7e482f7](https://github.com/certd/certd/commit/7e482f798c0142bce1866f84676cb40210f9638a))
* 修复namesilo ttl太短的问题 ([865f26d](https://github.com/certd/certd/commit/865f26d75c0d3dd4dc8b41448f8830068e45957c))
### Features
* 支持open api接口根据域名获取证书 ([52a4fd3](https://github.com/certd/certd/commit/52a4fd33180e9b3f71b8dc9f7671d7cd8e448c3b))
### Performance Improvements
* 证书仓库 ([91e7f45](https://github.com/certd/certd/commit/91e7f45a1c5ea1e0ec0aa3236b80028f03a6d0aa))
* 支持部署到阿里云ALB ([653940a](https://github.com/certd/certd/commit/653940a0ca64fc380178c1b0b58ae0af64dfaf07))
* 支持部署到阿里云NLB、SLB ([c085bac](https://github.com/certd/certd/commit/c085bac5d877c4250a8a79e17eb8673b8e4fc89c))
* 支持部署到腾讯云直播 ([417d37b](https://github.com/certd/certd/commit/417d37b199b79a42f790f9edab8f178eedf8fbf7))
* 支持部署证书到proxmox ([d10795e](https://github.com/certd/certd/commit/d10795ecd97eb8cf2ffa46aabfdbfc6812636396))
## [1.29.5](https://github.com/certd/certd/compare/v1.29.4...v1.29.5) (2025-01-07)
### Bug Fixes
* 修复复制到本机插件pfx格式复制时报错的bug ([f57116d](https://github.com/certd/certd/commit/f57116d2bebf33e47ad93e0b39c4efe8e4aea25c))
* 修复授权管理点击了查看原文按钮后无法修改值的bug ([85c99f7](https://github.com/certd/certd/commit/85c99f7f80761ac6efaf3255c03b933442db1686))
## [1.29.4](https://github.com/certd/certd/compare/v1.29.3...v1.29.4) (2025-01-06)
### Bug Fixes
* 修复站点监控域名校验无法通过的bug ([1cb4a53](https://github.com/certd/certd/commit/1cb4a539cc523721ffd4b22d40d0e3d2d68cd915))
### Performance Improvements
* 优化腾讯云CLB插件支持非sni情况sni情况支持填写多个域名 ([635b042](https://github.com/certd/certd/commit/635b042690637bff85e97e07c7aac4b87a8a124b))
## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04) ## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04)
### Bug Fixes ### Bug Fixes

View File

@@ -16,7 +16,6 @@ Certd 是一个免费全自动申请和自动部署更新SSL证书的管理系
* 私有化部署数据保存本地授权信息加密存储镜像由Github Actions构建过程公开透明 * 私有化部署数据保存本地授权信息加密存储镜像由Github Actions构建过程公开透明
* 支持SQLitePostgreSQL、MySQL数据库 * 支持SQLitePostgreSQL、MySQL数据库
> >
> 流水线数量现已调整为无限制,欢迎大家使用 > 流水线数量现已调整为无限制,欢迎大家使用
> >

View File

@@ -1 +1 @@
01:55 01:48

View File

@@ -57,6 +57,7 @@ export default defineConfig({
nav: [ nav: [
{ text: "首页", link: "/" }, { text: "首页", link: "/" },
{ text: "指南", link: "/guide/" }, { text: "指南", link: "/guide/" },
{ text: "商业版", link: "/comm/" },
{ text: "Demo体验", link: "https://certd.handfree.work" } { text: "Demo体验", link: "https://certd.handfree.work" }
], ],
sidebar: { sidebar: {
@@ -77,7 +78,8 @@ export default defineConfig({
] ]
}, },
{ text: "演示教程", link: "/guide/tutorial.md" }, { text: "演示教程", link: "/guide/tutorial.md" },
{ text: "版本升级", link: "/guide/install/upgrade.md" } { text: "版本升级", link: "/guide/install/upgrade.md" },
{ text: "切换数据库", link: "/guide/install/database.md" }
] ]
}, },
{ {
@@ -101,12 +103,12 @@ export default defineConfig({
{ text: "js脚本插件使用", link: "/guide/use/custom-script/index.md" }, { text: "js脚本插件使用", link: "/guide/use/custom-script/index.md" },
{ text: "邮箱配置", link: "/guide/use/email/index.md" }, { text: "邮箱配置", link: "/guide/use/email/index.md" },
{ text: "IPv6支持", link: "/guide/use/setting/ipv6.md" }, { text: "IPv6支持", link: "/guide/use/setting/ipv6.md" },
{ text: "如何贡献代码", link: "/guide/development/index.md" },
] ]
}, },
{ {
text: "其他", text: "其他",
items: [ items: [
{ text: "贡献代码", link: "/guide/development/index.md" },
{ text: "更新日志", link: "/guide/changelogs/CHANGELOG.md" }, { text: "更新日志", link: "/guide/changelogs/CHANGELOG.md" },
{ text: "镜像说明", link: "/guide/image.md" }, { text: "镜像说明", link: "/guide/image.md" },
{ text: "联系我们", link: "/guide/contact/" }, { text: "联系我们", link: "/guide/contact/" },
@@ -116,8 +118,20 @@ export default defineConfig({
] ]
} }
],
"/comm/": [
{
text: "商业版",
items: [
{ text: "支付宝配置", link: "/comm/payments/alipay.md" },
{ text: "微信支付配置", link: "/comm/payments/wxpay.md" },
{ text: "彩虹易支付配置", link: "/comm/payments/yizhifu.md" },
]
}
] ]
,
}, },
socialLinks: [ socialLinks: [
{ icon: "github", link: "https://github.com/certd/certd" } { icon: "github", link: "https://github.com/certd/certd" }
], ],

BIN
docs/comm/images/index.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

9
docs/comm/index.md Normal file
View File

@@ -0,0 +1,9 @@
# 商业版文档
![](./images/index.png)
## 支付方式配置
* [支付宝支付配置](./payments/alipay.md)
* [微信支付配置](./payments/wxpay.md)
* [彩虹易支付配置](./payments/yizhifu.md)

View File

@@ -0,0 +1,21 @@
# 支付宝配置
## 配置步骤
1. 创建应用获取APPID
* 登录支付宝开放平台进入开发者中心创建网页应用获取应用的AppId左上角复制
* 开发者中心https://open.alipay.com/develop/manage
2. 进入应用详情,选择开发设置,配置接口加签方式 (选择密钥类型)
* 参考文档https://opendocs.alipay.com/common/02kdnc?pathHash=fb0c752a
* 此步骤完成后,可以获取应用的私钥、支付宝公钥。
* 注意:支付宝不会保存应用的私钥,你需要自己保管好私钥。
3. 在Certd后台配置支付宝
* 进入“系统”->"设置"->“支付设置”
* 启用支付宝,选择“支付宝配置”,点击添加
* 填写支付宝AppId、应用私钥、支付宝公钥等信息即可。

View File

@@ -0,0 +1,27 @@
# 微信支付配置
## 配置步骤
1. 开通Native支付
* 登录微信支付平台
* 进入产品中心: https://pay.weixin.qq.com/index.php/extend/product/lists?tid=3
* 选择开通Native支付
2. 申请证书
* 进入“账户中心”->“API安全”->“商户API证书”->“管理证书”
* 根据指引生成证书
* 得到私钥和公钥
3. 填写APIv3密钥
* 进入“账户中心”->“API安全”->“解密回调”
* 填写APIv3密钥
* 参考文档 https://kf.qq.com/faq/180830E36vyQ180830AZFZvu.html
4. 在Certd后台配置微信支付
* 进入“系统”->"设置"->“支付设置”
* 启用微信支付,选择“微信支付配置”,点击添加
* 填写微信支付商户号、证书私钥、证书公钥、APIv3密钥即可。

View File

@@ -0,0 +1,19 @@
# 彩虹易支付配置
彩虹易支付是一款非常流行的php聚合支付系统。
## 配置步骤
1. 获取商户ID、商户密钥
* 登录彩虹易支付平台
* 进入用户中心https://xxxxxx.com/user/userinfo.php?mod=api
* 点击API信息
* 可以复制接口地址、商户ID、商户密钥key
* 点击查看文档了解支持的签名类型一般为MD5
2. 进入Certd后台配置彩虹易支付
* 进入“系统”->"设置"->“支付设置”
* 启用彩虹易支付,选择“彩虹易支付配置”,点击添加
* 填写接口地址、商户ID、商户密钥、签名方式等信息即可。

View File

@@ -3,6 +3,86 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
### Bug Fixes
* 修复腾讯云CLB多域名同证书部署报错的bug ([c3a5542](https://github.com/certd/certd/commit/c3a55429357e78f4b78c9592d3e5897db2d4d549))
* 修复新版本1panel密码需要加密无法登录的问题 ([ada0b71](https://github.com/certd/certd/commit/ada0b7106e97e551783829e4e719f76793a7123d))
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
### Bug Fixes
* 当前置任务被删除时进行校验 ([c89686a](https://github.com/certd/certd/commit/c89686a2fda251484930f0ae715417b618c21690))
* 修复cloudflare删除解析记录报错的bug ([00c2da4](https://github.com/certd/certd/commit/00c2da444f84adb89f3f1226d03294d7c6e3e4f1))
### Performance Improvements
* 上传自定义证书 ([75a38d9](https://github.com/certd/certd/commit/75a38d95f305b4271d9106babe7cffc1c89ae8f3))
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
### Bug Fixes
* 修复部署到阿里云ALB、NLB插件加载混乱的bug ([6ab83b6](https://github.com/certd/certd/commit/6ab83b662a2c5e715b9cb7eb1244de2ebb7f47b0))
* 修复腾讯clb重复执行会报错的bug ([e95d29f](https://github.com/certd/certd/commit/e95d29f446d06eced315a3087fc9e105a30b20bd))
* 修复tg消息内容中存在.和*就会发送失败的bug ([ae5dfc3](https://github.com/certd/certd/commit/ae5dfc3bee950267123ae2fbd1c11e7ce36626ea))
### Performance Improvements
* 创建流水线时,默认成功时也发送通知 ([52ae690](https://github.com/certd/certd/commit/52ae6902d203ca56e0312692b50c55cb6ddd3e39))
* http方式校验选择sftp时支持修改文件访问权限比如777 ([15d6eaf](https://github.com/certd/certd/commit/15d6eaf5532ed25acd4f8d58c429353a2f44206c))
# [1.30.0](https://github.com/certd/certd/compare/v1.29.5...v1.30.0) (2025-01-19)
### Bug Fixes
* 修复查看任务日志偶发性无法自动滚动底部的bug ([7e482f7](https://github.com/certd/certd/commit/7e482f798c0142bce1866f84676cb40210f9638a))
* 修复namesilo ttl太短的问题 ([865f26d](https://github.com/certd/certd/commit/865f26d75c0d3dd4dc8b41448f8830068e45957c))
### Features
* 支持open api接口根据域名获取证书 ([52a4fd3](https://github.com/certd/certd/commit/52a4fd33180e9b3f71b8dc9f7671d7cd8e448c3b))
### Performance Improvements
* 证书仓库 ([91e7f45](https://github.com/certd/certd/commit/91e7f45a1c5ea1e0ec0aa3236b80028f03a6d0aa))
* 支持部署到阿里云ALB ([653940a](https://github.com/certd/certd/commit/653940a0ca64fc380178c1b0b58ae0af64dfaf07))
* 支持部署到阿里云NLB、SLB ([c085bac](https://github.com/certd/certd/commit/c085bac5d877c4250a8a79e17eb8673b8e4fc89c))
* 支持部署到腾讯云直播 ([417d37b](https://github.com/certd/certd/commit/417d37b199b79a42f790f9edab8f178eedf8fbf7))
* 支持部署证书到proxmox ([d10795e](https://github.com/certd/certd/commit/d10795ecd97eb8cf2ffa46aabfdbfc6812636396))
## [1.29.5](https://github.com/certd/certd/compare/v1.29.4...v1.29.5) (2025-01-07)
### Bug Fixes
* 修复复制到本机插件pfx格式复制时报错的bug ([f57116d](https://github.com/certd/certd/commit/f57116d2bebf33e47ad93e0b39c4efe8e4aea25c))
* 修复授权管理点击了查看原文按钮后无法修改值的bug ([85c99f7](https://github.com/certd/certd/commit/85c99f7f80761ac6efaf3255c03b933442db1686))
## [1.29.4](https://github.com/certd/certd/compare/v1.29.3...v1.29.4) (2025-01-06)
### Bug Fixes
* 修复站点监控域名校验无法通过的bug ([1cb4a53](https://github.com/certd/certd/commit/1cb4a539cc523721ffd4b22d40d0e3d2d68cd915))
### Performance Improvements
* 优化腾讯云CLB插件支持非sni情况sni情况支持填写多个域名 ([635b042](https://github.com/certd/certd/commit/635b042690637bff85e97e07c7aac4b87a8a124b))
## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04)
### Bug Fixes
* 修复系统级授权无法查看密钥的bug ([8644348](https://github.com/certd/certd/commit/8644348fc41ae2e1672f946ca37e5d3a674e0218))
### Performance Improvements
* 优化站点证书检查页面检查增加3次重试 ([e6dd7cd](https://github.com/certd/certd/commit/e6dd7cd54a3e23897031b5df6e0c3cdc0545d35a))
* 优化acme sdk ([54db744](https://github.com/certd/certd/commit/54db74428259de64d12230c2ab7353ae11197bbc))
* 支持http校验方式申请证书 ([405591c](https://github.com/certd/certd/commit/405591c5d08fa1a3b228ee3980199e7731cfec4a))
* http校验方式支持七牛云oss、阿里云oss、腾讯云cos ([3f74d4d](https://github.com/certd/certd/commit/3f74d4d9e5f5d0e629b44cff1895b3f7a8fbcafc))
## [1.29.2](https://github.com/certd/certd/compare/v1.29.1...v1.29.2) (2024-12-25) ## [1.29.2](https://github.com/certd/certd/compare/v1.29.1...v1.29.2) (2024-12-25)
### Bug Fixes ### Bug Fixes

View File

@@ -19,7 +19,8 @@ https://1panel.cn/docs/installation/online_installation/
3. 点击确定,启动容器 3. 点击确定,启动容器
![](./images/2.png) ![](./images/2.png)
> 默认数据保存在`/data/certd`目录下,可以手动备份 > 默认使用sqlite数据库数据保存在`/data/certd`目录下,可以手动备份该目录
> certd还支持`mysql`和`postgresql`数据库,[点我了解如何切换其他数据库](../../database/)
3. 访问测试 3. 访问测试

View File

@@ -29,6 +29,9 @@
点击确定,等待启动完成 点击确定,等待启动完成
![](./images/2.png) ![](./images/2.png)
> certd默认使用sqlite数据库另外支持`mysql`和`postgresql`数据库,[点我了解如何切换其他数据库](../../database/)
## 二、访问应用 ## 二、访问应用
http://ip:7001 http://ip:7001
@@ -59,6 +62,7 @@ admin/123456
数据默认保存在`/data/certd`目录下,可以手动备份 数据默认保存在`/data/certd`目录下,可以手动备份
### 4.3 自动备份 ### 4.3 自动备份
> 建议配置一条 [数据库备份流水线](../../use/backup/),自动备份 > 建议配置一条 [数据库备份流水线](../../use/backup/),自动备份

View File

@@ -0,0 +1,73 @@
# 切换数据库
certd支持如下几种数据库
1. sqlite3 (默认)
2. mysql
3. postgresql
您可以按如下两种方式切换数据库
## 一、全新安装
::: tip
以下按照`docker-compose`安装方式介绍如何使用mysql或postgresql数据库
如果您使用其他方式部署,请自行修改对应的环境变量即可。
:::
### 1.1、使用mysql数据库
1. 安装mysql创建数据库 `(注意charset=utf8mb4, collation=utf8mb4_bin)`
2. 下载最新的docker-compose.yaml
3. 修改环境变量配置
```yaml
services:
certd:
environment:
# 使用mysql数据库需要提前创建数据库 charset=utf8mb4, collation=utf8mb4_bin
- certd_flyway_scriptDir=./db/migration-mysql # 升级脚本目录 【照抄】
- certd_typeorm_dataSource_default_type=mysql # 数据库类型, 或者 mariadb
- certd_typeorm_dataSource_default_host=localhost # 数据库地址
- certd_typeorm_dataSource_default_port=3306 # 数据库端口
- certd_typeorm_dataSource_default_username=root # 用户名
- certd_typeorm_dataSource_default_password=yourpasswd # 密码
- certd_typeorm_dataSource_default_database=certd # 数据库名
```
4. 启动certd
```shell
docker-compose up -d
```
### 1.2、使用Postgresql数据库
1. 安装postgresql创建数据库
2. 下载最新的docker-compose.yaml
3. 修改环境变量配置
```yaml
services:
certd:
environment:
# 使用postgresql数据库需要提前创建数据库
- certd_flyway_scriptDir=./db/migration-pg # 升级脚本目录 【照抄】
- certd_typeorm_dataSource_default_type=postgres # 数据库类型 【照抄】
- certd_typeorm_dataSource_default_host=localhost # 数据库地址
- certd_typeorm_dataSource_default_port=5433 # 数据库端口
- certd_typeorm_dataSource_default_username=postgres # 用户名
- certd_typeorm_dataSource_default_password=yourpasswd # 密码
- certd_typeorm_dataSource_default_database=certd # 数据库名
```
4. 启动certd
```shell
docker-compose up -d
```
## 二、从旧版的sqlite切换数据库
1. 先将`旧certd`升级到最新版 `建议备份sqlite数据库`
2. 按照上面全新安装方式部署一套`新的certd` `注意新旧版本的certd要一致`
3. 使用数据库工具将数据从sqlite导入到mysql或postgresql `注意flyway_history数据表不要导入`
4. 重启新certd
5. 确认没有问题之后删除旧版certd

View File

@@ -42,6 +42,8 @@ docker compose up -d
> 如果提示 没有docker compose命令,请安装docker-compose > 如果提示 没有docker compose命令,请安装docker-compose
> https://docs.docker.com/compose/install/linux/ > https://docs.docker.com/compose/install/linux/
> certd默认使用sqlite数据库另外还支持`mysql`和`postgresql`数据库,[点我了解如何切换其他数据库](../../database/)
### 3. 访问测试 ### 3. 访问测试

View File

@@ -9,5 +9,5 @@
} }
}, },
"npmClient": "pnpm", "npmClient": "pnpm",
"version": "1.29.3" "version": "1.30.4"
} }

View File

@@ -3,6 +3,36 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.4](https://github.com/publishlab/node-acme-client/compare/v1.30.3...v1.30.4) (2025-02-14)
**Note:** Version bump only for package @certd/acme-client
## [1.30.3](https://github.com/publishlab/node-acme-client/compare/v1.30.2...v1.30.3) (2025-02-13)
**Note:** Version bump only for package @certd/acme-client
## [1.30.2](https://github.com/publishlab/node-acme-client/compare/v1.30.1...v1.30.2) (2025-02-09)
**Note:** Version bump only for package @certd/acme-client
## [1.30.1](https://github.com/publishlab/node-acme-client/compare/v1.30.0...v1.30.1) (2025-01-20)
**Note:** Version bump only for package @certd/acme-client
# [1.30.0](https://github.com/publishlab/node-acme-client/compare/v1.29.5...v1.30.0) (2025-01-19)
### Bug Fixes
* 修复查看任务日志偶发性无法自动滚动底部的bug ([7e482f7](https://github.com/publishlab/node-acme-client/commit/7e482f798c0142bce1866f84676cb40210f9638a))
## [1.29.5](https://github.com/publishlab/node-acme-client/compare/v1.29.4...v1.29.5) (2025-01-07)
**Note:** Version bump only for package @certd/acme-client
## [1.29.4](https://github.com/publishlab/node-acme-client/compare/v1.29.3...v1.29.4) (2025-01-06)
**Note:** Version bump only for package @certd/acme-client
## [1.29.3](https://github.com/publishlab/node-acme-client/compare/v1.29.2...v1.29.3) (2025-01-04) ## [1.29.3](https://github.com/publishlab/node-acme-client/compare/v1.29.2...v1.29.3) (2025-01-04)
### Performance Improvements ### Performance Improvements

View File

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

View File

@@ -126,6 +126,7 @@ instance.interceptors.response.use(null, async (error) => {
/* Wait and retry the request */ /* Wait and retry the request */
await new Promise((resolve) => { setTimeout(resolve, (retryAfter * 1000)); }); await new Promise((resolve) => { setTimeout(resolve, (retryAfter * 1000)); });
log(`Retrying request to URL ${config.url}`);
return instance(config); return instance(config);
} }
} }

View File

@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
**Note:** Version bump only for package @certd/basic
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
**Note:** Version bump only for package @certd/basic
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
**Note:** Version bump only for package @certd/basic
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
**Note:** Version bump only for package @certd/basic
# [1.30.0](https://github.com/certd/certd/compare/v1.29.5...v1.30.0) (2025-01-19)
**Note:** Version bump only for package @certd/basic
## [1.29.5](https://github.com/certd/certd/compare/v1.29.4...v1.29.5) (2025-01-07)
**Note:** Version bump only for package @certd/basic
## [1.29.4](https://github.com/certd/certd/compare/v1.29.3...v1.29.4) (2025-01-06)
**Note:** Version bump only for package @certd/basic
## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04) ## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04)
**Note:** Version bump only for package @certd/basic **Note:** Version bump only for package @certd/basic

View File

@@ -1 +1 @@
01:09 14:56

View File

@@ -1,7 +1,7 @@
{ {
"name": "@certd/basic", "name": "@certd/basic",
"private": false, "private": false,
"version": "1.29.3", "version": "1.30.4",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
@@ -44,5 +44,5 @@
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "ed5634ff83405ad0eb13a8456f59270ed4218734" "gitHead": "d4474ff0fb59947e16963fca28301ee8faddc572"
} }

View File

@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
**Note:** Version bump only for package @certd/pipeline
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
**Note:** Version bump only for package @certd/pipeline
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
**Note:** Version bump only for package @certd/pipeline
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
### Bug Fixes
* 修复tg消息内容中存在.和*就会发送失败的bug ([ae5dfc3](https://github.com/certd/certd/commit/ae5dfc3bee950267123ae2fbd1c11e7ce36626ea))
# [1.30.0](https://github.com/certd/certd/compare/v1.29.5...v1.30.0) (2025-01-19)
### Performance Improvements
* 证书仓库 ([91e7f45](https://github.com/certd/certd/commit/91e7f45a1c5ea1e0ec0aa3236b80028f03a6d0aa))
## [1.29.5](https://github.com/certd/certd/compare/v1.29.4...v1.29.5) (2025-01-07)
**Note:** Version bump only for package @certd/pipeline
## [1.29.4](https://github.com/certd/certd/compare/v1.29.3...v1.29.4) (2025-01-06)
**Note:** Version bump only for package @certd/pipeline
## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04) ## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04)
### Performance Improvements ### Performance Improvements

View File

@@ -1,7 +1,7 @@
{ {
"name": "@certd/pipeline", "name": "@certd/pipeline",
"private": false, "private": false,
"version": "1.29.3", "version": "1.30.4",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
@@ -16,8 +16,8 @@
"test": "mocha --loader=ts-node/esm" "test": "mocha --loader=ts-node/esm"
}, },
"dependencies": { "dependencies": {
"@certd/basic": "^1.29.3", "@certd/basic": "^1.30.4",
"@certd/plus-core": "^1.29.3", "@certd/plus-core": "^1.30.4",
"dayjs": "^1.11.7", "dayjs": "^1.11.7",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"reflect-metadata": "^0.1.13" "reflect-metadata": "^0.1.13"
@@ -43,5 +43,5 @@
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "ed5634ff83405ad0eb13a8456f59270ed4218734" "gitHead": "d4474ff0fb59947e16963fca28301ee8faddc572"
} }

View File

@@ -11,6 +11,7 @@ import { ICnameProxyService, IEmailService, IPluginConfigService, IUrlService }
import { FileStore } from "./file-store.js"; import { FileStore } from "./file-store.js";
import { cloneDeep, forEach, merge } from "lodash-es"; import { cloneDeep, forEach, merge } from "lodash-es";
import { INotificationService } from "../notification/index.js"; import { INotificationService } from "../notification/index.js";
import { taskEmitterCreate } from "../service/emit.js";
export type SysInfo = { export type SysInfo = {
//系统标题 //系统标题
@@ -342,6 +343,10 @@ export class Executor {
signal: this.abort.signal, signal: this.abort.signal,
utils, utils,
user: this.options.user, user: this.options.user,
emitter: taskEmitterCreate({
step,
pipeline: this.pipeline,
}),
}; };
instance.setCtx(taskCtx); instance.setCtx(taskCtx);
@@ -430,7 +435,7 @@ export class Executor {
content, content,
userId: this.pipeline.userId, userId: this.pipeline.userId,
pipeline: this.pipeline, pipeline: this.pipeline,
result: this.lastRuntime.pipeline.status, result: this.lastRuntime?.pipeline?.status,
pipelineId: this.pipeline.id, pipelineId: this.pipeline.id,
historyId: this.runtime.id, historyId: this.runtime.id,
errorMessage, errorMessage,

View File

@@ -121,11 +121,11 @@ export abstract class BaseNotification implements INotification {
async onTestRequest() { async onTestRequest() {
await this.doSend({ await this.doSend({
userId: 0, userId: 0,
title: "【Certd】测试通知标题长度测试、测试、测试", title: "【Certd】测试通知【*.foo.com】,标题长度测试、测试、测试",
content: "测试通知", content: "测试通知,*.foo.com",
pipeline: { pipeline: {
id: 1, id: 1,
title: "测试流水线", title: "证书申请成功【测试流水线",
} as any, } as any,
pipelineId: 1, pipelineId: 1,
historyId: 1, historyId: 1,

View File

@@ -7,9 +7,10 @@ import { CancelError, IContext, RunHistory, RunnableCollection } from "../core/i
import { HttpRequestConfig, ILogger, logger, utils } from "@certd/basic"; import { HttpRequestConfig, ILogger, logger, utils } from "@certd/basic";
import { HttpClient } from "@certd/basic"; import { HttpClient } from "@certd/basic";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { IPluginConfigService } from "../service/config"; import { IPluginConfigService } from "../service/config.js";
import { upperFirst } from "lodash-es"; import { upperFirst } from "lodash-es";
import { INotificationService } from "../notification"; import { INotificationService } from "../notification/index.js";
import { TaskEmitter } from "../service/emit.js";
export type PluginRequestHandleReq<T = any> = { export type PluginRequestHandleReq<T = any> = {
typeName: string; typeName: string;
@@ -111,6 +112,8 @@ export type TaskInstanceContext = {
utils: typeof utils; utils: typeof utils;
//用户信息 //用户信息
user: UserInfo; user: UserInfo;
emitter: TaskEmitter;
}; };
export abstract class AbstractTaskPlugin implements ITaskPlugin { export abstract class AbstractTaskPlugin implements ITaskPlugin {

View File

@@ -0,0 +1,68 @@
import { logger } from "@certd/basic";
import { Pipeline, Runnable } from "../dt";
export type PipelineEventListener = (...args: any[]) => Promise<void>;
export type PipelineEvent<T> = {
pipeline: Pipeline;
step: Runnable;
event: T;
};
export class PipelineEmitter {
events: Record<string, PipelineEventListener[]>;
constructor() {
this.events = {};
}
on(event: string, listener: PipelineEventListener) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(listener);
}
async emit<T>(name: string, event: PipelineEvent<T>) {
const listeners = this.events[name];
if (listeners) {
for (const listener of listeners) {
try {
await listener(event);
} catch (e) {
logger.error(`事件<${name}>监听器执行失败:`, e);
}
}
}
}
off(event: string, listener: PipelineEventListener) {
if (this.events[event]) {
this.events[event] = this.events[event].filter((l) => l !== listener);
}
}
once(event: string, listener: PipelineEventListener) {
const onceListener = async (...args: any[]) => {
this.off(event, onceListener);
await listener(...args);
};
this.on(event, onceListener);
}
}
export const pipelineEmitter = new PipelineEmitter();
export type TaskEmitterCreateReq = {
step: Runnable;
pipeline: Pipeline;
};
export type TaskEmitter = {
emit: <T>(name: string, event: T) => Promise<void>;
};
export function taskEmitterCreate(req: TaskEmitterCreateReq) {
return {
emit: async <T>(name: string, event: T) => {
await pipelineEmitter.emit(name, {
pipeline: req.pipeline,
step: req.step,
event,
});
},
} as TaskEmitter;
}

View File

@@ -2,3 +2,4 @@ export * from "./email.js";
export * from "./cname.js"; export * from "./cname.js";
export * from "./config.js"; export * from "./config.js";
export * from "./url.js"; export * from "./url.js";
export * from "./emit.js";

View File

@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
**Note:** Version bump only for package @certd/lib-huawei
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
**Note:** Version bump only for package @certd/lib-huawei
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
**Note:** Version bump only for package @certd/lib-huawei
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
**Note:** Version bump only for package @certd/lib-huawei
# [1.30.0](https://github.com/certd/certd/compare/v1.29.5...v1.30.0) (2025-01-19)
**Note:** Version bump only for package @certd/lib-huawei
## [1.29.5](https://github.com/certd/certd/compare/v1.29.4...v1.29.5) (2025-01-07)
**Note:** Version bump only for package @certd/lib-huawei
## [1.29.4](https://github.com/certd/certd/compare/v1.29.3...v1.29.4) (2025-01-06)
**Note:** Version bump only for package @certd/lib-huawei
## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04) ## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04)
**Note:** Version bump only for package @certd/lib-huawei **Note:** Version bump only for package @certd/lib-huawei

View File

@@ -1,7 +1,7 @@
{ {
"name": "@certd/lib-huawei", "name": "@certd/lib-huawei",
"private": false, "private": false,
"version": "1.29.3", "version": "1.30.4",
"main": "./dist/bundle.js", "main": "./dist/bundle.js",
"module": "./dist/bundle.js", "module": "./dist/bundle.js",
"types": "./dist/d/index.d.ts", "types": "./dist/d/index.d.ts",
@@ -21,5 +21,5 @@
"prettier": "^2.8.8", "prettier": "^2.8.8",
"tslib": "^2.8.1" "tslib": "^2.8.1"
}, },
"gitHead": "ed5634ff83405ad0eb13a8456f59270ed4218734" "gitHead": "d4474ff0fb59947e16963fca28301ee8faddc572"
} }

View File

@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
**Note:** Version bump only for package @certd/lib-iframe
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
**Note:** Version bump only for package @certd/lib-iframe
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
**Note:** Version bump only for package @certd/lib-iframe
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
**Note:** Version bump only for package @certd/lib-iframe
# [1.30.0](https://github.com/certd/certd/compare/v1.29.5...v1.30.0) (2025-01-19)
**Note:** Version bump only for package @certd/lib-iframe
## [1.29.5](https://github.com/certd/certd/compare/v1.29.4...v1.29.5) (2025-01-07)
**Note:** Version bump only for package @certd/lib-iframe
## [1.29.4](https://github.com/certd/certd/compare/v1.29.3...v1.29.4) (2025-01-06)
**Note:** Version bump only for package @certd/lib-iframe
## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04) ## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04)
**Note:** Version bump only for package @certd/lib-iframe **Note:** Version bump only for package @certd/lib-iframe

View File

@@ -1,7 +1,7 @@
{ {
"name": "@certd/lib-iframe", "name": "@certd/lib-iframe",
"private": false, "private": false,
"version": "1.29.3", "version": "1.30.4",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
@@ -30,5 +30,5 @@
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "ed5634ff83405ad0eb13a8456f59270ed4218734" "gitHead": "d4474ff0fb59947e16963fca28301ee8faddc572"
} }

View File

@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
**Note:** Version bump only for package @certd/lib-k8s
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
**Note:** Version bump only for package @certd/lib-k8s
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
**Note:** Version bump only for package @certd/lib-k8s
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
**Note:** Version bump only for package @certd/lib-k8s
# [1.30.0](https://github.com/certd/certd/compare/v1.29.5...v1.30.0) (2025-01-19)
**Note:** Version bump only for package @certd/lib-k8s
## [1.29.5](https://github.com/certd/certd/compare/v1.29.4...v1.29.5) (2025-01-07)
**Note:** Version bump only for package @certd/lib-k8s
## [1.29.4](https://github.com/certd/certd/compare/v1.29.3...v1.29.4) (2025-01-06)
**Note:** Version bump only for package @certd/lib-k8s
## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04) ## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04)
**Note:** Version bump only for package @certd/lib-k8s **Note:** Version bump only for package @certd/lib-k8s

View File

@@ -1,7 +1,7 @@
{ {
"name": "@certd/lib-k8s", "name": "@certd/lib-k8s",
"private": false, "private": false,
"version": "1.29.3", "version": "1.30.4",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
@@ -16,7 +16,7 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@certd/basic": "^1.29.3", "@certd/basic": "^1.30.4",
"@kubernetes/client-node": "0.21.0" "@kubernetes/client-node": "0.21.0"
}, },
"devDependencies": { "devDependencies": {
@@ -31,5 +31,5 @@
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "ed5634ff83405ad0eb13a8456f59270ed4218734" "gitHead": "d4474ff0fb59947e16963fca28301ee8faddc572"
} }

View File

@@ -3,6 +3,36 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
**Note:** Version bump only for package @certd/lib-server
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
**Note:** Version bump only for package @certd/lib-server
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
**Note:** Version bump only for package @certd/lib-server
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
**Note:** Version bump only for package @certd/lib-server
# [1.30.0](https://github.com/certd/certd/compare/v1.29.5...v1.30.0) (2025-01-19)
### Features
* 支持open api接口根据域名获取证书 ([52a4fd3](https://github.com/certd/certd/commit/52a4fd33180e9b3f71b8dc9f7671d7cd8e448c3b))
## [1.29.5](https://github.com/certd/certd/compare/v1.29.4...v1.29.5) (2025-01-07)
**Note:** Version bump only for package @certd/lib-server
## [1.29.4](https://github.com/certd/certd/compare/v1.29.3...v1.29.4) (2025-01-06)
**Note:** Version bump only for package @certd/lib-server
## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04) ## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04)
### Bug Fixes ### Bug Fixes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@certd/lib-server", "name": "@certd/lib-server",
"version": "1.29.3", "version": "1.30.4",
"description": "midway with flyway, sql upgrade way ", "description": "midway with flyway, sql upgrade way ",
"private": false, "private": false,
"type": "module", "type": "module",
@@ -27,10 +27,10 @@
], ],
"license": "AGPL", "license": "AGPL",
"dependencies": { "dependencies": {
"@certd/acme-client": "^1.29.3", "@certd/acme-client": "^1.30.4",
"@certd/basic": "^1.29.3", "@certd/basic": "^1.30.4",
"@certd/pipeline": "^1.29.3", "@certd/pipeline": "^1.30.4",
"@certd/plus-core": "^1.29.3", "@certd/plus-core": "^1.30.4",
"@midwayjs/cache": "~3.14.0", "@midwayjs/cache": "~3.14.0",
"@midwayjs/core": "~3.17.1", "@midwayjs/core": "~3.17.1",
"@midwayjs/i18n": "~3.17.3", "@midwayjs/i18n": "~3.17.3",
@@ -61,5 +61,5 @@
"typeorm": "^0.3.11", "typeorm": "^0.3.11",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "ed5634ff83405ad0eb13a8456f59270ed4218734" "gitHead": "d4474ff0fb59947e16963fca28301ee8faddc572"
} }

View File

@@ -12,6 +12,8 @@ export const Constants = {
authOnly: '_authOnly_', authOnly: '_authOnly_',
//仅需要登录 //仅需要登录
loginOnly: '_authOnly_', loginOnly: '_authOnly_',
open: '_open_',
}, },
res: { res: {
serverError(message: string) { serverError(message: string) {
@@ -68,5 +70,33 @@ export const Constants = {
code: 10001, code: 10001,
message: '对不起,预览环境不允许修改此数据', message: '对不起,预览环境不允许修改此数据',
}, },
openKeyError: {
code: 20000,
message: 'ApiToken错误',
},
openKeySignError: {
code: 20001,
message: 'ApiToken签名错误',
},
openKeyExpiresError: {
code: 20002,
message: 'ApiToken时间戳错误',
},
openKeySignTypeError: {
code: 20003,
message: 'ApiToken签名类型不支持',
},
openParamError: {
code: 20010,
message: '请求参数错误',
},
openCertNotFound: {
code: 20011,
message: '证书不存在',
},
openCertNotReady: {
code: 20012,
message: '证书还未生成',
},
}, },
}; };

View File

@@ -5,10 +5,6 @@ import { BaseException } from './base-exception.js';
*/ */
export class AuthException extends BaseException { export class AuthException extends BaseException {
constructor(message) { constructor(message) {
super( super('AuthException', Constants.res.auth.code, message ? message : Constants.res.auth.message);
'AuthException',
Constants.res.auth.code,
message ? message : Constants.res.auth.message
);
} }
} }

View File

@@ -2,10 +2,10 @@
* 异常基类 * 异常基类
*/ */
export class BaseException extends Error { export class BaseException extends Error {
status: number; code: number;
constructor(name, code, message) { constructor(name, code, message) {
super(message); super(message);
this.name = name; this.name = name;
this.status = code; this.code = code;
} }
} }

View File

@@ -8,3 +8,9 @@ export class CommonException extends BaseException {
super('CommonException', Constants.res.error.code, message ? message : Constants.res.error.message); super('CommonException', Constants.res.error.code, message ? message : Constants.res.error.message);
} }
} }
export class CodeException extends BaseException {
constructor(res: { code: number; message: string }) {
super('CodeException', res.code, res.message);
}
}

View File

@@ -9,7 +9,7 @@ export class Result<T> {
} }
static error(code = 1, msg) { static error(code = 1, msg) {
return new Result(code, msg, null); return new Result(code, msg);
} }
static success(msg, data?) { static success(msg, data?) {

View File

@@ -1,2 +1,3 @@
export * from './service/plus-service.js'; export * from './service/plus-service.js';
export * from './service/file-service.js'; export * from './service/file-service.js';
export * from './service/encryptor.js';

View File

@@ -0,0 +1,29 @@
import crypto from 'crypto';
export class Encryptor {
secretKey: Buffer;
constructor(encryptSecret: string, encoding: BufferEncoding = 'base64') {
this.secretKey = Buffer.from(encryptSecret, encoding);
}
// 加密函数
encrypt(text: string) {
const iv = crypto.randomBytes(16); // 初始化向量
// const secretKey = crypto.randomBytes(32);
// const key = Buffer.from(secretKey);
const cipher = crypto.createCipheriv('aes-256-cbc', this.secretKey, iv);
let encrypted = cipher.update(text);
encrypted = Buffer.concat([encrypted, cipher.final()]);
return iv.toString('hex') + ':' + encrypted.toString('hex');
}
// 解密函数
decrypt(encryptedText: string) {
const textParts = encryptedText.split(':');
const iv = Buffer.from(textParts.shift(), 'hex');
const encrypted = Buffer.from(textParts.join(':'), 'hex');
const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(this.secretKey), iv);
let decrypted = decipher.update(encrypted);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
}
}

View File

@@ -91,7 +91,7 @@ export class SysSettingsService extends BaseService<SysSettingsEntity> {
entity.setting = JSON.stringify(bean); entity.setting = JSON.stringify(bean);
entity.access = type.__access__; entity.access = type.__access__;
if (key === SysSecretBackup.__key__ || key === SysSecret.__key__) { if (key === SysSecretBackup.__key__) {
//备份密钥不允许更新 //备份密钥不允许更新
return; return;
} }

View File

@@ -1,6 +1,5 @@
import { Init, Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core'; import { Init, Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
import crypto from 'crypto'; import { Encryptor, SysSecret, SysSettingsService } from '../../../system/index.js';
import { SysSecret, SysSettingsService } from '../../../system/index.js';
/** /**
* 授权 * 授权
@@ -8,7 +7,7 @@ import { SysSecret, SysSettingsService } from '../../../system/index.js';
@Provide() @Provide()
@Scope(ScopeEnum.Singleton) @Scope(ScopeEnum.Singleton)
export class EncryptService { export class EncryptService {
secretKey: Buffer; encryptor: Encryptor;
@Inject() @Inject()
sysSettingService: SysSettingsService; sysSettingService: SysSettingsService;
@@ -16,28 +15,16 @@ export class EncryptService {
@Init() @Init()
async init() { async init() {
const secret: SysSecret = await this.sysSettingService.getSecret(); const secret: SysSecret = await this.sysSettingService.getSecret();
this.secretKey = Buffer.from(secret.encryptSecret, 'base64'); this.encryptor = new Encryptor(secret.encryptSecret);
} }
// 加密函数 // 加密函数
encrypt(text: string) { encrypt(text: string) {
const iv = crypto.randomBytes(16); // 初始化向量 return this.encryptor.encrypt(text);
// const secretKey = crypto.randomBytes(32);
// const key = Buffer.from(secretKey);
const cipher = crypto.createCipheriv('aes-256-cbc', this.secretKey, iv);
let encrypted = cipher.update(text);
encrypted = Buffer.concat([encrypted, cipher.final()]);
return iv.toString('hex') + ':' + encrypted.toString('hex');
} }
// 解密函数 // 解密函数
decrypt(encryptedText: string) { decrypt(encryptedText: string) {
const textParts = encryptedText.split(':'); return this.encryptor.decrypt(encryptedText);
const iv = Buffer.from(textParts.shift(), 'hex');
const encrypted = Buffer.from(textParts.join(':'), 'hex');
const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(this.secretKey), iv);
let decrypted = decipher.update(encrypted);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
} }
} }

View File

@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
**Note:** Version bump only for package @certd/midway-flyway-js
# [1.30.0](https://github.com/certd/certd/compare/v1.29.5...v1.30.0) (2025-01-19)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.29.5](https://github.com/certd/certd/compare/v1.29.4...v1.29.5) (2025-01-07)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.29.4](https://github.com/certd/certd/compare/v1.29.3...v1.29.4) (2025-01-06)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04) ## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04)
**Note:** Version bump only for package @certd/midway-flyway-js **Note:** Version bump only for package @certd/midway-flyway-js

View File

@@ -1,6 +1,6 @@
{ {
"name": "@certd/midway-flyway-js", "name": "@certd/midway-flyway-js",
"version": "1.29.3", "version": "1.30.4",
"description": "midway with flyway, sql upgrade way ", "description": "midway with flyway, sql upgrade way ",
"private": false, "private": false,
"type": "module", "type": "module",
@@ -46,5 +46,5 @@
"typeorm": "^0.3.11", "typeorm": "^0.3.11",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "ed5634ff83405ad0eb13a8456f59270ed4218734" "gitHead": "d4474ff0fb59947e16963fca28301ee8faddc572"
} }

View File

@@ -3,6 +3,44 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
**Note:** Version bump only for package @certd/plugin-cert
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
**Note:** Version bump only for package @certd/plugin-cert
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
**Note:** Version bump only for package @certd/plugin-cert
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
### Performance Improvements
* http方式校验选择sftp时支持修改文件访问权限比如777 ([15d6eaf](https://github.com/certd/certd/commit/15d6eaf5532ed25acd4f8d58c429353a2f44206c))
# [1.30.0](https://github.com/certd/certd/compare/v1.29.5...v1.30.0) (2025-01-19)
### Bug Fixes
* 修复namesilo ttl太短的问题 ([865f26d](https://github.com/certd/certd/commit/865f26d75c0d3dd4dc8b41448f8830068e45957c))
### Performance Improvements
* 证书仓库 ([91e7f45](https://github.com/certd/certd/commit/91e7f45a1c5ea1e0ec0aa3236b80028f03a6d0aa))
## [1.29.5](https://github.com/certd/certd/compare/v1.29.4...v1.29.5) (2025-01-07)
### Bug Fixes
* 修复复制到本机插件pfx格式复制时报错的bug ([f57116d](https://github.com/certd/certd/commit/f57116d2bebf33e47ad93e0b39c4efe8e4aea25c))
## [1.29.4](https://github.com/certd/certd/compare/v1.29.3...v1.29.4) (2025-01-06)
**Note:** Version bump only for package @certd/plugin-cert
## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04) ## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04)
### Performance Improvements ### Performance Improvements

View File

@@ -1,7 +1,7 @@
{ {
"name": "@certd/plugin-cert", "name": "@certd/plugin-cert",
"private": false, "private": false,
"version": "1.29.3", "version": "1.30.4",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@@ -15,10 +15,10 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@certd/acme-client": "^1.29.3", "@certd/acme-client": "^1.30.4",
"@certd/basic": "^1.29.3", "@certd/basic": "^1.30.4",
"@certd/pipeline": "^1.29.3", "@certd/pipeline": "^1.30.4",
"@certd/plugin-lib": "^1.29.3", "@certd/plugin-lib": "^1.30.4",
"@google-cloud/publicca": "^1.3.0", "@google-cloud/publicca": "^1.3.0",
"dayjs": "^1.11.7", "dayjs": "^1.11.7",
"jszip": "^3.10.1", "jszip": "^3.10.1",
@@ -41,5 +41,5 @@
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "ed5634ff83405ad0eb13a8456f59270ed4218734" "gitHead": "d4474ff0fb59947e16963fca28301ee8faddc572"
} }

View File

@@ -1,4 +1,4 @@
import { AbstractTaskPlugin, IContext, NotificationBody, Step, TaskInput, TaskOutput } from "@certd/pipeline"; import { AbstractTaskPlugin, IContext, NotificationBody, Step, TaskEmitter, TaskInput, TaskOutput } from "@certd/pipeline";
import dayjs from "dayjs"; import dayjs from "dayjs";
import type { CertInfo } from "./acme.js"; import type { CertInfo } from "./acme.js";
import { CertReader } from "./cert-reader.js"; import { CertReader } from "./cert-reader.js";
@@ -6,8 +6,11 @@ import JSZip from "jszip";
import { CertConverter } from "./convert.js"; import { CertConverter } from "./convert.js";
import { pick } from "lodash-es"; import { pick } from "lodash-es";
export { CertReader }; export const EVENT_CERT_APPLY_SUCCESS = "CertApply.success";
export type { CertInfo };
export async function emitCertApplySuccess(emitter: TaskEmitter, cert: CertReader) {
await emitter.emit(EVENT_CERT_APPLY_SUCCESS, cert);
}
export abstract class CertApplyBasePlugin extends AbstractTaskPlugin { export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
@TaskInput({ @TaskInput({
@@ -55,7 +58,7 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
}, },
required: false, required: false,
order: 100, order: 100,
helper: "PFX、jks格式证书是否加密jks必须设置密码不传则默认123456", helper: "PFX、jks格式证书是否加密\njks必须设置密码不传则默认123456",
}) })
pfxPassword!: string; pfxPassword!: string;
@@ -63,12 +66,17 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
title: "PFX证书转换参数", title: "PFX证书转换参数",
value: "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES", value: "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES",
component: { component: {
name: "a-input", name: "a-auto-complete",
vModel: "value", vModel: "value",
options: [
{ value: "", label: "兼容 Windows Server 最新" },
{ value: "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES", label: "兼容 Windows Server 2016" },
{ value: "-nomac -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES", label: "兼容 Windows Server 2008" },
],
}, },
required: false, required: false,
order: 100, order: 100,
helper: "兼容Server 2016如果导入证书失败请删除此参数", helper: "兼容Windows Server各个版本",
}) })
pfxArgs = "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES"; pfxArgs = "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES";
@@ -119,7 +127,7 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
abstract onInit(): Promise<void>; abstract onInit(): Promise<void>;
abstract doCertApply(): Promise<any>; abstract doCertApply(): Promise<CertReader>;
async execute(): Promise<string | void> { async execute(): Promise<string | void> {
const oldCert = await this.condition(); const oldCert = await this.condition();
@@ -130,6 +138,8 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
const cert = await this.doCertApply(); const cert = await this.doCertApply();
if (cert != null) { if (cert != null) {
await this.output(cert, true); await this.output(cert, true);
await emitCertApplySuccess(this.ctx.emitter, cert);
//清空后续任务的状态,让后续任务能够重新执行 //清空后续任务的状态,让后续任务能够重新执行
this.clearLastStatus(); this.clearLastStatus();
@@ -234,28 +244,10 @@ cert.jksjks格式证书文件java服务器使用
// return null; // return null;
// } // }
let inputChanged = false;
//判断域名有没有变更
/**
* "renewDays": 35,
* "certApplyPlugin": "CertApply",
* "sslProvider": "letsencrypt",
* "privateKeyType": "rsa_2048_pkcs1",
* "dnsProviderType": "aliyun",
* "domains": [
* "*.handsfree.work"
* ],
* "email": "xiaojunnuo@qq.com",
* "dnsProviderAccess": 3,
* "useProxy": false,
* "skipLocalVerify": false,
* "successNotify": true,
* "pfxPassword": "123456"
*/
const checkInputChanges = ["domains", "sslProvider", "privateKeyType", "dnsProviderType", "pfxPassword"]; const checkInputChanges = ["domains", "sslProvider", "privateKeyType", "dnsProviderType", "pfxPassword"];
const oldInput = JSON.stringify(pick(this.lastStatus?.input, checkInputChanges)); const oldInput = JSON.stringify(pick(this.lastStatus?.input, checkInputChanges));
const thisInput = JSON.stringify(pick(this, checkInputChanges)); const thisInput = JSON.stringify(pick(this, checkInputChanges));
inputChanged = oldInput !== thisInput; const inputChanged = oldInput !== thisInput;
this.logger.info(`旧参数:${oldInput}`); this.logger.info(`旧参数:${oldInput}`);
this.logger.info(`新参数:${thisInput}`); this.logger.info(`新参数:${thisInput}`);

View File

@@ -2,7 +2,7 @@ import { CertInfo } from "./acme.js";
import fs from "fs"; import fs from "fs";
import os from "os"; import os from "os";
import path from "path"; import path from "path";
import { crypto } from "@certd/acme-client"; import { CertificateInfo, crypto } from "@certd/acme-client";
import { ILogger } from "@certd/basic"; import { ILogger } from "@certd/basic";
import dayjs from "dayjs"; import dayjs from "dayjs";
@@ -21,37 +21,22 @@ export type CertReaderHandle = (ctx: CertReaderHandleContext) => Promise<void>;
export type HandleOpts = { logger: ILogger; handle: CertReaderHandle }; export type HandleOpts = { logger: ILogger; handle: CertReaderHandle };
export class CertReader { export class CertReader {
cert: CertInfo; cert: CertInfo;
oc: string; //仅证书非fullchain证书
crt: string;
key: string;
csr: string;
ic: string; //中间证书
one: string; //crt + key 合成一个pem文件
detail: any; detail: CertificateInfo;
expires: number; expires: number;
constructor(certInfo: CertInfo) { constructor(certInfo: CertInfo) {
this.cert = certInfo; this.cert = certInfo;
this.crt = certInfo.crt;
this.key = certInfo.key;
this.csr = certInfo.csr;
this.ic = certInfo.ic; if (!certInfo.ic) {
if (!this.ic) { this.cert.ic = this.getIc();
this.ic = this.getIc();
this.cert.ic = this.ic;
} }
this.oc = certInfo.oc; if (!certInfo.oc) {
if (!this.oc) { this.cert.oc = this.getOc();
this.oc = this.getOc();
this.cert.oc = this.oc;
} }
this.one = certInfo.one; if (!certInfo.one) {
if (!this.one) { this.cert.one = this.cert.crt + "\n" + this.cert.key;
this.one = this.crt + "\n" + this.key;
this.cert.one = this.one;
} }
const { detail, expires } = this.getCrtDetail(this.cert.crt); const { detail, expires } = this.getCrtDetail(this.cert.crt);
@@ -62,20 +47,23 @@ export class CertReader {
getIc() { getIc() {
//中间证书ic 就是crt的第一个 -----END CERTIFICATE----- 之后的内容 //中间证书ic 就是crt的第一个 -----END CERTIFICATE----- 之后的内容
const endStr = "-----END CERTIFICATE-----"; const endStr = "-----END CERTIFICATE-----";
const firstBlockEndIndex = this.crt.indexOf(endStr); const firstBlockEndIndex = this.cert.crt.indexOf(endStr);
const start = firstBlockEndIndex + endStr.length + 1; const start = firstBlockEndIndex + endStr.length + 1;
if (this.crt.length <= start) { if (this.cert.crt.length <= start) {
return ""; return "";
} }
const ic = this.crt.substring(start); const ic = this.cert.crt.substring(start);
return ic.trim(); if (ic == null) {
return "";
}
return ic?.trim();
} }
getOc() { getOc() {
//原始证书 就是crt的第一个 -----END CERTIFICATE----- 之前的内容 //原始证书 就是crt的第一个 -----END CERTIFICATE----- 之前的内容
const endStr = "-----END CERTIFICATE-----"; const endStr = "-----END CERTIFICATE-----";
const arr = this.crt.split(endStr); const arr = this.cert.crt.split(endStr);
return arr[0] + endStr; return arr[0] + endStr;
} }
@@ -168,7 +156,7 @@ export class CertReader {
} }
} }
buildCertFileName(suffix: string, applyTime: number, prefix = "cert") { buildCertFileName(suffix: string, applyTime: any, prefix = "cert") {
const detail = this.getCrtDetail(); const detail = this.getCrtDetail();
let domain = detail.detail.domains.commonName; let domain = detail.detail.domains.commonName;
domain = domain.replace(".", "_").replace("*", "_"); domain = domain.replace(".", "_").replace("*", "_");

View File

@@ -10,7 +10,7 @@ import { CertApplyBasePlugin } from "./base.js";
import { GoogleClient } from "../../libs/google.js"; import { GoogleClient } from "../../libs/google.js";
import { EabAccess } from "../../access"; import { EabAccess } from "../../access";
import { httpChallengeUploaderFactory } from "./uploads/factory.js"; import { httpChallengeUploaderFactory } from "./uploads/factory.js";
export * from "./base.js";
export type { CertInfo }; export type { CertInfo };
export * from "./cert-reader.js"; export * from "./cert-reader.js";
export type CnameRecordInput = { export type CnameRecordInput = {
@@ -232,7 +232,7 @@ HTTP文件验证不支持泛域名需要配置网站文件上传`,
// { value: "ec_521", label: "EC 521" }, // { value: "ec_521", label: "EC 521" },
], ],
}, },
helper: "如无特殊需求,默认即可", helper: "如无特殊需求,默认即可\n选择RSA 2048 pkcs1可以获得旧版RSA证书",
required: true, required: true,
}) })
privateKeyType!: PrivateKeyType; privateKeyType!: PrivateKeyType;

View File

@@ -8,6 +8,9 @@ export class HttpChallengeUploaderFactory {
} else if (type === "ssh") { } else if (type === "ssh") {
const module = await import("./impls/ssh.js"); const module = await import("./impls/ssh.js");
return module.SshHttpChallengeUploader; return module.SshHttpChallengeUploader;
} else if (type === "sftp") {
const module = await import("./impls/sftp.js");
return module.SftpHttpChallengeUploader;
} else if (type === "ftp") { } else if (type === "ftp") {
const module = await import("./impls/ftp.js"); const module = await import("./impls/ftp.js");
return module.FtpHttpChallengeUploader; return module.FtpHttpChallengeUploader;

View File

@@ -0,0 +1,51 @@
import { BaseHttpChallengeUploader } from "../api.js";
import { SshAccess, SshClient } from "@certd/plugin-lib";
import path from "path";
import os from "os";
import fs from "fs";
import { SftpAccess } from "@certd/plugin-lib";
export class SftpHttpChallengeUploader extends BaseHttpChallengeUploader<SftpAccess> {
async upload(filePath: string, fileContent: Buffer) {
const tmpFilePath = path.join(os.tmpdir(), "cert", "http", filePath);
// Write file to temp path
const dir = path.dirname(tmpFilePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
fs.writeFileSync(tmpFilePath, fileContent);
const access = await this.ctx.accessService.getById<SshAccess>(this.access.sshAccess);
const key = this.rootDir + filePath;
try {
const client = new SshClient(this.logger);
await client.uploadFiles({
connectConf: access,
mkdirs: true,
transports: [
{
localPath: tmpFilePath,
remotePath: key,
},
],
opts: {
mode: this.access?.fileMode ?? undefined,
},
});
} finally {
// Remove temp file
fs.unlinkSync(tmpFilePath);
}
}
async remove(filePath: string) {
const access = await this.ctx.accessService.getById<SshAccess>(this.access.sshAccess);
const client = new SshClient(this.logger);
const key = this.rootDir + filePath;
await client.removeFiles({
connectConf: access,
files: [key],
});
}
}

View File

@@ -3,6 +3,43 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
**Note:** Version bump only for package @certd/plugin-lib
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
**Note:** Version bump only for package @certd/plugin-lib
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
**Note:** Version bump only for package @certd/plugin-lib
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
### Performance Improvements
* http方式校验选择sftp时支持修改文件访问权限比如777 ([15d6eaf](https://github.com/certd/certd/commit/15d6eaf5532ed25acd4f8d58c429353a2f44206c))
# [1.30.0](https://github.com/certd/certd/compare/v1.29.5...v1.30.0) (2025-01-19)
### Bug Fixes
* 修复查看任务日志偶发性无法自动滚动底部的bug ([7e482f7](https://github.com/certd/certd/commit/7e482f798c0142bce1866f84676cb40210f9638a))
### Performance Improvements
* 支持部署到阿里云ALB ([653940a](https://github.com/certd/certd/commit/653940a0ca64fc380178c1b0b58ae0af64dfaf07))
* 支持部署到阿里云NLB、SLB ([c085bac](https://github.com/certd/certd/commit/c085bac5d877c4250a8a79e17eb8673b8e4fc89c))
## [1.29.5](https://github.com/certd/certd/compare/v1.29.4...v1.29.5) (2025-01-07)
**Note:** Version bump only for package @certd/plugin-lib
## [1.29.4](https://github.com/certd/certd/compare/v1.29.3...v1.29.4) (2025-01-06)
**Note:** Version bump only for package @certd/plugin-lib
## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04) ## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04)
### Performance Improvements ### Performance Improvements

View File

@@ -1,7 +1,7 @@
{ {
"name": "@certd/plugin-lib", "name": "@certd/plugin-lib",
"private": false, "private": false,
"version": "1.29.3", "version": "1.30.4",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@@ -16,8 +16,8 @@
}, },
"dependencies": { "dependencies": {
"@alicloud/pop-core": "^1.7.10", "@alicloud/pop-core": "^1.7.10",
"@certd/basic": "^1.29.3", "@certd/basic": "^1.30.4",
"@certd/pipeline": "^1.29.3", "@certd/pipeline": "^1.30.4",
"@kubernetes/client-node": "0.21.0", "@kubernetes/client-node": "0.21.0",
"ali-oss": "^6.21.0", "ali-oss": "^6.21.0",
"basic-ftp": "^5.0.5", "basic-ftp": "^5.0.5",
@@ -48,5 +48,5 @@
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.4.2" "typescript": "^5.4.2"
}, },
"gitHead": "ed5634ff83405ad0eb13a8456f59270ed4218734" "gitHead": "d4474ff0fb59947e16963fca28301ee8faddc572"
} }

View File

@@ -35,7 +35,7 @@ export class AliyunClient {
} }
checkRet(ret: any) { checkRet(ret: any) {
if (ret.code != null) { if (ret.Code != null) {
throw new Error("执行失败:" + ret.Message); throw new Error("执行失败:" + ret.Message);
} }
} }

View File

@@ -47,7 +47,7 @@ export class AliossClient {
} }
checkRet(ret: any) { checkRet(ret: any) {
if (ret.code != null) { if (ret.Code != null) {
throw new Error("执行失败:" + ret.Message); throw new Error("执行失败:" + ret.Message);
} }
} }

View File

@@ -29,6 +29,8 @@ export type AliyunSslUploadCertReq = {
cert: AliyunCertInfo; cert: AliyunCertInfo;
}; };
export type CasCertInfo = { certId: number; certName: string; certIdentifier: string };
export class AliyunSslClient { export class AliyunSslClient {
opts: AliyunSslClientOpts; opts: AliyunSslClientOpts;
constructor(opts: AliyunSslClientOpts) { constructor(opts: AliyunSslClientOpts) {
@@ -36,7 +38,7 @@ export class AliyunSslClient {
} }
checkRet(ret: any) { checkRet(ret: any) {
if (ret.code != null) { if (ret.Code != null) {
throw new Error("执行失败:" + ret.Message); throw new Error("执行失败:" + ret.Message);
} }
} }
@@ -53,6 +55,22 @@ export class AliyunSslClient {
return client; return client;
} }
async getCertInfo(certId: number): Promise<CasCertInfo> {
const client = await this.getClient();
const params = {
CertId: certId,
};
const res = await client.request("GetUserCertificateDetail", params);
this.checkRet(res);
return {
certId: certId,
certName: res.Name,
certIdentifier: res.CertIdentifier,
};
}
async uploadCert(req: AliyunSslUploadCertReq) { async uploadCert(req: AliyunSslUploadCertReq) {
const client = await this.getClient(); const client = await this.getClient();
const params = { const params = {

View File

@@ -46,7 +46,13 @@ export function createRemoteSelectInputDefine(opts?: {
const type = opts?.type || "plugin"; const type = opts?.type || "plugin";
const watches = opts?.watches || []; const watches = opts?.watches || [];
const helper = opts?.helper || "请选择"; const helper = opts?.helper || "请选择";
const mode = opts?.mode || "tags"; let mode = "tags";
if (opts.multi === false) {
mode = undefined;
} else {
mode = opts?.mode ?? "tags";
}
const item = { const item = {
title, title,
component: { component: {

View File

@@ -1,2 +1,3 @@
export * from "./ssh.js"; export * from "./ssh.js";
export * from "./ssh-access.js"; export * from "./ssh-access.js";
export * from "./sftp-access.js";

View File

@@ -0,0 +1,34 @@
import { AccessInput, BaseAccess, IsAccess } from "@certd/pipeline";
@IsAccess({
name: "sftp",
title: "SFTP授权",
desc: "",
icon: "clarity:host-line",
input: {},
})
export class SftpAccess extends BaseAccess {
@AccessInput({
title: "SSH授权",
component: {
name: "access-selector",
type: "ssh",
vModel: "modelValue",
},
helper: "请选择一个SSH授权",
required: true,
})
sshAccess!: string;
@AccessInput({
title: "文件权限",
component: {
name: "a-input",
vModel: "value",
placeholder: "777",
},
helper: "文件上传后是否修改文件权限",
})
fileMode!: string;
}
new SftpAccess();

View File

@@ -80,11 +80,11 @@ export class AsyncSsh2Client {
}); });
} }
async fastPut(options: { sftp: any; localPath: string; remotePath: string }) { async fastPut(options: { sftp: any; localPath: string; remotePath: string; opts?: { mode?: string } }) {
const { sftp, localPath, remotePath } = options; const { sftp, localPath, remotePath, opts } = options;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.logger.info(`开始上传:${localPath} => ${remotePath}`); this.logger.info(`开始上传:${localPath} => ${remotePath}`);
sftp.fastPut(localPath, remotePath, (err: Error) => { sftp.fastPut(localPath, remotePath, { ...(opts ?? {}) }, (err: Error) => {
if (err) { if (err) {
reject(err); reject(err);
this.logger.error("请确认路径是否包含文件名,路径本身不能是目录,路径不能有*?之类的特殊符号,要有写入权限"); this.logger.error("请确认路径是否包含文件名,路径本身不能是目录,路径不能有*?之类的特殊符号,要有写入权限");
@@ -255,8 +255,8 @@ export class SshClient {
} }
* @param options * @param options
*/ */
async uploadFiles(options: { connectConf: SshAccess; transports: TransportItem[]; mkdirs: boolean }) { async uploadFiles(options: { connectConf: SshAccess; transports: TransportItem[]; mkdirs: boolean; opts?: { mode?: string } }) {
const { connectConf, transports, mkdirs } = options; const { connectConf, transports, mkdirs, opts } = options;
await this._call({ await this._call({
connectConf, connectConf,
callable: async (conn: AsyncSsh2Client) => { callable: async (conn: AsyncSsh2Client) => {
@@ -281,7 +281,7 @@ export class SshClient {
} }
await conn.exec(mkdirCmd); await conn.exec(mkdirCmd);
} }
await conn.fastPut({ sftp, ...transport }); await conn.fastPut({ sftp, ...transport, opts });
} }
this.logger.info("文件全部上传成功"); this.logger.info("文件全部上传成功");
}, },

View File

@@ -3,6 +3,53 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
**Note:** Version bump only for package @certd/ui-client
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
**Note:** Version bump only for package @certd/ui-client
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
### Bug Fixes
* 当前置任务被删除时进行校验 ([c89686a](https://github.com/certd/certd/commit/c89686a2fda251484930f0ae715417b618c21690))
### Performance Improvements
* 上传自定义证书 ([75a38d9](https://github.com/certd/certd/commit/75a38d95f305b4271d9106babe7cffc1c89ae8f3))
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
### Performance Improvements
* 创建流水线时,默认成功时也发送通知 ([52ae690](https://github.com/certd/certd/commit/52ae6902d203ca56e0312692b50c55cb6ddd3e39))
* http方式校验选择sftp时支持修改文件访问权限比如777 ([15d6eaf](https://github.com/certd/certd/commit/15d6eaf5532ed25acd4f8d58c429353a2f44206c))
# [1.30.0](https://github.com/certd/certd/compare/v1.29.5...v1.30.0) (2025-01-19)
### Bug Fixes
* 修复查看任务日志偶发性无法自动滚动底部的bug ([7e482f7](https://github.com/certd/certd/commit/7e482f798c0142bce1866f84676cb40210f9638a))
### Performance Improvements
* 证书仓库 ([91e7f45](https://github.com/certd/certd/commit/91e7f45a1c5ea1e0ec0aa3236b80028f03a6d0aa))
## [1.29.5](https://github.com/certd/certd/compare/v1.29.4...v1.29.5) (2025-01-07)
### Bug Fixes
* 修复授权管理点击了查看原文按钮后无法修改值的bug ([85c99f7](https://github.com/certd/certd/commit/85c99f7f80761ac6efaf3255c03b933442db1686))
## [1.29.4](https://github.com/certd/certd/compare/v1.29.3...v1.29.4) (2025-01-06)
### Bug Fixes
* 修复站点监控域名校验无法通过的bug ([1cb4a53](https://github.com/certd/certd/commit/1cb4a539cc523721ffd4b22d40d0e3d2d68cd915))
## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04) ## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04)
### Performance Improvements ### Performance Improvements

View File

@@ -1,6 +1,6 @@
{ {
"name": "@certd/ui-client", "name": "@certd/ui-client",
"version": "1.29.3", "version": "1.30.4",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite --open", "dev": "vite --open",
@@ -26,10 +26,10 @@
"dependencies": { "dependencies": {
"@ant-design/colors": "^7.0.2", "@ant-design/colors": "^7.0.2",
"@ant-design/icons-vue": "^6.1.0", "@ant-design/icons-vue": "^6.1.0",
"@fast-crud/fast-crud": "^1.23.4", "@fast-crud/fast-crud": "^1.25.0",
"@fast-crud/fast-extends": "^1.23.4", "@fast-crud/fast-extends": "^1.25.0",
"@fast-crud/ui-antdv4": "^1.23.4", "@fast-crud/ui-antdv4": "^1.25.0",
"@fast-crud/ui-interface": "^1.23.4", "@fast-crud/ui-interface": "^1.25.0",
"@iconify/vue": "^4.1.1", "@iconify/vue": "^4.1.1",
"@soerenmartius/vue3-clipboard": "^0.1.2", "@soerenmartius/vue3-clipboard": "^0.1.2",
"@vue-js-cron/light": "^4.0.5", "@vue-js-cron/light": "^4.0.5",
@@ -66,8 +66,8 @@
"vuedraggable": "^4.1.0" "vuedraggable": "^4.1.0"
}, },
"devDependencies": { "devDependencies": {
"@certd/lib-iframe": "^1.29.3", "@certd/lib-iframe": "^1.30.4",
"@certd/pipeline": "^1.29.3", "@certd/pipeline": "^1.30.4",
"@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-node-resolve": "^15.2.3",
"@types/chai": "^4.3.12", "@types/chai": "^4.3.12",

View File

@@ -10,9 +10,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import zhCN from "ant-design-vue/es/locale/zh_CN"; import zhCN from "ant-design-vue/es/locale/zh_CN";
import enUS from "ant-design-vue/es/locale/en_US"; import enUS from "ant-design-vue/es/locale/en_US";
import { nextTick, provide, ref } from "vue"; import { provide, ref } from "vue";
import { usePageStore } from "/src/store/modules/page"; import { usePageStore } from "/src/store/modules/page";
import { useResourceStore } from "/src/store/modules/resource";
import { useSettingStore } from "/@/store/modules/settings"; import { useSettingStore } from "/@/store/modules/settings";
import "dayjs/locale/zh-cn"; import "dayjs/locale/zh-cn";
import "dayjs/locale/en"; import "dayjs/locale/en";

View File

@@ -30,7 +30,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { Ref, ref, watch } from "vue"; import { Ref, ref, watch, nextTick } from "vue";
import { HttpRecord } from "/@/components/plugins/cert/domains-verify-plan-editor/type"; import { HttpRecord } from "/@/components/plugins/cert/domains-verify-plan-editor/type";
import { dict } from "@fast-crud/fast-crud"; import { dict } from "@fast-crud/fast-crud";
@@ -62,18 +62,20 @@ watch(
} }
); );
function onRecordChange() { async function onRecordChange() {
await nextTick();
emit("update:modelValue", records.value); emit("update:modelValue", records.value);
emit("change", records.value); emit("change", records.value);
} }
const uploaderTypeDict = dict({ const uploaderTypeDict = dict({
data: [ data: [
{ label: "SFTP/SSH", value: "ssh" }, { label: "SFTP", value: "sftp" },
{ label: "FTP", value: "ftp" }, { label: "FTP", value: "ftp" },
{ label: "阿里云OSS", value: "alioss" }, { label: "阿里云OSS", value: "alioss" },
{ label: "腾讯云COS", value: "tencentcos" }, { label: "腾讯云COS", value: "tencentcos" },
{ label: "七牛OSS", value: "qiniuoss" } { label: "七牛OSS", value: "qiniuoss" },
{ label: "SSH(已废弃请选择SFTP方式)", value: "ssh", disabled: true }
] ]
}); });
</script> </script>

View File

@@ -44,8 +44,15 @@ export default {
options.value = options.value.filter((item: any) => props.from.includes(item.type)); options.value = options.value.filter((item: any) => props.from.includes(item.type));
} }
} }
if (props.modelValue == null && options.value.length > 0) {
ctx.emit("update:modelValue", options.value[0].value); if (props.modelValue != null) {
const found = options.value.find((item: any) => item.value === props.modelValue);
if (!found) {
ctx.emit("update:modelValue", undefined);
}
} else {
const value = options.value.length > 0 ? options.value[0].value : undefined;
ctx.emit("update:modelValue", value);
} }
} }
onMounted(() => { onMounted(() => {

View File

@@ -40,6 +40,17 @@ export const certdResources = [
cache: true cache: true
} }
}, },
{
title: "证书仓库",
name: "CertStore",
path: "/certd/monitor/cert",
component: "/certd/monitor/cert/index.vue",
meta: {
icon: "ion:shield-checkmark-outline",
auth: true,
isMenu: true
}
},
{ {
title: "站点证书监控", title: "站点证书监控",
name: "SiteCertMonitor", name: "SiteCertMonitor",
@@ -80,21 +91,6 @@ export const certdResources = [
auth: true auth: true
} }
}, },
{
title: "证书仓库",
name: "CertStore",
path: "/certd/monitor/cert",
component: "/certd/monitor/cert/index.vue",
meta: {
show: () => {
const settingStore = useSettingStore();
return settingStore.isPlus;
},
icon: "ion:shield-checkmark-outline",
auth: true,
isMenu: false
}
},
{ {
title: "授权管理", title: "授权管理",
name: "AccessManager", name: "AccessManager",
@@ -106,6 +102,17 @@ export const certdResources = [
cache: true cache: true
} }
}, },
{
title: "OpenKey",
name: "OpenKey",
path: "/certd/open/openkey",
component: "/certd/open/openkey/index.vue",
meta: {
icon: "hugeicons:api",
auth: true,
cache: true
}
},
{ {
title: "通知设置", title: "通知设置",
name: "NotificationManager", name: "NotificationManager",

View File

@@ -49,7 +49,7 @@ export const sysResources = [
} }
}, },
{ {
title: "邮设置", title: "邮件服务器设置",
name: "EmailSetting", name: "EmailSetting",
path: "/sys/settings/email", path: "/sys/settings/email",
component: "/sys/settings/email/index.vue", component: "/sys/settings/email/index.vue",

View File

@@ -2,6 +2,7 @@
display: inline-flex; display: inline-flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
font-size:16px;
} }
@@ -9,6 +10,10 @@
display: inline-flex; display: inline-flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
.fs-iconify{
margin-right: 5px;
}
} }
.cd-icon-button { .cd-icon-button {

View File

@@ -41,7 +41,11 @@ export function getCommonColumnDefine(crudExpose: any, typeRef: any, api: any) {
column.suffixRender = (scope: { form: any; key: string }) => { column.suffixRender = (scope: { form: any; key: string }) => {
const { form, key } = scope; const { form, key } = scope;
const inputKey = scope.key.replace("access.", ""); const inputKey = scope.key.replace("access.", "");
return <SecretPlainGetter accessId={form.id} inputKey={inputKey} v-model={form[key]} />; const onChange = (val: any) => {
set(form, key, val);
};
const value = get(form, key);
return <SecretPlainGetter accessId={form.id} inputKey={inputKey} modalValue={value} onUpdate:modelValue={onChange} />;
}; };
} }
//eval //eval

View File

@@ -70,7 +70,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
key: "id", key: "id",
type: "number", type: "number",
column: { column: {
width: 100 width: 80
}, },
form: { form: {
show: false show: false

View File

@@ -1,54 +1,57 @@
import { request } from "/src/api/service"; import { request } from "/src/api/service";
export function createApi() { const apiPrefix = "/monitor/cert";
const apiPrefix = "/monitor/cert"; export const certInfoApi = {
return { async GetList(query: any) {
async GetList(query: any) { return await request({
return await request({ url: apiPrefix + "/page",
url: apiPrefix + "/page", method: "post",
method: "post", data: query
data: query });
}); },
},
async AddObj(obj: any) { async AddObj(obj: any) {
return await request({ return await request({
url: apiPrefix + "/add", url: apiPrefix + "/add",
method: "post", method: "post",
data: obj data: obj
}); });
}, },
async UpdateObj(obj: any) { async UpdateObj(obj: any) {
return await request({ return await request({
url: apiPrefix + "/update", url: apiPrefix + "/update",
method: "post", method: "post",
data: obj data: obj
}); });
}, },
async DelObj(id: number) { async DelObj(id: number) {
return await request({ return await request({
url: apiPrefix + "/delete", url: apiPrefix + "/delete",
method: "post", method: "post",
params: { id } params: { id }
}); });
}, },
async GetObj(id: number) { async GetObj(id: number) {
return await request({ return await request({
url: apiPrefix + "/info", url: apiPrefix + "/info",
method: "post", method: "post",
params: { id } params: { id }
}); });
}, },
async ListAll() { async ListAll() {
return await request({ return await request({
url: apiPrefix + "/all", url: apiPrefix + "/all",
method: "post" method: "post"
}); });
} },
}; async Upload(body: { id?: number; cert: { crt: string; key: string } }) {
} return await request({
url: apiPrefix + "/upload",
export const pipelineGroupApi = createApi(); method: "post",
data: body
});
}
};

View File

@@ -1,11 +1,14 @@
// @ts-ignore // @ts-ignore
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud"; import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, useFormWrapper, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { pipelineGroupApi } from "./api"; import { certInfoApi } from "./api";
import dayjs from "dayjs";
import { useUserStore } from "/@/store/modules/user";
import { useRouter } from "vue-router";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { t } = useI18n(); const { t } = useI18n();
const api = pipelineGroupApi; const api = certInfoApi;
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => { const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query); return await api.GetList(query);
}; };
@@ -25,7 +28,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
const res = await api.AddObj(form); const res = await api.AddObj(form);
return res; return res;
}; };
const { openCrudFormDialog } = useFormWrapper();
const router = useRouter();
return { return {
crudOptions: { crudOptions: {
request: { request: {
@@ -49,7 +53,68 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
width: 600 width: 600
} }
}, },
actionbar: { show: false }, actionbar: {
show: true,
buttons: {
add: {
text: "上传自定义证书",
type: "primary",
show: false,
async click() {
function createCrudOptions() {
return {
crudOptions: {
request: {
addRequest: async (form: any) => {
return await api.Upload(form);
},
editRequest: async (form: any) => {
return await api.Upload(form);
}
},
columns: {
id: {
title: "ID",
type: "number",
form: {
show: false
}
},
"cert.crt": {
title: "证书",
type: "textarea",
form: {
component: {
rows: 4
},
rules: [{ required: true, message: "此项必填" }]
}
},
"cert.key": {
title: "私钥",
type: "textarea",
form: {
component: {
rows: 4
},
rules: [{ required: true, message: "此项必填" }]
}
}
},
form: {
wrapper: {
title: "上传自定义证书"
}
}
}
};
}
const { crudOptions } = createCrudOptions();
const wrapperRef = await openCrudFormDialog({ crudOptions });
}
}
}
},
rowHandle: { rowHandle: {
width: 200, width: 200,
fixed: "right", fixed: "right",
@@ -78,37 +143,38 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
show: false show: false
} }
}, },
domain: { // domain: {
title: "主域名", // title: "主域名",
search: { // search: {
show: true // show: true
}, // },
type: "text", // type: "text",
form: { // form: {
show: false // show: false
}, // },
column: { // column: {
width: 180, // width: 180,
sorter: true, // sorter: true,
component: { // component: {
name: "fs-values-format" // name: "fs-values-format"
} // }
} // }
}, // },
domains: { domains: {
title: "全部域名", title: "全部域名",
search: { search: {
show: false show: true
}, },
type: "text", type: "text",
form: { form: {
rules: [{ required: true, message: "请输入域名" }] rules: [{ required: true, message: "请输入域名" }]
}, },
column: { column: {
width: 350, width: 450,
sorter: true, sorter: true,
component: { component: {
name: "fs-values-format" name: "fs-values-format",
color: "auto"
} }
} }
}, },
@@ -124,17 +190,40 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
show: false show: false
} }
}, },
"pipeline.title": { expiresTime: {
title: "已关联流水线", title: "过期时间",
search: { show: false }, search: {
type: "link", show: false
},
type: "date",
form: { form: {
show: false show: false
}, },
column: { column: {
width: 250,
sorter: true, sorter: true,
component: {} cellRender({ value }) {
if (!value) {
return "-";
}
const expireDate = dayjs(value).format("YYYY-MM-DD");
const leftDays = dayjs(value).diff(dayjs(), "day");
const color = leftDays < 20 ? "red" : "#389e0d";
const percent = (leftDays / 90) * 100;
return <a-progress title={expireDate + "过期"} percent={percent} strokeColor={color} format={(percent: number) => `${leftDays}`} />;
}
}
},
certProvider: {
title: "证书颁发机构",
search: {
show: false
},
type: "text",
form: {
show: false
},
column: {
width: 200
} }
}, },
applyTime: { applyTime: {
@@ -150,42 +239,23 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
sorter: true sorter: true
} }
}, },
expiresTime: { "pipeline.title": {
title: "过期时间", title: "关联流水线",
search: { search: { show: false },
show: true type: "link",
},
type: "date",
form: { form: {
show: false show: false
}, },
column: { column: {
sorter: true width: 350,
} sorter: true,
}, component: {
fromType: { on: {
title: "来源", onClick({ row }) {
search: { router.push({ path: "/certd/pipeline/detail", query: { id: row.pipelineId, editMode: "false" } });
show: true }
}, }
type: "text", }
form: { show: false },
column: {
width: 100,
sorter: true
}
},
certProvider: {
title: "证书颁发机构",
search: {
show: true
},
type: "text",
form: {
show: false
},
column: {
width: 400
} }
} }
} }

View File

@@ -3,7 +3,7 @@
<template #header> <template #header>
<div class="title"> <div class="title">
证书仓库 证书仓库
<span class="sub">管理证书后续将支持手动上传证书并部署</span> <span class="sub">从流水线生成的证书后续将支持手动上传证书并部署</span>
</div> </div>
</template> </template>
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud> <fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>

View File

@@ -145,7 +145,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
search: { search: {
show: true show: true
}, },
type: "copyable", type: "text",
form: { form: {
rules: [ rules: [
{ required: true, message: "请输入域名" }, { required: true, message: "请输入域名" },

View File

@@ -0,0 +1,53 @@
import { request } from "/src/api/service";
export const OPEN_API_DOC = "https://apifox.com/apidoc/shared-2e76f8c4-7c58-413b-a32d-a1316529af44/254949529e0";
const apiPrefix = "/open/key";
export const openkeyApi = {
async GetList(query: any) {
return await request({
url: apiPrefix + "/page",
method: "post",
data: query
});
},
async AddObj(obj: any) {
return await request({
url: apiPrefix + "/add",
method: "post",
data: obj
});
},
async UpdateObj(obj: any) {
return await request({
url: apiPrefix + "/update",
method: "post",
data: obj
});
},
async DelObj(id: number) {
return await request({
url: apiPrefix + "/delete",
method: "post",
params: { id }
});
},
async GetObj(id: number) {
return await request({
url: apiPrefix + "/info",
method: "post",
params: { id }
});
},
async GetApiToken(id: number) {
return await request({
url: apiPrefix + "/getApiToken",
method: "post",
data: { id }
});
}
};

View File

@@ -0,0 +1,185 @@
// @ts-ignore
import { useI18n } from "vue-i18n";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { OPEN_API_DOC, openkeyApi } from "./api";
import { useModal } from "/@/use/use-modal";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { t } = useI18n();
const api = openkeyApi;
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
};
const editRequest = async (req: EditReq) => {
const { form, row } = req;
form.id = row.id;
const res = await api.UpdateObj(form);
return res;
};
const delRequest = async (req: DelReq) => {
const { row } = req;
return await api.DelObj(row.id);
};
const addRequest = async (req: AddReq) => {
const { form } = req;
const res = await api.AddObj(form);
return res;
};
const model = useModal();
return {
crudOptions: {
request: {
pageRequest,
addRequest,
editRequest,
delRequest
},
search: {
show: false
},
form: {
labelCol: {
//固定label宽度
span: null,
style: {
width: "100px"
}
},
col: {
span: 22
},
wrapper: {
width: 600
}
},
actionbar: {
buttons: {
add: {
text: "生成新的Key"
}
}
},
rowHandle: {
width: 300,
fixed: "right",
buttons: {
view: { show: true },
copy: { show: false },
edit: { show: false },
remove: { show: true },
gen: {
text: "接口测试",
size: "mini",
icon: "devicon-plain:vitest",
type: "primary",
async click({ row }) {
const apiToken = await api.GetApiToken(row.id);
model.success({
title: "x-certd-token",
maskClosable: true,
okText: "确定",
width: 600,
content: () => {
return (
<div>
<div class={"m-10 p-10"}>
x-certd-token如下3使
<a href={OPEN_API_DOC} target={"_blank"}>
</a>
</div>
<div class={"m-10 p-10"} style={{ border: "1px solid #333" }}>
<fs-copyable model-value={apiToken}></fs-copyable>
</div>
</div>
);
}
});
}
}
}
},
columns: {
id: {
title: "ID",
key: "id",
type: "number",
search: {
show: false
},
column: {
width: 100,
editable: {
disabled: true
}
},
form: {
show: false
}
},
keyId: {
title: "KeyId",
type: ["text", "copyable"],
search: {
show: true
},
form: {
show: false
},
column: {
width: 250,
sorter: true
}
},
keySecret: {
title: "KeySecret",
type: ["text", "copyable"],
form: {
show: false
},
column: {
width: 580,
sorter: true
}
},
scope: {
title: "权限范围",
type: "dict-radio",
dict: dict({
data: [
{ label: "仅开放接口", value: "open", color: "blue" },
{ label: "账户所有权限", value: "user", color: "red" }
]
}),
form: {
value: "open",
show: true,
rules: [{ required: true, message: "此项必填" }],
helper: "仅开放接口只可以访问开放接口,账户所有权限可以访问所有接口",
component: {
vModel: "value"
}
},
column: {
width: 120,
align: "center",
sorter: true
}
},
createTime: {
title: "创建时间",
type: "datetime",
search: {
show: false
},
form: {
show: false
}
}
}
}
};
}

View File

@@ -0,0 +1,31 @@
<template>
<fs-page>
<template #header>
<div class="title">开放接口密钥管理</div>
<div class="more">
<a :href="OPEN_API_DOC" target="_blank">开放接口文档</a>
</div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
</fs-page>
</template>
<script lang="ts" setup>
import { onActivated, onMounted } from "vue";
import { useFs } from "@fast-crud/fast-crud";
import createCrudOptions from "./crud";
import { OPEN_API_DOC } from "/@/views/certd/open/openkey/api";
defineOptions({
name: "OpenKey"
});
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
// 页面打开后获取列表数据
onMounted(() => {
crudExpose.doRefresh();
});
onActivated(() => {
crudExpose.doRefresh();
});
</script>

View File

@@ -122,7 +122,7 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
if (form.notification != null) { if (form.notification != null) {
notifications.push({ notifications.push({
type: "custom", type: "custom",
when: ["error", "turnToSuccess"], when: ["error", "turnToSuccess", "success"],
notificationId: form.notification, notificationId: form.notification,
title: form.notificationTarget?.name || "自定义通知" title: form.notificationTarget?.name || "自定义通知"
}); });

View File

@@ -89,7 +89,11 @@ export default {
return; return;
} }
//判断当前是否在底部 //判断当前是否在底部
const isBottom = el ? el.scrollHeight - el.scrollTop === el.clientHeight : true; let isBottom = true;
if (el) {
isBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 5;
console.log("isBottom", isBottom, el.scrollHeight, el.scrollTop, el.clientHeight);
}
await nextTick(); await nextTick();
el = document.querySelector(`.pi-task-view-logs.id-${node.node.id}`); el = document.querySelector(`.pi-task-view-logs.id-${node.node.id}`);
//如果在底部则滚动到底部 //如果在底部则滚动到底部

View File

@@ -78,7 +78,8 @@
<div <div
class="task-container" class="task-container"
:class="{ :class="{
'first-task': taskIndex === 0 'first-task': taskIndex === 0,
'validate-error': hasValidateError(task.id)
}" }"
> >
<div class="line line-left"> <div class="line line-left">
@@ -98,14 +99,16 @@
{{ index + 1 }}. {{ item.title }} {{ index + 1 }}. {{ item.title }}
</span> </span>
<pi-status-show v-if="!editMode" :status="item.status?.result"></pi-status-show> <pi-status-show v-if="!editMode" :status="item.status?.result"></pi-status-show>
<fs-icon <a-tooltip title="强制重新执行此步骤">
v-if="!editMode" <fs-icon
class="pointer color-blue ml-2" v-if="!editMode"
style="font-size: 16px" class="pointer color-blue ml-2"
title="强制重新执行此步骤" style="font-size: 16px"
icon="icon-park-outline:replay-music" title="强制重新执行此步骤"
@click="run(item.id)" icon="icon-park-outline:replay-music"
></fs-icon> @click="run(item.id)"
></fs-icon>
</a-tooltip>
</div> </div>
</template> </template>
<span class="flex-o w-100"> <span class="flex-o w-100">
@@ -169,7 +172,6 @@
<div class="task"> <div class="task">
<a-button shape="round" type="dashed" @click="notificationAdd()"> <a-button shape="round" type="dashed" @click="notificationAdd()">
<fs-icon icon="ion:add-circle-outline"></fs-icon> <fs-icon icon="ion:add-circle-outline"></fs-icon>
添加通知 添加通知
</a-button> </a-button>
</div> </div>
@@ -624,7 +626,78 @@ export default defineComponent({
function toggleEditMode(editMode: boolean) { function toggleEditMode(editMode: boolean) {
ctx.emit("update:editMode", editMode); ctx.emit("update:editMode", editMode);
} }
const validateErrors: Ref = ref({});
function addValidateError(taskId: string, error: any) {
const errors = validateErrors.value[taskId] || [];
validateErrors.value[taskId] = errors;
errors.push(error);
}
function doValidate() {
validateErrors.value = {};
const stepIds: string[] = [];
//校验output id是否正确
const pp = pipeline.value;
function eachSteps(callback: any) {
if (pp.stages) {
for (const stage of pp.stages) {
if (stage.tasks) {
for (const task of stage.tasks) {
if (task.steps) {
for (const step of task.steps) {
callback(step, task, stage);
}
}
}
}
}
}
}
//检查输出的stepid是否存在
let hasError = false;
let errorMessage = "";
eachSteps((step: any, task: any, stage: any) => {
stepIds.push(step.id);
if (step.input) {
for (const key in step.input) {
const value = step.input[key];
if (value == null || typeof value != "string" || !value.startsWith("step.")) {
continue;
}
const arr = value.split(".");
if (arr.length != 3) {
continue;
}
const stepId = arr[1];
const paramName = arr[2];
if (!stepIds.includes(stepId)) {
hasError = true;
const message = `任务${step.title}的前置输出步骤${paramName}不存在,请重新修改此任务`;
addValidateError(task.id, {
message
});
addValidateError(step.id, {
message
});
errorMessage += message + "";
}
}
}
});
if (hasError) {
notification.error({ message: errorMessage });
throw new Error(errorMessage);
}
}
function hasValidateError(taskId: string) {
return validateErrors.value[taskId] != null;
}
const save = async () => { const save = async () => {
doValidate();
saveLoading.value = true; saveLoading.value = true;
try { try {
if (props.options.doSave) { if (props.options.doSave) {
@@ -661,7 +734,8 @@ export default defineComponent({
save, save,
edit, edit,
cancel, cancel,
saveLoading saveLoading,
hasValidateError
}; };
} }
@@ -873,6 +947,14 @@ export default defineComponent({
justify-content: center; justify-content: center;
align-items: center; align-items: center;
position: relative; position: relative;
&.validate-error {
.task {
.ant-btn {
border-color: red;
}
}
}
.task { .task {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@@ -63,6 +63,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
width: 240, width: 240,
fixed: "right", fixed: "right",
buttons: { buttons: {
view: { show: false },
edit: { show: false }, edit: { show: false },
copy: { show: false }, copy: { show: false },
syncStatus: { syncStatus: {

View File

@@ -217,9 +217,9 @@ async function loadPluginGroups() {
const pluginGroups = ref(); const pluginGroups = ref();
onMounted(async () => { onMounted(async () => {
await userStore.loadUserInfo(); await userStore.loadUserInfo();
await loadLatestVersion(); loadLatestVersion();
await loadCount(); loadCount();
await loadPluginGroups(); loadPluginGroups();
}); });
function openUpgradeUrl() { function openUpgradeUrl() {

View File

@@ -1,5 +1,5 @@
import { request } from "/src/api/service"; import { request } from "/src/api/service";
const apiPrefix = "/basic/email"; const apiPrefix = "/mine/email";
export async function TestSend(receiver: string) { export async function TestSend(receiver: string) {
await request({ await request({

View File

@@ -2,7 +2,7 @@
<fs-page class="page-setting-email"> <fs-page class="page-setting-email">
<template #header> <template #header>
<div class="title"> <div class="title">
邮件设置 邮件服务器设置
<span class="sub">设置邮件发送服务器</span> <span class="sub">设置邮件发送服务器</span>
</div> </div>
</template> </template>

View File

@@ -153,7 +153,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
}, },
icon: { icon: {
title: "图标", title: "图标",
type: "text", type: "icon",
column: { column: {
width: 300, width: 300,
cellRender: ({ row }) => { cellRender: ({ row }) => {
@@ -163,18 +163,6 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
form: { form: {
component: { component: {
placeholder: "ion:add-circle" placeholder: "ion:add-circle"
},
helper: {
render: () => {
return (
<span>
<a href="https://icon-sets.iconify.design/" target="_blank">
</a>
<span>--------</span>
</span>
);
}
} }
} }
}, },

View File

@@ -2,11 +2,14 @@
<div class="sys-settings-form sys-settings-payment"> <div class="sys-settings-form sys-settings-payment">
<a-form ref="formRef" :model="formState" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }" autocomplete="off"> <a-form ref="formRef" :model="formState" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }" autocomplete="off">
<div>支付方式</div> <div>支付方式</div>
<a-form-item label="易支付" :name="['yizhifu', 'enabled']" :required="true"> <a-form-item label="彩虹易支付" :name="['yizhifu', 'enabled']" :required="true">
<a-switch v-model:checked="formState.yizhifu.enabled" /> <a-switch v-model:checked="formState.yizhifu.enabled" />
</a-form-item> </a-form-item>
<a-form-item v-if="formState.yizhifu.enabled" label="易支付配置" :name="['yizhifu', 'accessId']" :required="true"> <a-form-item v-if="formState.yizhifu.enabled" label="易支付配置" :name="['yizhifu', 'accessId']" :required="true">
<access-selector v-model="formState.yizhifu.accessId" type="yizhifu" from="sys" /> <access-selector v-model="formState.yizhifu.accessId" type="yizhifu" from="sys" />
<div class="helper">
<a href="https://certd.docmirror.cn/comm/payments/yizhifu.html">彩虹易支付配置帮助文档</a>
</div>
</a-form-item> </a-form-item>
<a-form-item label="支付宝" :name="['alipay', 'enabled']" :required="true"> <a-form-item label="支付宝" :name="['alipay', 'enabled']" :required="true">
@@ -14,7 +17,7 @@
</a-form-item> </a-form-item>
<a-form-item v-if="formState.alipay.enabled" label="支付宝配置" :name="['alipay', 'accessId']" :required="true"> <a-form-item v-if="formState.alipay.enabled" label="支付宝配置" :name="['alipay', 'accessId']" :required="true">
<access-selector v-model="formState.alipay.accessId" type="alipay" from="sys" /> <access-selector v-model="formState.alipay.accessId" type="alipay" from="sys" />
<div class="helper">需要开通电脑网站支付</div> <div class="helper">需要开通电脑网站支付 <a href="https://certd.docmirror.cn/comm/payments/alipay.html">支付宝配置帮助文档</a></div>
</a-form-item> </a-form-item>
<a-form-item label="微信支付" :name="['wxpay', 'enabled']" :required="true"> <a-form-item label="微信支付" :name="['wxpay', 'enabled']" :required="true">
@@ -22,7 +25,7 @@
</a-form-item> </a-form-item>
<a-form-item v-if="formState.wxpay.enabled" label="微信支付配置" :name="['wxpay', 'accessId']" :required="true"> <a-form-item v-if="formState.wxpay.enabled" label="微信支付配置" :name="['wxpay', 'accessId']" :required="true">
<access-selector v-model="formState.wxpay.accessId" type="wxpay" from="sys" /> <access-selector v-model="formState.wxpay.accessId" type="wxpay" from="sys" />
<div class="helper">需要开通Native支付</div> <div class="helper">需要开通Native支付 <a href="https://certd.docmirror.cn/comm/payments/wxpay.html">微信配置帮助文档</a></div>
</a-form-item> </a-form-item>
<a-form-item :wrapper-col="{ offset: 8, span: 16 }"> <a-form-item :wrapper-col="{ offset: 8, span: 16 }">

View File

@@ -70,6 +70,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
width: 320, width: 320,
fixed: "right", fixed: "right",
buttons: { buttons: {
view: {
show: false
},
copy: { copy: {
show: false show: false
}, },

View File

@@ -3,6 +3,70 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
### Bug Fixes
* 适配最新版1panel密码编码方式 ([78044c0](https://github.com/certd/certd/commit/78044c062e20cdd04f08baef9fb6745bf25eddcf))
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
### Bug Fixes
* 修复腾讯云CLB多域名同证书部署报错的bug ([c3a5542](https://github.com/certd/certd/commit/c3a55429357e78f4b78c9592d3e5897db2d4d549))
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
### Bug Fixes
* 修复cloudflare删除解析记录报错的bug ([00c2da4](https://github.com/certd/certd/commit/00c2da444f84adb89f3f1226d03294d7c6e3e4f1))
### Performance Improvements
* 上传自定义证书 ([75a38d9](https://github.com/certd/certd/commit/75a38d95f305b4271d9106babe7cffc1c89ae8f3))
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
### Bug Fixes
* 修复部署到阿里云ALB、NLB插件加载混乱的bug ([6ab83b6](https://github.com/certd/certd/commit/6ab83b662a2c5e715b9cb7eb1244de2ebb7f47b0))
* 修复腾讯clb重复执行会报错的bug ([e95d29f](https://github.com/certd/certd/commit/e95d29f446d06eced315a3087fc9e105a30b20bd))
* 修复tg消息内容中存在.和*就会发送失败的bug ([ae5dfc3](https://github.com/certd/certd/commit/ae5dfc3bee950267123ae2fbd1c11e7ce36626ea))
### Performance Improvements
* http方式校验选择sftp时支持修改文件访问权限比如777 ([15d6eaf](https://github.com/certd/certd/commit/15d6eaf5532ed25acd4f8d58c429353a2f44206c))
# [1.30.0](https://github.com/certd/certd/compare/v1.29.5...v1.30.0) (2025-01-19)
### Bug Fixes
* 修复namesilo ttl太短的问题 ([865f26d](https://github.com/certd/certd/commit/865f26d75c0d3dd4dc8b41448f8830068e45957c))
### Features
* 支持open api接口根据域名获取证书 ([52a4fd3](https://github.com/certd/certd/commit/52a4fd33180e9b3f71b8dc9f7671d7cd8e448c3b))
### Performance Improvements
* 证书仓库 ([91e7f45](https://github.com/certd/certd/commit/91e7f45a1c5ea1e0ec0aa3236b80028f03a6d0aa))
* 支持部署到阿里云ALB ([653940a](https://github.com/certd/certd/commit/653940a0ca64fc380178c1b0b58ae0af64dfaf07))
* 支持部署到阿里云NLB、SLB ([c085bac](https://github.com/certd/certd/commit/c085bac5d877c4250a8a79e17eb8673b8e4fc89c))
* 支持部署到腾讯云直播 ([417d37b](https://github.com/certd/certd/commit/417d37b199b79a42f790f9edab8f178eedf8fbf7))
* 支持部署证书到proxmox ([d10795e](https://github.com/certd/certd/commit/d10795ecd97eb8cf2ffa46aabfdbfc6812636396))
## [1.29.5](https://github.com/certd/certd/compare/v1.29.4...v1.29.5) (2025-01-07)
### Bug Fixes
* 修复复制到本机插件pfx格式复制时报错的bug ([f57116d](https://github.com/certd/certd/commit/f57116d2bebf33e47ad93e0b39c4efe8e4aea25c))
## [1.29.4](https://github.com/certd/certd/compare/v1.29.3...v1.29.4) (2025-01-06)
### Performance Improvements
* 优化腾讯云CLB插件支持非sni情况sni情况支持填写多个域名 ([635b042](https://github.com/certd/certd/commit/635b042690637bff85e97e07c7aac4b87a8a124b))
## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04) ## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04)
### Bug Fixes ### Bug Fixes

View File

@@ -11,6 +11,5 @@
```shell ```shell
npm run heap npm run heap
``` ```

View File

@@ -0,0 +1,16 @@
CREATE TABLE `cd_open_key`
(
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
`user_id` bigint,
`key_id` varchar(50),
`key_secret` varchar(100),
`scope` varchar(50),
`disabled` boolean NOT NULL DEFAULT false,
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX `index_open_key_user_id` ON `cd_open_key` (`user_id`);
CREATE INDEX `index_open_key_key_id` ON `cd_open_key` (`key_id`);

View File

@@ -0,0 +1,16 @@
CREATE TABLE "cd_open_key"
(
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY NOT NULL,
"user_id" bigint,
"key_id" varchar(50),
"key_secret" varchar(100),
"scope" varchar(50),
"disabled" boolean NOT NULL DEFAULT (false),
"create_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP),
"update_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP)
);
CREATE INDEX "index_open_key_user_id" ON "cd_open_key" ("user_id");
CREATE INDEX "index_open_key_key_id" ON "cd_open_key" ("key_id");

View File

@@ -0,0 +1,16 @@
CREATE TABLE "cd_open_key"
(
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
"user_id" integer,
"key_id" varchar(50),
"key_secret" varchar(100),
"scope" varchar(50),
"disabled" boolean NOT NULL DEFAULT (false),
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
);
CREATE INDEX "index_open_key_user_id" ON "cd_open_key" ("user_id");
CREATE INDEX "index_open_key_key_id" ON "cd_open_key" ("key_id");

View File

@@ -67,7 +67,8 @@ function transformMysql() {
pgSql = pgSql.replaceAll(/DEFAULT \(([^)]*)\)/g, 'DEFAULT $1'); pgSql = pgSql.replaceAll(/DEFAULT \(([^)]*)\)/g, 'DEFAULT $1');
pgSql = pgSql.replaceAll(/integer/g, 'bigint'); pgSql = pgSql.replaceAll(/integer/g, 'bigint');
pgSql = pgSql.replaceAll(/last_insert_rowid\(\)/g, 'LAST_INSERT_ID()'); pgSql = pgSql.replaceAll(/last_insert_rowid\(\)/g, 'LAST_INSERT_ID()');
//text 改成longtext
pgSql = pgSql.replaceAll(/text/g, 'longtext');
//双引号 替换成反引号 //双引号 替换成反引号
pgSql = pgSql.replaceAll(/"/g, '`'); pgSql = pgSql.replaceAll(/"/g, '`');

View File

@@ -1,6 +1,6 @@
{ {
"name": "@certd/ui-server", "name": "@certd/ui-server",
"version": "1.29.3", "version": "1.30.4",
"description": "fast-server base midway", "description": "fast-server base midway",
"private": true, "private": true,
"type": "module", "type": "module",
@@ -34,18 +34,19 @@
"@aws-sdk/client-acm": "^3.699.0", "@aws-sdk/client-acm": "^3.699.0",
"@aws-sdk/client-cloudfront": "^3.699.0", "@aws-sdk/client-cloudfront": "^3.699.0",
"@aws-sdk/client-s3": "^3.705.0", "@aws-sdk/client-s3": "^3.705.0",
"@certd/acme-client": "^1.29.3", "@certd/acme-client": "^1.30.4",
"@certd/basic": "^1.29.3", "@certd/basic": "^1.30.4",
"@certd/commercial-core": "^1.29.3", "@certd/commercial-core": "^1.30.4",
"@certd/lib-huawei": "^1.29.3", "@certd/lib-huawei": "^1.30.4",
"@certd/lib-k8s": "^1.29.3", "@certd/lib-k8s": "^1.30.4",
"@certd/lib-server": "^1.29.3", "@certd/lib-server": "^1.30.4",
"@certd/midway-flyway-js": "^1.29.3", "@certd/midway-flyway-js": "^1.30.4",
"@certd/pipeline": "^1.29.3", "@certd/pipeline": "^1.30.4",
"@certd/plugin-cert": "^1.29.3", "@certd/plugin-cert": "^1.30.4",
"@certd/plugin-lib": "^1.29.3", "@certd/plugin-lib": "^1.30.4",
"@certd/plugin-plus": "^1.29.3", "@certd/plugin-plus": "^1.30.4",
"@certd/plus-core": "^1.29.3", "@certd/plus-core": "^1.30.4",
"@corsinvest/cv4pve-api-javascript": "^8.3.0",
"@huaweicloud/huaweicloud-sdk-cdn": "^3.1.120", "@huaweicloud/huaweicloud-sdk-cdn": "^3.1.120",
"@huaweicloud/huaweicloud-sdk-core": "^3.1.120", "@huaweicloud/huaweicloud-sdk-core": "^3.1.120",
"@koa/cors": "^5.0.0", "@koa/cors": "^5.0.0",

View File

@@ -19,7 +19,6 @@ import * as libServer from '@certd/lib-server';
import * as commercial from '@certd/commercial-core'; import * as commercial from '@certd/commercial-core';
import * as upload from '@midwayjs/upload'; import * as upload from '@midwayjs/upload';
import { setLogger } from '@certd/acme-client'; import { setLogger } from '@certd/acme-client';
process.on('uncaughtException', error => { process.on('uncaughtException', error => {
console.error('未捕获的异常:', error); console.error('未捕获的异常:', error);
// 在这里可以添加日志记录、发送错误通知等操作 // 在这里可以添加日志记录、发送错误通知等操作

View File

@@ -15,12 +15,13 @@ export class AppController extends BaseController {
@Get('/latest', { summary: Constants.per.authOnly }) @Get('/latest', { summary: Constants.per.authOnly })
async latest(): Promise<any> { async latest(): Promise<any> {
const res = await http.request({
url: 'https://registry.npmmirror.com/@certd/pipeline',
method: 'get',
logRes: false,
});
try { try {
const res = await http.request({
url: 'https://registry.npmmirror.com/@certd/pipeline',
method: 'get',
logRes: false,
timeout: 5000,
});
const latest = res['dist-tags'].latest; const latest = res['dist-tags'].latest;
return this.ok(latest); return this.ok(latest);
} catch (e: any) { } catch (e: any) {

View File

@@ -11,6 +11,7 @@ import {
SysSuiteSetting, SysSuiteSetting,
} from '@certd/lib-server'; } from '@certd/lib-server';
import { AppKey, getPlusInfo, isComm } from '@certd/plus-core'; import { AppKey, getPlusInfo, isComm } from '@certd/plus-core';
import { cloneDeep } from 'lodash-es';
/** /**
*/ */
@@ -62,7 +63,10 @@ export class BasicSettingsController extends BaseController {
} }
async plusInfo() { async plusInfo() {
return getPlusInfo(); const res = getPlusInfo();
const copy = cloneDeep(res);
delete copy.secret;
return copy;
} }
@Get('/all', { summary: Constants.per.guest }) @Get('/all', { summary: Constants.per.guest })

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