Compare commits

..

31 Commits

Author SHA1 Message Date
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
64 changed files with 838 additions and 184 deletions

View File

@@ -3,6 +3,37 @@
All notable changes to this project will be documented in this file.
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

View File

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

View File

@@ -1 +1 @@
23:19
16:12

View File

@@ -78,7 +78,8 @@ export default defineConfig({
]
},
{ text: "演示教程", link: "/guide/tutorial.md" },
{ text: "版本升级", link: "/guide/install/upgrade.md" }
{ text: "版本升级", link: "/guide/install/upgrade.md" },
{ text: "切换数据库", link: "/guide/install/database.md" }
]
},
{
@@ -102,12 +103,12 @@ export default defineConfig({
{ text: "js脚本插件使用", link: "/guide/use/custom-script/index.md" },
{ text: "邮箱配置", link: "/guide/use/email/index.md" },
{ text: "IPv6支持", link: "/guide/use/setting/ipv6.md" },
{ text: "如何贡献代码", link: "/guide/development/index.md" },
]
},
{
text: "其他",
items: [
{ text: "贡献代码", link: "/guide/development/index.md" },
{ text: "更新日志", link: "/guide/changelogs/CHANGELOG.md" },
{ text: "镜像说明", link: "/guide/image.md" },
{ text: "联系我们", link: "/guide/contact/" },

View File

@@ -3,6 +3,49 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.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

View File

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

View File

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

View File

@@ -9,5 +9,5 @@
}
},
"npmClient": "pnpm",
"version": "1.30.0"
"version": "1.30.3"
}

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [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

View File

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

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
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)
**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

View File

@@ -1 +1 @@
00:34
01:44

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/basic",
"private": false,
"version": "1.30.0",
"version": "1.30.3",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
@@ -44,5 +44,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "98a81385a66e6289682c7263b81969dd2773c389"
"gitHead": "bcacafeb84cf2798a6733ee58b48ecc9bffdafb9"
}

View File

@@ -3,6 +3,20 @@
All notable changes to this project will be documented in this file.
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)
**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

View File

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

View File

@@ -435,7 +435,7 @@ export class Executor {
content,
userId: this.pipeline.userId,
pipeline: this.pipeline,
result: this.lastRuntime.pipeline.status,
result: this.lastRuntime?.pipeline?.status,
pipelineId: this.pipeline.id,
historyId: this.runtime.id,
errorMessage,

View File

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

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
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)
**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

View File

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

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
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)
**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

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/lib-iframe",
"private": false,
"version": "1.30.0",
"version": "1.30.3",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
@@ -30,5 +30,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "98a81385a66e6289682c7263b81969dd2773c389"
"gitHead": "bcacafeb84cf2798a6733ee58b48ecc9bffdafb9"
}

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
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)
**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

View File

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

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
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)
**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

View File

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

View File

@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
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)
**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

View File

@@ -1,6 +1,6 @@
{
"name": "@certd/midway-flyway-js",
"version": "1.30.0",
"version": "1.30.3",
"description": "midway with flyway, sql upgrade way ",
"private": false,
"type": "module",
@@ -46,5 +46,5 @@
"typeorm": "^0.3.11",
"typescript": "^5.4.2"
},
"gitHead": "98a81385a66e6289682c7263b81969dd2773c389"
"gitHead": "bcacafeb84cf2798a6733ee58b48ecc9bffdafb9"
}

View File

@@ -3,6 +3,20 @@
All notable changes to this project will be documented in this file.
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)
**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

View File

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

View File

@@ -58,7 +58,7 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
},
required: false,
order: 100,
helper: "PFX、jks格式证书是否加密jks必须设置密码不传则默认123456",
helper: "PFX、jks格式证书是否加密\njks必须设置密码不传则默认123456",
})
pfxPassword!: string;
@@ -66,12 +66,17 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
title: "PFX证书转换参数",
value: "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES",
component: {
name: "a-input",
name: "a-auto-complete",
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,
order: 100,
helper: "兼容Server 2016如果导入证书失败请删除此参数",
helper: "兼容Windows Server各个版本",
})
pfxArgs = "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES";

View File

