mirror of
https://github.com/certd/certd.git
synced 2026-04-14 12:30:54 +08:00
Compare commits
48 Commits
v1.36.6
...
v2-dev-ord
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69e6f2362e | ||
|
|
ab84835362 | ||
|
|
41ce8489dc | ||
|
|
edf089ec9e | ||
|
|
0ae9a3605c | ||
|
|
7f9c4e52ac | ||
|
|
35947f96a8 | ||
|
|
b0f91f1eea | ||
|
|
13dfca1749 | ||
|
|
9d9cd8a362 | ||
|
|
5e5c41fda5 | ||
|
|
3ebdc52b3e | ||
|
|
8656059151 | ||
|
|
a6d38f2458 | ||
|
|
085bdf5cfa | ||
|
|
6883bcacee | ||
|
|
2ecc6e0368 | ||
|
|
8fb5ca2fe1 | ||
|
|
e40345095f | ||
|
|
ffc0c7bb7b | ||
|
|
58fadc8928 | ||
|
|
d96a607c04 | ||
|
|
2ea2c8c05f | ||
|
|
b15f514018 | ||
|
|
05a33a0ec9 | ||
|
|
747d266742 | ||
|
|
6135a44a8d | ||
|
|
7c7d646792 | ||
|
|
4a36fd2ec3 | ||
|
|
b1bcc287cb | ||
|
|
6f5868a9d7 | ||
|
|
75863441f4 | ||
|
|
9763cb00e5 | ||
|
|
1921a64f4b | ||
|
|
6b73f5d555 | ||
|
|
e0408f30ba | ||
|
|
dca44fa093 | ||
|
|
bbacb76581 | ||
|
|
1da8617a53 | ||
|
|
e5967f7e9d | ||
|
|
65d84f9e9d | ||
|
|
93e9498b41 | ||
|
|
95332d5db9 | ||
|
|
9864792bbf | ||
|
|
ca9d1eed7a | ||
|
|
38e867c917 | ||
|
|
3ee1dbb8a5 | ||
|
|
b4571d5c98 |
39
CHANGELOG.md
39
CHANGELOG.md
@@ -3,6 +3,45 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 安全更新,备份数据库插件仅限管理员运行 ([13dfca1](https://github.com/certd/certd/commit/13dfca1749275526c82465a17c482b607c820fdd))
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 企业微信通知改成text类型,因为markdown类型不支持@用户 ([747d266](https://github.com/certd/certd/commit/747d26674248082e678a3fd5ecc94712641a2716))
|
||||||
|
* api接口获取不到证书的bug ([05a33a0](https://github.com/certd/certd/commit/05a33a0ec9999e2802f6c7b23cc1c61a2b9e963d))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 部署到阿里云oss插件支持选择上传到阿里云cas中的证书 ([2ea2c8c](https://github.com/certd/certd/commit/2ea2c8c05fc40f79595f1bbde67c1413558bf684))
|
||||||
|
* 优化子域名托管的说明 ([b15f514](https://github.com/certd/certd/commit/b15f514018b728acb0922ee3f93c1f302eb5d471))
|
||||||
|
* 账号即将过期通知 ([e403450](https://github.com/certd/certd/commit/e40345095f31e2fb8e2333a6647466659133fa0c))
|
||||||
|
* 子域名托管重复域名不允许添加 ([ffc0c7b](https://github.com/certd/certd/commit/ffc0c7bb7b16d9904fd2d905d1c4e1d4854e92a9))
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复ssh无法执行命令的bug ([9763cb0](https://github.com/certd/certd/commit/9763cb00e5d95b2fa5d1c2d3d4a8eecac71600e6))
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复流水线列表页报length错误的bug ([9864792](https://github.com/certd/certd/commit/9864792bbfd149e770d6e1ffa809573694f99dd3))
|
||||||
|
* 修复流水线页面状态没有刷新的bug ([93e9498](https://github.com/certd/certd/commit/93e9498b410353f504e11e264db62468895d7290))
|
||||||
|
* 修复自定义证书检查时间重启之后不生效的bug ([38e867c](https://github.com/certd/certd/commit/38e867c917bbc68bd228bdd8064f3e7358d6413d))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持上传证书到各种对象存储,oss、cos、七牛、s3、minio等 ([1da8617](https://github.com/certd/certd/commit/1da8617a53a675776635bbc3bcb3c6d7dff83e27))
|
||||||
|
* 支持邮箱发送证书 ([95332d5](https://github.com/certd/certd/commit/95332d5db96cd54ddab6ab737332417a09169b39))
|
||||||
|
|
||||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
10:51
|
12:27
|
||||||
|
|||||||
@@ -3,6 +3,60 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 安全更新,备份数据库插件仅限管理员运行 ([13dfca1](https://github.com/certd/certd/commit/13dfca1749275526c82465a17c482b607c820fdd))
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 企业微信通知改成text类型,因为markdown类型不支持@用户 ([747d266](https://github.com/certd/certd/commit/747d26674248082e678a3fd5ecc94712641a2716))
|
||||||
|
* api接口获取不到证书的bug ([05a33a0](https://github.com/certd/certd/commit/05a33a0ec9999e2802f6c7b23cc1c61a2b9e963d))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 部署到阿里云oss插件支持选择上传到阿里云cas中的证书 ([2ea2c8c](https://github.com/certd/certd/commit/2ea2c8c05fc40f79595f1bbde67c1413558bf684))
|
||||||
|
* 优化子域名托管的说明 ([b15f514](https://github.com/certd/certd/commit/b15f514018b728acb0922ee3f93c1f302eb5d471))
|
||||||
|
* 账号即将过期通知 ([e403450](https://github.com/certd/certd/commit/e40345095f31e2fb8e2333a6647466659133fa0c))
|
||||||
|
* 子域名托管重复域名不允许添加 ([ffc0c7b](https://github.com/certd/certd/commit/ffc0c7bb7b16d9904fd2d905d1c4e1d4854e92a9))
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复ssh无法执行命令的bug ([9763cb0](https://github.com/certd/certd/commit/9763cb00e5d95b2fa5d1c2d3d4a8eecac71600e6))
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复流水线列表页报length错误的bug ([9864792](https://github.com/certd/certd/commit/9864792bbfd149e770d6e1ffa809573694f99dd3))
|
||||||
|
* 修复流水线页面状态没有刷新的bug ([93e9498](https://github.com/certd/certd/commit/93e9498b410353f504e11e264db62468895d7290))
|
||||||
|
* 修复自定义证书检查时间重启之后不生效的bug ([38e867c](https://github.com/certd/certd/commit/38e867c917bbc68bd228bdd8064f3e7358d6413d))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持上传证书到各种对象存储,oss、cos、七牛、s3、minio等 ([1da8617](https://github.com/certd/certd/commit/1da8617a53a675776635bbc3bcb3c6d7dff83e27))
|
||||||
|
* 支持邮箱发送证书 ([95332d5](https://github.com/certd/certd/commit/95332d5db96cd54ddab6ab737332417a09169b39))
|
||||||
|
|
||||||
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复某些页面翻译不全显示错误的bug ([0b3158f](https://github.com/certd/certd/commit/0b3158fdd5fe5bb0a98c4e65715dbc3de2c38047))
|
||||||
|
* 修复运行流水线后会闪烁一下的bug ([dfc9362](https://github.com/certd/certd/commit/dfc9362084082ee535b898f23b2609c1d946a6fd))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 部署plesk证书,支持删除未使用的证书 ([902d246](https://github.com/certd/certd/commit/902d246d1a7473ad90f604028c4eb09c8c67d99c))
|
||||||
|
* 通知和定时器的删除按钮显示为红色更显眼 ([61ba83c](https://github.com/certd/certd/commit/61ba83c77546c3d505d081e19a3d68c127662bf1))
|
||||||
|
* 优化流水线列表页面、详情页面性能,精简返回数据 ([609ac9c](https://github.com/certd/certd/commit/609ac9c9a2dde605eb09834ae59693c1cb238765))
|
||||||
|
* 支持自动选择校验方式申请证书 ([3f99432](https://github.com/certd/certd/commit/3f9943270cfb12946e38e6272bc5e8d95ad6ab9e))
|
||||||
|
* OpenAPI支持autoApply参数 ([42f4d14](https://github.com/certd/certd/commit/42f4d1477dc791520a874aed56035abcbc8c433b))
|
||||||
|
|
||||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -9,5 +9,5 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npmClient": "pnpm",
|
"npmClient": "pnpm",
|
||||||
"version": "1.36.6"
|
"version": "1.36.11"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
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.36.11](https://github.com/publishlab/node-acme-client/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/publishlab/node-acme-client/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/publishlab/node-acme-client/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/publishlab/node-acme-client/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
## [1.36.6](https://github.com/publishlab/node-acme-client/compare/v1.36.5...v1.36.6) (2025-07-14)
|
## [1.36.6](https://github.com/publishlab/node-acme-client/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/acme-client
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|||||||
@@ -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.36.6",
|
"version": "1.36.11",
|
||||||
"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.36.6",
|
"@certd/basic": "^1.36.11",
|
||||||
"@peculiar/x509": "^1.11.0",
|
"@peculiar/x509": "^1.11.0",
|
||||||
"asn1js": "^3.0.5",
|
"asn1js": "^3.0.5",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
@@ -69,5 +69,5 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||||
},
|
},
|
||||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/basic
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
23:48
|
12:23
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/basic",
|
"name": "@certd/basic",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.36.6",
|
"version": "1.36.11",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -45,5 +45,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,26 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 安全更新,备份数据库插件仅限管理员运行 ([13dfca1](https://github.com/certd/certd/commit/13dfca1749275526c82465a17c482b607c820fdd))
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持邮箱发送证书 ([95332d5](https://github.com/certd/certd/commit/95332d5db96cd54ddab6ab737332417a09169b39))
|
||||||
|
|
||||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/pipeline
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/pipeline",
|
"name": "@certd/pipeline",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.36.6",
|
"version": "1.36.11",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
"pub": "npm publish"
|
"pub": "npm publish"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.36.6",
|
"@certd/basic": "^1.36.11",
|
||||||
"@certd/plus-core": "^1.36.6",
|
"@certd/plus-core": "^1.36.11",
|
||||||
"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"
|
||||||
@@ -44,5 +44,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -352,6 +352,7 @@ export class Executor {
|
|||||||
pipeline: this.pipeline,
|
pipeline: this.pipeline,
|
||||||
runtime: this.runtime,
|
runtime: this.runtime,
|
||||||
step,
|
step,
|
||||||
|
define: cloneDeep(define),
|
||||||
lastStatus,
|
lastStatus,
|
||||||
http,
|
http,
|
||||||
download,
|
download,
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ export type PluginDefine = Registrable & {
|
|||||||
form: any;
|
form: any;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
onlyAdmin?: boolean;
|
||||||
needPlus?: boolean;
|
needPlus?: boolean;
|
||||||
showRunStrategy?: boolean;
|
showRunStrategy?: boolean;
|
||||||
pluginType?: string; //类型
|
pluginType?: string; //类型
|
||||||
@@ -85,6 +86,7 @@ export type TaskInstanceContext = {
|
|||||||
runtime: RunHistory;
|
runtime: RunHistory;
|
||||||
//步骤定义
|
//步骤定义
|
||||||
step: Step;
|
step: Step;
|
||||||
|
define: PluginDefine;
|
||||||
//日志
|
//日志
|
||||||
logger: ILogger;
|
logger: ILogger;
|
||||||
//当前步骤输入参数跟上一次执行比较是否有变化
|
//当前步骤输入参数跟上一次执行比较是否有变化
|
||||||
@@ -162,6 +164,12 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
|||||||
this.registerSecret(cert.key);
|
this.registerSecret(cert.key);
|
||||||
this.registerSecret(cert.one);
|
this.registerSecret(cert.one);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.ctx.define.onlyAdmin) {
|
||||||
|
if (!this.isAdmin()) {
|
||||||
|
throw new Error("只有管理员才能运行此任务");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAccess<T = any>(accessId: string | number, isCommon = false) {
|
async getAccess<T = any>(accessId: string | number, isCommon = false) {
|
||||||
|
|||||||
@@ -30,4 +30,5 @@ export const pluginGroups = {
|
|||||||
qiniu: new PluginGroup("qiniu", "七牛云", 5, "svg:icon-qiniuyun"),
|
qiniu: new PluginGroup("qiniu", "七牛云", 5, "svg:icon-qiniuyun"),
|
||||||
aws: new PluginGroup("aws", "亚马逊云", 6, "svg:icon-aws"),
|
aws: new PluginGroup("aws", "亚马逊云", 6, "svg:icon-aws"),
|
||||||
other: new PluginGroup("other", "其他", 10, "clarity:plugin-line"),
|
other: new PluginGroup("other", "其他", 10, "clarity:plugin-line"),
|
||||||
|
admin: new PluginGroup("admin", "管理", 11, "ion:settings-outline"),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
export type EmailSend = {
|
export type EmailSend = {
|
||||||
subject: string;
|
subject: string;
|
||||||
content: string;
|
|
||||||
receivers: string[];
|
receivers: string[];
|
||||||
|
content?: string;
|
||||||
|
attachments?: any[];
|
||||||
|
html?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IEmailService {
|
export interface IEmailService {
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-huawei
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-huawei",
|
"name": "@certd/lib-huawei",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.36.6",
|
"version": "1.36.11",
|
||||||
"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",
|
||||||
@@ -24,5 +24,5 @@
|
|||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
"tslib": "^2.8.1"
|
"tslib": "^2.8.1"
|
||||||
},
|
},
|
||||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-iframe
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-iframe",
|
"name": "@certd/lib-iframe",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.36.6",
|
"version": "1.36.11",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -31,5 +31,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/jdcloud
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/jdcloud",
|
"name": "@certd/jdcloud",
|
||||||
"version": "1.36.6",
|
"version": "1.36.11",
|
||||||
"description": "jdcloud openApi sdk",
|
"description": "jdcloud openApi sdk",
|
||||||
"main": "./dist/bundle.js",
|
"main": "./dist/bundle.js",
|
||||||
"module": "./dist/bundle.js",
|
"module": "./dist/bundle.js",
|
||||||
@@ -61,5 +61,5 @@
|
|||||||
"fetch"
|
"fetch"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-k8s
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-k8s",
|
"name": "@certd/lib-k8s",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.36.6",
|
"version": "1.36.11",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
"pub": "npm publish"
|
"pub": "npm publish"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.36.6",
|
"@certd/basic": "^1.36.11",
|
||||||
"@kubernetes/client-node": "0.21.0"
|
"@kubernetes/client-node": "0.21.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -32,5 +32,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
export * from './lib/k8s.client.js';
|
export * from "./lib/k8s.client.js";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { CoreV1Api, KubeConfig, NetworkingV1Api, V1Ingress, V1Secret } from '@kubernetes/client-node';
|
import { CoreV1Api, KubeConfig, NetworkingV1Api, V1Ingress, V1Secret } from "@kubernetes/client-node";
|
||||||
import dns from 'dns';
|
import dns from "dns";
|
||||||
import { ILogger } from '@certd/basic';
|
import { ILogger } from "@certd/basic";
|
||||||
import _ from 'lodash-es';
|
import _ from "lodash-es";
|
||||||
|
|
||||||
export type K8sClientOpts = {
|
export type K8sClientOpts = {
|
||||||
kubeConfigStr: string;
|
kubeConfigStr: string;
|
||||||
@@ -9,6 +9,7 @@ export type K8sClientOpts = {
|
|||||||
//{ [domain]:{ip:'xxx.xx.xxx'} }
|
//{ [domain]:{ip:'xxx.xx.xxx'} }
|
||||||
//暂时没用
|
//暂时没用
|
||||||
lookup?: any;
|
lookup?: any;
|
||||||
|
skipTLSVerify?: boolean;
|
||||||
};
|
};
|
||||||
export class K8sClient {
|
export class K8sClient {
|
||||||
kubeconfig!: KubeConfig;
|
kubeconfig!: KubeConfig;
|
||||||
@@ -16,10 +17,12 @@ export class K8sClient {
|
|||||||
lookup!: (hostnameReq: any, options: any, callback: any) => void;
|
lookup!: (hostnameReq: any, options: any, callback: any) => void;
|
||||||
client!: CoreV1Api;
|
client!: CoreV1Api;
|
||||||
logger: ILogger;
|
logger: ILogger;
|
||||||
|
skipTLSVerify?: boolean;
|
||||||
constructor(opts: K8sClientOpts) {
|
constructor(opts: K8sClientOpts) {
|
||||||
this.kubeConfigStr = opts.kubeConfigStr;
|
this.kubeConfigStr = opts.kubeConfigStr;
|
||||||
this.logger = opts.logger;
|
this.logger = opts.logger;
|
||||||
this.setLookup(opts.lookup);
|
this.setLookup(opts.lookup);
|
||||||
|
this.skipTLSVerify = opts.skipTLSVerify;
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,6 +30,18 @@ export class K8sClient {
|
|||||||
const kubeconfig = new KubeConfig();
|
const kubeconfig = new KubeConfig();
|
||||||
kubeconfig.loadFromString(this.kubeConfigStr);
|
kubeconfig.loadFromString(this.kubeConfigStr);
|
||||||
this.kubeconfig = kubeconfig;
|
this.kubeconfig = kubeconfig;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (this.skipTLSVerify == true) {
|
||||||
|
for (const cluster of kubeconfig.getClusters()) {
|
||||||
|
// @ts-ignore
|
||||||
|
cluster["skipTLSVerify"] = this.skipTLSVerify;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.warn("skipTLSVerify error", e);
|
||||||
|
}
|
||||||
|
|
||||||
this.client = kubeconfig.makeApiClient(CoreV1Api);
|
this.client = kubeconfig.makeApiClient(CoreV1Api);
|
||||||
|
|
||||||
// const reqOpts = { kubeconfig, request: {} } as any;
|
// const reqOpts = { kubeconfig, request: {} } as any;
|
||||||
@@ -47,9 +62,9 @@ export class K8sClient {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.lookup = (hostnameReq: any, options: any, callback: any) => {
|
this.lookup = (hostnameReq: any, options: any, callback: any) => {
|
||||||
this.logger.info('custom lookup', hostnameReq, localRecords);
|
this.logger.info("custom lookup", hostnameReq, localRecords);
|
||||||
if (localRecords[hostnameReq]) {
|
if (localRecords[hostnameReq]) {
|
||||||
this.logger.info('local record', hostnameReq, localRecords[hostnameReq]);
|
this.logger.info("local record", hostnameReq, localRecords[hostnameReq]);
|
||||||
callback(null, localRecords[hostnameReq].ip, 4);
|
callback(null, localRecords[hostnameReq].ip, 4);
|
||||||
} else {
|
} else {
|
||||||
dns.lookup(hostnameReq, options, callback);
|
dns.lookup(hostnameReq, options, callback);
|
||||||
@@ -63,7 +78,7 @@ export class K8sClient {
|
|||||||
* @returns secretsList
|
* @returns secretsList
|
||||||
*/
|
*/
|
||||||
async getSecrets(opts: { namespace: string }) {
|
async getSecrets(opts: { namespace: string }) {
|
||||||
const namespace = opts.namespace || 'default';
|
const namespace = opts.namespace || "default";
|
||||||
return await this.client.listNamespacedSecret(namespace);
|
return await this.client.listNamespacedSecret(namespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,9 +88,9 @@ export class K8sClient {
|
|||||||
* @returns {Promise<*>}
|
* @returns {Promise<*>}
|
||||||
*/
|
*/
|
||||||
async createSecret(opts: { namespace: string; body: V1Secret }) {
|
async createSecret(opts: { namespace: string; body: V1Secret }) {
|
||||||
const namespace = opts.namespace || 'default';
|
const namespace = opts.namespace || "default";
|
||||||
const created = await this.client.createNamespacedSecret(namespace, opts.body);
|
const created = await this.client.createNamespacedSecret(namespace, opts.body);
|
||||||
this.logger.info('new secrets:', opts.body);
|
this.logger.info("new secrets:", opts.body);
|
||||||
return created.body;
|
return created.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,24 +104,24 @@ export class K8sClient {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
async patchSecret(opts: { namespace: string; secretName: string; body: V1Secret }) {
|
async patchSecret(opts: { namespace: string; secretName: string; body: V1Secret }) {
|
||||||
const namespace = opts.namespace || 'default';
|
const namespace = opts.namespace || "default";
|
||||||
const secretName = opts.secretName;
|
const secretName = opts.secretName;
|
||||||
if (secretName == null) {
|
if (secretName == null) {
|
||||||
throw new Error('secretName 不能为空');
|
throw new Error("secretName 不能为空");
|
||||||
}
|
}
|
||||||
this.logger.info('patch secret:', secretName, namespace);
|
this.logger.info("patch secret:", secretName, namespace);
|
||||||
const oldSecret = await this.client.readNamespacedSecret(secretName, namespace);
|
const oldSecret = await this.client.readNamespacedSecret(secretName, namespace);
|
||||||
const newSecret = _.merge(oldSecret.body, opts.body);
|
const newSecret = _.merge(oldSecret.body, opts.body);
|
||||||
const res = await this.client.replaceNamespacedSecret(secretName, namespace, newSecret);
|
const res = await this.client.replaceNamespacedSecret(secretName, namespace, newSecret);
|
||||||
this.logger.info('secret updated');
|
this.logger.info("secret updated");
|
||||||
return res.body;
|
return res.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getIngressList(opts: { namespace: string }) {
|
async getIngressList(opts: { namespace: string }) {
|
||||||
const namespace = opts.namespace || 'default';
|
const namespace = opts.namespace || "default";
|
||||||
const client = this.kubeconfig.makeApiClient(NetworkingV1Api);
|
const client = this.kubeconfig.makeApiClient(NetworkingV1Api);
|
||||||
const res = await client.listNamespacedIngress(namespace);
|
const res = await client.listNamespacedIngress(namespace);
|
||||||
this.logger.info('ingress list get:', res.body);
|
this.logger.info("ingress list get:", res.body);
|
||||||
return res.body;
|
return res.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,17 +137,17 @@ export class K8sClient {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
async patchIngress(opts: { namespace: string; ingressName: string; body: V1Ingress }) {
|
async patchIngress(opts: { namespace: string; ingressName: string; body: V1Ingress }) {
|
||||||
const namespace = opts.namespace || 'default';
|
const namespace = opts.namespace || "default";
|
||||||
const ingressName = opts.ingressName;
|
const ingressName = opts.ingressName;
|
||||||
if (!ingressName) {
|
if (!ingressName) {
|
||||||
throw new Error('ingressName 不能为空');
|
throw new Error("ingressName 不能为空");
|
||||||
}
|
}
|
||||||
this.logger.info('patch ingress:', ingressName, namespace);
|
this.logger.info("patch ingress:", ingressName, namespace);
|
||||||
const client = this.kubeconfig.makeApiClient(NetworkingV1Api);
|
const client = this.kubeconfig.makeApiClient(NetworkingV1Api);
|
||||||
const oldIngress = await client.readNamespacedIngress(ingressName, namespace);
|
const oldIngress = await client.readNamespacedIngress(ingressName, namespace);
|
||||||
const newIngress = _.merge(oldIngress.body, opts.body);
|
const newIngress = _.merge(oldIngress.body, opts.body);
|
||||||
const res = await client.replaceNamespacedIngress(ingressName, namespace, newIngress);
|
const res = await client.replaceNamespacedIngress(ingressName, namespace, newIngress);
|
||||||
this.logger.info('ingress patched', opts.body);
|
this.logger.info("ingress patched", opts.body);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-server",
|
"name": "@certd/lib-server",
|
||||||
"version": "1.36.6",
|
"version": "1.36.11",
|
||||||
"description": "midway with flyway, sql upgrade way ",
|
"description": "midway with flyway, sql upgrade way ",
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -27,10 +27,10 @@
|
|||||||
],
|
],
|
||||||
"license": "AGPL",
|
"license": "AGPL",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/acme-client": "^1.36.6",
|
"@certd/acme-client": "^1.36.11",
|
||||||
"@certd/basic": "^1.36.6",
|
"@certd/basic": "^1.36.11",
|
||||||
"@certd/pipeline": "^1.36.6",
|
"@certd/pipeline": "^1.36.11",
|
||||||
"@certd/plus-core": "^1.36.6",
|
"@certd/plus-core": "^1.36.11",
|
||||||
"@midwayjs/cache": "~3.14.0",
|
"@midwayjs/cache": "~3.14.0",
|
||||||
"@midwayjs/core": "~3.20.3",
|
"@midwayjs/core": "~3.20.3",
|
||||||
"@midwayjs/i18n": "~3.20.3",
|
"@midwayjs/i18n": "~3.20.3",
|
||||||
@@ -61,5 +61,5 @@
|
|||||||
"typeorm": "^0.3.11",
|
"typeorm": "^0.3.11",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/midway-flyway-js",
|
"name": "@certd/midway-flyway-js",
|
||||||
"version": "1.36.6",
|
"version": "1.36.11",
|
||||||
"description": "midway with flyway, sql upgrade way ",
|
"description": "midway with flyway, sql upgrade way ",
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -46,5 +46,5 @@
|
|||||||
"typeorm": "^0.3.11",
|
"typeorm": "^0.3.11",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,24 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持邮箱发送证书 ([95332d5](https://github.com/certd/certd/commit/95332d5db96cd54ddab6ab737332417a09169b39))
|
||||||
|
|
||||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/plugin-cert",
|
"name": "@certd/plugin-cert",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.36.6",
|
"version": "1.36.11",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -16,10 +16,10 @@
|
|||||||
"pub": "npm publish"
|
"pub": "npm publish"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/acme-client": "^1.36.6",
|
"@certd/acme-client": "^1.36.11",
|
||||||
"@certd/basic": "^1.36.6",
|
"@certd/basic": "^1.36.11",
|
||||||
"@certd/pipeline": "^1.36.6",
|
"@certd/pipeline": "^1.36.11",
|
||||||
"@certd/plugin-lib": "^1.36.6",
|
"@certd/plugin-lib": "^1.36.11",
|
||||||
"@google-cloud/publicca": "^1.3.0",
|
"@google-cloud/publicca": "^1.3.0",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
@@ -43,5 +43,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { AbstractTaskPlugin, IContext, Step, TaskInput, TaskOutput } from "@certd/pipeline";
|
import { AbstractTaskPlugin, FileItem, IContext, Step, TaskInput, TaskOutput } from "@certd/pipeline";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import type { CertInfo } from "./acme.js";
|
import type { CertInfo } from "./acme.js";
|
||||||
import { CertReader } from "./cert-reader.js";
|
import { CertReader } from "./cert-reader.js";
|
||||||
@@ -71,6 +71,12 @@ export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
|
|||||||
})
|
})
|
||||||
cert?: CertInfo;
|
cert?: CertInfo;
|
||||||
|
|
||||||
|
@TaskOutput({
|
||||||
|
title: "域名证书压缩文件",
|
||||||
|
type: "certZip",
|
||||||
|
})
|
||||||
|
certZip?: FileItem;
|
||||||
|
|
||||||
async onInstance() {
|
async onInstance() {
|
||||||
this.userContext = this.ctx.userContext;
|
this.userContext = this.ctx.userContext;
|
||||||
this.lastStatus = this.ctx.lastStatus as Step;
|
this.lastStatus = this.ctx.lastStatus as Step;
|
||||||
@@ -131,6 +137,7 @@ export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
|
|||||||
} else {
|
} else {
|
||||||
this.extendsFiles();
|
this.extendsFiles();
|
||||||
}
|
}
|
||||||
|
this.certZip = this._result.files[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
async zipCert(cert: CertInfo, filename: string) {
|
async zipCert(cert: CertInfo, filename: string) {
|
||||||
|
|||||||
@@ -3,6 +3,26 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复ssh无法执行命令的bug ([9763cb0](https://github.com/certd/certd/commit/9763cb00e5d95b2fa5d1c2d3d4a8eecac71600e6))
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复流水线页面状态没有刷新的bug ([93e9498](https://github.com/certd/certd/commit/93e9498b410353f504e11e264db62468895d7290))
|
||||||
|
|
||||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/plugin-lib
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/plugin-lib",
|
"name": "@certd/plugin-lib",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.36.6",
|
"version": "1.36.11",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
"@alicloud/pop-core": "^1.7.10",
|
"@alicloud/pop-core": "^1.7.10",
|
||||||
"@alicloud/tea-util": "^1.4.10",
|
"@alicloud/tea-util": "^1.4.10",
|
||||||
"@aws-sdk/client-s3": "^3.787.0",
|
"@aws-sdk/client-s3": "^3.787.0",
|
||||||
"@certd/basic": "^1.36.6",
|
"@certd/basic": "^1.36.11",
|
||||||
"@certd/pipeline": "^1.36.6",
|
"@certd/pipeline": "^1.36.11",
|
||||||
"@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",
|
||||||
@@ -53,5 +53,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ export default class SshOssClientImpl extends BaseOssClient<SshAccess> {
|
|||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
}
|
}
|
||||||
async upload(filePath: string, fileContent: Buffer) {
|
async upload(filePath: string, fileContent: Buffer) {
|
||||||
|
if (!filePath) {
|
||||||
|
filePath = "";
|
||||||
|
}
|
||||||
|
filePath = filePath.trim();
|
||||||
const tmpFilePath = path.join(os.tmpdir(), "cert", "http", filePath);
|
const tmpFilePath = path.join(os.tmpdir(), "cert", "http", filePath);
|
||||||
|
|
||||||
// Write file to temp path
|
// Write file to temp path
|
||||||
|
|||||||
@@ -506,10 +506,6 @@ export class SshClient {
|
|||||||
isWinCmd = await this.isCmd(conn);
|
isWinCmd = await this.isCmd(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLinux && options.stopOnError !== false) {
|
|
||||||
script = "set -e\n" + script;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.env) {
|
if (options.env) {
|
||||||
for (const key in options.env) {
|
for (const key in options.env) {
|
||||||
if (isLinux) {
|
if (isLinux) {
|
||||||
@@ -525,10 +521,10 @@ export class SshClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isWinCmd) {
|
if (isWinCmd) {
|
||||||
//组合成&&的形式
|
|
||||||
if (typeof script === "string") {
|
if (typeof script === "string") {
|
||||||
script = script.split("\n");
|
script = script.split("\n");
|
||||||
}
|
}
|
||||||
|
//组合成&&的形式
|
||||||
script = envScripts.concat(script);
|
script = envScripts.concat(script);
|
||||||
script = script as Array<string>;
|
script = script as Array<string>;
|
||||||
script = script.join(" && ");
|
script = script.join(" && ");
|
||||||
@@ -543,6 +539,10 @@ export class SshClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isLinux && options.stopOnError !== false) {
|
||||||
|
script = "set -e\n" + script;
|
||||||
|
}
|
||||||
|
|
||||||
return await conn.exec(script as string, { throwOnStdErr });
|
return await conn.exec(script as string, { throwOnStdErr });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
1
packages/ui/certd-client/.gitignore
vendored
1
packages/ui/certd-client/.gitignore
vendored
@@ -9,3 +9,4 @@ yarn.lock
|
|||||||
/.idea/
|
/.idea/
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
vite-profile.cpuprofile
|
vite-profile.cpuprofile
|
||||||
|
!build
|
||||||
@@ -3,6 +3,28 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/ui-client
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化子域名托管的说明 ([b15f514](https://github.com/certd/certd/commit/b15f514018b728acb0922ee3f93c1f302eb5d471))
|
||||||
|
* 账号即将过期通知 ([e403450](https://github.com/certd/certd/commit/e40345095f31e2fb8e2333a6647466659133fa0c))
|
||||||
|
* 子域名托管重复域名不允许添加 ([ffc0c7b](https://github.com/certd/certd/commit/ffc0c7bb7b16d9904fd2d905d1c4e1d4854e92a9))
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/ui-client
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复流水线页面状态没有刷新的bug ([93e9498](https://github.com/certd/certd/commit/93e9498b410353f504e11e264db62468895d7290))
|
||||||
|
|
||||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/ui-client",
|
"name": "@certd/ui-client",
|
||||||
"version": "1.36.6",
|
"version": "1.36.11",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --open",
|
"dev": "vite --open",
|
||||||
@@ -103,8 +103,8 @@
|
|||||||
"zod-defaults": "^0.1.3"
|
"zod-defaults": "^0.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@certd/lib-iframe": "^1.36.6",
|
"@certd/lib-iframe": "^1.36.11",
|
||||||
"@certd/pipeline": "^1.36.6",
|
"@certd/pipeline": "^1.36.11",
|
||||||
"@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",
|
||||||
|
|||||||
@@ -280,6 +280,10 @@ function openUpgrade() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const productListUrl = computed(() => {
|
||||||
|
return `http://localhost:1017/subject/#/product/list?appKey=${settingStore.installInfo.appKey}&subjectId=${settingStore.installInfo.siteId}`;
|
||||||
|
});
|
||||||
|
|
||||||
const modalRef = modal.confirm({
|
const modalRef = modal.confirm({
|
||||||
title,
|
title,
|
||||||
async onOk() {
|
async onOk() {
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ export default {
|
|||||||
runCount: "Run Count",
|
runCount: "Run Count",
|
||||||
expiringCerts: "Soon-to-Expire Certificates",
|
expiringCerts: "Soon-to-Expire Certificates",
|
||||||
supportedTasks: "Overview of Supported Deployment Tasks",
|
supportedTasks: "Overview of Supported Deployment Tasks",
|
||||||
|
changeLog: "Change Log",
|
||||||
},
|
},
|
||||||
steps: {
|
steps: {
|
||||||
createPipeline: "Create Certificate Pipeline",
|
createPipeline: "Create Certificate Pipeline",
|
||||||
@@ -449,7 +450,7 @@ export default {
|
|||||||
batchDeleteConfirm: "Are you sure to batch delete these {count} records?",
|
batchDeleteConfirm: "Are you sure to batch delete these {count} records?",
|
||||||
selectRecordFirst: "Please select records first",
|
selectRecordFirst: "Please select records first",
|
||||||
subdomainHosted: "Hosted Subdomain",
|
subdomainHosted: "Hosted Subdomain",
|
||||||
subdomainHelpText: "If you don't understand what subdomain hosting is, please refer to the documentation ",
|
subdomainHelpText: "If you don't understand what subdomain hosting is,Do not set it randomly, as it may result in the inability to apply for the certificate. please refer to the documentation ",
|
||||||
subdomainManagement: "Subdomain Management",
|
subdomainManagement: "Subdomain Management",
|
||||||
isDisabled: "Is Disabled",
|
isDisabled: "Is Disabled",
|
||||||
enabled: "Enabled",
|
enabled: "Enabled",
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ export default {
|
|||||||
runCount: "运行次数",
|
runCount: "运行次数",
|
||||||
expiringCerts: "最快到期证书",
|
expiringCerts: "最快到期证书",
|
||||||
supportedTasks: "已支持的部署任务总览",
|
supportedTasks: "已支持的部署任务总览",
|
||||||
|
changeLog: "更新日志",
|
||||||
},
|
},
|
||||||
steps: {
|
steps: {
|
||||||
createPipeline: "创建证书流水线",
|
createPipeline: "创建证书流水线",
|
||||||
@@ -415,7 +416,7 @@ export default {
|
|||||||
is_present_no: "否",
|
is_present_no: "否",
|
||||||
basicInfo: "基础信息",
|
basicInfo: "基础信息",
|
||||||
titlea: "名称",
|
titlea: "名称",
|
||||||
disabled: "是否禁用",
|
disabled: "禁用",
|
||||||
ordera: "排序",
|
ordera: "排序",
|
||||||
supportBuy: "支持购买",
|
supportBuy: "支持购买",
|
||||||
intro: "介绍",
|
intro: "介绍",
|
||||||
@@ -455,7 +456,7 @@ export default {
|
|||||||
batchDeleteConfirm: "确定要批量删除这{count}条记录吗",
|
batchDeleteConfirm: "确定要批量删除这{count}条记录吗",
|
||||||
selectRecordFirst: "请先勾选记录",
|
selectRecordFirst: "请先勾选记录",
|
||||||
subdomainHosted: "托管的子域名",
|
subdomainHosted: "托管的子域名",
|
||||||
subdomainHelpText: "如果您不理解什么是子域托管,可以参考文档",
|
subdomainHelpText: "如果您不理解什么是子域托管,请不要随意设置,可能导致证书无法申请,可以参考文档",
|
||||||
subdomainManagement: "子域管理",
|
subdomainManagement: "子域管理",
|
||||||
isDisabled: "是否禁用",
|
isDisabled: "是否禁用",
|
||||||
enabled: "启用",
|
enabled: "启用",
|
||||||
|
|||||||
@@ -112,7 +112,8 @@ function menuIcon(menu: MenuRecordRaw) {
|
|||||||
|
|
||||||
.vben-normal-menu__name,
|
.vben-normal-menu__name,
|
||||||
.vben-normal-menu__icon {
|
.vben-normal-menu__icon {
|
||||||
@apply text-primary-foreground font-semibold;
|
//@apply text-primary-foreground font-semibold;
|
||||||
|
@apply font-semibold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,43 +26,45 @@
|
|||||||
</template>
|
</template>
|
||||||
<div class="flex-col h-100 w-100 overflow-hidden">
|
<div class="flex-col h-100 w-100 overflow-hidden">
|
||||||
<a-tabs v-model:active-key="pluginGroupActive" tab-position="left" class="flex-1 overflow-hidden">
|
<a-tabs v-model:active-key="pluginGroupActive" tab-position="left" class="flex-1 overflow-hidden">
|
||||||
<a-tab-pane v-for="group of computedPluginGroups" :key="group.key" class="scroll-y">
|
<template v-for="group of computedPluginGroups" :key="group.key">
|
||||||
<template #tab>
|
<a-tab-pane v-if="(group.key === 'admin' && userStore.isAdmin) || group.key !== 'admin'" :key="group.key" class="scroll-y">
|
||||||
<div class="cd-step-form-tab-label">
|
<template #tab>
|
||||||
<fs-icon :icon="group.icon" class="mr-2" />
|
<div class="cd-step-form-tab-label">
|
||||||
<div>{{ group.title }}</div>
|
<fs-icon :icon="group.icon" class="mr-2" />
|
||||||
</div>
|
<div>{{ group.title }}</div>
|
||||||
</template>
|
</div>
|
||||||
<a-row v-if="!group.plugins || group.plugins.length === 0" :gutter="10">
|
</template>
|
||||||
<a-col class="flex-o">
|
<a-row v-if="!group.plugins || group.plugins.length === 0" :gutter="10">
|
||||||
<div class="flex-o m-10">没有找到插件</div>
|
<a-col class="flex-o">
|
||||||
</a-col>
|
<div class="flex-o m-10">没有找到插件</div>
|
||||||
</a-row>
|
</a-col>
|
||||||
<a-row v-else :gutter="10">
|
</a-row>
|
||||||
<a-col v-for="item of group.plugins" :key="item.key" class="step-plugin w-full md:w-[50%]">
|
<a-row v-else :gutter="10">
|
||||||
<a-card
|
<a-col v-for="item of group.plugins" :key="item.key" class="step-plugin w-full md:w-[50%]">
|
||||||
hoverable
|
<a-card
|
||||||
:class="{ current: item.name === currentStep.type }"
|
hoverable
|
||||||
@click="stepTypeSelected(item)"
|
:class="{ current: item.name === currentStep.type }"
|
||||||
@dblclick="
|
@click="stepTypeSelected(item)"
|
||||||
stepTypeSelected(item);
|
@dblclick="
|
||||||
stepTypeSave();
|
stepTypeSelected(item);
|
||||||
"
|
stepTypeSave();
|
||||||
>
|
"
|
||||||
<a-card-meta>
|
>
|
||||||
<template #title>
|
<a-card-meta>
|
||||||
<fs-icon class="plugin-icon" :icon="item.icon || 'clarity:plugin-line'"></fs-icon>
|
<template #title>
|
||||||
<span class="title" :title="item.title">{{ item.title }}</span>
|
<fs-icon class="plugin-icon" :icon="item.icon || 'clarity:plugin-line'"></fs-icon>
|
||||||
<vip-button v-if="item.needPlus" mode="icon" />
|
<span class="title" :title="item.title">{{ item.title }}</span>
|
||||||
</template>
|
<vip-button v-if="item.needPlus" mode="icon" />
|
||||||
<template #description>
|
</template>
|
||||||
<span :title="item.desc" v-html="transformDesc(item.desc)"></span>
|
<template #description>
|
||||||
</template>
|
<span :title="item.desc" v-html="transformDesc(item.desc)"></span>
|
||||||
</a-card-meta>
|
</template>
|
||||||
</a-card>
|
</a-card-meta>
|
||||||
</a-col>
|
</a-card>
|
||||||
</a-row>
|
</a-col>
|
||||||
</a-tab-pane>
|
</a-row>
|
||||||
|
</a-tab-pane>
|
||||||
|
</template>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -124,6 +126,7 @@ import { useReference } from "/@/use/use-refrence";
|
|||||||
import { useSettingStore } from "/@/store/settings";
|
import { useSettingStore } from "/@/store/settings";
|
||||||
import { mitter } from "/@/utils/util.mitt";
|
import { mitter } from "/@/utils/util.mitt";
|
||||||
import { utils } from "/@/utils";
|
import { utils } from "/@/utils";
|
||||||
|
import { useUserStore } from "/@/store/user";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "PiStepForm",
|
name: "PiStepForm",
|
||||||
@@ -138,7 +141,7 @@ const props = defineProps({
|
|||||||
const emit = defineEmits(["update"]);
|
const emit = defineEmits(["update"]);
|
||||||
|
|
||||||
const pluginStore = usePluginStore();
|
const pluginStore = usePluginStore();
|
||||||
|
const userStore = useUserStore();
|
||||||
function transformDesc(desc: string = "") {
|
function transformDesc(desc: string = "") {
|
||||||
return utils.transformLink(desc);
|
return utils.transformLink(desc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -374,6 +374,7 @@ export default defineComponent({
|
|||||||
const detail: RunHistory = await props.options?.getHistoryDetail({ historyId: currentHistory.value.id });
|
const detail: RunHistory = await props.options?.getHistoryDetail({ historyId: currentHistory.value.id });
|
||||||
currentHistory.value.logs = detail.logs;
|
currentHistory.value.logs = detail.logs;
|
||||||
currentHistory.value.pipeline = detail.pipeline;
|
currentHistory.value.pipeline = detail.pipeline;
|
||||||
|
currentHistory.value.status = detail.pipeline.status.result;
|
||||||
};
|
};
|
||||||
const changeCurrentHistory = async (history?: RunHistory) => {
|
const changeCurrentHistory = async (history?: RunHistory) => {
|
||||||
if (!history) {
|
if (!history) {
|
||||||
@@ -385,7 +386,7 @@ export default defineComponent({
|
|||||||
currentHistory.value = history;
|
currentHistory.value = history;
|
||||||
await loadCurrentHistoryDetail();
|
await loadCurrentHistoryDetail();
|
||||||
pipeline.value = currentHistory.value.pipeline;
|
pipeline.value = currentHistory.value.pipeline;
|
||||||
currentPipeline.value = cloneDeep(pipeline.value);
|
currentPipeline.value = currentHistory.value.pipeline;
|
||||||
};
|
};
|
||||||
|
|
||||||
async function loadHistoryList(reload = false) {
|
async function loadHistoryList(reload = false) {
|
||||||
@@ -439,8 +440,13 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (currentHistory.value != null) {
|
if (currentHistory.value != null) {
|
||||||
if (currentHistory.value.pipeline?.status?.status === "start") {
|
if (currentHistory.value.status === "start") {
|
||||||
await loadCurrentHistoryDetail();
|
await loadCurrentHistoryDetail();
|
||||||
|
pipeline.value = currentHistory.value.pipeline;
|
||||||
|
// if (currentHistory.value.pipeline?.status?.status !== "start") {
|
||||||
|
// 不传true好像不会刷新
|
||||||
|
// await loadHistoryList(true);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -3,7 +3,12 @@
|
|||||||
<template #header>
|
<template #header>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{ t("certd.subdomainHosting") }}
|
{{ t("certd.subdomainHosting") }}
|
||||||
<span class="sub">{{ t("certd.subdomainHostingHint") }}</span>
|
<span class="sub">
|
||||||
|
{{ t("certd.subdomainHostingHint") }}; {{ t("certd.subdomainHelpText") }}
|
||||||
|
<a href="https://help.aliyun.com/zh/dns/subdomain-management" target="_blank">
|
||||||
|
{{ t("certd.subdomainManagement") }}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<fs-crud ref="crudRef" v-bind="crudBinding">
|
<fs-crud ref="crudRef" v-bind="crudBinding">
|
||||||
|
|||||||
@@ -29,6 +29,10 @@
|
|||||||
</a-tag>
|
</a-tag>
|
||||||
</a-badge>
|
</a-badge>
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
|
<a-tag color="blue" class="flex-inline pointer mr-0" @click="openChangeLogUrl()">
|
||||||
|
{{ t("certd.dashboard.changeLog") }}
|
||||||
|
</a-tag>
|
||||||
|
<a-divider type="vertical" />
|
||||||
<vip-button mode="nav" style="font-size: 12px"></vip-button>
|
<vip-button mode="nav" style="font-size: 12px"></vip-button>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="settingsStore.isComm">
|
<template v-if="settingsStore.isComm">
|
||||||
@@ -255,6 +259,9 @@ onMounted(async () => {
|
|||||||
function openUpgradeUrl() {
|
function openUpgradeUrl() {
|
||||||
window.open("https://certd.docmirror.cn/guide/install/upgrade.html");
|
window.open("https://certd.docmirror.cn/guide/install/upgrade.html");
|
||||||
}
|
}
|
||||||
|
function openChangeLogUrl() {
|
||||||
|
window.open("https://certd.docmirror.cn/guide/changelogs/CHANGELOG.html");
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import * as api from "./api";
|
import * as api from "./api";
|
||||||
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
import { useUserStore } from "/@/store/user";
|
import { useUserStore } from "/@/store/user";
|
||||||
import { Modal, notification } from "ant-design-vue";
|
import { Modal, notification } from "ant-design-vue";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { useSettingStore } from "/@/store/settings";
|
import { useSettingStore } from "/@/store/settings";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
|
import { computed } from "vue";
|
||||||
|
|
||||||
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@@ -26,7 +27,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
|
|||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
const settingStore = useSettingStore();
|
const settingStore = useSettingStore();
|
||||||
const userValidTimeEnabled = compute(() => {
|
const userValidTimeEnabled = computed(() => {
|
||||||
return settingStore.sysPublic.userValidTimeEnabled === true;
|
return settingStore.sysPublic.userValidTimeEnabled === true;
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
@@ -226,7 +227,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
|
|||||||
column: {
|
column: {
|
||||||
align: "center",
|
align: "center",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
width: 100,
|
width: 160,
|
||||||
show: userValidTimeEnabled,
|
show: userValidTimeEnabled,
|
||||||
cellRender({ value }) {
|
cellRender({ value }) {
|
||||||
if (value == null || value === 0) {
|
if (value == null || value === 0) {
|
||||||
|
|||||||
@@ -3,6 +3,42 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 安全更新,备份数据库插件仅限管理员运行 ([13dfca1](https://github.com/certd/certd/commit/13dfca1749275526c82465a17c482b607c820fdd))
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 企业微信通知改成text类型,因为markdown类型不支持@用户 ([747d266](https://github.com/certd/certd/commit/747d26674248082e678a3fd5ecc94712641a2716))
|
||||||
|
* api接口获取不到证书的bug ([05a33a0](https://github.com/certd/certd/commit/05a33a0ec9999e2802f6c7b23cc1c61a2b9e963d))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 部署到阿里云oss插件支持选择上传到阿里云cas中的证书 ([2ea2c8c](https://github.com/certd/certd/commit/2ea2c8c05fc40f79595f1bbde67c1413558bf684))
|
||||||
|
* 账号即将过期通知 ([e403450](https://github.com/certd/certd/commit/e40345095f31e2fb8e2333a6647466659133fa0c))
|
||||||
|
* 子域名托管重复域名不允许添加 ([ffc0c7b](https://github.com/certd/certd/commit/ffc0c7bb7b16d9904fd2d905d1c4e1d4854e92a9))
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/ui-server
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复流水线列表页报length错误的bug ([9864792](https://github.com/certd/certd/commit/9864792bbfd149e770d6e1ffa809573694f99dd3))
|
||||||
|
* 修复流水线页面状态没有刷新的bug ([93e9498](https://github.com/certd/certd/commit/93e9498b410353f504e11e264db62468895d7290))
|
||||||
|
* 修复自定义证书检查时间重启之后不生效的bug ([38e867c](https://github.com/certd/certd/commit/38e867c917bbc68bd228bdd8064f3e7358d6413d))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持上传证书到各种对象存储,oss、cos、七牛、s3、minio等 ([1da8617](https://github.com/certd/certd/commit/1da8617a53a675776635bbc3bcb3c6d7dff83e27))
|
||||||
|
* 支持邮箱发送证书 ([95332d5](https://github.com/certd/certd/commit/95332d5db96cd54ddab6ab737332417a09169b39))
|
||||||
|
|
||||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/ui-server",
|
"name": "@certd/ui-server",
|
||||||
"version": "1.36.6",
|
"version": "1.36.11",
|
||||||
"description": "fast-server base midway",
|
"description": "fast-server base midway",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -42,20 +42,20 @@
|
|||||||
"@aws-sdk/client-cloudfront": "^3.699.0",
|
"@aws-sdk/client-cloudfront": "^3.699.0",
|
||||||
"@aws-sdk/client-iam": "^3.699.0",
|
"@aws-sdk/client-iam": "^3.699.0",
|
||||||
"@aws-sdk/client-s3": "^3.705.0",
|
"@aws-sdk/client-s3": "^3.705.0",
|
||||||
"@certd/acme-client": "^1.36.6",
|
"@certd/acme-client": "^1.36.11",
|
||||||
"@certd/basic": "^1.36.6",
|
"@certd/basic": "^1.36.11",
|
||||||
"@certd/commercial-core": "^1.36.6",
|
"@certd/commercial-core": "^1.36.11",
|
||||||
"@certd/cv4pve-api-javascript": "^8.4.1",
|
"@certd/cv4pve-api-javascript": "^8.4.1",
|
||||||
"@certd/jdcloud": "^1.36.6",
|
"@certd/jdcloud": "^1.36.11",
|
||||||
"@certd/lib-huawei": "^1.36.6",
|
"@certd/lib-huawei": "^1.36.11",
|
||||||
"@certd/lib-k8s": "^1.36.6",
|
"@certd/lib-k8s": "^1.36.11",
|
||||||
"@certd/lib-server": "^1.36.6",
|
"@certd/lib-server": "^1.36.11",
|
||||||
"@certd/midway-flyway-js": "^1.36.6",
|
"@certd/midway-flyway-js": "^1.36.11",
|
||||||
"@certd/pipeline": "^1.36.6",
|
"@certd/pipeline": "^1.36.11",
|
||||||
"@certd/plugin-cert": "^1.36.6",
|
"@certd/plugin-cert": "^1.36.11",
|
||||||
"@certd/plugin-lib": "^1.36.6",
|
"@certd/plugin-lib": "^1.36.11",
|
||||||
"@certd/plugin-plus": "^1.36.6",
|
"@certd/plugin-plus": "^1.36.11",
|
||||||
"@certd/plus-core": "^1.36.6",
|
"@certd/plus-core": "^1.36.11",
|
||||||
"@huaweicloud/huaweicloud-sdk-cdn": "^3.1.120",
|
"@huaweicloud/huaweicloud-sdk-cdn": "^3.1.120",
|
||||||
"@huaweicloud/huaweicloud-sdk-core": "^3.1.120",
|
"@huaweicloud/huaweicloud-sdk-core": "^3.1.120",
|
||||||
"@koa/cors": "^5.0.0",
|
"@koa/cors": "^5.0.0",
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
import { Autoload, Config, Init, Inject, Scope, ScopeEnum } from '@midwayjs/core';
|
import {Autoload, Config, Init, Inject, Scope, ScopeEnum} from '@midwayjs/core';
|
||||||
import { PipelineService } from '../pipeline/service/pipeline-service.js';
|
import {PipelineService} from '../pipeline/service/pipeline-service.js';
|
||||||
import { logger } from '@certd/basic';
|
import {logger} from '@certd/basic';
|
||||||
import {SysSettingsService, SysSiteInfo} from '@certd/lib-server';
|
import {SysSettingsService, SysSiteInfo} from '@certd/lib-server';
|
||||||
import { SiteInfoService } from '../monitor/index.js';
|
import {SiteInfoService} from '../monitor/index.js';
|
||||||
import { Cron } from '../cron/cron.js';
|
import {Cron} from '../cron/cron.js';
|
||||||
import {UserSettingsService} from "../mine/service/user-settings-service.js";
|
import {UserSettingsService} from "../mine/service/user-settings-service.js";
|
||||||
import {UserSiteMonitorSetting} from "../mine/service/models.js";
|
import {UserSiteMonitorSetting} from "../mine/service/models.js";
|
||||||
import {getPlusInfo} from "@certd/plus-core";
|
import {getPlusInfo} from "@certd/plus-core";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import {NotificationService} from "../pipeline/service/notification-service.js";
|
import {NotificationService} from "../pipeline/service/notification-service.js";
|
||||||
import {UserService} from "../sys/authority/service/user-service.js";
|
import {UserService} from "../sys/authority/service/user-service.js";
|
||||||
|
import {Between} from "typeorm";
|
||||||
|
|
||||||
@Autoload()
|
@Autoload()
|
||||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||||
@@ -58,6 +59,8 @@ export class AutoCRegisterCron {
|
|||||||
|
|
||||||
|
|
||||||
await this.registerPlusExpireCheckCron();
|
await this.registerPlusExpireCheckCron();
|
||||||
|
|
||||||
|
await this.registerUserExpireCheckCron()
|
||||||
}
|
}
|
||||||
|
|
||||||
async registerSiteMonitorCron() {
|
async registerSiteMonitorCron() {
|
||||||
@@ -71,7 +74,7 @@ export class AutoCRegisterCron {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
for (const item of monitorSettingList) {
|
for (const item of monitorSettingList) {
|
||||||
const setting = item.setting ?? JSON.parse(item.setting)
|
const setting = item.setting ? JSON.parse(item.setting):{}
|
||||||
if(!setting?.cron){
|
if(!setting?.cron){
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -137,4 +140,61 @@ export class AutoCRegisterCron {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
registerUserExpireCheckCron() {
|
||||||
|
// 添加plus即将到期检查任务
|
||||||
|
this.cron.register({
|
||||||
|
name: 'user-expire-check',
|
||||||
|
cron: `0 20 9 * * *`, // 一天只能检查一次,否则会重复发送通知
|
||||||
|
job: async () => {
|
||||||
|
|
||||||
|
const getExpiresDaysUsers = async (days: number) => {
|
||||||
|
const targetDate = dayjs().add(days, 'day')
|
||||||
|
const startTime = targetDate.startOf('day').valueOf()
|
||||||
|
const endTime = targetDate.endOf('day').valueOf()
|
||||||
|
return await this.userService.find({
|
||||||
|
where: {
|
||||||
|
validTime: Between(startTime, endTime),
|
||||||
|
status: 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const notifyExpiresDaysUsers = async (days: number) => {
|
||||||
|
const list = await getExpiresDaysUsers(days)
|
||||||
|
if (list.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let title = `账号即将到期`
|
||||||
|
let content = `您的账号剩余${days}天到期,请及时续期,以免影响业务`
|
||||||
|
if (days <= 0) {
|
||||||
|
title = `账号已过期`
|
||||||
|
content = `您的账号已过期${Math.abs(days)}天,请尽快续期,以免影响业务`
|
||||||
|
}
|
||||||
|
const url = await this.notificationService.getBindUrl("");
|
||||||
|
for (const user of list) {
|
||||||
|
logger.info(`发送到期通知给用户:${user.username}`)
|
||||||
|
await this.notificationService.send({
|
||||||
|
useDefault: true,
|
||||||
|
logger: logger,
|
||||||
|
body: {
|
||||||
|
title,
|
||||||
|
content,
|
||||||
|
errorMessage: title,
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}, user.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await notifyExpiresDaysUsers(7)
|
||||||
|
await notifyExpiresDaysUsers(3)
|
||||||
|
await notifyExpiresDaysUsers(1)
|
||||||
|
await notifyExpiresDaysUsers(0)
|
||||||
|
await notifyExpiresDaysUsers(-1)
|
||||||
|
await notifyExpiresDaysUsers(-3)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ export class EmailService implements IEmailService {
|
|||||||
to: email.receivers.join(', '), // list of receivers
|
to: email.receivers.join(', '), // list of receivers
|
||||||
subject: subject,
|
subject: subject,
|
||||||
text: email.content,
|
text: email.content,
|
||||||
|
html: email.html,
|
||||||
|
attachments: email.attachments,
|
||||||
};
|
};
|
||||||
await transporter.sendMail(mailOptions);
|
await transporter.sendMail(mailOptions);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,12 @@ export class CertInfoFacade {
|
|||||||
if (certId) {
|
if (certId) {
|
||||||
return await this.certInfoService.getCertInfoById({ id: certId, userId });
|
return await this.certInfoService.getCertInfoById({ id: certId, userId });
|
||||||
}
|
}
|
||||||
|
if (!domains) {
|
||||||
|
throw new CodeException({
|
||||||
|
...Constants.res.openParamError,
|
||||||
|
message: "参数错误,certId和domains必须传一个",
|
||||||
|
});
|
||||||
|
}
|
||||||
const domainArr = domains.split(',');
|
const domainArr = domains.split(',');
|
||||||
|
|
||||||
const matchedList = await this.certInfoService.getMatchCertList({domains:domainArr,userId})
|
const matchedList = await this.certInfoService.getMatchCertList({domains:domainArr,userId})
|
||||||
@@ -42,12 +48,15 @@ export class CertInfoFacade {
|
|||||||
const pipeline:PipelineEntity = await this.createAutoPipeline({domains:domainArr,userId})
|
const pipeline:PipelineEntity = await this.createAutoPipeline({domains:domainArr,userId})
|
||||||
await this.triggerApplyPipeline({pipelineId:pipeline.id})
|
await this.triggerApplyPipeline({pipelineId:pipeline.id})
|
||||||
}else{
|
}else{
|
||||||
throw new CodeException(Constants.res.openCertNotFound);
|
throw new CodeException({
|
||||||
|
...Constants.res.openCertNotFound,
|
||||||
|
message:"在证书仓库中没有找到匹配域名的证书,请先创建证书流水线,或传入autoApply参数,自动创建"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
matched = null;
|
matched = null;
|
||||||
for (const item of matchedList) {
|
for (const item of matchedList) {
|
||||||
if (item.expiresTime>0 && item.expiresTime < new Date().getTime()) {
|
if (item.expiresTime>0 && item.expiresTime > new Date().getTime()) {
|
||||||
matched = item;
|
matched = item;
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -59,7 +68,10 @@ export class CertInfoFacade {
|
|||||||
await this.triggerApplyPipeline({pipelineId:first.pipelineId})
|
await this.triggerApplyPipeline({pipelineId:first.pipelineId})
|
||||||
return
|
return
|
||||||
}else{
|
}else{
|
||||||
throw new CodeException(Constants.res.openCertNotFound);
|
throw new CodeException({
|
||||||
|
...Constants.res.openCertNotFound,
|
||||||
|
message:"证书已过期,请触发流水线申请,或者传入autoApply参数,自动触发"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,10 +121,12 @@ export class CertInfoFacade {
|
|||||||
await this.pipelineService.trigger(req.pipelineId)
|
await this.pipelineService.trigger(req.pipelineId)
|
||||||
await utils.sleep(1000)
|
await utils.sleep(1000)
|
||||||
}
|
}
|
||||||
|
const certInfo = await this.certInfoService.getByPipelineId(req.pipelineId)
|
||||||
throw new CodeException({
|
throw new CodeException({
|
||||||
...Constants.res.openCertApplying,
|
...Constants.res.openCertApplying,
|
||||||
data:{
|
data:{
|
||||||
pipelineId:req.pipelineId
|
pipelineId:req.pipelineId,
|
||||||
|
certId:certInfo?.id
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,10 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
|||||||
async getMatchCertList(params: { domains: string[]; userId: number }) {
|
async getMatchCertList(params: { domains: string[]; userId: number }) {
|
||||||
const { domains, userId } = params;
|
const { domains, userId } = params;
|
||||||
if (!domains) {
|
if (!domains) {
|
||||||
throw new CodeException(Constants.res.openCertNotFound);
|
throw new CodeException({
|
||||||
|
...Constants.res.openCertNotFound,
|
||||||
|
message:"域名不能为空"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const list = await this.find({
|
const list = await this.find({
|
||||||
@@ -99,6 +102,9 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
|||||||
where: {
|
where: {
|
||||||
userId,
|
userId,
|
||||||
},
|
},
|
||||||
|
order: {
|
||||||
|
id: 'DESC',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
//遍历查找
|
//遍历查找
|
||||||
return list.filter(item => {
|
return list.filter(item => {
|
||||||
@@ -161,4 +167,12 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
|||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getByPipelineId(pipelineId: number) {
|
||||||
|
return await this.repository.findOne({
|
||||||
|
where: {
|
||||||
|
pipelineId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ export class SiteIpService extends BaseService<SiteIpEntity> {
|
|||||||
if (oldIps.length === ips.length ){
|
if (oldIps.length === ips.length ){
|
||||||
//检查是否有变化
|
//检查是否有变化
|
||||||
const oldIpList = oldIps.map(ip=>ip.ipAddress).sort().join(",")
|
const oldIpList = oldIps.map(ip=>ip.ipAddress).sort().join(",")
|
||||||
const newIpList = ips.filter(ip=>!oldIpList.includes(ip)).sort().join(",")
|
const newIpList = ips.sort().join(",")
|
||||||
if(oldIpList === newIpList){
|
if(oldIpList === newIpList){
|
||||||
//无变化
|
//无变化
|
||||||
hasChanged = false
|
hasChanged = false
|
||||||
|
|||||||
@@ -128,13 +128,15 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
}
|
}
|
||||||
const pipeline = JSON.parse(item.content);
|
const pipeline = JSON.parse(item.content);
|
||||||
let stepCount = 0;
|
let stepCount = 0;
|
||||||
RunnableCollection.each(pipeline.stages, (runnable: any) => {
|
if(pipeline.stages){
|
||||||
stepCount++;
|
RunnableCollection.each(pipeline.stages, (runnable: any) => {
|
||||||
});
|
stepCount++;
|
||||||
|
});
|
||||||
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
item.stepCount = stepCount;
|
item.stepCount = stepCount;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
item.triggerCount = pipeline.triggers.length;
|
item.triggerCount = pipeline.triggers?.length;
|
||||||
delete item.content;
|
delete item.content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,4 +36,25 @@ export class SubDomainService extends BaseService<SubDomainEntity> {
|
|||||||
return list.map(item=>item.domain);
|
return list.map(item=>item.domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async add(bean: SubDomainEntity) {
|
||||||
|
const {domain, userId} = bean;
|
||||||
|
if (!domain) {
|
||||||
|
throw new Error('域名不能为空');
|
||||||
|
}
|
||||||
|
if (!userId) {
|
||||||
|
throw new Error('用户ID不能为空');
|
||||||
|
}
|
||||||
|
const exist = await this.repository.findOne({
|
||||||
|
where: {
|
||||||
|
domain,
|
||||||
|
userId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (exist) {
|
||||||
|
throw new Error('域名已存在');
|
||||||
|
}
|
||||||
|
return await super.add(bean)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,3 +30,4 @@ export * from './plugin-github/index.js'
|
|||||||
export * from './plugin-namesilo/index.js'
|
export * from './plugin-namesilo/index.js'
|
||||||
export * from './plugin-proxmox/index.js'
|
export * from './plugin-proxmox/index.js'
|
||||||
export * from './plugin-wangsu/index.js'
|
export * from './plugin-wangsu/index.js'
|
||||||
|
export * from './plugin-admin/index.js'
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export * from './plugin-restart.js';
|
||||||
|
export * from './plugin-script.js';
|
||||||
|
export * from './plugin-db-backup.js';
|
||||||
@@ -14,14 +14,15 @@ const defaultFilePrefix = 'db_backup';
|
|||||||
name: 'DBBackupPlugin',
|
name: 'DBBackupPlugin',
|
||||||
title: '数据库备份',
|
title: '数据库备份',
|
||||||
icon: 'lucide:database-backup',
|
icon: 'lucide:database-backup',
|
||||||
desc: '仅支持备份SQLite数据库',
|
desc: '【仅管理员可用】仅支持备份SQLite数据库',
|
||||||
group: pluginGroups.other.key,
|
group: pluginGroups.admin.key,
|
||||||
showRunStrategy: true,
|
showRunStrategy: true,
|
||||||
default: {
|
default: {
|
||||||
strategy: {
|
strategy: {
|
||||||
runStrategy: RunStrategy.AlwaysRun,
|
runStrategy: RunStrategy.AlwaysRun,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
onlyAdmin:true,
|
||||||
needPlus: true,
|
needPlus: true,
|
||||||
})
|
})
|
||||||
export class DBBackupPlugin extends AbstractPlusTaskPlugin {
|
export class DBBackupPlugin extends AbstractPlusTaskPlugin {
|
||||||
@@ -157,6 +158,11 @@ export class DBBackupPlugin extends AbstractPlusTaskPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async execute(): Promise<void> {
|
async execute(): Promise<void> {
|
||||||
|
|
||||||
|
if (!this.isAdmin()) {
|
||||||
|
throw new Error('只有管理员才能运行此任务');
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.info('开始备份数据库');
|
this.logger.info('开始备份数据库');
|
||||||
|
|
||||||
let dbPath = process.env.certd_typeorm_dataSource_default_database;
|
let dbPath = process.env.certd_typeorm_dataSource_default_database;
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy } from '@certd/pipeline';
|
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy } from '@certd/pipeline';
|
||||||
import { httpsServer } from '../../../modules/auto/https/server.js';
|
import { httpsServer } from '../../modules/auto/https/server.js';
|
||||||
|
|
||||||
@IsTaskPlugin({
|
@IsTaskPlugin({
|
||||||
name: 'RestartCertd',
|
name: 'RestartCertd',
|
||||||
title: '重启 Certd',
|
title: '重启 Certd',
|
||||||
icon: 'mdi:restart',
|
icon: 'mdi:restart',
|
||||||
desc: '【仅管理员可用】 重启 certd的https服务,用于更新 Certd 的 ssl 证书',
|
desc: '【仅管理员可用】 重启 certd的https服务,用于更新 Certd 的 ssl 证书',
|
||||||
group: pluginGroups.other.key,
|
group: pluginGroups.admin.key,
|
||||||
|
onlyAdmin:true,
|
||||||
default: {
|
default: {
|
||||||
strategy: {
|
strategy: {
|
||||||
runStrategy: RunStrategy.SkipWhenSucceed,
|
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||||
@@ -11,8 +11,9 @@ export type CustomScriptContext = {
|
|||||||
title: '自定义js脚本',
|
title: '自定义js脚本',
|
||||||
icon: 'ri:javascript-line',
|
icon: 'ri:javascript-line',
|
||||||
desc: '【仅管理员】运行自定义js脚本执行',
|
desc: '【仅管理员】运行自定义js脚本执行',
|
||||||
group: pluginGroups.other.key,
|
group: pluginGroups.admin.key,
|
||||||
showRunStrategy: true,
|
showRunStrategy: true,
|
||||||
|
onlyAdmin: true,
|
||||||
default: {
|
default: {
|
||||||
strategy: {
|
strategy: {
|
||||||
runStrategy: RunStrategy.SkipWhenSucceed,
|
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||||
import { AliyunAccess } from '@certd/plugin-lib';
|
import {AliyunAccess, AliyunSslClient} from '@certd/plugin-lib';
|
||||||
import { CertInfo } from '@certd/plugin-cert';
|
import {CertInfo, CertReader} from '@certd/plugin-cert';
|
||||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||||
@IsTaskPlugin({
|
@IsTaskPlugin({
|
||||||
name: 'DeployCertToAliyunOSS',
|
name: 'DeployCertToAliyunOSS',
|
||||||
@@ -82,11 +82,27 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
|
|||||||
helper: '请选择前置任务输出的域名证书',
|
helper: '请选择前置任务输出的域名证书',
|
||||||
component: {
|
component: {
|
||||||
name: 'output-selector',
|
name: 'output-selector',
|
||||||
from: [...CertApplyPluginNames],
|
from: [...CertApplyPluginNames,"uploadCertToAliyun"],
|
||||||
},
|
},
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
cert!: CertInfo;
|
cert!: CertInfo | string;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: '证书服务接入点',
|
||||||
|
helper: '不会选就按默认',
|
||||||
|
value: 'cas.aliyuncs.com',
|
||||||
|
component: {
|
||||||
|
name: 'a-select',
|
||||||
|
options: [
|
||||||
|
{ value: 'cn-hangzhou', label: '中国大陆' },
|
||||||
|
{ value: 'southeast-1', label: '新加坡' },
|
||||||
|
{ value: 'eu-central-1', label: '德国(法兰克福)' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
casRegion!: string;
|
||||||
|
|
||||||
@TaskInput({
|
@TaskInput({
|
||||||
title: 'Access授权',
|
title: 'Access授权',
|
||||||
@@ -103,12 +119,42 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
|
|||||||
async execute(): Promise<void> {
|
async execute(): Promise<void> {
|
||||||
this.logger.info('开始部署证书到阿里云OSS');
|
this.logger.info('开始部署证书到阿里云OSS');
|
||||||
const access = (await this.getAccess(this.accessId)) as AliyunAccess;
|
const access = (await this.getAccess(this.accessId)) as AliyunAccess;
|
||||||
|
|
||||||
|
await this.getAliyunCertId(access)
|
||||||
this.logger.info(`bucket: ${this.bucket}, region: ${this.region}, domainName: ${this.domainName}`);
|
this.logger.info(`bucket: ${this.bucket}, region: ${this.region}, domainName: ${this.domainName}`);
|
||||||
const client = await this.getClient(access);
|
const client = await this.getClient(access);
|
||||||
await this.doRequest(client, {});
|
await this.doRequest(client, {});
|
||||||
this.logger.info('部署完成');
|
this.logger.info('部署完成');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getAliyunCertId(access: AliyunAccess) {
|
||||||
|
let certId: any = this.cert;
|
||||||
|
let certName: any = this.appendTimeSuffix("certd");
|
||||||
|
if (typeof this.cert === "object") {
|
||||||
|
let endpoint = `cas.${this.casRegion}.aliyuncs.com`;
|
||||||
|
if (this.casRegion === "cn-hangzhou"){
|
||||||
|
endpoint = "cas.aliyuncs.com";
|
||||||
|
}
|
||||||
|
const sslClient = new AliyunSslClient({
|
||||||
|
access,
|
||||||
|
logger: this.logger,
|
||||||
|
endpoint: endpoint
|
||||||
|
});
|
||||||
|
|
||||||
|
certName = this.buildCertName(CertReader.getMainDomain(this.cert.crt));
|
||||||
|
|
||||||
|
certId = await sslClient.uploadCert({
|
||||||
|
name: certName,
|
||||||
|
cert: this.cert
|
||||||
|
});
|
||||||
|
this.logger.info("上传证书成功", certId, certName);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
certId,
|
||||||
|
certName
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async getClient(access: AliyunAccess) {
|
async getClient(access: AliyunAccess) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const OSS = await import('ali-oss');
|
const OSS = await import('ali-oss');
|
||||||
@@ -129,13 +175,24 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
|
|||||||
cname: '',
|
cname: '',
|
||||||
comp: 'add',
|
comp: 'add',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let certStr = ""
|
||||||
|
if (typeof this.cert === "object" ){
|
||||||
|
certStr = `
|
||||||
|
<PrivateKey>${this.cert.key}</PrivateKey>
|
||||||
|
<Certificate>${this.cert.crt}</Certificate>
|
||||||
|
`
|
||||||
|
}else{
|
||||||
|
certStr = `<CertId>${this.cert}-${this.casRegion}</CertId>`
|
||||||
|
}
|
||||||
|
|
||||||
const xml = `
|
const xml = `
|
||||||
<BucketCnameConfiguration>
|
<BucketCnameConfiguration>
|
||||||
<Cname>
|
<Cname>
|
||||||
<Domain>${this.domainName}</Domain>
|
<Domain>${this.domainName}</Domain>
|
||||||
<CertificateConfiguration>
|
<CertificateConfiguration>
|
||||||
<PrivateKey>${this.cert.key}</PrivateKey>
|
${certStr}
|
||||||
<Certificate>${this.cert.crt}</Certificate>
|
<Force>true</Force>
|
||||||
</CertificateConfiguration>
|
</CertificateConfiguration>
|
||||||
</Cname>
|
</Cname>
|
||||||
</BucketCnameConfiguration>`;
|
</BucketCnameConfiguration>`;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const regionDict = [
|
|||||||
|
|
||||||
@IsTaskPlugin({
|
@IsTaskPlugin({
|
||||||
name: 'uploadCertToAliyun',
|
name: 'uploadCertToAliyun',
|
||||||
title: '阿里云-上传证书到阿里云',
|
title: '阿里云-上传证书到阿里云CAS',
|
||||||
icon: 'svg:icon-aliyun',
|
icon: 'svg:icon-aliyun',
|
||||||
group: pluginGroups.aliyun.key,
|
group: pluginGroups.aliyun.key,
|
||||||
desc: '上传证书到阿里云数字证书管理服务(CAS),注意:不会部署到任何应用上;如果不想在阿里云上同一份证书上传多次,可以把此任务作为前置任务,其他阿里云任务证书那一项选择此任务的输出',
|
desc: '上传证书到阿里云数字证书管理服务(CAS),注意:不会部署到任何应用上;如果不想在阿里云上同一份证书上传多次,可以把此任务作为前置任务,其他阿里云任务证书那一项选择此任务的输出',
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export * from './host-shell-execute/index.js';
|
export * from './host-shell-execute/index.js';
|
||||||
export * from './upload-to-host/index.js';
|
export * from './upload-to-host/index.js';
|
||||||
export * from './copy-to-local/index.js'
|
export * from './copy-to-local/index.js'
|
||||||
|
export * from './plugin-upload-to-oss.js'
|
||||||
|
|||||||
@@ -0,0 +1,274 @@
|
|||||||
|
import {AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput} from '@certd/pipeline';
|
||||||
|
import {CertInfo} from "@certd/plugin-cert";
|
||||||
|
import {ossClientFactory} from "@certd/plugin-lib";
|
||||||
|
import {utils} from "@certd/basic";
|
||||||
|
|
||||||
|
@IsTaskPlugin({
|
||||||
|
name: 'UploadCertToOss',
|
||||||
|
title: '上传证书到对象存储OSS',
|
||||||
|
icon: 'ion:cloud-upload-outline',
|
||||||
|
desc: '支持阿里云OSS、腾讯云COS、七牛云KODO、S3、MinIO、FTP、SFTP',
|
||||||
|
group: pluginGroups.host.key,
|
||||||
|
showRunStrategy:false,
|
||||||
|
default: {
|
||||||
|
strategy: {
|
||||||
|
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
export class UploadCertToOssPlugin extends AbstractTaskPlugin {
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: '域名证书',
|
||||||
|
helper: '请选择前置任务输出的域名证书',
|
||||||
|
component: {
|
||||||
|
name: 'output-selector',
|
||||||
|
from: [":cert:"],
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
cert!: CertInfo;
|
||||||
|
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: 'OSS类型',
|
||||||
|
component: {
|
||||||
|
name: 'a-select',
|
||||||
|
vModel:"value",
|
||||||
|
options: [
|
||||||
|
{ label: "阿里云OSS", value: "alioss" },
|
||||||
|
{ label: "腾讯云COS", value: "tencentcos" },
|
||||||
|
{ label: "七牛OSS", value: "qiniuoss" },
|
||||||
|
{ label: "S3/Minio", value: "s3" },
|
||||||
|
{ label: "SFTP", value: "sftp" },
|
||||||
|
{ label: "FTP", value: "ftp" },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
uploaderType!: string;
|
||||||
|
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: 'OSS授权',
|
||||||
|
component: {
|
||||||
|
name: 'access-selector',
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
mergeScript: `
|
||||||
|
return {
|
||||||
|
component: {
|
||||||
|
type: ctx.compute(({form})=>{
|
||||||
|
return form.uploaderType;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
accessId!: string;
|
||||||
|
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: '证书格式',
|
||||||
|
helper: '要部署的证书格式,支持pem、pfx、der、jks',
|
||||||
|
component: {
|
||||||
|
name: 'a-select',
|
||||||
|
options: [
|
||||||
|
{ value: 'pem', label: 'pem(crt),Nginx等大部分应用' },
|
||||||
|
{ value: 'pfx', label: 'pfx,一般用于IIS' },
|
||||||
|
{ value: 'der', label: 'der,一般用于Apache' },
|
||||||
|
{ value: 'jks', label: 'jks,一般用于JAVA应用' },
|
||||||
|
{ value: 'one', label: '证书私钥一体,crt+key简单合并为一个pem文件' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
certType!: string;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: '证书保存路径',
|
||||||
|
helper: '路径要包含证书文件名,例如:/tmp/cert.pem',
|
||||||
|
component: {
|
||||||
|
placeholder: '/root/deploy/nginx/full_chain.pem',
|
||||||
|
},
|
||||||
|
mergeScript: `
|
||||||
|
return {
|
||||||
|
show: ctx.compute(({form})=>{
|
||||||
|
return form.certType === 'pem';
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
required: true,
|
||||||
|
rules: [{ type: 'filepath' }],
|
||||||
|
})
|
||||||
|
crtPath!: string;
|
||||||
|
@TaskInput({
|
||||||
|
title: '私钥保存路径',
|
||||||
|
helper: '路径要包含私钥文件名,例如:/tmp/cert.key',
|
||||||
|
component: {
|
||||||
|
placeholder: '/root/deploy/nginx/cert.key',
|
||||||
|
},
|
||||||
|
mergeScript: `
|
||||||
|
return {
|
||||||
|
show: ctx.compute(({form})=>{
|
||||||
|
return form.certType === 'pem';
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
required: true,
|
||||||
|
rules: [{ type: 'filepath' }],
|
||||||
|
})
|
||||||
|
keyPath!: string;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: '中间证书保存路径',
|
||||||
|
helper: '路径要包含文件名,一般情况传上面两个文件即可,极少数情况需要这个中间证书',
|
||||||
|
component: {
|
||||||
|
placeholder: '/root/deploy/nginx/intermediate.pem',
|
||||||
|
},
|
||||||
|
mergeScript: `
|
||||||
|
return {
|
||||||
|
show: ctx.compute(({form})=>{
|
||||||
|
return form.certType === 'pem';
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
rules: [{ type: 'filepath' }],
|
||||||
|
})
|
||||||
|
icPath!: string;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: 'PFX证书保存路径',
|
||||||
|
helper: '路径要包含证书文件名,例如:D:\\iis\\cert.pfx',
|
||||||
|
component: {
|
||||||
|
placeholder: 'D:\\iis\\cert.pfx',
|
||||||
|
},
|
||||||
|
mergeScript: `
|
||||||
|
return {
|
||||||
|
show: ctx.compute(({form})=>{
|
||||||
|
return form.certType === 'pfx';
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
required: true,
|
||||||
|
rules: [{ type: 'filepath' }],
|
||||||
|
})
|
||||||
|
pfxPath!: string;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: 'DER证书保存路径',
|
||||||
|
helper: '路径要包含证书文件名,例如:/tmp/cert.der',
|
||||||
|
component: {
|
||||||
|
placeholder: '/root/deploy/apache/cert.der',
|
||||||
|
},
|
||||||
|
mergeScript: `
|
||||||
|
return {
|
||||||
|
show: ctx.compute(({form})=>{
|
||||||
|
return form.certType === 'der';
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
required: true,
|
||||||
|
rules: [{ type: 'filepath' }],
|
||||||
|
})
|
||||||
|
derPath!: string;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: 'jks证书保存路径',
|
||||||
|
helper: '路径要包含证书文件名,例如:/tmp/cert.jks',
|
||||||
|
component: {
|
||||||
|
placeholder: '/root/deploy/java_app/cert.jks',
|
||||||
|
},
|
||||||
|
mergeScript: `
|
||||||
|
return {
|
||||||
|
show: ctx.compute(({form})=>{
|
||||||
|
return form.certType === 'jks';
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
required: true,
|
||||||
|
rules: [{ type: 'filepath' }],
|
||||||
|
})
|
||||||
|
jksPath!: string;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: '一体证书保存路径',
|
||||||
|
helper: '路径要包含证书文件名,例如:/tmp/crt_key.pem',
|
||||||
|
component: {
|
||||||
|
placeholder: '/app/crt_key.pem',
|
||||||
|
},
|
||||||
|
mergeScript: `
|
||||||
|
return {
|
||||||
|
show: ctx.compute(({form})=>{
|
||||||
|
return form.certType === 'one';
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
required: true,
|
||||||
|
rules: [{ type: 'filepath' }],
|
||||||
|
})
|
||||||
|
onePath!: string;
|
||||||
|
|
||||||
|
|
||||||
|
async onInstance() {}
|
||||||
|
async execute(): Promise<void> {
|
||||||
|
const { accessId } = this;
|
||||||
|
let { crtPath, keyPath, icPath, pfxPath, derPath, jksPath, onePath } = this;
|
||||||
|
if (!accessId) {
|
||||||
|
throw new Error('OSS授权配置不能为空');
|
||||||
|
}
|
||||||
|
|
||||||
|
const uploaderType = this.uploaderType
|
||||||
|
const uploaderAccess = this.accessId
|
||||||
|
|
||||||
|
const httpUploaderContext = {
|
||||||
|
accessService: this.ctx.accessService,
|
||||||
|
logger: this.logger,
|
||||||
|
utils,
|
||||||
|
};
|
||||||
|
|
||||||
|
const access = await this.getAccess(uploaderAccess);
|
||||||
|
this.logger.info("上传方式", uploaderType);
|
||||||
|
const httpUploader = await ossClientFactory.createOssClientByType(uploaderType, {
|
||||||
|
access,
|
||||||
|
rootDir: "",
|
||||||
|
ctx: httpUploaderContext,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
this.logger.info('准备上传文件到OSS');
|
||||||
|
|
||||||
|
if (crtPath) {
|
||||||
|
await httpUploader.upload(crtPath, Buffer.from(this.cert.crt))
|
||||||
|
this.logger.info(`上传证书:${crtPath}`);
|
||||||
|
}
|
||||||
|
if (keyPath) {
|
||||||
|
await httpUploader.upload(keyPath, Buffer.from(this.cert.key))
|
||||||
|
this.logger.info(`上传私钥:${keyPath}`);
|
||||||
|
}
|
||||||
|
if (icPath) {
|
||||||
|
await httpUploader.upload(icPath, Buffer.from(this.cert.ic))
|
||||||
|
this.logger.info(`上传中间证书:${icPath}`);
|
||||||
|
}
|
||||||
|
if (pfxPath) {
|
||||||
|
await httpUploader.upload(pfxPath, Buffer.from(this.cert.pfx, "base64"))
|
||||||
|
this.logger.info(`上传PFX证书:${pfxPath}`);
|
||||||
|
}
|
||||||
|
if (derPath) {
|
||||||
|
await httpUploader.upload(derPath, Buffer.from(this.cert.der, "base64"))
|
||||||
|
this.logger.info(`上传DER证书:${derPath}`);
|
||||||
|
}
|
||||||
|
if (this.jksPath) {
|
||||||
|
await httpUploader.upload(jksPath,Buffer.from(this.cert.jks, "base64"))
|
||||||
|
this.logger.info(`上传jks证书:${jksPath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onePath) {
|
||||||
|
await httpUploader.upload(onePath, Buffer.from(this.cert.one))
|
||||||
|
this.logger.info(`上传一体证书:${onePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.info('上传文件成功');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new UploadCertToOssPlugin();
|
||||||
@@ -47,26 +47,35 @@ export class QywxNotification extends BaseNotification {
|
|||||||
if (!this.webhook) {
|
if (!this.webhook) {
|
||||||
throw new Error('webhook地址不能为空');
|
throw new Error('webhook地址不能为空');
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
*
|
|
||||||
* "msgtype": "text",
|
|
||||||
* "text": {
|
|
||||||
* "content": "hello world"
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
const color = body.errorMessage?'red':'green';
|
|
||||||
await this.http.request({
|
await this.http.request({
|
||||||
url: this.webhook,
|
url: this.webhook,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: {
|
data: {
|
||||||
msgtype: 'markdown',
|
msgtype: 'text',
|
||||||
markdown: {
|
text: {
|
||||||
content: `<font color='${color}'>${body.title}</font>\n\n\n${body.content}\n\n[查看详情](${body.url})`,
|
content: `${body.title}\n${body.content}\n查看详情: ${body.url}`,
|
||||||
mentioned_list: this.mentionedList,
|
mentioned_list: this.mentionedList,
|
||||||
mentioned_mobile_list: this.mentionedMobileList,
|
mentioned_mobile_list: this.mentionedMobileList,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//Markdown 模式不支持@
|
||||||
|
|
||||||
|
// const color = body.errorMessage?'red':'green';
|
||||||
|
// await this.http.request({
|
||||||
|
// url: this.webhook,
|
||||||
|
// method: 'POST',
|
||||||
|
// data: {
|
||||||
|
// msgtype: 'markdown',
|
||||||
|
// markdown: {
|
||||||
|
// content: `<font color='${color}'>${body.title}</font>\n\n\n${body.content}\n\n[查看详情](${body.url})`,
|
||||||
|
// mentioned_list: this.mentionedList,
|
||||||
|
// mentioned_mobile_list: this.mentionedMobileList,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,2 @@
|
|||||||
export * from './plugin-restart.js';
|
|
||||||
export * from './plugin-script.js';
|
|
||||||
export * from './plugin-wait.js';
|
export * from './plugin-wait.js';
|
||||||
export * from './plugin-db-backup.js';
|
export * from './plugin-deploy-to-mail.js';
|
||||||
|
|||||||
@@ -0,0 +1,186 @@
|
|||||||
|
import {AbstractTaskPlugin, FileItem, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput} from '@certd/pipeline';
|
||||||
|
import {CertInfo, CertReader} from "@certd/plugin-cert";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
@IsTaskPlugin({
|
||||||
|
name: 'DeployCertToMailPlugin',
|
||||||
|
title: '邮件发送证书',
|
||||||
|
icon: 'ion:mail-outline',
|
||||||
|
desc: '通过邮件发送证书',
|
||||||
|
group: pluginGroups.other.key,
|
||||||
|
showRunStrategy:false,
|
||||||
|
default: {
|
||||||
|
strategy: {
|
||||||
|
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
export class DeployCertToMailPlugin extends AbstractTaskPlugin {
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: '域名证书',
|
||||||
|
helper: '请选择前置任务输出的域名证书',
|
||||||
|
component: {
|
||||||
|
name: 'output-selector',
|
||||||
|
from: [":cert:"],
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
cert!: CertInfo;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: '证书压缩文件',
|
||||||
|
helper: '请选择前置任务输出的域名证书压缩文件',
|
||||||
|
component: {
|
||||||
|
name: 'output-selector',
|
||||||
|
from: [":certZip:"],
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
certZip!: FileItem;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: '接收邮箱',
|
||||||
|
component: {
|
||||||
|
name: 'EmailSelector',
|
||||||
|
vModel: 'value',
|
||||||
|
mode:"tags",
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
email!: string[];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* title:
|
||||||
|
* title: 邮件标题
|
||||||
|
* helper: |-
|
||||||
|
* 请输入邮件标题否则将使用默认标题
|
||||||
|
* 域名:${certDomains}
|
||||||
|
* component:
|
||||||
|
* name: a-input
|
||||||
|
* required: false
|
||||||
|
* template:
|
||||||
|
* title: 邮件模版
|
||||||
|
* helper: |-
|
||||||
|
* 请输入模版内容否则将使用默认模版
|
||||||
|
* 域名:${certDomains}
|
||||||
|
* value: |-
|
||||||
|
* 尊敬的用户你好:
|
||||||
|
* 以下是域名(${certDomains})证书文件
|
||||||
|
* component:
|
||||||
|
* name: a-textarea
|
||||||
|
* autosize:
|
||||||
|
* minRows: 6
|
||||||
|
* maxRows: 10
|
||||||
|
* required: false
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: '邮件标题',
|
||||||
|
component: {
|
||||||
|
name: 'a-input',
|
||||||
|
vModel: 'value',
|
||||||
|
placeholder:`证书申请成功【$\{mainDomain}】`,
|
||||||
|
},
|
||||||
|
helper: '请输入邮件标题否则将使用默认标题\n模板变量:主域名=$\{mainDomain}、全部域名=$\{domains}、过期时间=$\{expiresTime}、备注=$\{remark}、证书PEM=$\{crt}、证书私钥=$\{key}、中间证书/CA证书=$\{ic}',
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
|
title!: string;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: '邮件模版',
|
||||||
|
component: {
|
||||||
|
name: 'a-textarea',
|
||||||
|
vModel: 'value',
|
||||||
|
autosize: {
|
||||||
|
minRows: 6,
|
||||||
|
maxRows: 10,
|
||||||
|
},
|
||||||
|
placeholder: `
|
||||||
|
<div>
|
||||||
|
<p>证书申请成功</p>
|
||||||
|
<p>域名:$\{domains}</p>
|
||||||
|
<p>证书有效期:$\{expiresTime}</p>
|
||||||
|
<p>备注:$\{remark}</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
helper: `请输入模版内容否则将使用默认模版,模板变量同上`,
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
|
template!: string;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: '备注',
|
||||||
|
component: {
|
||||||
|
name: 'a-input',
|
||||||
|
vModel: 'value',
|
||||||
|
},
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
|
remark!: string;
|
||||||
|
|
||||||
|
async onInstance() {}
|
||||||
|
async execute(): Promise<void> {
|
||||||
|
|
||||||
|
this.logger.info(`开始发送邮件`);
|
||||||
|
const certReader = new CertReader(this.cert)
|
||||||
|
const mainDomain = certReader.getMainDomain();
|
||||||
|
const domains = certReader.getAllDomains().join(',');
|
||||||
|
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
mainDomain,
|
||||||
|
domains,
|
||||||
|
expiresTime: dayjs(certReader.expires).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
|
remark:this.remark ||"",
|
||||||
|
crt: this.cert.crt,
|
||||||
|
key: this.cert.key,
|
||||||
|
ic: this.cert.ic
|
||||||
|
}
|
||||||
|
|
||||||
|
let title = `证书申请成功【${mainDomain}】`;
|
||||||
|
let html = `
|
||||||
|
<div>
|
||||||
|
<p>证书申请成功</p>
|
||||||
|
<p>域名:${domains}</p>
|
||||||
|
<p>证书有效期:${data.expiresTime}</p>
|
||||||
|
<p>备注:${this.remark||""}</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
if (this.title) {
|
||||||
|
const compile = this.compile(this.title);
|
||||||
|
title = compile(data);
|
||||||
|
}
|
||||||
|
if (this.template) {
|
||||||
|
const compile = this.compile(this.template);
|
||||||
|
html = compile(data);
|
||||||
|
}
|
||||||
|
const file = this.certZip
|
||||||
|
if (!file) {
|
||||||
|
throw new Error('证书压缩文件还未生成,重新运行证书任务');
|
||||||
|
}
|
||||||
|
await this.ctx.emailService.send({
|
||||||
|
subject:title,
|
||||||
|
html: html,
|
||||||
|
receivers: this.email,
|
||||||
|
attachments: [
|
||||||
|
{
|
||||||
|
filename: file.filename,
|
||||||
|
path: file.path,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
compile(templateString:string) {
|
||||||
|
return new Function('data', ` with(data || {}) {
|
||||||
|
return \`${templateString}\`;
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new DeployCertToMailPlugin();
|
||||||
@@ -5,7 +5,7 @@ import { TencentAccess } from "@certd/plugin-lib";
|
|||||||
name: 'DeployCertToTencentEO',
|
name: 'DeployCertToTencentEO',
|
||||||
title: '腾讯云-部署到腾讯云EO',
|
title: '腾讯云-部署到腾讯云EO',
|
||||||
icon: 'svg:icon-tencentcloud',
|
icon: 'svg:icon-tencentcloud',
|
||||||
desc: '腾讯云边缘安全加速平台EO,必须配置上传证书到腾讯云任务',
|
desc: '腾讯云边缘安全加速平台EdgeOne(EO),必须配置上传证书到腾讯云任务',
|
||||||
group: pluginGroups.tencent.key,
|
group: pluginGroups.tencent.key,
|
||||||
default: {
|
default: {
|
||||||
strategy: {
|
strategy: {
|
||||||
|
|||||||
@@ -136,6 +136,18 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
|
|||||||
ingressName!: string | string[];
|
ingressName!: string | string[];
|
||||||
|
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: "忽略证书校验",
|
||||||
|
required: false,
|
||||||
|
helper: "是否忽略证书校验",
|
||||||
|
component: {
|
||||||
|
name: "a-switch",
|
||||||
|
vModel: "checked",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
skipTLSVerify!:boolean
|
||||||
|
|
||||||
|
|
||||||
// @TaskInput({ title: "集群内网ip", helper: "如果开启了外网的话,无需设置" })
|
// @TaskInput({ title: "集群内网ip", helper: "如果开启了外网的话,无需设置" })
|
||||||
// clusterIp!: string;
|
// clusterIp!: string;
|
||||||
|
|
||||||
@@ -163,7 +175,8 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
|
|||||||
this.logger.info("kubeconfig已成功获取");
|
this.logger.info("kubeconfig已成功获取");
|
||||||
const k8sClient = new this.K8sClient({
|
const k8sClient = new this.K8sClient({
|
||||||
kubeConfigStr,
|
kubeConfigStr,
|
||||||
logger: this.logger
|
logger: this.logger,
|
||||||
|
skipTLSVerify: this.skipTLSVerify,
|
||||||
});
|
});
|
||||||
// if (this.clusterIp != null) {
|
// if (this.clusterIp != null) {
|
||||||
// if (!this.clusterDomain) {
|
// if (!this.clusterDomain) {
|
||||||
|
|||||||
823
pnpm-lock.yaml
generated
823
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user