diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ba2f74e..a6cde127 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,29 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11) + +### Bug Fixes + +* 某些插件找不到的bug ([4b3f4a8](https://github.com/certd/certd/commit/4b3f4a868a8b0800c5c59de9d0f47bddc079e7b3)) + +## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10) + +### Bug Fixes + +* 修复查看证书对话框翻译错误的bug ([8626b6d](https://github.com/certd/certd/commit/8626b6d9f235c511766f2ae98e0a37f6cebb621c)) +* 修复translation后分组编辑打不开的bug ([46a1b74](https://github.com/certd/certd/commit/46a1b7479923d2feb2dece202a5932b99981b2cd)) +* 执行windows nginx命令时,改为return code判断是否执行成功 ([b37cffd](https://github.com/certd/certd/commit/b37cffd704cd08b8bdd68a6e284706eabe59e78d)) + +### Performance Improvements + +* 优化证书进度条颜色 ([2af91db](https://github.com/certd/certd/commit/2af91dbf2ae36a4ed17c6788bc2a2a79a3bb29f8)) +* 站点证书即将过期通知标题颜色优化为红色 ([80c5331](https://github.com/certd/certd/commit/80c5331a5d4c320323d9b9b800e4ea3b72577b33)) +* 支持部署到阿里云vod ([98da4e1](https://github.com/certd/certd/commit/98da4e1791ed8bb21daf2a9914fda875d14633c9)) +* 支持部署证书到网宿CDN ([c3da026](https://github.com/certd/certd/commit/c3da026b33106f5195959825a68cadbe49efef00)) +* 重置管理员密码同时可以清除管理员的2FA设置 ([1ece091](https://github.com/certd/certd/commit/1ece0915f172d5f8b8adb866434e7efcc5c8c46d)) +* output-selector from参数支持更丰富的过滤规则 ([87853a2](https://github.com/certd/certd/commit/87853a201535f3bfe8505c40f8f5229d82ffcc73)) + ## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07) ### Bug Fixes diff --git a/build.trigger b/build.trigger index e70c1942..e217ac05 100644 --- a/build.trigger +++ b/build.trigger @@ -1 +1 @@ -22:21 +10:51 diff --git a/docs/guide/changelogs/CHANGELOG.md b/docs/guide/changelogs/CHANGELOG.md index 2ba2f74e..a6cde127 100644 --- a/docs/guide/changelogs/CHANGELOG.md +++ b/docs/guide/changelogs/CHANGELOG.md @@ -3,6 +3,29 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11) + +### Bug Fixes + +* 某些插件找不到的bug ([4b3f4a8](https://github.com/certd/certd/commit/4b3f4a868a8b0800c5c59de9d0f47bddc079e7b3)) + +## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10) + +### Bug Fixes + +* 修复查看证书对话框翻译错误的bug ([8626b6d](https://github.com/certd/certd/commit/8626b6d9f235c511766f2ae98e0a37f6cebb621c)) +* 修复translation后分组编辑打不开的bug ([46a1b74](https://github.com/certd/certd/commit/46a1b7479923d2feb2dece202a5932b99981b2cd)) +* 执行windows nginx命令时,改为return code判断是否执行成功 ([b37cffd](https://github.com/certd/certd/commit/b37cffd704cd08b8bdd68a6e284706eabe59e78d)) + +### Performance Improvements + +* 优化证书进度条颜色 ([2af91db](https://github.com/certd/certd/commit/2af91dbf2ae36a4ed17c6788bc2a2a79a3bb29f8)) +* 站点证书即将过期通知标题颜色优化为红色 ([80c5331](https://github.com/certd/certd/commit/80c5331a5d4c320323d9b9b800e4ea3b72577b33)) +* 支持部署到阿里云vod ([98da4e1](https://github.com/certd/certd/commit/98da4e1791ed8bb21daf2a9914fda875d14633c9)) +* 支持部署证书到网宿CDN ([c3da026](https://github.com/certd/certd/commit/c3da026b33106f5195959825a68cadbe49efef00)) +* 重置管理员密码同时可以清除管理员的2FA设置 ([1ece091](https://github.com/certd/certd/commit/1ece0915f172d5f8b8adb866434e7efcc5c8c46d)) +* output-selector from参数支持更丰富的过滤规则 ([87853a2](https://github.com/certd/certd/commit/87853a201535f3bfe8505c40f8f5229d82ffcc73)) + ## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07) ### Bug Fixes diff --git a/docs/guide/install/images/github-release-2.png b/docs/guide/install/images/github-release-2.png new file mode 100644 index 00000000..4e9bb779 Binary files /dev/null and b/docs/guide/install/images/github-release-2.png differ diff --git a/docs/guide/install/images/github-release.png b/docs/guide/install/images/github-release.png new file mode 100644 index 00000000..fc06603e Binary files /dev/null and b/docs/guide/install/images/github-release.png differ diff --git a/docs/guide/install/upgrade.md b/docs/guide/install/upgrade.md index 11c6dc42..0f562ec5 100644 --- a/docs/guide/install/upgrade.md +++ b/docs/guide/install/upgrade.md @@ -13,4 +13,54 @@ ::: ## 升级日志 +可以查看最新版本号,以及所有版本的更新日志 [CHANGELOG](../changelogs/CHANGELOG.md) + + +## 自动升级配置 + +### 1. 方法一:使用watchtower监控 + +修改docker-compose.yaml文件增加如下配置, 使用watchtower监控自动升级 +```yaml +services: + certd: + ... + labels: + com.centurylinklabs.watchtower.enable: "true" + +# ↓↓↓↓ --------------------------------------------------------- 自动升级,上面certd的版本号要保持为latest + certd-updater: # 添加 Watchtower 服务 + image: containrrr/watchtower:latest + container_name: certd-updater + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock + # 配置 自动更新 + environment: + - WATCHTOWER_CLEANUP=true # 自动清理旧版本容器 + - WATCHTOWER_INCLUDE_STOPPED=false # 不更新已停止的容器 + - WATCHTOWER_LABEL_ENABLE=true # 根据容器标签进行更新 + - WATCHTOWER_POLL_INTERVAL=600 # 每 10 分钟检查一次更新 + +``` + + +### 2. 方法二:使用Certd版本监控功能 + +选择Github-检查Release版本插件 +![](./images/github-release.png) +按如下图填写配置 +![](./images/github-release-2.png) + + +检测到新版本后执行宿主机升级命令: + +```shell +# 拉取最新镜像 +docker pull registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest +# 升级容器命令, 替换成你自己的certd更新命令 +export RESTART_CERT='sleep 10; cd ~/deploy/certd/ ; docker compose down; docker compose up -d' +# 构造一个脚本10s后在后台执行,避免容器销毁时执行太快,导致流水线任务无法结束 +nohup sh -c '$RESTART_CERT' >/dev/null 2>&1 & echo '10秒后重启' && exit +``` \ No newline at end of file diff --git a/lerna.json b/lerna.json index a97a23c8..64ac2e14 100644 --- a/lerna.json +++ b/lerna.json @@ -9,5 +9,5 @@ } }, "npmClient": "pnpm", - "version": "1.36.3" + "version": "1.36.5" } diff --git a/packages/core/acme-client/CHANGELOG.md b/packages/core/acme-client/CHANGELOG.md index 1c4725eb..45f54c2f 100644 --- a/packages/core/acme-client/CHANGELOG.md +++ b/packages/core/acme-client/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.36.5](https://github.com/publishlab/node-acme-client/compare/v1.36.4...v1.36.5) (2025-07-11) + +**Note:** Version bump only for package @certd/acme-client + +## [1.36.4](https://github.com/publishlab/node-acme-client/compare/v1.36.3...v1.36.4) (2025-07-10) + +**Note:** Version bump only for package @certd/acme-client + ## [1.36.3](https://github.com/publishlab/node-acme-client/compare/v1.36.2...v1.36.3) (2025-07-07) **Note:** Version bump only for package @certd/acme-client diff --git a/packages/core/acme-client/package.json b/packages/core/acme-client/package.json index ecf424b3..833bd1cb 100644 --- a/packages/core/acme-client/package.json +++ b/packages/core/acme-client/package.json @@ -3,7 +3,7 @@ "description": "Simple and unopinionated ACME client", "private": false, "author": "nmorsman", - "version": "1.36.3", + "version": "1.36.5", "type": "module", "module": "scr/index.js", "main": "src/index.js", @@ -18,7 +18,7 @@ "types" ], "dependencies": { - "@certd/basic": "^1.36.3", + "@certd/basic": "^1.36.5", "@peculiar/x509": "^1.11.0", "asn1js": "^3.0.5", "axios": "^1.7.2", @@ -69,5 +69,5 @@ "bugs": { "url": "https://github.com/publishlab/node-acme-client/issues" }, - "gitHead": "1bde777beead9dd23b8d3d98479d616170b8bb69" + "gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd" } diff --git a/packages/core/basic/CHANGELOG.md b/packages/core/basic/CHANGELOG.md index 8d834d98..12314e27 100644 --- a/packages/core/basic/CHANGELOG.md +++ b/packages/core/basic/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11) + +**Note:** Version bump only for package @certd/basic + +## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10) + +**Note:** Version bump only for package @certd/basic + ## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07) **Note:** Version bump only for package @certd/basic diff --git a/packages/core/basic/build.md b/packages/core/basic/build.md index ac4aa04c..ec71cc3d 100644 --- a/packages/core/basic/build.md +++ b/packages/core/basic/build.md @@ -1 +1 @@ -22:18 +10:46 diff --git a/packages/core/basic/package.json b/packages/core/basic/package.json index 7c6fed96..9b96d2af 100644 --- a/packages/core/basic/package.json +++ b/packages/core/basic/package.json @@ -1,7 +1,7 @@ { "name": "@certd/basic", "private": false, - "version": "1.36.3", + "version": "1.36.5", "type": "module", "main": "./dist/index.js", "module": "./dist/index.js", @@ -45,5 +45,5 @@ "tslib": "^2.8.1", "typescript": "^5.4.2" }, - "gitHead": "1bde777beead9dd23b8d3d98479d616170b8bb69" + "gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd" } diff --git a/packages/core/pipeline/CHANGELOG.md b/packages/core/pipeline/CHANGELOG.md index 9aa06328..4771e8a6 100644 --- a/packages/core/pipeline/CHANGELOG.md +++ b/packages/core/pipeline/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11) + +**Note:** Version bump only for package @certd/pipeline + +## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10) + +**Note:** Version bump only for package @certd/pipeline + ## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07) **Note:** Version bump only for package @certd/pipeline diff --git a/packages/core/pipeline/package.json b/packages/core/pipeline/package.json index a1742fd8..c545d254 100644 --- a/packages/core/pipeline/package.json +++ b/packages/core/pipeline/package.json @@ -1,7 +1,7 @@ { "name": "@certd/pipeline", "private": false, - "version": "1.36.3", + "version": "1.36.5", "type": "module", "main": "./dist/index.js", "module": "./dist/index.js", @@ -17,8 +17,8 @@ "pub": "npm publish" }, "dependencies": { - "@certd/basic": "^1.36.3", - "@certd/plus-core": "^1.36.3", + "@certd/basic": "^1.36.5", + "@certd/plus-core": "^1.36.5", "dayjs": "^1.11.7", "lodash-es": "^4.17.21", "reflect-metadata": "^0.1.13" @@ -44,5 +44,5 @@ "tslib": "^2.8.1", "typescript": "^5.4.2" }, - "gitHead": "1bde777beead9dd23b8d3d98479d616170b8bb69" + "gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd" } diff --git a/packages/libs/lib-huawei/CHANGELOG.md b/packages/libs/lib-huawei/CHANGELOG.md index 5a5f3be8..6a375336 100644 --- a/packages/libs/lib-huawei/CHANGELOG.md +++ b/packages/libs/lib-huawei/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11) + +**Note:** Version bump only for package @certd/lib-huawei + +## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10) + +**Note:** Version bump only for package @certd/lib-huawei + ## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07) **Note:** Version bump only for package @certd/lib-huawei diff --git a/packages/libs/lib-huawei/package.json b/packages/libs/lib-huawei/package.json index 5321ef44..9893897d 100644 --- a/packages/libs/lib-huawei/package.json +++ b/packages/libs/lib-huawei/package.json @@ -1,7 +1,7 @@ { "name": "@certd/lib-huawei", "private": false, - "version": "1.36.3", + "version": "1.36.5", "main": "./dist/bundle.js", "module": "./dist/bundle.js", "types": "./dist/d/index.d.ts", @@ -24,5 +24,5 @@ "prettier": "^2.8.8", "tslib": "^2.8.1" }, - "gitHead": "1bde777beead9dd23b8d3d98479d616170b8bb69" + "gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd" } diff --git a/packages/libs/lib-iframe/CHANGELOG.md b/packages/libs/lib-iframe/CHANGELOG.md index 575e873b..7fbe9c75 100644 --- a/packages/libs/lib-iframe/CHANGELOG.md +++ b/packages/libs/lib-iframe/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11) + +**Note:** Version bump only for package @certd/lib-iframe + +## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10) + +**Note:** Version bump only for package @certd/lib-iframe + ## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07) **Note:** Version bump only for package @certd/lib-iframe diff --git a/packages/libs/lib-iframe/package.json b/packages/libs/lib-iframe/package.json index b843139f..26184f3d 100644 --- a/packages/libs/lib-iframe/package.json +++ b/packages/libs/lib-iframe/package.json @@ -1,7 +1,7 @@ { "name": "@certd/lib-iframe", "private": false, - "version": "1.36.3", + "version": "1.36.5", "type": "module", "main": "./dist/index.js", "module": "./dist/index.js", @@ -31,5 +31,5 @@ "tslib": "^2.8.1", "typescript": "^5.4.2" }, - "gitHead": "1bde777beead9dd23b8d3d98479d616170b8bb69" + "gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd" } diff --git a/packages/libs/lib-jdcloud/CHANGELOG.md b/packages/libs/lib-jdcloud/CHANGELOG.md index a3cef1f5..a8fede16 100644 --- a/packages/libs/lib-jdcloud/CHANGELOG.md +++ b/packages/libs/lib-jdcloud/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11) + +**Note:** Version bump only for package @certd/jdcloud + +## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10) + +**Note:** Version bump only for package @certd/jdcloud + ## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07) **Note:** Version bump only for package @certd/jdcloud diff --git a/packages/libs/lib-jdcloud/package.json b/packages/libs/lib-jdcloud/package.json index fa0a198e..4a779605 100644 --- a/packages/libs/lib-jdcloud/package.json +++ b/packages/libs/lib-jdcloud/package.json @@ -1,6 +1,6 @@ { "name": "@certd/jdcloud", - "version": "1.36.3", + "version": "1.36.5", "description": "jdcloud openApi sdk", "main": "./dist/bundle.js", "module": "./dist/bundle.js", @@ -61,5 +61,5 @@ "fetch" ] }, - "gitHead": "1bde777beead9dd23b8d3d98479d616170b8bb69" + "gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd" } diff --git a/packages/libs/lib-k8s/CHANGELOG.md b/packages/libs/lib-k8s/CHANGELOG.md index 27fb3d70..d1bfa449 100644 --- a/packages/libs/lib-k8s/CHANGELOG.md +++ b/packages/libs/lib-k8s/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11) + +**Note:** Version bump only for package @certd/lib-k8s + +## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10) + +**Note:** Version bump only for package @certd/lib-k8s + ## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07) **Note:** Version bump only for package @certd/lib-k8s diff --git a/packages/libs/lib-k8s/package.json b/packages/libs/lib-k8s/package.json index 16093394..77b2dd86 100644 --- a/packages/libs/lib-k8s/package.json +++ b/packages/libs/lib-k8s/package.json @@ -1,7 +1,7 @@ { "name": "@certd/lib-k8s", "private": false, - "version": "1.36.3", + "version": "1.36.5", "type": "module", "main": "./dist/index.js", "module": "./dist/index.js", @@ -17,7 +17,7 @@ "pub": "npm publish" }, "dependencies": { - "@certd/basic": "^1.36.3", + "@certd/basic": "^1.36.5", "@kubernetes/client-node": "0.21.0" }, "devDependencies": { @@ -32,5 +32,5 @@ "tslib": "^2.8.1", "typescript": "^5.4.2" }, - "gitHead": "1bde777beead9dd23b8d3d98479d616170b8bb69" + "gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd" } diff --git a/packages/libs/lib-server/CHANGELOG.md b/packages/libs/lib-server/CHANGELOG.md index 87bf42ee..f8e2f7c3 100644 --- a/packages/libs/lib-server/CHANGELOG.md +++ b/packages/libs/lib-server/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11) + +**Note:** Version bump only for package @certd/lib-server + +## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10) + +**Note:** Version bump only for package @certd/lib-server + ## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07) **Note:** Version bump only for package @certd/lib-server diff --git a/packages/libs/lib-server/package.json b/packages/libs/lib-server/package.json index e6973853..d0e4e8f1 100644 --- a/packages/libs/lib-server/package.json +++ b/packages/libs/lib-server/package.json @@ -1,6 +1,6 @@ { "name": "@certd/lib-server", - "version": "1.36.3", + "version": "1.36.5", "description": "midway with flyway, sql upgrade way ", "private": false, "type": "module", @@ -27,10 +27,10 @@ ], "license": "AGPL", "dependencies": { - "@certd/acme-client": "^1.36.3", - "@certd/basic": "^1.36.3", - "@certd/pipeline": "^1.36.3", - "@certd/plus-core": "^1.36.3", + "@certd/acme-client": "^1.36.5", + "@certd/basic": "^1.36.5", + "@certd/pipeline": "^1.36.5", + "@certd/plus-core": "^1.36.5", "@midwayjs/cache": "~3.14.0", "@midwayjs/core": "~3.20.3", "@midwayjs/i18n": "~3.20.3", @@ -61,5 +61,5 @@ "typeorm": "^0.3.11", "typescript": "^5.4.2" }, - "gitHead": "1bde777beead9dd23b8d3d98479d616170b8bb69" + "gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd" } diff --git a/packages/libs/midway-flyway-js/CHANGELOG.md b/packages/libs/midway-flyway-js/CHANGELOG.md index f36f0c6a..dfb102ef 100644 --- a/packages/libs/midway-flyway-js/CHANGELOG.md +++ b/packages/libs/midway-flyway-js/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11) + +**Note:** Version bump only for package @certd/midway-flyway-js + +## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10) + +**Note:** Version bump only for package @certd/midway-flyway-js + ## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07) **Note:** Version bump only for package @certd/midway-flyway-js diff --git a/packages/libs/midway-flyway-js/package.json b/packages/libs/midway-flyway-js/package.json index 06d92409..6790ed2f 100644 --- a/packages/libs/midway-flyway-js/package.json +++ b/packages/libs/midway-flyway-js/package.json @@ -1,6 +1,6 @@ { "name": "@certd/midway-flyway-js", - "version": "1.36.3", + "version": "1.36.5", "description": "midway with flyway, sql upgrade way ", "private": false, "type": "module", @@ -46,5 +46,5 @@ "typeorm": "^0.3.11", "typescript": "^5.4.2" }, - "gitHead": "1bde777beead9dd23b8d3d98479d616170b8bb69" + "gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd" } diff --git a/packages/plugins/plugin-cert/CHANGELOG.md b/packages/plugins/plugin-cert/CHANGELOG.md index bca605c6..771675ea 100644 --- a/packages/plugins/plugin-cert/CHANGELOG.md +++ b/packages/plugins/plugin-cert/CHANGELOG.md @@ -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.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11) + +**Note:** Version bump only for package @certd/plugin-cert + +## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10) + +### Performance Improvements + +* 优化证书进度条颜色 ([2af91db](https://github.com/certd/certd/commit/2af91dbf2ae36a4ed17c6788bc2a2a79a3bb29f8)) +* 支持部署到阿里云vod ([98da4e1](https://github.com/certd/certd/commit/98da4e1791ed8bb21daf2a9914fda875d14633c9)) +* output-selector from参数支持更丰富的过滤规则 ([87853a2](https://github.com/certd/certd/commit/87853a201535f3bfe8505c40f8f5229d82ffcc73)) + ## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07) **Note:** Version bump only for package @certd/plugin-cert diff --git a/packages/plugins/plugin-cert/package.json b/packages/plugins/plugin-cert/package.json index 120ff8a6..e59fdcaa 100644 --- a/packages/plugins/plugin-cert/package.json +++ b/packages/plugins/plugin-cert/package.json @@ -1,7 +1,7 @@ { "name": "@certd/plugin-cert", "private": false, - "version": "1.36.3", + "version": "1.36.5", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -16,10 +16,10 @@ "pub": "npm publish" }, "dependencies": { - "@certd/acme-client": "^1.36.3", - "@certd/basic": "^1.36.3", - "@certd/pipeline": "^1.36.3", - "@certd/plugin-lib": "^1.36.3", + "@certd/acme-client": "^1.36.5", + "@certd/basic": "^1.36.5", + "@certd/pipeline": "^1.36.5", + "@certd/plugin-lib": "^1.36.5", "@google-cloud/publicca": "^1.3.0", "dayjs": "^1.11.7", "jszip": "^3.10.1", @@ -43,5 +43,5 @@ "tslib": "^2.8.1", "typescript": "^5.4.2" }, - "gitHead": "1bde777beead9dd23b8d3d98479d616170b8bb69" + "gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd" } diff --git a/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts b/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts index 9eee841a..adcfe468 100644 --- a/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts +++ b/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts @@ -204,4 +204,11 @@ export class CertReader { domain = domain.replaceAll(".", "_").replaceAll("*", "_"); return `${domain}_${dayjs().format("YYYYMMDDHHmmssSSS")}`; } + + static appendTimeSuffix(name?: string) { + if (name == null) { + name = "certd"; + } + return name + "_" + dayjs().format("YYYYMMDDHHmmssSSS"); + } } diff --git a/packages/plugins/plugin-lib/CHANGELOG.md b/packages/plugins/plugin-lib/CHANGELOG.md index 5d549331..26f0f9c0 100644 --- a/packages/plugins/plugin-lib/CHANGELOG.md +++ b/packages/plugins/plugin-lib/CHANGELOG.md @@ -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.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11) + +**Note:** Version bump only for package @certd/plugin-lib + +## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10) + +### Bug Fixes + +* 执行windows nginx命令时,改为return code判断是否执行成功 ([b37cffd](https://github.com/certd/certd/commit/b37cffd704cd08b8bdd68a6e284706eabe59e78d)) + +### Performance Improvements + +* 支持部署到阿里云vod ([98da4e1](https://github.com/certd/certd/commit/98da4e1791ed8bb21daf2a9914fda875d14633c9)) + ## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07) **Note:** Version bump only for package @certd/plugin-lib diff --git a/packages/plugins/plugin-lib/package.json b/packages/plugins/plugin-lib/package.json index 84bd2a52..1d1ffac0 100644 --- a/packages/plugins/plugin-lib/package.json +++ b/packages/plugins/plugin-lib/package.json @@ -1,7 +1,7 @@ { "name": "@certd/plugin-lib", "private": false, - "version": "1.36.3", + "version": "1.36.5", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -21,8 +21,8 @@ "@alicloud/pop-core": "^1.7.10", "@alicloud/tea-util": "^1.4.10", "@aws-sdk/client-s3": "^3.787.0", - "@certd/basic": "^1.36.3", - "@certd/pipeline": "^1.36.3", + "@certd/basic": "^1.36.5", + "@certd/pipeline": "^1.36.5", "@kubernetes/client-node": "0.21.0", "ali-oss": "^6.22.0", "basic-ftp": "^5.0.5", @@ -53,5 +53,5 @@ "tslib": "^2.8.1", "typescript": "^5.4.2" }, - "gitHead": "1bde777beead9dd23b8d3d98479d616170b8bb69" + "gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd" } diff --git a/packages/plugins/plugin-lib/src/aliyun/access/aliyun-access.ts b/packages/plugins/plugin-lib/src/aliyun/access/aliyun-access.ts index 364e9f32..f7c493b9 100644 --- a/packages/plugins/plugin-lib/src/aliyun/access/aliyun-access.ts +++ b/packages/plugins/plugin-lib/src/aliyun/access/aliyun-access.ts @@ -1,6 +1,5 @@ -import { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline"; +import { AccessInput, BaseAccess, IsAccess } from "@certd/pipeline"; import { ILogger } from "@certd/basic"; - export type AliyunClientV2Req = { action: string; version: string; diff --git a/packages/plugins/plugin-lib/src/aliyun/lib/ssl-client.ts b/packages/plugins/plugin-lib/src/aliyun/lib/ssl-client.ts index 2cf090a0..112b858c 100644 --- a/packages/plugins/plugin-lib/src/aliyun/lib/ssl-client.ts +++ b/packages/plugins/plugin-lib/src/aliyun/lib/ssl-client.ts @@ -33,8 +33,10 @@ export type CasCertInfo = { certId: number; certName: string; certIdentifier: st export class AliyunSslClient { opts: AliyunSslClientOpts; + logger: ILogger; constructor(opts: AliyunSslClientOpts) { this.opts = opts; + this.logger = opts.logger; } checkRet(ret: any) { diff --git a/packages/plugins/plugin-lib/src/ssh/ssh.ts b/packages/plugins/plugin-lib/src/ssh/ssh.ts index ccd12caf..b7d203a6 100644 --- a/packages/plugins/plugin-lib/src/ssh/ssh.ts +++ b/packages/plugins/plugin-lib/src/ssh/ssh.ts @@ -491,7 +491,7 @@ export class SshClient { * Set-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\cmd.exe" * @param options */ - async exec(options: { connectConf: SshAccess; script: string | Array; env?: any; throwOnStdErr?: boolean }): Promise { + async exec(options: { connectConf: SshAccess; script: string | Array; env?: any; throwOnStdErr?: boolean; stopOnError?: boolean }): Promise { let { script } = options; const { connectConf, throwOnStdErr } = options; @@ -506,6 +506,10 @@ export class SshClient { isWinCmd = await this.isCmd(conn); } + if (isLinux && options.stopOnError !== false) { + script = "set -e\n" + script; + } + if (options.env) { for (const key in options.env) { if (isLinux) { @@ -538,6 +542,7 @@ export class SshClient { script = envScripts.join(newLine) + newLine + script; } } + return await conn.exec(script as string, { throwOnStdErr }); }, }); diff --git a/packages/ui/certd-client/CHANGELOG.md b/packages/ui/certd-client/CHANGELOG.md index 8f5dabd8..5ab819fa 100644 --- a/packages/ui/certd-client/CHANGELOG.md +++ b/packages/ui/certd-client/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11) + +**Note:** Version bump only for package @certd/ui-client + +## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10) + +### Bug Fixes + +* 修复查看证书对话框翻译错误的bug ([8626b6d](https://github.com/certd/certd/commit/8626b6d9f235c511766f2ae98e0a37f6cebb621c)) +* 修复translation后分组编辑打不开的bug ([46a1b74](https://github.com/certd/certd/commit/46a1b7479923d2feb2dece202a5932b99981b2cd)) + +### Performance Improvements + +* 优化证书进度条颜色 ([2af91db](https://github.com/certd/certd/commit/2af91dbf2ae36a4ed17c6788bc2a2a79a3bb29f8)) +* output-selector from参数支持更丰富的过滤规则 ([87853a2](https://github.com/certd/certd/commit/87853a201535f3bfe8505c40f8f5229d82ffcc73)) + ## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07) ### Bug Fixes diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index b27e8a0f..67502ccb 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -1,6 +1,6 @@ { "name": "@certd/ui-client", - "version": "1.36.3", + "version": "1.36.5", "private": true, "scripts": { "dev": "vite --open", @@ -103,8 +103,8 @@ "zod-defaults": "^0.1.3" }, "devDependencies": { - "@certd/lib-iframe": "^1.36.3", - "@certd/pipeline": "^1.36.3", + "@certd/lib-iframe": "^1.36.5", + "@certd/pipeline": "^1.36.5", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", "@types/chai": "^4.3.12", diff --git a/packages/ui/certd-client/src/locales/langs/en-US/certd.ts b/packages/ui/certd-client/src/locales/langs/en-US/certd.ts index 7f9d1f5f..0d917c33 100644 --- a/packages/ui/certd-client/src/locales/langs/en-US/certd.ts +++ b/packages/ui/certd-client/src/locales/langs/en-US/certd.ts @@ -471,7 +471,7 @@ export default { statusError: "Error", actionImportBatch: "Batch Import", actionSyncIp: "Sync IP", - modalTitleSyncIp: "Sync IP", + TitleSyncIp: "Sync IP", modalContentSyncIp: "Are you sure to sync IP?", notificationSyncComplete: "Sync Complete", actionCheckAll: "Check All", @@ -708,6 +708,10 @@ export default { showRunStrategyHelper: "Allow modify the run strategy of the task", }, }, + modal: { + close: "Close", + viewCertificateTitle: "View Certificate", + }, domain: { domainManager: "Domain Manager", domain: "Domain", diff --git a/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts b/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts index edbdd17c..b5d8f37d 100644 --- a/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts +++ b/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts @@ -711,6 +711,10 @@ export default { showRunStrategyHelper: "任务设置中是否允许选择运行策略", }, }, + modal: { + close: "关闭", + viewCertificateTitle: "查看证书", + }, domain: { domainManager: "域名管理", domain: "域名", diff --git a/packages/ui/certd-server/CHANGELOG.md b/packages/ui/certd-server/CHANGELOG.md index 51a91a0c..e375227b 100644 --- a/packages/ui/certd-server/CHANGELOG.md +++ b/packages/ui/certd-server/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11) + +### Bug Fixes + +* 某些插件找不到的bug ([4b3f4a8](https://github.com/certd/certd/commit/4b3f4a868a8b0800c5c59de9d0f47bddc079e7b3)) + +## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10) + +### Performance Improvements + +* 站点证书即将过期通知标题颜色优化为红色 ([80c5331](https://github.com/certd/certd/commit/80c5331a5d4c320323d9b9b800e4ea3b72577b33)) +* 支持部署到阿里云vod ([98da4e1](https://github.com/certd/certd/commit/98da4e1791ed8bb21daf2a9914fda875d14633c9)) +* 支持部署证书到网宿CDN ([c3da026](https://github.com/certd/certd/commit/c3da026b33106f5195959825a68cadbe49efef00)) +* 重置管理员密码同时可以清除管理员的2FA设置 ([1ece091](https://github.com/certd/certd/commit/1ece0915f172d5f8b8adb866434e7efcc5c8c46d)) +* output-selector from参数支持更丰富的过滤规则 ([87853a2](https://github.com/certd/certd/commit/87853a201535f3bfe8505c40f8f5229d82ffcc73)) + ## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07) ### Performance Improvements diff --git a/packages/ui/certd-server/package.json b/packages/ui/certd-server/package.json index 68898e4d..73d4ae50 100644 --- a/packages/ui/certd-server/package.json +++ b/packages/ui/certd-server/package.json @@ -1,6 +1,6 @@ { "name": "@certd/ui-server", - "version": "1.36.3", + "version": "1.36.5", "description": "fast-server base midway", "private": true, "type": "module", @@ -42,20 +42,20 @@ "@aws-sdk/client-cloudfront": "^3.699.0", "@aws-sdk/client-iam": "^3.699.0", "@aws-sdk/client-s3": "^3.705.0", - "@certd/acme-client": "^1.36.3", - "@certd/basic": "^1.36.3", - "@certd/commercial-core": "^1.36.3", + "@certd/acme-client": "^1.36.5", + "@certd/basic": "^1.36.5", + "@certd/commercial-core": "^1.36.5", "@certd/cv4pve-api-javascript": "^8.4.1", - "@certd/jdcloud": "^1.36.3", - "@certd/lib-huawei": "^1.36.3", - "@certd/lib-k8s": "^1.36.3", - "@certd/lib-server": "^1.36.3", - "@certd/midway-flyway-js": "^1.36.3", - "@certd/pipeline": "^1.36.3", - "@certd/plugin-cert": "^1.36.3", - "@certd/plugin-lib": "^1.36.3", - "@certd/plugin-plus": "^1.36.3", - "@certd/plus-core": "^1.36.3", + "@certd/jdcloud": "^1.36.5", + "@certd/lib-huawei": "^1.36.5", + "@certd/lib-k8s": "^1.36.5", + "@certd/lib-server": "^1.36.5", + "@certd/midway-flyway-js": "^1.36.5", + "@certd/pipeline": "^1.36.5", + "@certd/plugin-cert": "^1.36.5", + "@certd/plugin-lib": "^1.36.5", + "@certd/plugin-plus": "^1.36.5", + "@certd/plus-core": "^1.36.5", "@huaweicloud/huaweicloud-sdk-cdn": "^3.1.120", "@huaweicloud/huaweicloud-sdk-core": "^3.1.120", "@koa/cors": "^5.0.0", diff --git a/packages/ui/certd-server/src/configuration.ts b/packages/ui/certd-server/src/configuration.ts index 00d4ddff..a730e592 100644 --- a/packages/ui/certd-server/src/configuration.ts +++ b/packages/ui/certd-server/src/configuration.ts @@ -26,11 +26,11 @@ process.on('uncaughtException', error => { }); @Configuration({ - // detectorOptions: { - // ignore: [ - // '**/plugins/**' - // ] - // }, + detectorOptions: { + ignore: [ + '**/plugins/**' + ] + }, imports: [ koa, orm, diff --git a/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts b/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts index 62126bcf..c56df2bd 100644 --- a/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts +++ b/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts @@ -291,7 +291,8 @@ export class SiteInfoService extends BaseService { body: { title: `站点证书即将过期,剩余${validDays}天,<${site.name}>`, content, - url + url, + errorMessage: "站点证书即将过期" } }, site.userId diff --git a/packages/ui/certd-server/src/plugins/index.ts b/packages/ui/certd-server/src/plugins/index.ts index 485b2216..20d6311b 100644 --- a/packages/ui/certd-server/src/plugins/index.ts +++ b/packages/ui/certd-server/src/plugins/index.ts @@ -25,3 +25,8 @@ export * from './plugin-flex/index.js' export * from './plugin-farcdn/index.js' export * from './plugin-fnos/index.js' export * from './plugin-rainyun/index.js' +export * from './plugin-cloudflare/index.js' +export * from './plugin-github/index.js' +export * from './plugin-namesilo/index.js' +export * from './plugin-proxmox/index.js' +export * from './plugin-wangsu/index.js' diff --git a/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/deploy-to-vod/index.ts b/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/deploy-to-vod/index.ts new file mode 100644 index 00000000..5eee547b --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/deploy-to-vod/index.ts @@ -0,0 +1,185 @@ +import { AbstractTaskPlugin, IsTaskPlugin, PageSearch, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline"; +import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert"; +import { AliyunAccess, createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib"; + +@IsTaskPlugin({ + name: "AliyunDeployCertToVod", + title: "阿里云-部署至VOD", + icon: "svg:icon-aliyun", + group: pluginGroups.aliyun.key, + desc: "部署证书到阿里云视频点播(vod)", + needPlus: false, + default: { + strategy: { + runStrategy: RunStrategy.SkipWhenSucceed + } + } +}) +export class AliyunDeployCertToVod extends AbstractTaskPlugin { + @TaskInput({ + title: "域名证书", + helper: "请选择证书申请任务输出的域名证书", + component: { + name: "output-selector", + from: [...CertApplyPluginNames] + }, + required: true + }) + cert!: CertInfo; + + @TaskInput(createCertDomainGetterInputDefine({ props: { required: false } })) + certDomains!: string[]; + + // @TaskInput({ + // title: "大区", + // value: "cn-hangzhou", + // component: { + // name: "a-auto-complete", + // vModel: "value", + // options: [ + // { value: "cn-hangzhou", label: "华东1(杭州)" }, + // { value: "ap-southeast-1", label: "新加坡" } + // ] + // }, + // required: true + // }) + // regionId!: string; + + @TaskInput({ + title: "证书接入点", + helper: "不会选就保持默认即可", + value: "cas.aliyuncs.com", + component: { + name: "a-select", + options: [ + { value: "cas.aliyuncs.com", label: "中国大陆" }, + { value: "cas.ap-southeast-1.aliyuncs.com", label: "新加坡" }, + { value: "cas.eu-central-1.aliyuncs.com", label: "德国(法兰克福)" } + ] + }, + required: true + }) + casEndpoint!: string; + + + @TaskInput({ + title: "Access授权", + helper: "阿里云授权AccessKeyId、AccessKeySecret", + component: { + name: "access-selector", + type: "aliyun" + }, + required: true + }) + accessId!: string; + + @TaskInput( + createRemoteSelectInputDefine({ + title: "加速域名", + helper: "请选择要部署证书的域名", + action: AliyunDeployCertToVod.prototype.onGetDomainList.name, + watches: ["accessId"], + pager: true, + search: true + }) + ) + domainList!: string[]; + + + async onInstance() { + } + + + async execute(): Promise { + this.logger.info("开始部署证书到阿里云VOD"); + const access = await this.getAccess(this.accessId); + + const client = await this.getClient(access); + + + for (const siteId of this.domainList) { + /** + * let queries : {[key: string ]: any} = { }; + * queries["DomainName"] = "324234234"; + * queries["CertName"] = "ccccccc"; + * queries["SSLProtocol"] = "on"; + * queries["SSLPub"] = "cert"; + * queries["SSLPri"] = "key"; + * // runtime options + * let runtime = new $Util.RuntimeOptions({ }); + * let request = new $OpenApi.OpenApiRequest({ + * query: OpenApiUtil.query(queries), + * }); + */ + const res = await client.doRequest({ + action: "SetVodDomainCertificate", + version: "2017-03-21", + protocol: "HTTPS", + data: { + query: { + DomainName: siteId, + CertName: this.appendTimeSuffix("certd"), + SSLProtocol: "on", + SSLPub: this.cert.crt, + SSLPri: this.cert.key + } + } + }); + this.logger.info(`部署站点[${siteId}]证书成功:${JSON.stringify(res)}`); + } + } + + async getClient(access: AliyunAccess) { + const endpoint = `vod.cn-shanghai.aliyuncs.com`; + return access.getClient(endpoint); + } + + async onGetDomainList(data: PageSearch) { + if (!this.accessId) { + throw new Error("请选择Access授权"); + } + const access = await this.getAccess(this.accessId); + + /** + * let queries : {[key: string ]: any} = { }; + * queries["PageSize"] = 50; + * queries["PageNumber"] = 1; + * queries["DomainName"] = "5555"; + * // runtime options + * let runtime = new $Util.RuntimeOptions({ }); + * let request = new $OpenApi.OpenApiRequest({ + * query: OpenApiUtil.query(queries), + * }); + */ + const client = await this.getClient(access); + const res = await client.doRequest({ + action: "DescribeVodUserDomains", + version: "2017-03-21", + protocol: "HTTPS", + data: { + query: { + DomainName: data.searchKey, + PageNumber: data.pageNo, + PageSize: data.pageSize + } + } + }); + + const list = res?.Domains.PageData; + if (!list || list.length === 0) { + throw new Error("没有找到加速域名,请先在阿里云添加点播加速域名"); + } + + const options = list.map((item: any) => { + return { + label: item.DomainName, + value: item.DomainName, + domain: item.DomainName + }; + }); + return this.ctx.utils.options.buildGroupOptions(options, this.certDomains); + } + +} + +new AliyunDeployCertToVod(); diff --git a/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/index.ts b/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/index.ts index ebb1db9e..d011be82 100644 --- a/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/index.ts @@ -7,3 +7,5 @@ export * from './deploy-to-alb/index.js'; export * from './deploy-to-nlb/index.js'; export * from './deploy-to-slb/index.js'; export * from './deploy-to-fc/index.js'; +export * from './deploy-to-esa/index.js'; +export * from './deploy-to-vod/index.js'; diff --git a/packages/ui/certd-server/src/plugins/plugin-aliyun/utils/index.ts b/packages/ui/certd-server/src/plugins/plugin-aliyun/utils/index.ts index 6ad771bd..b9832d14 100644 --- a/packages/ui/certd-server/src/plugins/plugin-aliyun/utils/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-aliyun/utils/index.ts @@ -1,4 +1,6 @@ -import dayjs from 'dayjs'; +import dayjs from "dayjs"; +import { AliyunSslClient } from "@certd/plugin-lib"; +import { CertInfo, CertReader } from "@certd/plugin-cert"; export const ZoneOptions = [{ value: 'cn-hangzhou' }]; export function appendTimeSuffix(name: string) { @@ -13,3 +15,27 @@ export function checkRet(ret: any) { throw new Error('执行失败:' + ret.Message); } } + + +export async function getAliyunCertId(opts:{ + cert: string | CertInfo, + sslClient: AliyunSslClient, +}) { + const { cert, sslClient } = opts; + let certId: any = cert; + let certName: any = CertReader.appendTimeSuffix("certd"); + if (typeof cert === "object") { + const certReader = new CertReader(cert) + certName = certReader.buildCertName() + + certId = await sslClient.uploadCert({ + name: certName, + cert: cert, + }); + sslClient.logger.info("上传证书成功", certId, certName); + } + return { + certId, + certName, + }; +} diff --git a/packages/ui/certd-server/src/plugins/plugin-aws/plugins/index.ts b/packages/ui/certd-server/src/plugins/plugin-aws/plugins/index.ts index b2dfca5d..b715dc42 100644 --- a/packages/ui/certd-server/src/plugins/plugin-aws/plugins/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-aws/plugins/index.ts @@ -1 +1,2 @@ export * from './plugin-deploy-to-cloudfront.js'; +export * from './plugin-upload-to-acm.js' diff --git a/packages/ui/certd-server/src/plugins/plugin-github/plugins/plugin-check-release.ts b/packages/ui/certd-server/src/plugins/plugin-github/plugins/plugin-check-release.ts index 2a596e84..2b34cbb1 100644 --- a/packages/ui/certd-server/src/plugins/plugin-github/plugins/plugin-check-release.ts +++ b/packages/ui/certd-server/src/plugins/plugin-github/plugins/plugin-check-release.ts @@ -47,7 +47,7 @@ export class GithubCheckRelease extends AbstractTaskPlugin { mode:"tags" } }, - required:true, + required:false, }) notificationIds!: number[]; @@ -74,9 +74,21 @@ export class GithubCheckRelease extends AbstractTaskPlugin { name: 'a-textarea', vModel: 'value', rows: 6, - placeholder: `#拉取最新版镜像\ndocker pull greper/certd:latest \n#重建容器 \nnohup sh -c 'sleep 10; cd ~/deploy/certd/ ; docker compose down; docker compose up -d' >/dev/null & `, + placeholder: ` +# 拉取最新镜像 +docker pull registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest +# 升级容器命令, 替换成你自己的实际部署位置及更新命令 +export RESTART_CERT='sleep 10; cd ~/deploy/certd/ ; docker compose down; docker compose up -d' +# 构造一个脚本10s后在后台执行,避免容器销毁时执行太快,导致流水线任务无法结束 +nohup sh -c '$RESTART_CERT' >/dev/null 2>&1 & echo '10秒后重启' && exit`, }, - helper: '有新版本后执行命令,比如:拉取最新版镜像,然后重建容器\n注意:自己升级自己需要使用nobup配合sleep', + helper: `有新版本后执行命令,比如:拉取最新版镜像,然后重建容器 +注意:自己升级自己需要使用nohup配合sleep +自动升级命令示例: +docker pull registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest +export RESTART_CERT='sleep 10; cd ~/deploy/certd/ ; docker compose down; docker compose up -d' +nohup sh -c '$RESTART_CERT' >/dev/null 2>&1 & echo '10秒后重启' && exit +`, required: false, }) script!: string; @@ -108,24 +120,24 @@ export class GithubCheckRelease extends AbstractTaskPlugin { //仅每行开头的* 替换成 -, *号前面可以有空格 const body = res.body.replace(/^(\s*)\* /gm, "$1- ") - if (this.notificationIds == null){ - this.notificationIds = [0] - } - //发送通知 - for (const notificationId of this.notificationIds) { - await this.ctx.notificationService.send({ - id: notificationId, - useDefault: false, - useEmail:false, - logger: this.logger, - body: { - title: `${this.repoName} 新版本 ${this.lastVersion} 发布`, - content: `${body}\n\n > [Certd](https://certd.docmirror.cn),不止证书自动化,插件解锁无限可能!\n\n`, - url: `https://github.com/${this.repoName}/releases/tag/${this.lastVersion}`, - } - }) + if (this.notificationIds && this.notificationIds.length > 0){ + //发送通知 + for (const notificationId of this.notificationIds) { + await this.ctx.notificationService.send({ + id: notificationId, + useDefault: false, + useEmail:false, + logger: this.logger, + body: { + title: `${this.repoName} 新版本 ${this.lastVersion} 发布`, + content: `${body}\n\n > [Certd](https://certd.docmirror.cn),不止证书自动化,插件解锁无限可能!\n\n`, + url: `https://github.com/${this.repoName}/releases/tag/${this.lastVersion}`, + } + }) + } } + if (this.script != null && this.script.trim() != "") { const connectConf = await this.getAccess(this.sshAccessId); const sshClient = new SshClient(this.logger); diff --git a/packages/ui/certd-server/src/plugins/plugin-host/plugin/index.ts b/packages/ui/certd-server/src/plugins/plugin-host/plugin/index.ts index 16349501..6bb828b9 100644 --- a/packages/ui/certd-server/src/plugins/plugin-host/plugin/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-host/plugin/index.ts @@ -1,2 +1,3 @@ export * from './host-shell-execute/index.js'; export * from './upload-to-host/index.js'; +export * from './copy-to-local/index.js' diff --git a/packages/ui/certd-server/src/plugins/plugin-huawei/index.ts b/packages/ui/certd-server/src/plugins/plugin-huawei/index.ts index c9aa8714..f6e792f0 100644 --- a/packages/ui/certd-server/src/plugins/plugin-huawei/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-huawei/index.ts @@ -1,3 +1,3 @@ export * from './access/index.js'; export * from './dns-provider/index.js'; -export * from './plugins/deploy-to-cdn/index.js'; +export * from './plugins/index.js'; diff --git a/packages/ui/certd-server/src/plugins/plugin-huawei/plugins/index.ts b/packages/ui/certd-server/src/plugins/plugin-huawei/plugins/index.ts new file mode 100644 index 00000000..3043939b --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-huawei/plugins/index.ts @@ -0,0 +1,2 @@ +export * from './deploy-to-cdn/index.js' +export * from './upload-to-ccm/index.js' diff --git a/packages/ui/certd-server/src/plugins/plugin-notification/feishu/index.ts b/packages/ui/certd-server/src/plugins/plugin-notification/feishu/index.ts index bc79c468..0fed0b1c 100644 --- a/packages/ui/certd-server/src/plugins/plugin-notification/feishu/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-notification/feishu/index.ts @@ -7,7 +7,7 @@ import { BaseNotification, IsNotification, NotificationBody, NotificationInput } needPlus: true, }) // https://open.dingtalk.com/document/orgapp/the-creation-and-installation-of-the-application-robot-in-the?spm=ding_open_doc.document.0.0.242d1563cDgZz3 -export class DingTalkNotification extends BaseNotification { +export class FeishuNotification extends BaseNotification { @NotificationInput({ title: 'webhook地址', component: { diff --git a/packages/ui/certd-server/src/plugins/plugin-notification/index.ts b/packages/ui/certd-server/src/plugins/plugin-notification/index.ts index db431331..aab72469 100644 --- a/packages/ui/certd-server/src/plugins/plugin-notification/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-notification/index.ts @@ -10,3 +10,5 @@ export * from './discord/index.js'; export * from './slack/index.js'; export * from './bark/index.js'; export * from './feishu/index.js'; +export * from './dingtalk/index.js'; +export * from './vocechat/index.js'; diff --git a/packages/ui/certd-server/src/plugins/plugin-other/access/index.ts b/packages/ui/certd-server/src/plugins/plugin-other/access/index.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/ui/certd-server/src/plugins/plugin-qiniu/plugin/index.ts b/packages/ui/certd-server/src/plugins/plugin-qiniu/plugin/index.ts index 71437bc9..b1ada785 100644 --- a/packages/ui/certd-server/src/plugins/plugin-qiniu/plugin/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-qiniu/plugin/index.ts @@ -1 +1,2 @@ export * from './deploy-to-cdn/index.js'; +export * from './upload-cert/index.js'; diff --git a/packages/ui/certd-server/src/plugins/plugin-rainyun/index.ts b/packages/ui/certd-server/src/plugins/plugin-rainyun/index.ts index 02dc3945..fc34cee7 100644 --- a/packages/ui/certd-server/src/plugins/plugin-rainyun/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-rainyun/index.ts @@ -1,2 +1,3 @@ export * from "./plugins/index.js"; export * from "./access.js"; +export * from "./dns-provider.js"; diff --git a/packages/ui/certd-server/src/plugins/plugin-rainyun/plugins/index.ts b/packages/ui/certd-server/src/plugins/plugin-rainyun/plugins/index.ts index e69de29b..3ce4f30c 100644 --- a/packages/ui/certd-server/src/plugins/plugin-rainyun/plugins/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-rainyun/plugins/index.ts @@ -0,0 +1 @@ +export * from './plugin-refresh-cert.js' diff --git a/packages/ui/certd-server/src/plugins/plugin-tencent/plugin/index.ts b/packages/ui/certd-server/src/plugins/plugin-tencent/plugin/index.ts index 88ed5ee2..60db3827 100644 --- a/packages/ui/certd-server/src/plugins/plugin-tencent/plugin/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-tencent/plugin/index.ts @@ -7,3 +7,5 @@ export * from './deploy-to-cos/index.js'; export * from './deploy-to-eo/index.js'; export * from './delete-expiring-cert/index.js'; export * from './deploy-to-tke-ingress/index.js'; +export * from './deploy-to-live/index.js'; +export * from './start-instances/index.js'; diff --git a/packages/ui/certd-server/src/plugins/plugin-volcengine/cdn-client.ts b/packages/ui/certd-server/src/plugins/plugin-volcengine/cdn-client.ts index 90fcbe78..93c80c38 100644 --- a/packages/ui/certd-server/src/plugins/plugin-volcengine/cdn-client.ts +++ b/packages/ui/certd-server/src/plugins/plugin-volcengine/cdn-client.ts @@ -1,4 +1,4 @@ -import { VolcengineOpts } from "./dns-client.js"; +import { VolcengineOpts } from "./ve-client.js"; import { CertInfo } from "@certd/plugin-cert"; export class VolcengineCdnClient { diff --git a/packages/ui/certd-server/src/plugins/plugin-volcengine/dns-client.ts b/packages/ui/certd-server/src/plugins/plugin-volcengine/dns-client.ts index d4dbb215..2228e599 100644 --- a/packages/ui/certd-server/src/plugins/plugin-volcengine/dns-client.ts +++ b/packages/ui/certd-server/src/plugins/plugin-volcengine/dns-client.ts @@ -1,12 +1,7 @@ -import { VolcengineAccess } from "./access.js"; -import { http, HttpClient, ILogger } from "@certd/basic"; +import {http} from "@certd/basic"; import querystring from "querystring"; +import {VolcengineOpts} from "./ve-client.js"; -export type VolcengineOpts = { - access: VolcengineAccess - logger: ILogger - http: HttpClient -} export type VolcengineReq = { method?: string; diff --git a/packages/ui/certd-server/src/plugins/plugin-volcengine/index.ts b/packages/ui/certd-server/src/plugins/plugin-volcengine/index.ts index a0225ab8..04bb4047 100644 --- a/packages/ui/certd-server/src/plugins/plugin-volcengine/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-volcengine/index.ts @@ -1,3 +1,6 @@ export * from './plugins/index.js'; export * from './access.js'; export * from './volcengine-dns-provider.js'; +export * from './ve-client.js'; +export * from './dns-client.js'; +export * from './cdn-client.js'; diff --git a/packages/ui/certd-server/src/plugins/plugin-volcengine/plugins/index.ts b/packages/ui/certd-server/src/plugins/plugin-volcengine/plugins/index.ts index 1f6adb71..21483913 100644 --- a/packages/ui/certd-server/src/plugins/plugin-volcengine/plugins/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-volcengine/plugins/index.ts @@ -3,3 +3,5 @@ export * from './plugin-deploy-to-clb.js' export * from './plugin-upload-to-cert-center.js' export * from './plugin-deploy-to-alb.js' export * from './plugin-deploy-to-live.js' +export * from './plugin-deploy-to-dcdn.js' +export * from './plugin-deploy-to-vod.js' diff --git a/packages/ui/certd-server/src/plugins/plugin-wangsu/access.ts b/packages/ui/certd-server/src/plugins/plugin-wangsu/access.ts new file mode 100644 index 00000000..a55f0075 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-wangsu/access.ts @@ -0,0 +1,161 @@ +import { AccessInput, BaseAccess, IsAccess } from "@certd/pipeline"; +import { HttpRequestConfig } from "@certd/basic"; +import { CertInfo } from "@certd/plugin-cert"; + + + +/** + */ +@IsAccess({ + name: "wangsu", + title: "网宿授权", + desc: "", + icon: "svg:icon-lucky" +}) +export class WangsuAccess extends BaseAccess { + + @AccessInput({ + title: "accessKeyId", + component: { + placeholder: "accessKeyId", + component: { + name: "a-input", + vModel: "value" + } + }, + helper: "[点击前往获取AccessKey](https://console.wangsu.com/account/accessKey?rsr=ws)", + encrypt: false, + required: true + }) + accessKeyId!: string; + + @AccessInput({ + title: "accessKeySecret", + component: { + placeholder: "accessKeySecret", + component: { + name: "a-input", + vModel: "value" + } + }, + encrypt: true, + required: true + }) + accessKeySecret!: string; + + + @AccessInput({ + title: "测试", + component: { + name: "api-test", + action: "TestRequest" + }, + helper: "点击测试接口是否正常" + }) + testRequest = true; + + async onTestRequest() { + await this.getCertList({ }); + return "ok"; + } + + async getCertList(req: { }) { + /** + * certificate-id + * name + * dns-names + */ + const res = await this.doRequest({ + url: "/api/ssl/certificate", + method: "GET", + }); + + return res["ssl-certificate"] + } + + async getCertInfo(req:{certId:string}){ + return await this.doRequest({ + url: `/api/certificate/${req.certId}`, + method:"GET", + }); + } + + async updateCert(req: { + certId: string, + cert: CertInfo, + }) { + + const certInfo= await this.getCertInfo({certId:req.certId}); + + const name = certInfo.name; + const {cert,certId} = req; + return await this.doRequest({ + url: `/api/certificate/${certId}`, + method:"PUT", + data: { + /** + * name: string; + * certificate?: string; + * privateKey?: string; + * autoRenew?: string; + * isNeedAlarm?: string; + * csrId?: number; + * comment?: string; + */ + name:name, + certificate: cert.crt, + privateKey: cert.key, + autoRenew:"false", + isNeedAlarm:"false", + comment: "certd" + } + }); + } + + + + + async doRequest(req: HttpRequestConfig) { + + const data: any = req.data; + + const {AkSkConfig,AkSkAuth} = await import("./lib/index.js"); + + const akskConfig = new AkSkConfig(); + akskConfig.accessKey = this.accessKeyId; + akskConfig.secretKey = this.accessKeySecret; + akskConfig.endPoint = "open.chinanetcenter.com"; + akskConfig.uri = req.url; + akskConfig.method = req.method; + + const requestMsg = AkSkAuth.transferHttpRequestMsg(akskConfig,data?JSON.stringify(data):""); + AkSkAuth.getAuthAndSetHeaders(requestMsg, akskConfig.accessKey, akskConfig.secretKey); + + let response = undefined + try{ + response = await this.ctx.http.request({ + method: requestMsg.method, + url: requestMsg.url, + headers: requestMsg.headers, + data: requestMsg.body + }); + }catch (e) { + if (e.response?.data?.result) { + throw new Error(e.response?.data?.result); + } + throw e; + } + + if (response.code != null && response.code != 0){ + throw new Error(response.message); + } + if (response.data != null && response.code!==null){ + return response.data; + } + return response; + + } +} + + +new WangsuAccess(); diff --git a/packages/ui/certd-server/src/plugins/plugin-wangsu/index.ts b/packages/ui/certd-server/src/plugins/plugin-wangsu/index.ts new file mode 100644 index 00000000..02dc3945 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-wangsu/index.ts @@ -0,0 +1,2 @@ +export * from "./plugins/index.js"; +export * from "./access.js"; diff --git a/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/auth/AkSkAuth.ts b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/auth/AkSkAuth.ts new file mode 100644 index 00000000..c3cd2ca8 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/auth/AkSkAuth.ts @@ -0,0 +1,87 @@ +import { HttpRequestMsg } from "../model/HttpRequestMsg.js"; +import { AkSkConfig } from "../model/AkSkConfig.js"; +import { CryptoUtils } from "../util/CryptoUtils.js"; +import { HttpUtils } from "../util/HttpUtils.js"; +import { Constant } from "../common/Constant.js"; + +export class AkSkAuth { + + public static invoke(akSkConfig: AkSkConfig, jsonBody: string): Promise { + const requestMsg = AkSkAuth.transferHttpRequestMsg(akSkConfig, jsonBody); + AkSkAuth.getAuthAndSetHeaders(requestMsg, akSkConfig.accessKey, akSkConfig.secretKey); + return HttpUtils.call(requestMsg); + } + + static transferHttpRequestMsg(akSkConfig: AkSkConfig, jsonBody: string): HttpRequestMsg { + const requestMsg = new HttpRequestMsg(); + requestMsg.uri = akSkConfig.uri; + if (akSkConfig.endPoint && akSkConfig.endPoint !== Constant.END_POINT) { + requestMsg.host = akSkConfig.endPoint; + requestMsg.url = `${Constant.HTTPS_REQUEST_PREFIX}${akSkConfig.endPoint}${requestMsg.uri}`; + } else { + requestMsg.host = Constant.HTTP_DOMAIN; + requestMsg.url = `${Constant.HTTP_REQUEST_PREFIX}${requestMsg.uri}`; + } + requestMsg.method = akSkConfig.method; + requestMsg.signedHeaders = AkSkAuth.getSignedHeaders(akSkConfig.signedHeaders); + if (['POST', 'PUT', 'PATCH', 'DELETE'].indexOf(akSkConfig.method) !== -1) { + requestMsg.body = jsonBody; + } + return requestMsg; + } + + static getAuthAndSetHeaders(requestMsg: HttpRequestMsg, accessKey: string, secretKey: string): void { + const timeStamp = (Date.now() / 1000 | 0).toString(); + requestMsg.headers['Host'] = requestMsg.host; + requestMsg.headers[Constant.HEAD_SIGN_ACCESS_KEY] = accessKey; + requestMsg.headers[Constant.HEAD_SIGN_TIMESTAMP] = timeStamp; + requestMsg.headers["Accept"] = Constant.APPLICATION_JSON; + const signature = AkSkAuth.getSignature(requestMsg, secretKey, timeStamp); + requestMsg.headers['Authorization'] = AkSkAuth.genAuthorization(accessKey, AkSkAuth.getSignedHeaders(requestMsg.signedHeaders), signature); + } + + private static genAuthorization(accessKey: string, signedHeaders: string, signature: string): string { + return `${Constant.HEAD_SIGN_ALGORITHM} Credential=${accessKey}, SignedHeaders=${signedHeaders}, Signature=${signature}`; + } + + private static getSignature(requestMsg: HttpRequestMsg, secretKey: string, timestamp: string): string { + let bodyStr = requestMsg.body || ""; + const hashedRequestPayload = CryptoUtils.sha256Hex(bodyStr); + const canonicalRequest = `${requestMsg.method}\n${requestMsg.uri.split("?")[0]}\n${decodeURIComponent(requestMsg.getQueryString())}\n${AkSkAuth.getCanonicalHeaders(requestMsg.headers, AkSkAuth.getSignedHeaders(requestMsg.signedHeaders))}\n${AkSkAuth.getSignedHeaders(requestMsg.signedHeaders)}\n${hashedRequestPayload}`; + const stringToSign = `${Constant.HEAD_SIGN_ALGORITHM}\n${timestamp}\n${CryptoUtils.sha256Hex(canonicalRequest)}`; + return CryptoUtils.hmac256(secretKey, stringToSign).toLowerCase(); + } + + private static getCanonicalHeaders(headers: Record, signedHeaders: string): string { + const headerNames = signedHeaders.split(";"); + let canonicalHeaders = ""; + for (const headerName of headerNames) { + const headerValue = AkSkAuth.getValueByHeader(headerName, headers); + if (headerValue !== null) { + canonicalHeaders += `${headerName}:${headerValue.toLowerCase()}\n`; + } else { + // Handle missing headers if necessary, e.g., log a warning or skip + console.warn(`Header ${headerName} not found in provided headers.`); + } + } + return canonicalHeaders; + } + + + private static getSignedHeaders(signedHeaders: string): string { + if (!signedHeaders) { + return "content-type;host"; + } + const headers = signedHeaders.split(";"); + return headers.map(header => header.toLowerCase()).sort().join(";"); + } + + private static getValueByHeader(name: string, customHeaderMap: { [key: string]: string }): string | null { + for (const key in customHeaderMap) { + if (key.toLowerCase() === name.toLowerCase()) { + return customHeaderMap[key]; + } + } + return null; + } +} diff --git a/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/common/Constant.ts b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/common/Constant.ts new file mode 100644 index 00000000..6d860509 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/common/Constant.ts @@ -0,0 +1,19 @@ +export class Constant { + private constructor() {} + + public static readonly HTTP_REQUEST_PREFIX: string = "https://open.chinanetcenter.com"; + public static readonly HTTPS_REQUEST_PREFIX: string = "https://"; + public static readonly HTTP_DOMAIN: string = "open.chinanetcenter.com"; + + public static readonly APPLICATION_JSON: string = "application/json"; + + public static readonly HEAD_SIGN_ACCESS_KEY: string = "x-cnc-accessKey"; + public static readonly HEAD_SIGN_TIMESTAMP: string = "x-cnc-timestamp"; + public static readonly HEAD_SIGN_ALGORITHM: string = "CNC-HMAC-SHA256"; + + public static readonly X_CNC_AUTH_METHOD: string = "x-cnc-auth-method"; + + public static readonly AUTH_METHOD: string = "AKSK"; + + public static readonly END_POINT: string = "{endPoint}"; +} diff --git a/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/exception/ApiAuthException.ts b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/exception/ApiAuthException.ts new file mode 100644 index 00000000..5117760d --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/exception/ApiAuthException.ts @@ -0,0 +1,9 @@ +export class ApiAuthException extends Error { + public cause?: any; + + constructor(message: string, cause?: any) { + super(message); + this.cause = cause; + this.name = 'ApiAuthException'; + } +} diff --git a/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/index.ts b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/index.ts new file mode 100644 index 00000000..ebdf314e --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/index.ts @@ -0,0 +1,4 @@ +import { AkSkConfig } from "./model/AkSkConfig.js"; +import { AkSkAuth } from "./auth/AkSkAuth.js"; + +export { AkSkAuth, AkSkConfig} diff --git a/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/model/AkSkConfig.ts b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/model/AkSkConfig.ts new file mode 100644 index 00000000..ab41c4af --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/model/AkSkConfig.ts @@ -0,0 +1,56 @@ +export class AkSkConfig { + private _accessKey: string | undefined; + private _secretKey: string | undefined; + private _uri: string | undefined; + private _endPoint: string | undefined; + private _method: string | undefined; + private _signedHeaders: string | undefined; + + public get accessKey(): string { + return this._accessKey; + } + + public set accessKey(value: string) { + this._accessKey = value; + } + + public get secretKey(): string { + return this._secretKey; + } + + public set secretKey(value: string) { + this._secretKey = value; + } + + public get uri(): string { + return this._uri; + } + + public set uri(value: string) { + this._uri = value; + } + + public get endPoint(): string { + return this._endPoint; + } + + public set endPoint(value: string) { + this._endPoint = value; + } + + public get method(): string { + return this._method; + } + + public set method(value: string) { + this._method = value; + } + + public get signedHeaders(): string { + return this._signedHeaders; + } + + public set signedHeaders(value: string) { + this._signedHeaders = value; + } +} diff --git a/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/model/HttpRequestMsg.ts b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/model/HttpRequestMsg.ts new file mode 100644 index 00000000..89c761ef --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/model/HttpRequestMsg.ts @@ -0,0 +1,75 @@ +import { Constant } from '../common/Constant.js'; // Assuming you have a TypeScript version of this + +export class HttpRequestMsg { + uri: string ; + url: string; + host: string; + method: string; + protocol: string; + params: Record; + headers: Record; + body: string; + signedHeaders: string; + msg: any; + + constructor() { + this.params = {}; + this.headers = {}; + this.putHeader('Content-Type', Constant.APPLICATION_JSON); + this.putHeader(Constant.X_CNC_AUTH_METHOD, Constant.AUTH_METHOD); + } + + putParam(name: string, value: string): void { + this.params[name] = value; + } + + getParam(name: string): string | null { + const value = this.params[name]; + return value && value.trim() !== '' ? value : null; + } + + getQueryString(): string { + if(this.uri == undefined) + return ""; + const index = this.uri.indexOf("?"); + if (this.method === 'POST' || index === -1) { + return ""; + } + return this.uri.substring(index + 1); + } + + putHeader(name: string, value: string): void { + this.headers[name] = value; + } + + getHeader(name: string): string | null { + for (const key in this.headers) { + if (key.toLowerCase() === name.toLowerCase()) { + return this.headers[key]; + } + } + return null; + } + + getHeaderByNames(...names: string[]): string | null { + for (const name of names) { + const value = this.getHeader(name); + if (value) { + return value; + } + } + return null; + } + + removeHeader(name: string): void { + for (const key in this.headers) { + if (key.toLowerCase() === name.toLowerCase()) { + delete this.headers[key]; + } + } + } + + setJsonBody(object: any): void { + this.body = JSON.stringify(object); + } +} diff --git a/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/util/CryptoUtils.ts b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/util/CryptoUtils.ts new file mode 100644 index 00000000..11a310e7 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/util/CryptoUtils.ts @@ -0,0 +1,23 @@ +import CryptoJS from 'crypto-js'; + +export class CryptoUtils { + private constructor() {} + + /** + * hmac+sha256+hex + */ + public static sha256Hex(s: string): string { + const hash = CryptoJS.SHA256(s); + return hash.toString(CryptoJS.enc.Hex).toLowerCase(); + } + + /** + * hmac+sha256 + */ + public static hmac256(secretKey: string, message: string): string { + const keyWordArray = CryptoJS.enc.Utf8.parse(secretKey); + const messageWordArray = CryptoJS.enc.Utf8.parse(message); + const hash = CryptoJS.HmacSHA256(messageWordArray, keyWordArray); + return hash.toString(CryptoJS.enc.Hex).toLowerCase(); + } +} diff --git a/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/util/HttpUtils.ts b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/util/HttpUtils.ts new file mode 100644 index 00000000..81c33249 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-wangsu/lib/util/HttpUtils.ts @@ -0,0 +1,30 @@ +import { HttpRequestMsg } from '../model/HttpRequestMsg.js'; // Assuming you have a TypeScript version of this +import { ApiAuthException } from '../exception/ApiAuthException.js'; // Assuming you have a TypeScript version of this +import axios, { AxiosError } from 'axios'; + +export class HttpUtils { + private constructor() { } + public static async call(requestMsg: HttpRequestMsg): Promise { + var response; + try { + response = await axios({ + method: requestMsg.method, + url: requestMsg.url, + headers: requestMsg.headers, + data: requestMsg.body + }); + console.info("API invoke success. Response:", response.data); + return response.data; + } catch (error) { + if (error instanceof AxiosError) { + // Handle AxiosError specifically + console.error('API invoke failed. Response:', error.response.data); + return error.response.data; + } else { + // Handle other types of errors + console.error('API invoke failed.', error); + } + throw new ApiAuthException('API invoke failed.'); + } + } +} diff --git a/packages/ui/certd-server/src/plugins/plugin-wangsu/plugins/index.ts b/packages/ui/certd-server/src/plugins/plugin-wangsu/plugins/index.ts new file mode 100644 index 00000000..b8237e4f --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-wangsu/plugins/index.ts @@ -0,0 +1 @@ +export * from "./plugin-refresh-cert.js"; diff --git a/packages/ui/certd-server/src/plugins/plugin-wangsu/plugins/plugin-refresh-cert.ts b/packages/ui/certd-server/src/plugins/plugin-wangsu/plugins/plugin-refresh-cert.ts new file mode 100644 index 00000000..f7f12eb5 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-wangsu/plugins/plugin-refresh-cert.ts @@ -0,0 +1,121 @@ +import { + AbstractTaskPlugin, + IsTaskPlugin, + PageSearch, + pluginGroups, + RunStrategy, + TaskInput +} from "@certd/pipeline"; +import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert"; +import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib"; +import { WangsuAccess } from "../access.js"; + +@IsTaskPlugin({ + //命名规范,插件类型+功能(就是目录plugin-demo中的demo),大写字母开头,驼峰命名 + name: "WangsuRefreshCert", + title: "网宿-更新证书", + desc: "网宿证书自动更新", + icon: "svg:icon-lucky", + //插件分组 + group: pluginGroups.cdn.key, + needPlus: false, + default: { + //默认值配置照抄即可 + strategy: { + runStrategy: RunStrategy.SkipWhenSucceed + } + } +}) +//类名规范,跟上面插件名称(name)一致 +export class WangsuRefreshCert extends AbstractTaskPlugin { + //证书选择,此项必须要有 + @TaskInput({ + title: "域名证书", + helper: "请选择前置任务输出的域名证书", + component: { + name: "output-selector", + from: [...CertApplyPluginNames] + } + // required: true, // 必填 + }) + cert!: CertInfo; + + @TaskInput(createCertDomainGetterInputDefine({ props: { required: false } })) + certDomains!: string[]; + + //授权选择框 + @TaskInput({ + title: "网宿授权", + component: { + name: "access-selector", + type: "wangsu" //固定授权类型 + }, + required: true //必填 + }) + accessId!: string; + // + + @TaskInput( + createRemoteSelectInputDefine({ + title: "证书Id", + helper: "要更新的网宿证书id", + action: WangsuRefreshCert.prototype.onGetCertList.name, + pager: false, + search: false + }) + ) + certList!: string[]; + + //插件实例化时执行的方法 + async onInstance() { + } + + //插件执行方法 + async execute(): Promise { + const access = await this.getAccess(this.accessId); + + for (const item of this.certList) { + this.logger.info(`----------- 开始更新证书:${item}`); + await access.updateCert({ + certId: item, + cert: this.cert + }); + this.logger.info(`----------- 更新证书${item}成功`); + } + + this.logger.info("部署完成"); + } + + async onGetCertList(data: PageSearch = {}) { + const access = await this.getAccess(this.accessId); + + const list = await access.getCertList({}); + if (!list || list.length === 0) { + throw new Error("没有找到证书,请先在控制台上传一次证书且关联域名"); + } + + /** + * certificate-id + * name + * dns-names + */ + const options = list.map((item: any) => { + const domains = item["dns-names"] + const certId = item["certificate-id"]; + return { + label: `${item.name}<${certId}-${domains[0]}>`, + value: certId, + domain: item["dns-names"] + }; + }); + return { + list: this.ctx.utils.options.buildGroupOptions(options, this.certDomains), + total: list.length, + pageNo: 1, + pageSize: list.length + }; + } +} + +//实例化一下,注册插件 +new WangsuRefreshCert();