@@ -232,7 +232,7 @@ HTTP文件验证不支持泛域名需要配置网站文件上传`,
// { value: "ec_521", label: "EC 521" },
],
},
helper: "如无特殊需求,默认即可",
helper: "如无特殊需求,默认即可\n选择RSA 2048 pkcs1可以获得旧版RSA证书",
required: true,
})
privateKeyType!: PrivateKeyType;

View File

@@ -8,6 +8,9 @@ export class HttpChallengeUploaderFactory {
} else if (type === "ssh") {
const module = await import("./impls/ssh.js");
return module.SshHttpChallengeUploader;
} else if (type === "sftp") {
const module = await import("./impls/sftp.js");
return module.SftpHttpChallengeUploader;
} else if (type === "ftp") {
const module = await import("./impls/ftp.js");
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,20 @@
All notable changes to this project will be documented in this file.
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)
**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

View File

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

View File

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

View File

@@ -3,6 +3,27 @@
All notable changes to this project will be documented in this file.
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)
**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

View File

@@ -1,6 +1,6 @@
{
"name": "@certd/ui-client",
"version": "1.30.0",
"version": "1.30.3",
"private": true,
"scripts": {
"dev": "vite --open",
@@ -66,8 +66,8 @@
"vuedraggable": "^4.1.0"
},
"devDependencies": {
"@certd/lib-iframe": "^1.30.0",
"@certd/pipeline": "^1.30.0",
"@certd/lib-iframe": "^1.30.3",
"@certd/pipeline": "^1.30.3",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"@types/chai": "^4.3.12",

View File

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

View File

@@ -30,7 +30,7 @@
</template>
<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 { dict } from "@fast-crud/fast-crud";
@@ -62,18 +62,20 @@ watch(
}
);
function onRecordChange() {
async function onRecordChange() {
await nextTick();
emit("update:modelValue", records.value);
emit("change", records.value);
}
const uploaderTypeDict = dict({
data: [
{ label: "SFTP/SSH", value: "ssh" },
{ label: "SFTP", value: "sftp" },
{ label: "FTP", value: "ftp" },
{ label: "阿里云OSS", value: "alioss" },
{ label: "腾讯云COS", value: "tencentcos" },
{ label: "七牛OSS", value: "qiniuoss" }
{ label: "七牛OSS", value: "qiniuoss" },
{ label: "SSH(已废弃请选择SFTP方式)", value: "ssh", disabled: true }
]
});
</script>

View File

@@ -44,8 +44,15 @@ export default {
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(() => {

View File

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

View File

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

View File

@@ -1,12 +1,14 @@
// @ts-ignore
import { useI18n } from "vue-i18n";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { pipelineGroupApi } from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, useFormWrapper, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
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 {
const { t } = useI18n();
const api = pipelineGroupApi;
const api = certInfoApi;
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
};
@@ -26,7 +28,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
const res = await api.AddObj(form);
return res;
};
const { openCrudFormDialog } = useFormWrapper();
const router = useRouter();
return {
crudOptions: {
request: {
@@ -50,7 +53,68 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
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: {
width: 200,
fixed: "right",
@@ -176,7 +240,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
}
},
"pipeline.title": {
title: "关联流水线",
title: "关联流水线",
search: { show: false },
type: "link",
form: {
@@ -185,7 +249,13 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
column: {
width: 350,
sorter: true,
component: {}
component: {
on: {
onClick({ row }) {
router.push({ path: "/certd/pipeline/detail", query: { id: row.pipelineId, editMode: "false" } });
}
}
}
}
}
}

View File

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

View File

@@ -78,7 +78,8 @@
<div
class="task-container"
:class="{
'first-task': taskIndex === 0
'first-task': taskIndex === 0,
'validate-error': hasValidateError(task.id)
}"
>
<div class="line line-left">
@@ -171,7 +172,6 @@
<div class="task">
<a-button shape="round" type="dashed" @click="notificationAdd()">
<fs-icon icon="ion:add-circle-outline"></fs-icon>
添加通知
</a-button>
</div>
@@ -626,7 +626,78 @@ export default defineComponent({
function toggleEditMode(editMode: boolean) {
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 () => {
doValidate();
saveLoading.value = true;
try {
if (props.options.doSave) {
@@ -663,7 +734,8 @@ export default defineComponent({
save,
edit,
cancel,
saveLoading
saveLoading,
hasValidateError
};
}
@@ -875,6 +947,14 @@ export default defineComponent({
justify-content: center;
align-items: center;
position: relative;
&.validate-error {
.task {
.ant-btn {
border-color: red;
}
}
}
.task {
display: flex;
flex-direction: column;

View File

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

View File

@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file.
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))
## [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

View File

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

View File

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

View File

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

View File

@@ -84,4 +84,15 @@ export class CertInfoController extends CrudController<CertInfoService> {
});
return this.ok(list);
}
@Post('/upload', { summary: Constants.per.authOnly })
async upload(@Body(ALL) body: any) {
if (body.id) {
await this.service.checkUserId(body.id, this.getUserId());
}
const res = await this.service.upload(body);
return this.ok(res);
}
}

View File

@@ -16,7 +16,7 @@ export class AutoEPipelineEmitterRegister {
}
async onCertApplySuccess() {
pipelineEmitter.on(EVENT_CERT_APPLY_SUCCESS, async (event: PipelineEvent<CertReader>) => {
await this.certInfoService.updateCert(event.pipeline.id, event.event);
await this.certInfoService.updateCertByPipelineId(event.pipeline.id, event.event);
});
}
}

View File

@@ -1,11 +1,17 @@
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { BaseService, CodeException, Constants, PageReq } from '@certd/lib-server';
import { BaseService, CodeException, CommonException, Constants, PageReq } from '@certd/lib-server';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { CertInfoEntity } from '../entity/cert-info.js';
import { utils } from '@certd/basic';
import { CertInfo, CertReader } from '@certd/plugin-cert';
export type UploadCertReq = {
id?: number;
certReader: CertReader;
fromType?: string;
};
@Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
export class CertInfoService extends BaseService<CertInfoEntity> {
@@ -125,15 +131,27 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
return certReader.toCertInfo();
}
async updateCert(pipelineId: number, certReader: CertReader) {
async updateCertByPipelineId(pipelineId: number, certReader: CertReader, fromType = 'pipeline') {
const found = await this.repository.findOne({
where: {
pipelineId,
},
});
const bean = await this.updateCert({
id: found?.id,
certReader,
fromType,
});
return bean;
}
private async updateCert(req: UploadCertReq) {
const bean = new CertInfoEntity();
if (found) {
bean.id = found.id;
const { id, fromType, certReader } = req;
if (id) {
bean.id = id;
} else {
bean.fromType = fromType;
}
const certInfo = certReader.toCertInfo();
bean.certInfo = JSON.stringify(certInfo);
@@ -146,5 +164,19 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
bean.certProvider = certReader.detail.issuer.commonName;
await this.addOrUpdate(bean);
return bean;
}
async upload(body: { id?: number; cert: CertInfo }) {
const { id, cert } = body;
if (!cert) {
throw new CommonException("cert can't be empty");
}
const res = await this.updateCert({
id,
certReader: new CertReader(cert),
fromType: 'upload',
});
return res.id;
}
}

View File

@@ -3,7 +3,7 @@ import { CertInfo } from '@certd/plugin-cert';
import { AliyunAccess, AliyunClient, AliyunSslClient, createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from '@certd/plugin-lib';
@IsTaskPlugin({
name: 'AliyunDeployCertToLB',
name: 'AliyunDeployCertToALB',
title: '阿里云-部署至ALB应用负载均衡',
icon: 'ant-design:aliyun-outlined',
group: pluginGroups.aliyun.key,
@@ -43,7 +43,7 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
@TaskInput(
createRemoteSelectInputDefine({
title: 'LB所在地区',
title: 'ALB所在地区',
typeName: 'AliyunDeployCertToALB',
multi: false,
action: AliyunDeployCertToALB.prototype.onGetRegionList.name,

View File

@@ -3,7 +3,7 @@ import { CertInfo } from '@certd/plugin-cert';
import { AliyunAccess, AliyunClient, AliyunSslClient, createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from '@certd/plugin-lib';
@IsTaskPlugin({
name: 'AliyunDeployCertToLB',
name: 'AliyunDeployCertToNLB',
title: '阿里云-部署至NLB网络负载均衡',
icon: 'ant-design:aliyun-outlined',
group: pluginGroups.aliyun.key,
@@ -43,7 +43,7 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
@TaskInput(
createRemoteSelectInputDefine({
title: 'LB所在地区',
title: 'NLB所在地区',
typeName: 'AliyunDeployCertToNLB',
multi: false,
action: AliyunDeployCertToNLB.prototype.onGetRegionList.name,

View File

@@ -106,6 +106,7 @@ export class CloudflareDnsProvider extends AbstractDnsProvider<CloudflareRecord>
this.logger.info(`dns解析记录:${JSON.stringify(record)}`);
}
//本接口需要返回本次创建的dns解析记录这个记录会在删除的时候用到
record.zone_id = zoneId;
return record;
}

View File

@@ -5,10 +5,10 @@ import { SshAccess, SshClient } from '@certd/plugin-lib';
@IsTaskPlugin({
name: 'uploadCertToHost',
title: '主机-部署证书到主机',
title: '主机-部署证书到SSH主机',
icon: 'line-md:uploading-loop',
group: pluginGroups.host.key,
desc: '上传证书到主机,然后执行部署脚本命令',
desc: 'SFTP上传证书到主机,然后SSH执行部署脚本命令',
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,

View File

@@ -58,13 +58,16 @@ export class TelegramNotification extends BaseNotification {
})
skipSslVerify: boolean;
replaceText(text: string) {
return text.replaceAll('.', '\\.').replaceAll('*', '\\*');
}
async send(body: NotificationBody) {
if (!this.botToken || !this.chatId) {
throw new Error('Bot Token 和聊天ID不能为空');
}
// 构建消息内容
const messageContent = `*${body.title}*\n\n${body.content}\n\n[查看详情](${body.url})`;
const messageContent = `${this.replaceText(body.title)}\n\n${this.replaceText(body.content)}\n\n[查看详情](${body.url})`;
// Telegram API URL
const url = `https://api.telegram.org/bot${this.botToken}/sendMessage`;

