Compare commits

...

11 Commits

Author SHA1 Message Date
xiaojunnuo 112a565bf7 v1.39.10 2026-04-11 23:46:27 +08:00
xiaojunnuo 59e5c76286 build: prepare to build 2026-04-11 23:43:16 +08:00
xiaojunnuo 21620ac6bd perf: 流水线修改编辑之后,增加未保存提示 2026-04-11 23:41:20 +08:00
xiaojunnuo d05129ec67 perf: 部署到1panel面板支持mux模式 2026-04-11 23:20:19 +08:00
xiaojunnuo 0998de4ae6 chore: 首页时间动态刷新 2026-04-11 23:10:51 +08:00
xiaojunnuo 2bdf1832da perf: 增加域名管理 子域名检查提醒 2026-04-11 22:43:42 +08:00
xiaojunnuo a846c4b66e chore: 1 2026-04-11 22:21:02 +08:00
xiaojunnuo ee535895a3 perf: 修复检查全部某些情况下无效的bug,优化公共触发站点证书检查定时逻辑 2026-04-11 21:50:44 +08:00
xiaojunnuo 1e549dfd43 fix: 修复流水线任务编辑页面复制粘贴按钮在夜间模式显示问题 2026-04-11 21:07:23 +08:00
xiaojunnuo 6ee718a252 perf: 站点监控域名气泡增加端口显示 2026-04-11 21:02:31 +08:00
xiaojunnuo 557e98c33f fix: 修复用户管理添加用户无法上传头像的bug 2026-04-11 20:56:51 +08:00
56 changed files with 422 additions and 167 deletions
+19
View File
@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.10](https://github.com/certd/certd/compare/v1.39.9...v1.39.10) (2026-04-11)
### Bug Fixes
* 修复创建流水线无法选择通知的bug ([a88d0a6](https://github.com/certd/certd/commit/a88d0a6ae15cb6170d0b36e21daf89f0dbd5f681))
* 修复流水线任务编辑页面复制粘贴按钮在夜间模式显示问题 ([1e549df](https://github.com/certd/certd/commit/1e549dfd431ed74e2bcdfce63e5f640c51603af3))
* 修复用户管理添加用户无法上传头像的bug ([557e98c](https://github.com/certd/certd/commit/557e98c33f5462167d8f6289f70dad68bb114a97))
* 修复自定义插件删除后没有反注册的bug ([df98463](https://github.com/certd/certd/commit/df9846332596d2afaba53e66d2897aa1c598f9c4))
* 修复spaceship创建record报错的bug ([70b46d4](https://github.com/certd/certd/commit/70b46d4a8f89cf8eded21ebb237e8c8ce6c40d30))
### Performance Improvements
* 1panel支持先上传证书再选择证书 ([7a9eec8](https://github.com/certd/certd/commit/7a9eec88e8eddf40dba055c072b5b2b0f67c1407))
* 部署到1panel面板支持mux模式 ([d05129e](https://github.com/certd/certd/commit/d05129ec67893b0b639003a4bca6878d128f56ad))
* 流水线修改编辑之后,增加未保存提示 ([21620ac](https://github.com/certd/certd/commit/21620ac6bdeb57e43509156a77037fc07c44282a))
* 修复检查全部某些情况下无效的bug,优化公共触发站点证书检查定时逻辑 ([ee53589](https://github.com/certd/certd/commit/ee535895a3166c6f9046963e28fa8f22f018b574))
* 增加域名管理 子域名检查提醒 ([2bdf183](https://github.com/certd/certd/commit/2bdf1832da73a3728f3ac415837bc26e70531cd6))
* 站点监控域名气泡增加端口显示 ([6ee718a](https://github.com/certd/certd/commit/6ee718a25265a9db2115343af9a1a01958f34b81))
## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05) ## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05)
### Bug Fixes ### Bug Fixes
+1 -1
View File
@@ -9,5 +9,5 @@
} }
}, },
"npmClient": "pnpm", "npmClient": "pnpm",
"version": "1.39.9" "version": "1.39.10"
} }
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.10](https://github.com/publishlab/node-acme-client/compare/v1.39.9...v1.39.10) (2026-04-11)
**Note:** Version bump only for package @certd/acme-client
## [1.39.9](https://github.com/publishlab/node-acme-client/compare/v1.39.8...v1.39.9) (2026-04-05) ## [1.39.9](https://github.com/publishlab/node-acme-client/compare/v1.39.8...v1.39.9) (2026-04-05)
**Note:** Version bump only for package @certd/acme-client **Note:** Version bump only for package @certd/acme-client
+2 -2
View File
@@ -3,7 +3,7 @@
"description": "Simple and unopinionated ACME client", "description": "Simple and unopinionated ACME client",
"private": false, "private": false,
"author": "nmorsman", "author": "nmorsman",
"version": "1.39.9", "version": "1.39.10",
"type": "module", "type": "module",
"module": "scr/index.js", "module": "scr/index.js",
"main": "src/index.js", "main": "src/index.js",
@@ -18,7 +18,7 @@
"types" "types"
], ],
"dependencies": { "dependencies": {
"@certd/basic": "^1.39.9", "@certd/basic": "^1.39.10",
"@peculiar/x509": "^1.11.0", "@peculiar/x509": "^1.11.0",
"asn1js": "^3.0.5", "asn1js": "^3.0.5",
"axios": "^1.9.0", "axios": "^1.9.0",
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.10](https://github.com/certd/certd/compare/v1.39.9...v1.39.10) (2026-04-11)
### Performance Improvements
* 流水线修改编辑之后,增加未保存提示 ([21620ac](https://github.com/certd/certd/commit/21620ac6bdeb57e43509156a77037fc07c44282a))
## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05) ## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05)
### Performance Improvements ### Performance Improvements
+1 -1
View File
@@ -1 +1 @@
01:21 23:43
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@certd/basic", "name": "@certd/basic",
"private": false, "private": false,
"version": "1.39.9", "version": "1.39.10",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
@@ -126,7 +126,7 @@ export function createAxiosService({ logger }: { logger: ILogger }) {
if (config.skipSslVerify || config.httpProxy) { if (config.skipSslVerify || config.httpProxy) {
let rejectUnauthorized = true; let rejectUnauthorized = true;
if (config.skipSslVerify) { if (config.skipSslVerify) {
logger.info("跳过SSL验"); logger.info("忽略接口请求的SSL验");
rejectUnauthorized = false; rejectUnauthorized = false;
} }
const proxy: any = {}; const proxy: any = {};
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.10](https://github.com/certd/certd/compare/v1.39.9...v1.39.10) (2026-04-11)
**Note:** Version bump only for package @certd/pipeline
## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05) ## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05)
### Performance Improvements ### Performance Improvements
+3 -3
View File
@@ -1,7 +1,7 @@
{ {
"name": "@certd/pipeline", "name": "@certd/pipeline",
"private": false, "private": false,
"version": "1.39.9", "version": "1.39.10",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
@@ -18,8 +18,8 @@
"compile": "tsc --skipLibCheck --watch" "compile": "tsc --skipLibCheck --watch"
}, },
"dependencies": { "dependencies": {
"@certd/basic": "^1.39.9", "@certd/basic": "^1.39.10",
"@certd/plus-core": "^1.39.9", "@certd/plus-core": "^1.39.10",
"dayjs": "^1.11.7", "dayjs": "^1.11.7",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"reflect-metadata": "^0.1.13" "reflect-metadata": "^0.1.13"
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.10](https://github.com/certd/certd/compare/v1.39.9...v1.39.10) (2026-04-11)
**Note:** Version bump only for package @certd/lib-huawei
## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05) ## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05)
**Note:** Version bump only for package @certd/lib-huawei **Note:** Version bump only for package @certd/lib-huawei
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@certd/lib-huawei", "name": "@certd/lib-huawei",
"private": false, "private": false,
"version": "1.39.9", "version": "1.39.10",
"main": "./dist/bundle.js", "main": "./dist/bundle.js",
"module": "./dist/bundle.js", "module": "./dist/bundle.js",
"types": "./dist/d/index.d.ts", "types": "./dist/d/index.d.ts",
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.10](https://github.com/certd/certd/compare/v1.39.9...v1.39.10) (2026-04-11)
**Note:** Version bump only for package @certd/lib-iframe
## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05) ## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05)
**Note:** Version bump only for package @certd/lib-iframe **Note:** Version bump only for package @certd/lib-iframe
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@certd/lib-iframe", "name": "@certd/lib-iframe",
"private": false, "private": false,
"version": "1.39.9", "version": "1.39.10",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.10](https://github.com/certd/certd/compare/v1.39.9...v1.39.10) (2026-04-11)
**Note:** Version bump only for package @certd/jdcloud
## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05) ## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05)
**Note:** Version bump only for package @certd/jdcloud **Note:** Version bump only for package @certd/jdcloud
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@certd/jdcloud", "name": "@certd/jdcloud",
"version": "1.39.9", "version": "1.39.10",
"description": "jdcloud openApi sdk", "description": "jdcloud openApi sdk",
"main": "./dist/bundle.js", "main": "./dist/bundle.js",
"module": "./dist/bundle.js", "module": "./dist/bundle.js",
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.10](https://github.com/certd/certd/compare/v1.39.9...v1.39.10) (2026-04-11)
**Note:** Version bump only for package @certd/lib-k8s
## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05) ## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05)
**Note:** Version bump only for package @certd/lib-k8s **Note:** Version bump only for package @certd/lib-k8s
+2 -2
View File
@@ -1,7 +1,7 @@
{ {
"name": "@certd/lib-k8s", "name": "@certd/lib-k8s",
"private": false, "private": false,
"version": "1.39.9", "version": "1.39.10",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
@@ -18,7 +18,7 @@
"compile": "tsc --skipLibCheck --watch" "compile": "tsc --skipLibCheck --watch"
}, },
"dependencies": { "dependencies": {
"@certd/basic": "^1.39.9", "@certd/basic": "^1.39.10",
"@kubernetes/client-node": "0.21.0" "@kubernetes/client-node": "0.21.0"
}, },
"devDependencies": { "devDependencies": {
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.10](https://github.com/certd/certd/compare/v1.39.9...v1.39.10) (2026-04-11)
### Bug Fixes
* 修复自定义插件删除后没有反注册的bug ([df98463](https://github.com/certd/certd/commit/df9846332596d2afaba53e66d2897aa1c598f9c4))
## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05) ## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05)
**Note:** Version bump only for package @certd/lib-server **Note:** Version bump only for package @certd/lib-server
+6 -6
View File
@@ -1,6 +1,6 @@
{ {
"name": "@certd/lib-server", "name": "@certd/lib-server",
"version": "1.39.9", "version": "1.39.10",
"description": "midway with flyway, sql upgrade way ", "description": "midway with flyway, sql upgrade way ",
"private": false, "private": false,
"type": "module", "type": "module",
@@ -28,11 +28,11 @@
], ],
"license": "AGPL", "license": "AGPL",
"dependencies": { "dependencies": {
"@certd/acme-client": "^1.39.9", "@certd/acme-client": "^1.39.10",
"@certd/basic": "^1.39.9", "@certd/basic": "^1.39.10",
"@certd/pipeline": "^1.39.9", "@certd/pipeline": "^1.39.10",
"@certd/plugin-lib": "^1.39.9", "@certd/plugin-lib": "^1.39.10",
"@certd/plus-core": "^1.39.9", "@certd/plus-core": "^1.39.10",
"@midwayjs/cache": "3.14.0", "@midwayjs/cache": "3.14.0",
"@midwayjs/core": "3.20.11", "@midwayjs/core": "3.20.11",
"@midwayjs/i18n": "3.20.13", "@midwayjs/i18n": "3.20.13",
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.10](https://github.com/certd/certd/compare/v1.39.9...v1.39.10) (2026-04-11)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05) ## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05)
**Note:** Version bump only for package @certd/midway-flyway-js **Note:** Version bump only for package @certd/midway-flyway-js
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@certd/midway-flyway-js", "name": "@certd/midway-flyway-js",
"version": "1.39.9", "version": "1.39.10",
"description": "midway with flyway, sql upgrade way ", "description": "midway with flyway, sql upgrade way ",
"private": false, "private": false,
"type": "module", "type": "module",
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.10](https://github.com/certd/certd/compare/v1.39.9...v1.39.10) (2026-04-11)
**Note:** Version bump only for package @certd/plugin-cert
## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05) ## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05)
**Note:** Version bump only for package @certd/plugin-cert **Note:** Version bump only for package @certd/plugin-cert
+5 -5
View File
@@ -1,7 +1,7 @@
{ {
"name": "@certd/plugin-cert", "name": "@certd/plugin-cert",
"private": false, "private": false,
"version": "1.39.9", "version": "1.39.10",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@@ -17,10 +17,10 @@
"compile": "tsc --skipLibCheck --watch" "compile": "tsc --skipLibCheck --watch"
}, },
"dependencies": { "dependencies": {
"@certd/acme-client": "^1.39.9", "@certd/acme-client": "^1.39.10",
"@certd/basic": "^1.39.9", "@certd/basic": "^1.39.10",
"@certd/pipeline": "^1.39.9", "@certd/pipeline": "^1.39.10",
"@certd/plugin-lib": "^1.39.9", "@certd/plugin-lib": "^1.39.10",
"psl": "^1.9.0", "psl": "^1.9.0",
"punycode.js": "^2.3.1" "punycode.js": "^2.3.1"
}, },
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.10](https://github.com/certd/certd/compare/v1.39.9...v1.39.10) (2026-04-11)
### Performance Improvements
* 1panel支持先上传证书再选择证书 ([7a9eec8](https://github.com/certd/certd/commit/7a9eec88e8eddf40dba055c072b5b2b0f67c1407))
## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05) ## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05)
**Note:** Version bump only for package @certd/plugin-lib **Note:** Version bump only for package @certd/plugin-lib
+5 -5
View File
@@ -1,7 +1,7 @@
{ {
"name": "@certd/plugin-lib", "name": "@certd/plugin-lib",
"private": false, "private": false,
"version": "1.39.9", "version": "1.39.10",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@@ -22,10 +22,10 @@
"@alicloud/pop-core": "^1.7.10", "@alicloud/pop-core": "^1.7.10",
"@alicloud/tea-util": "^1.4.11", "@alicloud/tea-util": "^1.4.11",
"@aws-sdk/client-s3": "^3.964.0", "@aws-sdk/client-s3": "^3.964.0",
"@certd/acme-client": "^1.39.9", "@certd/acme-client": "^1.39.10",
"@certd/basic": "^1.39.9", "@certd/basic": "^1.39.10",
"@certd/pipeline": "^1.39.9", "@certd/pipeline": "^1.39.10",
"@certd/plus-core": "^1.39.9", "@certd/plus-core": "^1.39.10",
"@kubernetes/client-node": "0.21.0", "@kubernetes/client-node": "0.21.0",
"ali-oss": "^6.22.0", "ali-oss": "^6.22.0",
"basic-ftp": "^5.0.5", "basic-ftp": "^5.0.5",
+17
View File
@@ -3,6 +3,23 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.10](https://github.com/certd/certd/compare/v1.39.9...v1.39.10) (2026-04-11)
### Bug Fixes
* 修复创建流水线无法选择通知的bug ([a88d0a6](https://github.com/certd/certd/commit/a88d0a6ae15cb6170d0b36e21daf89f0dbd5f681))
* 修复流水线任务编辑页面复制粘贴按钮在夜间模式显示问题 ([1e549df](https://github.com/certd/certd/commit/1e549dfd431ed74e2bcdfce63e5f640c51603af3))
* 修复用户管理添加用户无法上传头像的bug ([557e98c](https://github.com/certd/certd/commit/557e98c33f5462167d8f6289f70dad68bb114a97))
* 修复自定义插件删除后没有反注册的bug ([df98463](https://github.com/certd/certd/commit/df9846332596d2afaba53e66d2897aa1c598f9c4))
### Performance Improvements
* 1panel支持先上传证书再选择证书 ([7a9eec8](https://github.com/certd/certd/commit/7a9eec88e8eddf40dba055c072b5b2b0f67c1407))
* 流水线修改编辑之后,增加未保存提示 ([21620ac](https://github.com/certd/certd/commit/21620ac6bdeb57e43509156a77037fc07c44282a))
* 修复检查全部某些情况下无效的bug,优化公共触发站点证书检查定时逻辑 ([ee53589](https://github.com/certd/certd/commit/ee535895a3166c6f9046963e28fa8f22f018b574))
* 增加域名管理 子域名检查提醒 ([2bdf183](https://github.com/certd/certd/commit/2bdf1832da73a3728f3ac415837bc26e70531cd6))
* 站点监控域名气泡增加端口显示 ([6ee718a](https://github.com/certd/certd/commit/6ee718a25265a9db2115343af9a1a01958f34b81))
## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05) ## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05)
### Bug Fixes ### Bug Fixes
+3 -3
View File
@@ -1,6 +1,6 @@
{ {
"name": "@certd/ui-client", "name": "@certd/ui-client",
"version": "1.39.9", "version": "1.39.10",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite --open", "dev": "vite --open",
@@ -106,8 +106,8 @@
"zod-defaults": "^0.1.3" "zod-defaults": "^0.1.3"
}, },
"devDependencies": { "devDependencies": {
"@certd/lib-iframe": "^1.39.9", "@certd/lib-iframe": "^1.39.10",
"@certd/pipeline": "^1.39.9", "@certd/pipeline": "^1.39.10",
"@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-node-resolve": "^15.2.3",
"@types/chai": "^4.3.12", "@types/chai": "^4.3.12",
@@ -13,13 +13,11 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import parser from "cron-parser";
import { computed, ref } from "vue"; import { computed, ref } from "vue";
import dayjs from "dayjs";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { getCronNextTimes } from "/@/components/cron-editor/utils";
const { t } = useI18n(); const { t } = useI18n();
import { getCronNextTimes } from "/@/components/cron-editor/utils";
defineOptions({ defineOptions({
name: "CronEditor", name: "CronEditor",
}); });
@@ -2,7 +2,7 @@
<div class="domains-verify-plan-editor" :class="{ fullscreen }"> <div class="domains-verify-plan-editor" :class="{ fullscreen }">
<div class="fullscreen-modal" @click="fullscreenExit"></div> <div class="fullscreen-modal" @click="fullscreenExit"></div>
<div class="plan-wrapper"> <div class="plan-wrapper">
<div class="plan-box"> <div class="plan-box bg-white dark:bg-neutral-700">
<div class="fullscreen-button pointer flex-center" @click="fullscreen = !fullscreen"> <div class="fullscreen-button pointer flex-center" @click="fullscreen = !fullscreen">
<span v-if="!fullscreen" style="font-size: 10px" class="flex-center"> <span v-if="!fullscreen" style="font-size: 10px" class="flex-center">
这里可以放大 这里可以放大
@@ -273,7 +273,7 @@ watch(
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: rgba(74, 74, 74, 0.78); // background-color: rgba(74, 74, 74, 0.78);
z-index: 1000; z-index: 1000;
margin: auto; margin: auto;
display: flex; display: flex;
@@ -287,7 +287,6 @@ watch(
.plan-box { .plan-box {
position: relative; position: relative;
margin: auto; margin: auto;
background-color: #fff;
} }
} }
@@ -315,7 +314,7 @@ watch(
height: 100%; height: 100%;
//table-layout: fixed; //table-layout: fixed;
th { th {
background-color: #f5f5f5; // background-color: #f5f5f5;
border-top: 1px solid #e8e8e8; border-top: 1px solid #e8e8e8;
border-left: 1px solid #e8e8e8; border-left: 1px solid #e8e8e8;
border-bottom: 1px solid #e8e8e8; border-bottom: 1px solid #e8e8e8;
@@ -33,7 +33,7 @@ export default {
async function onCreate() { async function onCreate() {
await pluginStore.init(); await pluginStore.init();
options.value = pluginStore.group.getPreStepOutputOptions({ options.value = pluginStore.group.getPreStepOutputOptions({
pipeline: pipeline.value, pipeline: pipeline?.value,
currentStageIndex: currentStageIndex.value, currentStageIndex: currentStageIndex.value,
currentTaskIndex: currentTaskIndex.value, currentTaskIndex: currentTaskIndex.value,
currentStepIndex: currentStepIndex.value, currentStepIndex: currentStepIndex.value,
@@ -130,4 +130,16 @@ button.ant-btn.ant-btn-default.isPlus{
background-color: rgba(50, 54, 57, 0.04); background-color: rgba(50, 54, 57, 0.04);
box-shadow: none; box-shadow: none;
} }
}
.dark{
button.ant-btn.ant-btn-default.isPlus{
color: #c5913f;
border: 1px solid #c5913f;
&:disabled {
border-color: hsl(0, 0%, 31%);
color: rgba(233, 233, 233, 0.25);
}
}
} }
@@ -131,7 +131,7 @@ const userStore = useUserStore();
const projectStore = useProjectStore(); const projectStore = useProjectStore();
async function emitValue(value: any) { async function emitValue(value: any) {
// target.value = optionsDictRef.dataMap[value]; // target.value = optionsDictRef.dataMap[value];
if (pipeline.value) { if (pipeline?.value) {
const userId = userStore.userInfo.id; const userId = userStore.userInfo.id;
const isEnterprice = projectStore.isEnterprise; const isEnterprice = projectStore.isEnterprise;
if (isEnterprice) { if (isEnterprice) {
@@ -99,3 +99,11 @@ export async function SyncExpirationStatus() {
method: "post", method: "post",
}); });
} }
export async function IsSubdomain(body: any) {
return await request({
url: apiPrefix + "/isSubdomain",
method: "post",
data: body,
});
}
@@ -52,6 +52,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
}); });
const openDomainImportManageDialog = useDomainImportManage(); const openDomainImportManageDialog = useDomainImportManage();
const subdomainConfirmed = ref(false);
return { return {
crudOptions: { crudOptions: {
settings: { settings: {
@@ -85,10 +87,29 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
fixed: "right", fixed: "right",
}, },
form: { form: {
beforeSubmit({ form }) { async beforeSubmit({ form }) {
if (form.challengeType === "cname") { if (form.challengeType === "cname") {
throw new Error("CNAME方式请前往CNAME记录页面进行管理"); throw new Error("CNAME方式请前往CNAME记录页面进行管理");
} }
if (form.challengeType === "dns") {
const isSubdomain = await api.IsSubdomain({ domain: form.domain });
if (isSubdomain && !subdomainConfirmed.value) {
Modal.confirm({
title: "子域名确认",
content: `检测到${form.domain}为子域名,只有托管子域名和免费二级子域名才需要在此处维护,否则会导致申请证书失败,请确认是否继续?`,
okText: "确认",
okType: "danger",
onOk: () => {
subdomainConfirmed.value = true;
crudExpose.getFormWrapperRef().submit();
},
});
return false;
}
}
},
afterSubmit({ form }) {
subdomainConfirmed.value = false;
}, },
}, },
actionbar: { actionbar: {
@@ -163,6 +184,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
}, },
form: { form: {
required: true, required: true,
helper: "注意:DNS校验方式下,子域名不需要在此处维护,否则会影响证书申请(子域名托管或免费二级域名除外)",
}, },
editForm: { editForm: {
component: { component: {
@@ -346,12 +346,13 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
width: 230, width: 230,
sorter: true, sorter: true,
cellRender({ value, row }) { cellRender({ value, row }) {
const url = `https://${value}:${row.httpsPort}`; const domainPort = value + ":" + row.httpsPort;
const url = `https://${domainPort}`;
return ( return (
<a-tooltip title={value} placement="left"> <a-tooltip title={domainPort} placement="left">
<fs-copyable modelValue={value}> <fs-copyable modelValue={domainPort} title={domainPort}>
<a target="_blank" href={url}> <a target="_blank" href={url}>
{value}:{row.httpsPort} {domainPort}
</a> </a>
</fs-copyable> </fs-copyable>
</a-tooltip> </a-tooltip>
@@ -24,6 +24,9 @@
</a-tabs> </a-tabs>
<template #footer> <template #footer>
<fs-button v-if="settingsStore.sysPublic.aiChatEnabled !== false" key="aiChat" :tooltip="{ title: 'AI分析异常' }" type="primary" icon="ion:color-wand-outline" @click="taskModal.onAiChat">AI分析</fs-button> <fs-button v-if="settingsStore.sysPublic.aiChatEnabled !== false" key="aiChat" :tooltip="{ title: 'AI分析异常' }" type="primary" icon="ion:color-wand-outline" @click="taskModal.onAiChat">AI分析</fs-button>
<!-- <fs-button v-if="!settingsStore.isComm && currentStatus === 'error'" key="1v1" :tooltip="{ title: '升级专业版,获得一对一分析服务,为您排忧解难' }" class="isPlus" icon="imingcute:vip-1-line" @click="callService">
呼叫专家
</fs-button> -->
<fs-button key="rerun" type="primary" :tooltip="{ title: '强制重新执行此步骤' }" text="重新运行" icon="icon-park-outline:replay-music" @click="triggerRun(activeKey)"></fs-button> <fs-button key="rerun" type="primary" :tooltip="{ title: '强制重新执行此步骤' }" text="重新运行" icon="icon-park-outline:replay-music" @click="triggerRun(activeKey)"></fs-button>
<fs-button key="downloadLogs" type="primary" :tooltip="{ title: '当前任务日志下载' }" icon="ion:arrow-down-circle-outline" @click="taskModal.onDownloadLogs">下载日志</fs-button> <fs-button key="downloadLogs" type="primary" :tooltip="{ title: '当前任务日志下载' }" icon="ion:arrow-down-circle-outline" @click="taskModal.onDownloadLogs">下载日志</fs-button>
<fs-button key="cancel" :tooltip="{ title: '关闭窗口' }" icon="ion:close-circle-outline" @click="taskModal.onOk">关闭</fs-button> <fs-button key="cancel" :tooltip="{ title: '关闭窗口' }" icon="ion:close-circle-outline" @click="taskModal.onOk">关闭</fs-button>
@@ -39,6 +42,7 @@ import PiStatusShow from "/@/views/certd/pipeline/pipeline/component/status-show
import { usePreferences } from "/@/vben/preferences"; import { usePreferences } from "/@/vben/preferences";
import { useSettingStore } from "/@/store/settings/index"; import { useSettingStore } from "/@/store/settings/index";
import { notification } from "ant-design-vue"; import { notification } from "ant-design-vue";
import { mitter } from "/@/utils/util.mitt";
export default { export default {
name: "PiTaskView", name: "PiTaskView",
components: { PiStatusShow }, components: { PiStatusShow },
@@ -196,6 +200,19 @@ export default {
taskModal.value.open = false; taskModal.value.open = false;
} }
const currentNode = computed(() => {
return detail.value?.nodes?.find(item => item.node.id === activeKey.value);
});
const currentStatus = computed(() => {
return currentNode.value?.node?.status?.result || "";
});
function callService() {
if (!settingsStore.isPlus) {
mitter.emit("openVipModal");
}
}
const settingsStore = useSettingStore(); const settingsStore = useSettingStore();
return { return {
detail, detail,
@@ -206,6 +223,9 @@ export default {
tabPosition, tabPosition,
triggerRun, triggerRun,
settingsStore, settingsStore,
currentNode,
currentStatus,
callService,
}; };
}, },
}; };
@@ -334,7 +334,7 @@ import { useCertViewer } from "/@/views/certd/pipeline/use";
import { useI18n } from "/@/locales"; import { useI18n } from "/@/locales";
import TriggerIcon from "./component/trigger-icon.vue"; import TriggerIcon from "./component/trigger-icon.vue";
import { useCrudPermission } from "/@/plugin/permission"; import { useCrudPermission } from "/@/plugin/permission";
import { onBeforeRouteLeave } from "vue-router";
export default defineComponent({ export default defineComponent({
name: "PipelineEdit", name: "PipelineEdit",
// eslint-disable-next-line vue/no-unused-components // eslint-disable-next-line vue/no-unused-components
@@ -372,10 +372,22 @@ export default defineComponent({
}, },
emits: ["update:modelValue", "update:editMode"], emits: ["update:modelValue", "update:editMode"],
setup(props, ctx) { setup(props, ctx) {
onBeforeRouteLeave((to, from) => {
const newPipelineStr = JSON.stringify(pipeline.value || {});
if (pipelineOriginStr.value && pipelineOriginStr.value !== newPipelineStr) {
const answer = window.confirm("流水线还未保存,确定要离开吗?");
if (!answer) {
return false; // false
}
return true;
}
});
const { t } = useI18n(); const { t } = useI18n();
//pipeline //pipeline
const currentPipeline: Ref<any> = ref({}); const currentPipeline: Ref<any> = ref({});
const pipeline: Ref<any> = ref({}); const pipeline: Ref<any> = ref({});
const pipelineOriginStr = ref("");
const pipelineDetail: Ref<any> = ref({}); const pipelineDetail: Ref<any> = ref({});
const histories: Ref<RunHistory[]> = ref([]); const histories: Ref<RunHistory[]> = ref([]);
@@ -423,6 +435,7 @@ export default defineComponent({
await loadCurrentHistoryDetail(); await loadCurrentHistoryDetail();
pipeline.value = currentHistory.value.pipeline; pipeline.value = currentHistory.value.pipeline;
currentPipeline.value = currentHistory.value.pipeline; currentPipeline.value = currentHistory.value.pipeline;
pipelineOriginStr.value = JSON.stringify(pipeline.value);
}; };
async function loadHistoryList(reload = false, historyId: number = null) { async function loadHistoryList(reload = false, historyId: number = null) {
@@ -880,6 +893,7 @@ export default defineComponent({
pipeline.value.version = version; pipeline.value.version = version;
currentPipeline.value.version = version; currentPipeline.value.version = version;
} }
pipelineOriginStr.value = JSON.stringify(pipeline.value);
} }
if (offEdit) { if (offEdit) {
toggleEditMode(false); toggleEditMode(false);
@@ -238,10 +238,14 @@ const avatar = computed(() => {
} }
return `/api/basic/file/download?key=${avt}`; return `/api/basic/file/download?key=${avt}`;
}); });
const dateNow = ref(Date.now());
const now = computed(() => { const now = computed(() => {
const serverTime = Date.now() - settingStore.app.deltaTime; const serverTime = dateNow.value - settingStore.app.deltaTime;
return dayjs(serverTime).format("YYYY-MM-DD HH:mm:ss"); return dayjs(serverTime).format("YYYY-MM-DD HH:mm:ss");
}); });
setInterval(() => {
dateNow.value = Date.now();
}, 5000);
const deltaTimeWarning = computed(() => { const deltaTimeWarning = computed(() => {
return Math.abs(settingStore.app.deltaTime) > 1000 * 60 * 4; return Math.abs(settingStore.app.deltaTime) > 1000 * 60 * 4;
@@ -172,7 +172,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
width: "auto", width: "auto",
}, },
buildUrl(key: string) { buildUrl(key: string) {
return `api/basic/file/download?&key=` + key; return `api/basic/file/download?token=${userStore.getToken}&key=` + key;
}, },
}, },
}, },
@@ -188,7 +188,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
onReady: null, onReady: null,
uploader: { uploader: {
type: "form", type: "form",
action: "/basic/file/upload", action: "/basic/file/upload?token=" + userStore.getToken,
name: "file", name: "file",
headers: { headers: {
Authorization: "Bearer " + userStore.getToken, Authorization: "Bearer " + userStore.getToken,
@@ -2,7 +2,7 @@
import { request } from "/src/api/service"; import { request } from "/src/api/service";
const apiPrefix = "/sys/site"; const apiPrefix = "/sys/site";
export async function SettingsGet(key: string) { export async function SettingsGet() {
return await request({ return await request({
url: apiPrefix + "/get", url: apiPrefix + "/get",
method: "post", method: "post",
@@ -88,7 +88,7 @@ const onFinish = async (form: any) => {
const userStore = useUserStore(); const userStore = useUserStore();
const uploaderConfig = ref({ const uploaderConfig = ref({
type: "form", type: "form",
action: "/basic/file/upload", action: "/basic/file/upload?token=" + userStore.getToken,
name: "file", name: "file",
headers: { headers: {
Authorization: "Bearer " + userStore.getToken, Authorization: "Bearer " + userStore.getToken,
+15
View File
@@ -3,6 +3,21 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.39.10](https://github.com/certd/certd/compare/v1.39.9...v1.39.10) (2026-04-11)
### Bug Fixes
* 修复自定义插件删除后没有反注册的bug ([df98463](https://github.com/certd/certd/commit/df9846332596d2afaba53e66d2897aa1c598f9c4))
* 修复spaceship创建record报错的bug ([70b46d4](https://github.com/certd/certd/commit/70b46d4a8f89cf8eded21ebb237e8c8ce6c40d30))
### Performance Improvements
* 1panel支持先上传证书再选择证书 ([7a9eec8](https://github.com/certd/certd/commit/7a9eec88e8eddf40dba055c072b5b2b0f67c1407))
* 部署到1panel面板支持mux模式 ([d05129e](https://github.com/certd/certd/commit/d05129ec67893b0b639003a4bca6878d128f56ad))
* 流水线修改编辑之后,增加未保存提示 ([21620ac](https://github.com/certd/certd/commit/21620ac6bdeb57e43509156a77037fc07c44282a))
* 修复检查全部某些情况下无效的bug,优化公共触发站点证书检查定时逻辑 ([ee53589](https://github.com/certd/certd/commit/ee535895a3166c6f9046963e28fa8f22f018b574))
* 增加域名管理 子域名检查提醒 ([2bdf183](https://github.com/certd/certd/commit/2bdf1832da73a3728f3ac415837bc26e70531cd6))
## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05) ## [1.39.9](https://github.com/certd/certd/compare/v1.39.8...v1.39.9) (2026-04-05)
### Bug Fixes ### Bug Fixes
@@ -23,7 +23,7 @@ input:
component: component:
name: api-test name: api-test
action: TestRequest action: TestRequest
helper: 测试 API 连接是否正常 helper: 测试 API 连接是否正常,需要域名查询权限
pluginType: access pluginType: access
type: builtIn type: builtIn
scriptFilePath: /plugins/plugin-spaceship/access.js scriptFilePath: /plugins/plugin-spaceship/access.js
@@ -72,6 +72,22 @@ input:
helper: 要更新的1Panel证书的节点信息,目前只有v2存在此概念 helper: 要更新的1Panel证书的节点信息,目前只有v2存在此概念
order: 0 order: 0
sslMode:
title: SSL模式
helper: SSL模式,只有2.1.x以上版本才支持,旧版本保持默认即可
component:
name: a-select
vMode: value
options:
- label: 启用SSL(旧版本)
value: enable
- label: Strict模式(>=2.1.x)
value: Enable
- label: Mux模式(>=2.1.x)
value: Mux
value: enable
required: true
order: 0
output: {} output: {}
pluginType: deploy pluginType: deploy
type: builtIn type: builtIn
@@ -88,6 +88,7 @@ input:
- certDomains - certDomains
- accessId - accessId
- accessId - accessId
uploadCert: {}
required: true required: true
mergeScript: |2- mergeScript: |2-
+14 -14
View File
@@ -1,6 +1,6 @@
{ {
"name": "@certd/ui-server", "name": "@certd/ui-server",
"version": "1.39.9", "version": "1.39.10",
"description": "fast-server base midway", "description": "fast-server base midway",
"private": true, "private": true,
"type": "module", "type": "module",
@@ -50,20 +50,20 @@
"@aws-sdk/client-route-53": "^3.964.0", "@aws-sdk/client-route-53": "^3.964.0",
"@aws-sdk/client-s3": "^3.964.0", "@aws-sdk/client-s3": "^3.964.0",
"@aws-sdk/client-sts": "^3.990.0", "@aws-sdk/client-sts": "^3.990.0",
"@certd/acme-client": "^1.39.9", "@certd/acme-client": "^1.39.10",
"@certd/basic": "^1.39.9", "@certd/basic": "^1.39.10",
"@certd/commercial-core": "^1.39.9", "@certd/commercial-core": "^1.39.10",
"@certd/cv4pve-api-javascript": "^8.4.2", "@certd/cv4pve-api-javascript": "^8.4.2",
"@certd/jdcloud": "^1.39.9", "@certd/jdcloud": "^1.39.10",
"@certd/lib-huawei": "^1.39.9", "@certd/lib-huawei": "^1.39.10",
"@certd/lib-k8s": "^1.39.9", "@certd/lib-k8s": "^1.39.10",
"@certd/lib-server": "^1.39.9", "@certd/lib-server": "^1.39.10",
"@certd/midway-flyway-js": "^1.39.9", "@certd/midway-flyway-js": "^1.39.10",
"@certd/pipeline": "^1.39.9", "@certd/pipeline": "^1.39.10",
"@certd/plugin-cert": "^1.39.9", "@certd/plugin-cert": "^1.39.10",
"@certd/plugin-lib": "^1.39.9", "@certd/plugin-lib": "^1.39.10",
"@certd/plugin-plus": "^1.39.9", "@certd/plugin-plus": "^1.39.10",
"@certd/plus-core": "^1.39.9", "@certd/plus-core": "^1.39.10",
"@google-cloud/publicca": "^1.3.0", "@google-cloud/publicca": "^1.3.0",
"@huaweicloud/huaweicloud-sdk-cdn": "^3.1.185", "@huaweicloud/huaweicloud-sdk-cdn": "^3.1.185",
"@huaweicloud/huaweicloud-sdk-core": "^3.1.185", "@huaweicloud/huaweicloud-sdk-core": "^3.1.185",
@@ -3,6 +3,7 @@ import { Constants, CrudController } from '@certd/lib-server';
import { DomainService } from "../../../modules/cert/service/domain-service.js"; import { DomainService } from "../../../modules/cert/service/domain-service.js";
import { checkPlus } from '@certd/plus-core'; import { checkPlus } from '@certd/plus-core';
import { ApiTags } from '@midwayjs/swagger'; import { ApiTags } from '@midwayjs/swagger';
import { parseDomainByPsl } from '@certd/plugin-lib';
/** /**
* *
@@ -187,4 +188,12 @@ export class DomainController extends CrudController<DomainService> {
return this.ok(setting); return this.ok(setting);
} }
@Post('/isSubdomain', { description: Constants.per.authOnly, summary: "判断是否为子域名" })
async isSubdomain(@Body(ALL) body: any) {
const { domain } = body;
const parsed = parseDomainByPsl(domain)
const mainDomain = parsed.domain || ''
return this.ok(mainDomain !== domain);
}
} }
@@ -121,7 +121,7 @@ export class SiteInfoController extends CrudController<SiteInfoService> {
@Post('/checkAll', { description: Constants.per.authOnly, summary: "检查所有站点监控" }) @Post('/checkAll', { description: Constants.per.authOnly, summary: "检查所有站点监控" })
async checkAll() { async checkAll() {
const { projectId, userId } = await this.getProjectUserIdWrite() const { projectId, userId } = await this.getProjectUserIdWrite()
await this.service.checkAllByUsers(userId,projectId); this.service.triggerJobOnce(userId,projectId);
return this.ok(); return this.ok();
} }
@@ -1,17 +1,18 @@
import {Autoload, Config, Init, Inject, Scope, ScopeEnum} from '@midwayjs/core'; import { logger } from '@certd/basic';
import {PipelineService} from '../pipeline/service/pipeline-service.js'; import { SysSettingsService, SysSiteInfo } from '@certd/lib-server';
import {logger} from '@certd/basic'; import { getPlusInfo, isPlus } from "@certd/plus-core";
import {SysSettingsService, SysSiteInfo} from '@certd/lib-server'; import { Autoload, Config, Init, Inject, Scope, ScopeEnum } from '@midwayjs/core';
import {SiteInfoService} from '../monitor/index.js';
import {Cron} from '../cron/cron.js';
import {UserSettingsService} from "../mine/service/user-settings-service.js";
import {UserSiteMonitorSetting} from "../mine/service/models.js";
import {getPlusInfo, isPlus} from "@certd/plus-core";
import dayjs from "dayjs"; import dayjs from "dayjs";
import {NotificationService} from "../pipeline/service/notification-service.js"; import { Between } from "typeorm";
import {UserService} from "../sys/authority/service/user-service.js";
import {Between} from "typeorm";
import { DomainService } from '../cert/service/domain-service.js'; import { DomainService } from '../cert/service/domain-service.js';
import { Cron } from '../cron/cron.js';
import { UserSiteMonitorSetting } from "../mine/service/models.js";
import { UserSettingsService } from "../mine/service/user-settings-service.js";
import { SiteInfoService } from '../monitor/index.js';
import { NotificationService } from "../pipeline/service/notification-service.js";
import { PipelineService } from '../pipeline/service/pipeline-service.js';
import { UserService } from "../sys/authority/service/user-service.js";
import { ProjectService } from '../sys/enterprise/service/project-service.js';
@Autoload() @Autoload()
@Scope(ScopeEnum.Request, { allowDowngrade: true }) @Scope(ScopeEnum.Request, { allowDowngrade: true })
@@ -47,6 +48,9 @@ export class AutoCRegisterCron {
@Inject() @Inject()
domainService: DomainService; domainService: DomainService;
@Inject()
projectService: ProjectService;
@Init() @Init()
@@ -72,9 +76,23 @@ export class AutoCRegisterCron {
async registerSiteMonitorCron() { async registerSiteMonitorCron() {
//先注册公共job //先注册公共job
await this.siteInfoService.registerSiteMonitorJob() logger.info(`注册公共站点证书检查定时任务`)
const randomMinute = Math.floor(Math.random() * 60)
this.cron.register({
name: 'siteMonitor',
cron: `0 ${randomMinute} 0 * * *`,
job:async ()=>{
logger.info(`开始公共站点证书检查任务`)
await this.siteInfoService.triggerCommonJob()
logger.info(`公共站点证书检查任务完成`)
},
});
logger.info(`注册公共站点证书检查定时任务完成`)
//注册用户独立的检查时间 //注册用户独立的检查时间
logger.info(`注册用户独立站点证书检查定时任务`)
const monitorSettingList = await this.userSettingsService.list({ const monitorSettingList = await this.userSettingsService.list({
query:{ query:{
key: UserSiteMonitorSetting.__key__, key: UserSiteMonitorSetting.__key__,
@@ -87,10 +105,11 @@ export class AutoCRegisterCron {
} }
await this.siteInfoService.registerSiteMonitorJob(item.userId,item.projectId) await this.siteInfoService.registerSiteMonitorJob(item.userId,item.projectId)
} }
logger.info(`注册用户独立站点证书检查定时任务完成`)
if (this.immediateTriggerSiteMonitor) { if (this.immediateTriggerSiteMonitor) {
logger.info(`立即触发一次站点证书检查任务`) logger.info(`立即触发一次公共站点证书检查任务`)
await this.siteInfoService.triggerJobOnce() await this.siteInfoService.triggerCommonJob()
} }
} }
@@ -1,5 +1,5 @@
import {Inject, Provide, Scope, ScopeEnum} from "@midwayjs/core"; import {Inject, Provide, Scope, ScopeEnum} from "@midwayjs/core";
import {BaseService, NeedSuiteException, NeedVIPException, SysSettingsService} from "@certd/lib-server"; import {BaseService, Constants, NeedSuiteException, NeedVIPException, SysSettingsService} from "@certd/lib-server";
import {InjectEntityModel} from "@midwayjs/typeorm"; import {InjectEntityModel} from "@midwayjs/typeorm";
import {In, Repository} from "typeorm"; import {In, Repository} from "typeorm";
import {SiteInfoEntity} from "../entity/site-info.js"; import {SiteInfoEntity} from "../entity/site-info.js";
@@ -19,6 +19,8 @@ import { dnsContainer } from "./dns-custom.js";
import { merge } from "lodash-es"; import { merge } from "lodash-es";
import { JobHistoryService } from "./job-history-service.js"; import { JobHistoryService } from "./job-history-service.js";
import { JobHistoryEntity } from "../entity/job-history.js"; import { JobHistoryEntity } from "../entity/job-history.js";
import { UserService } from "../../sys/authority/service/user-service.js";
import { ProjectService } from "../../sys/enterprise/service/project-service.js";
@Provide() @Provide()
@Scope(ScopeEnum.Request, {allowDowngrade: true}) @Scope(ScopeEnum.Request, {allowDowngrade: true})
@@ -44,6 +46,10 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
@Inject() @Inject()
jobHistoryService: JobHistoryService; jobHistoryService: JobHistoryService;
@Inject()
userService: UserService;
@Inject()
projectService: ProjectService;
@Inject() @Inject()
cron: Cron; cron: Cron;
@@ -353,18 +359,7 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
} }
} }
async checkAllByUsers(userId: any,projectId?: number) { async checkList(sites: SiteInfoEntity[]) {
if (userId==null) {
throw new Error("userId is required");
}
// const sites = await this.repository.find({
// where: {userId,projectId}
// });
// this.checkList(sites,false);
await this.triggerJobOnce(userId,projectId);
}
async checkList(sites: SiteInfoEntity[],isCommon: boolean) {
const cache = {} const cache = {}
const getFromCache = async (userId: number,projectId?: number) =>{ const getFromCache = async (userId: number,projectId?: number) =>{
const key = `${userId}_${projectId??""}` const key = `${userId}_${projectId??""}`
@@ -377,13 +372,6 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
} }
for (const site of sites) { for (const site of sites) {
const setting = await getFromCache(site.userId,site.projectId) const setting = await getFromCache(site.userId,site.projectId)
if (isCommon) {
//公共的检查,排除有设置cron的用户
if (setting?.cron) {
//设置了cron,跳过公共检查
continue;
}
}
let retryTimes = setting?.retryTimes let retryTimes = setting?.retryTimes
this.doCheck(site,true,retryTimes).catch(e => { this.doCheck(site,true,retryTimes).catch(e => {
logger.error(`检查站点证书失败,${site.domain}`, e.message); logger.error(`检查站点证书失败,${site.domain}`, e.message);
@@ -492,57 +480,73 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
} }
async registerSiteMonitorJob(userId?: number,projectId?: number) { async registerSiteMonitorJob(userId?: number,projectId?: number) {
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId,projectId, UserSiteMonitorSetting);
if (!setting.cron) {
return;
}
//注册个人的 或项目的
this.cron.register({
name: `siteMonitor_${userId}_${projectId||""}`,
cron: setting.cron,
job: () => this.triggerJobOnce(userId,projectId),
});
}
if(userId == null){ async triggerCommonJob(){
//注册公共job //遍历用户
logger.info(`注册站点证书检查定时任务`) const userIds = await this.userService.getAllUserIds()
this.cron.register({ for (const userId of userIds) {
name: 'siteMonitor', const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId,null,UserSiteMonitorSetting)
cron: '0 0 0 * * *', if(setting && setting.cron){
job:async ()=>{ //该用户有自定义检查时间,跳过公共job
await this.triggerJobOnce() continue
},
});
logger.info(`注册站点证书检查定时任务完成`)
}else{
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId,projectId, UserSiteMonitorSetting);
if (!setting.cron) {
return;
} }
//注册个人的 或项目的 await this.triggerJobOnce(userId)
this.cron.register({
name: `siteMonitor_${userId}_${projectId||""}`,
cron: setting.cron,
job: () => this.triggerJobOnce(userId,projectId),
});
} }
//遍历项目
const projectIds = await this.projectService.getAllProjectIds()
for (const projectId of projectIds) {
const userId = Constants.enterpriseUserId
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId,projectId,UserSiteMonitorSetting)
if(setting && setting.cron){
//该项目有自定义检查时间,跳过公共job
continue
}
await this.triggerJobOnce(userId,projectId)
}
} }
async triggerJobOnce(userId?:number,projectId?:number) { async triggerJobOnce(userId?:number,projectId?:number) {
logger.info(`站点证书检查开始执行[${userId??'所有用户'}_${projectId??'所有项目'}]`); if(userId==null){
const query:any = { disabled: false }; throw new Error("userId is required");
let jobEntity :Partial<JobHistoryEntity> = null;
if(userId!=null){
query.userId = userId;
if(projectId){
query.projectId = projectId;
}
//判断是否已关闭
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId,projectId, UserSiteMonitorSetting);
if (setting && !setting.cron) {
return;
}
jobEntity = {
userId,
projectId,
type:"siteCertMonitor",
title: '站点证书检查',
result:"start",
startAt:new Date().getTime(),
}
await this.jobHistoryService.add(jobEntity);
} }
const query:any = { disabled: false };
query.userId = userId;
if(projectId){
query.projectId = projectId;
}
const siteCount = await this.repository.count({
where: query,
});
if (siteCount === 0) {
logger.info(`用户/项目[${userId}_${projectId||""}]没有站点证书需要检查`)
return;
}
logger.info(`站点证书检查开始执行[${userId}_${projectId||""}]`);
let jobEntity :Partial<JobHistoryEntity> = null;
jobEntity = {
userId,
projectId,
type:"siteCertMonitor",
title: '站点证书检查',
result:"start",
startAt:new Date().getTime(),
}
await this.jobHistoryService.add(jobEntity);
let offset = 0; let offset = 0;
const limit = 50; const limit = 50;
let count = 0; let count = 0;
@@ -557,21 +561,18 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
break; break;
} }
offset += records.length; offset += records.length;
const isCommon = !userId;
count += records.length; count += records.length;
await this.checkList(records,isCommon); await this.checkList(records);
} }
logger.info(`站点证书检查完成[${userId??'所有用户'}_${projectId??'所有项目'}]`); logger.info(`站点证书检查完成[${userId}_${projectId||""}]`);
if(jobEntity){ await this.jobHistoryService.update({
await this.jobHistoryService.update({ id: jobEntity.id,
id: jobEntity.id, result: "done",
result: "done", content:`共检查${count}个站点`,
content:`共检查${count}个站点`, endAt:new Date().getTime(),
endAt:new Date().getTime(), updateTime:new Date(),
updateTime:new Date(), });
});
}
} }
async batchDelete(ids: number[], userId: number,projectId?:number): Promise<void> { async batchDelete(ids: number[], userId: number,projectId?:number): Promise<void> {
@@ -320,8 +320,6 @@ export class SiteIpService extends BaseService<SiteIpEntity> {
for (const item of list) { for (const item of list) {
await this.add(item); await this.add(item);
} }
// await this.checkAllByUsers(req.userId);
}; };
await batchAdd(list); await batchAdd(list);
} }
@@ -400,7 +400,15 @@ export class UserService extends BaseService<UserEntity> {
id: userId, id: userId,
...body, ...body,
}) })
}
async getAllUserIds() {
const users = await this.repository.find({
select: ['id'],
where: {
status: 1,
},
})
return users.map(item => item.id);
} }
} }
@@ -284,4 +284,14 @@ export class ProjectService extends BaseService<ProjectEntity> {
return project?.isSystem ?? false; return project?.isSystem ?? false;
} }
async getAllProjectIds() {
const projects = await this.repository.find({
select: ['id'],
where: {
disabled: false,
},
})
return projects.map(item => item.id);
}
} }
@@ -100,10 +100,8 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
helper: "将检查证书数量限制,如果超限将删除最旧的那张证书", helper: "将检查证书数量限制,如果超限将删除最旧的那张证书",
required: true required: true
}) })
certLimit: number = 2; certLimit: number = 2;
async onInstance() { async onInstance() {
} }
@@ -123,7 +121,7 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
certId = casCert.certId; certId = casCert.certId;
certName = casCert.certName; certName = casCert.certName;
} else if (certInfo.crt) { } else if (certInfo.crt) {
certName = this.buildCertName(CertReader.getMainDomain(certInfo.crt)); certName = this.buildCertName(CertReader.getMainDomain(certInfo.crt),"certd");
const certIdRes = await sslClient.uploadCertificate({ const certIdRes = await sslClient.uploadCertificate({
name: certName, name: certName,
@@ -58,6 +58,22 @@ export class OnePanelDeployToPanelPlugin extends AbstractTaskPlugin {
) )
currentNode!: string; currentNode!: string;
@TaskInput({
title: "SSL模式",
helper: "SSL模式,只有2.1.x以上版本才支持,旧版本保持默认即可",
component: {
name: "a-select",
vMode: "value",
options: [
{ label: "启用SSL(旧版本)", value: "enable" },
{ label: "Strict模式(>=2.1.x)", value: "Enable" },
{ label: "Mux模式(>=2.1.x)", value: "Mux" }
],
},
value: "enable",
required: true,
})
sslMode!: string;
access: OnePanelAccess; access: OnePanelAccess;
async onInstance() { async onInstance() {
@@ -102,7 +118,7 @@ export class OnePanelDeployToPanelPlugin extends AbstractTaskPlugin {
cert: this.cert.crt, cert: this.cert.crt,
key: this.cert.key, key: this.cert.key,
domain: domain, domain: domain,
ssl: "Enable", ssl: this.sslMode,
sslID: null, sslID: null,
sslType: "import-paste", sslType: "import-paste",
}, },