View File

@@ -135,32 +135,33 @@ export class DeployCertToTencentCLB extends AbstractTaskPlugin {
const domains = Array.isArray(this.domain) ? this.domain : [this.domain];
for (const domain of domains) {
this.logger.info(`开始更新域名证书:${domain},请确保已经开启了sni`);
const lastCertId = await this.getCertIdFromProps(client, domain);
// const lastCertId = await this.getCertIdFromProps(client, domain);
await this.updateByDomainAttr(client, domain);
const checkDeployed = async (wait = 5) => {
await this.ctx.utils.sleep(wait * 1000);
this.logger.info(`等待${wait}`);
const newCertId = await this.getCertIdFromProps(client, domain);
this.logger.info(`oldCertId:${lastCertId} , newCertId:${newCertId}`);
if ((lastCertId && newCertId === lastCertId) || (!lastCertId && !newCertId)) {
return false;
}
this.logger.info('腾讯云证书ID:', newCertId);
return true;
};
let count = 0;
while (true) {
count++;
const res = await checkDeployed(5);
if (res) {
break;
}
if (count > 6) {
throw new Error('部署可能失败请确认是否已开启sni');
}
}
// 不要做检查相同的证书不会生成新的证书id
// const checkDeployed = async (wait = 5) => {
// await this.ctx.utils.sleep(wait * 1000);
// this.logger.info(`等待${wait}秒`);
// const newCertId = await this.getCertIdFromProps(client, domain);
// this.logger.info(`oldCertId:${lastCertId} , newCertId:${newCertId}`);
// if ((lastCertId && newCertId === lastCertId) || (!lastCertId && !newCertId)) {
// return false;
// }
// this.logger.info('腾讯云证书ID:', newCertId);
// return true;
// };
// let count = 0;
// while (true) {
// count++;
// const res = await checkDeployed(5);
// if (res) {
// break;
// }
// if (count > 6) {
// this.logger.warn('等待超时,可能证书未部署成功');
// }
// }
}
}
@@ -205,7 +206,24 @@ export class DeployCertToTencentCLB extends AbstractTaskPlugin {
params.Domain = domain;
const ret = await client.ModifyDomainAttributes(params);
this.checkRet(ret);
this.logger.info('设置腾讯云CLB证书(sni)成功:', ret.RequestId, '->loadBalancerId:', this.loadBalancerId, 'listenerId', this.listenerId, 'domain:', domain);
this.logger.info(
`[${domain}] 设置腾讯云CLB证书(sni)任务已提交:taskId${ret.RequestId}loadBalancerId:${this.loadBalancerId}listenerId:${this.listenerId}`
);
const requestId = ret.RequestId;
while (true) {
const statusRes = await client.DescribeTaskStatus({ TaskId: requestId });
if (statusRes.Status === 0) {
this.logger.info(`[${domain}] 腾讯云CLB证书(sni)设置成功`);
break;
} else if (statusRes.Status === 2) {
this.logger.info(`[${domain}] 腾讯云CLB证书(sni)设置进行中,请耐心等待`);
} else if (statusRes.Status === 1) {
throw new Error(`[${domain}] 腾讯云CLB证书(sni)设置失败:` + statusRes.Message);
}
await this.ctx.utils.sleep(5000);
}
return ret;
}
appendTimeSuffix(name: string) {