mirror of
https://github.com/certd/certd.git
synced 2026-04-03 22:20:51 +08:00
Compare commits
50 Commits
v2-dev-aut
...
v1.36.10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
29d49d72f9 | ||
|
|
81de0fc7e4 | ||
|
|
9d5d266d2a | ||
|
|
b97935299f | ||
|
|
32a7ea1c16 | ||
|
|
9fd95e6a1e | ||
|
|
61ba83c775 | ||
|
|
6369fed5fc | ||
|
|
42f4d1477d | ||
|
|
609ac9c9a2 | ||
|
|
79f2367472 | ||
|
|
dfc9362084 | ||
|
|
487b469603 | ||
|
|
19e1df1e5d | ||
|
|
fc55010888 | ||
|
|
902d246d1a |
48
CHANGELOG.md
48
CHANGELOG.md
@@ -3,6 +3,54 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [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)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1 +1 @@
|
||||
10:51
|
||||
16:54
|
||||
|
||||
@@ -3,6 +3,40 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [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)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
}
|
||||
},
|
||||
"npmClient": "pnpm",
|
||||
"version": "1.36.5"
|
||||
"version": "1.36.10"
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
},
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@certd/ui-server": "link:packages/ui/certd-server",
|
||||
"axios": "^1.7.7",
|
||||
"copyfiles": "^2.4.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.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)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.36.5](https://github.com/publishlab/node-acme-client/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "Simple and unopinionated ACME client",
|
||||
"private": false,
|
||||
"author": "nmorsman",
|
||||
"version": "1.36.5",
|
||||
"version": "1.36.10",
|
||||
"type": "module",
|
||||
"module": "scr/index.js",
|
||||
"main": "src/index.js",
|
||||
@@ -18,7 +18,7 @@
|
||||
"types"
|
||||
],
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.36.5",
|
||||
"@certd/basic": "^1.36.10",
|
||||
"@peculiar/x509": "^1.11.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"axios": "^1.7.2",
|
||||
@@ -69,5 +69,5 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||
},
|
||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||
"gitHead": "4a36fd2ec343794c5442e4402b21fa6869dfd90e"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.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)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
@@ -1 +1 @@
|
||||
10:46
|
||||
23:02
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/basic",
|
||||
"private": false,
|
||||
"version": "1.36.5",
|
||||
"version": "1.36.10",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -45,5 +45,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||
"gitHead": "4a36fd2ec343794c5442e4402b21fa6869dfd90e"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,24 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [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)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/pipeline",
|
||||
"private": false,
|
||||
"version": "1.36.5",
|
||||
"version": "1.36.10",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -17,8 +17,8 @@
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.36.5",
|
||||
"@certd/plus-core": "^1.36.5",
|
||||
"@certd/basic": "^1.36.10",
|
||||
"@certd/plus-core": "^1.36.10",
|
||||
"dayjs": "^1.11.7",
|
||||
"lodash-es": "^4.17.21",
|
||||
"reflect-metadata": "^0.1.13"
|
||||
@@ -44,5 +44,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||
"gitHead": "4a36fd2ec343794c5442e4402b21fa6869dfd90e"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
export type EmailSend = {
|
||||
subject: string;
|
||||
content: string;
|
||||
receivers: string[];
|
||||
content?: string;
|
||||
attachments?: any[];
|
||||
html?: string;
|
||||
};
|
||||
|
||||
export interface IEmailService {
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.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)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-huawei",
|
||||
"private": false,
|
||||
"version": "1.36.5",
|
||||
"version": "1.36.10",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
@@ -24,5 +24,5 @@
|
||||
"prettier": "^2.8.8",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||
"gitHead": "4a36fd2ec343794c5442e4402b21fa6869dfd90e"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.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)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-iframe",
|
||||
"private": false,
|
||||
"version": "1.36.5",
|
||||
"version": "1.36.10",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -31,5 +31,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||
"gitHead": "4a36fd2ec343794c5442e4402b21fa6869dfd90e"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.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)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/jdcloud",
|
||||
"version": "1.36.5",
|
||||
"version": "1.36.10",
|
||||
"description": "jdcloud openApi sdk",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
@@ -61,5 +61,5 @@
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||
"gitHead": "4a36fd2ec343794c5442e4402b21fa6869dfd90e"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.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)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-k8s",
|
||||
"private": false,
|
||||
"version": "1.36.5",
|
||||
"version": "1.36.10",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -17,7 +17,7 @@
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.36.5",
|
||||
"@certd/basic": "^1.36.10",
|
||||
"@kubernetes/client-node": "0.21.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -32,5 +32,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||
"gitHead": "4a36fd2ec343794c5442e4402b21fa6869dfd90e"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,25 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [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)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化流水线列表页面、详情页面性能,精简返回数据 ([609ac9c](https://github.com/certd/certd/commit/609ac9c9a2dde605eb09834ae59693c1cb238765))
|
||||
* 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)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/lib-server",
|
||||
"version": "1.36.5",
|
||||
"version": "1.36.10",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -27,10 +27,10 @@
|
||||
],
|
||||
"license": "AGPL",
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.36.5",
|
||||
"@certd/basic": "^1.36.5",
|
||||
"@certd/pipeline": "^1.36.5",
|
||||
"@certd/plus-core": "^1.36.5",
|
||||
"@certd/acme-client": "^1.36.10",
|
||||
"@certd/basic": "^1.36.10",
|
||||
"@certd/pipeline": "^1.36.10",
|
||||
"@certd/plus-core": "^1.36.10",
|
||||
"@midwayjs/cache": "~3.14.0",
|
||||
"@midwayjs/core": "~3.20.3",
|
||||
"@midwayjs/i18n": "~3.20.3",
|
||||
@@ -61,5 +61,5 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||
"gitHead": "4a36fd2ec343794c5442e4402b21fa6869dfd90e"
|
||||
}
|
||||
|
||||
@@ -164,8 +164,11 @@ export abstract class BaseService<T> {
|
||||
}
|
||||
|
||||
private buildListQuery(listReq: ListReq<T>) {
|
||||
const { query, sort, buildQuery } = listReq;
|
||||
const { query, sort, buildQuery,select } = listReq;
|
||||
const qb = this.getRepository().createQueryBuilder('main');
|
||||
if (select) {
|
||||
qb.setFindOptions({select});
|
||||
}
|
||||
if (query) {
|
||||
const keys = Object.keys(query);
|
||||
for (const key of keys) {
|
||||
@@ -191,6 +194,7 @@ export abstract class BaseService<T> {
|
||||
if (buildQuery) {
|
||||
buildQuery(qb);
|
||||
}
|
||||
|
||||
return qb;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,5 +107,17 @@ export const Constants = {
|
||||
code: 20012,
|
||||
message: '证书还未生成',
|
||||
},
|
||||
openCertApplying: {
|
||||
code: 20013,
|
||||
message: '证书正在申请中,请稍后重新获取',
|
||||
},
|
||||
openDomainNoVerifier:{
|
||||
code: 20014,
|
||||
message: '域名校验方式未配置',
|
||||
},
|
||||
openEmailNotFound: {
|
||||
code: 20021,
|
||||
message: '用户邮箱还未配置',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -11,13 +11,13 @@ export class CommonException extends BaseException {
|
||||
}
|
||||
|
||||
export class CodeException extends BaseException {
|
||||
constructor(res: { code: number; message: string }) {
|
||||
super("CodeException", res.code, res.message);
|
||||
constructor(res: { code: number; message: string; data?: any }) {
|
||||
super("CodeException", res.code, res.message, res.data);
|
||||
}
|
||||
}
|
||||
|
||||
export class TextException extends BaseException {
|
||||
constructor(name, code,message, data?) {
|
||||
constructor(name, code, message, data?) {
|
||||
super(name, code, message, data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.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)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/midway-flyway-js",
|
||||
"version": "1.36.5",
|
||||
"version": "1.36.10",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -46,5 +46,5 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||
"gitHead": "4a36fd2ec343794c5442e4402b21fa6869dfd90e"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,27 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.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)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持自动选择校验方式申请证书 ([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)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-cert",
|
||||
"private": false,
|
||||
"version": "1.36.5",
|
||||
"version": "1.36.10",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -16,10 +16,10 @@
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.36.5",
|
||||
"@certd/basic": "^1.36.5",
|
||||
"@certd/pipeline": "^1.36.5",
|
||||
"@certd/plugin-lib": "^1.36.5",
|
||||
"@certd/acme-client": "^1.36.10",
|
||||
"@certd/basic": "^1.36.10",
|
||||
"@certd/pipeline": "^1.36.10",
|
||||
"@certd/plugin-lib": "^1.36.10",
|
||||
"@google-cloud/publicca": "^1.3.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"jszip": "^3.10.1",
|
||||
@@ -43,5 +43,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||
"gitHead": "4a36fd2ec343794c5442e4402b21fa6869dfd90e"
|
||||
}
|
||||
|
||||
@@ -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 type { CertInfo } from "./acme.js";
|
||||
import { CertReader } from "./cert-reader.js";
|
||||
@@ -71,6 +71,12 @@ export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
|
||||
})
|
||||
cert?: CertInfo;
|
||||
|
||||
@TaskOutput({
|
||||
title: "域名证书压缩文件",
|
||||
type: "certZip",
|
||||
})
|
||||
certZip?: FileItem;
|
||||
|
||||
async onInstance() {
|
||||
this.userContext = this.ctx.userContext;
|
||||
this.lastStatus = this.ctx.lastStatus as Step;
|
||||
@@ -131,6 +137,7 @@ export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
|
||||
} else {
|
||||
this.extendsFiles();
|
||||
}
|
||||
this.certZip = this._result.files[0];
|
||||
}
|
||||
|
||||
async zipCert(cert: CertInfo, filename: string) {
|
||||
|
||||
@@ -470,6 +470,9 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
||||
const domain = fullDomain.replaceAll("*.", "");
|
||||
const mainDomain = await domainParser.parse(domain);
|
||||
const planSetting: DomainVerifyPlanInput = verifyPlanSetting[mainDomain];
|
||||
if (planSetting == null) {
|
||||
throw new Error(`没有找到域名(${domain})的校验计划`);
|
||||
}
|
||||
if (planSetting.type === "dns") {
|
||||
plan[domain] = await this.createDnsDomainVerifyPlan(planSetting, domain, mainDomain);
|
||||
} else if (planSetting.type === "cname") {
|
||||
@@ -498,6 +501,9 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
||||
|
||||
for (const domain in verifiers) {
|
||||
const verifier = verifiers[domain];
|
||||
if (verifier == null) {
|
||||
throw new Error(`没有找到与该域名(${domain})匹配的校验方式,请先到‘域名管理’页面添加校验方式`);
|
||||
}
|
||||
if (verifier.type === "dns") {
|
||||
plan[domain] = await this.createDnsDomainVerifyPlan(verifier.dns, domain, verifier.mainDomain);
|
||||
} else if (verifier.type === "cname") {
|
||||
|
||||
@@ -3,6 +3,26 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [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)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-lib",
|
||||
"private": false,
|
||||
"version": "1.36.5",
|
||||
"version": "1.36.10",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -21,8 +21,8 @@
|
||||
"@alicloud/pop-core": "^1.7.10",
|
||||
"@alicloud/tea-util": "^1.4.10",
|
||||
"@aws-sdk/client-s3": "^3.787.0",
|
||||
"@certd/basic": "^1.36.5",
|
||||
"@certd/pipeline": "^1.36.5",
|
||||
"@certd/basic": "^1.36.10",
|
||||
"@certd/pipeline": "^1.36.10",
|
||||
"@kubernetes/client-node": "0.21.0",
|
||||
"ali-oss": "^6.22.0",
|
||||
"basic-ftp": "^5.0.5",
|
||||
@@ -53,5 +53,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||
"gitHead": "4a36fd2ec343794c5442e4402b21fa6869dfd90e"
|
||||
}
|
||||
|
||||
@@ -16,6 +16,10 @@ export default class SshOssClientImpl extends BaseOssClient<SshAccess> {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
async upload(filePath: string, fileContent: Buffer) {
|
||||
if (!filePath) {
|
||||
filePath = "";
|
||||
}
|
||||
filePath = filePath.trim();
|
||||
const tmpFilePath = path.join(os.tmpdir(), "cert", "http", filePath);
|
||||
|
||||
// Write file to temp path
|
||||
|
||||
@@ -506,10 +506,6 @@ export class SshClient {
|
||||
isWinCmd = await this.isCmd(conn);
|
||||
}
|
||||
|
||||
if (isLinux && options.stopOnError !== false) {
|
||||
script = "set -e\n" + script;
|
||||
}
|
||||
|
||||
if (options.env) {
|
||||
for (const key in options.env) {
|
||||
if (isLinux) {
|
||||
@@ -525,10 +521,10 @@ export class SshClient {
|
||||
}
|
||||
|
||||
if (isWinCmd) {
|
||||
//组合成&&的形式
|
||||
if (typeof script === "string") {
|
||||
script = script.split("\n");
|
||||
}
|
||||
//组合成&&的形式
|
||||
script = envScripts.concat(script);
|
||||
script = script as Array<string>;
|
||||
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 });
|
||||
},
|
||||
});
|
||||
|
||||
@@ -3,6 +3,37 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.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)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复某些页面翻译不全显示错误的bug ([0b3158f](https://github.com/certd/certd/commit/0b3158fdd5fe5bb0a98c4e65715dbc3de2c38047))
|
||||
* 修复运行流水线后会闪烁一下的bug ([dfc9362](https://github.com/certd/certd/commit/dfc9362084082ee535b898f23b2609c1d946a6fd))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 通知和定时器的删除按钮显示为红色更显眼 ([61ba83c](https://github.com/certd/certd/commit/61ba83c77546c3d505d081e19a3d68c127662bf1))
|
||||
* 优化流水线列表页面、详情页面性能,精简返回数据 ([609ac9c](https://github.com/certd/certd/commit/609ac9c9a2dde605eb09834ae59693c1cb238765))
|
||||
* 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)
|
||||
|
||||
**Note:** Version bump only for package @certd/ui-client
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-client",
|
||||
"version": "1.36.5",
|
||||
"version": "1.36.10",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
@@ -103,8 +103,8 @@
|
||||
"zod-defaults": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/lib-iframe": "^1.36.5",
|
||||
"@certd/pipeline": "^1.36.5",
|
||||
"@certd/lib-iframe": "^1.36.10",
|
||||
"@certd/pipeline": "^1.36.10",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/chai": "^4.3.12",
|
||||
|
||||
@@ -449,7 +449,7 @@ export default {
|
||||
batchDeleteConfirm: "Are you sure to batch delete these {count} records?",
|
||||
selectRecordFirst: "Please select records first",
|
||||
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",
|
||||
isDisabled: "Is Disabled",
|
||||
enabled: "Enabled",
|
||||
|
||||
@@ -415,7 +415,7 @@ export default {
|
||||
is_present_no: "否",
|
||||
basicInfo: "基础信息",
|
||||
titlea: "名称",
|
||||
disabled: "是否禁用",
|
||||
disabled: "禁用",
|
||||
ordera: "排序",
|
||||
supportBuy: "支持购买",
|
||||
intro: "介绍",
|
||||
@@ -455,7 +455,7 @@ export default {
|
||||
batchDeleteConfirm: "确定要批量删除这{count}条记录吗",
|
||||
selectRecordFirst: "请先勾选记录",
|
||||
subdomainHosted: "托管的子域名",
|
||||
subdomainHelpText: "如果您不理解什么是子域托管,可以参考文档",
|
||||
subdomainHelpText: "如果您不理解什么是子域托管,请不要随意设置,可能导致证书无法申请,可以参考文档",
|
||||
subdomainManagement: "子域管理",
|
||||
isDisabled: "是否禁用",
|
||||
enabled: "启用",
|
||||
|
||||
@@ -46,6 +46,20 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
|
||||
const { openSiteIpMonitorDialog } = useSiteIpMonitor();
|
||||
const { openSiteImportDialog } = useSiteImport();
|
||||
|
||||
function checkAll() {
|
||||
Modal.confirm({
|
||||
title: t("certd.monitor.confirmTitle"), // "确认"
|
||||
content: t("certd.monitor.confirmContent"), // "确认触发检查全部站点证书吗?"
|
||||
onOk: async () => {
|
||||
await siteInfoApi.CheckAll();
|
||||
notification.success({
|
||||
message: t("certd.monitor.checkSubmitted"), // "检查任务已提交"
|
||||
description: t("certd.monitor.pleaseRefresh"), // "请稍后刷新页面查看结果"
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
return {
|
||||
id: "siteMonitorCrud",
|
||||
crudOptions: {
|
||||
@@ -114,6 +128,14 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
});
|
||||
},
|
||||
},
|
||||
checkAll: {
|
||||
show: true,
|
||||
text: t("certd.monitor.checkAll"),
|
||||
type: "primary",
|
||||
click() {
|
||||
checkAll();
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
rowHandle: {
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="more">
|
||||
<a-button type="primary" @click="checkAll">{{ t("certd.monitor.checkAll") }}</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||
</fs-page>
|
||||
@@ -35,19 +32,6 @@ defineOptions({
|
||||
name: "SiteCertMonitor",
|
||||
});
|
||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
|
||||
function checkAll() {
|
||||
Modal.confirm({
|
||||
title: t("certd.monitor.confirmTitle"), // "确认"
|
||||
content: t("certd.monitor.confirmContent"), // "确认触发检查全部站点证书吗?"
|
||||
onOk: async () => {
|
||||
await siteInfoApi.CheckAll();
|
||||
notification.success({
|
||||
message: t("certd.monitor.checkSubmitted"), // "检查任务已提交"
|
||||
description: t("certd.monitor.pleaseRefresh"), // "请稍后刷新页面查看结果"
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 页面打开后获取列表数据
|
||||
onMounted(() => {
|
||||
|
||||
@@ -125,6 +125,7 @@ export function useCertPipelineCreator() {
|
||||
const pluginStore = usePluginStore();
|
||||
const randomHour = Math.floor(Math.random() * 6);
|
||||
const randomMin = Math.floor(Math.random() * 60);
|
||||
const randomCron = `0 ${randomMin} ${randomHour} * * *`;
|
||||
|
||||
const groupDictRef = dict({
|
||||
url: "/pi/pipeline/group/all",
|
||||
@@ -193,7 +194,7 @@ export function useCertPipelineCreator() {
|
||||
title: t("certd.pipelineForm.triggerCronTitle"),
|
||||
type: "text",
|
||||
form: {
|
||||
value: `0 ${randomMin} ${randomHour} * * *`,
|
||||
value: randomCron,
|
||||
component: {
|
||||
name: "cron-editor",
|
||||
vModel: "modelValue",
|
||||
|
||||
@@ -335,7 +335,7 @@ export default function ({ crudExpose, context: { groupDictRef, selectedRowKeys
|
||||
}
|
||||
},
|
||||
},
|
||||
_triggerCount: {
|
||||
triggerCount: {
|
||||
title: t("certd.fields.scheduledTaskCount"),
|
||||
type: "number",
|
||||
column: {
|
||||
@@ -346,7 +346,7 @@ export default function ({ crudExpose, context: { groupDictRef, selectedRowKeys
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
_stepCount: {
|
||||
stepCount: {
|
||||
title: t("certd.fields.deployTaskCount"),
|
||||
type: "number",
|
||||
form: { show: false },
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<fs-icon v-bind="status" :color="status.iconColor || status.color" />
|
||||
</template>
|
||||
<p>
|
||||
<fs-date-format :model-value="runnable.status?.startTime"></fs-date-format>
|
||||
<fs-date-format :model-value="runnable.createTime"></fs-date-format>
|
||||
<a-tag class="ml-5" :color="status.color" :closable="status.value === 'start'" @close="cancelTask">
|
||||
{{ status.label }}
|
||||
</a-tag>
|
||||
@@ -46,7 +46,7 @@ export default defineComponent({
|
||||
emits: ["view", "cancel"],
|
||||
setup(props: any, ctx: any) {
|
||||
const status = computed(() => {
|
||||
return statusUtil.get(props.runnable?.status?.result);
|
||||
return statusUtil.get(props.runnable?.status);
|
||||
});
|
||||
|
||||
function view() {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<template #title>
|
||||
<div>
|
||||
{{ t("certd.edit_notification") }}
|
||||
<a-button v-if="mode === 'edit'" @click="notificationDelete()">
|
||||
<a-button v-if="mode === 'edit'" danger @click="notificationDelete()">
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<template #title>
|
||||
<div>
|
||||
编辑任务
|
||||
<a-button v-if="editMode" @click="taskDelete()">
|
||||
<a-button v-if="editMode" danger @click="taskDelete()">
|
||||
<template #icon><DeleteOutlined /></template>
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<template #title>
|
||||
<div>
|
||||
{{ t("certd.editTrigger") }}
|
||||
<a-button v-if="mode === 'edit'" @click="triggerDelete()">
|
||||
<a-button v-if="mode === 'edit'" danger @click="triggerDelete()">
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
<a-timeline class="mt-10">
|
||||
<template v-for="item of histories" :key="item.id">
|
||||
<pi-history-timeline-item
|
||||
:runnable="item.pipeline"
|
||||
:runnable="item"
|
||||
:history-id="item.id"
|
||||
:is-current="currentHistory?.id === item.id"
|
||||
:edit-mode="editMode"
|
||||
@@ -280,7 +280,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, onMounted, onUnmounted, provide, Ref, ref, watch, computed } from "vue";
|
||||
import { computed, defineComponent, onMounted, onUnmounted, provide, ref, Ref, watch } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import PiTaskForm from "./component/task-form/index.vue";
|
||||
import PiTriggerForm from "./component/trigger-form/index.vue";
|
||||
@@ -288,7 +288,7 @@ import PiNotificationForm from "./component/notification-form/index.vue";
|
||||
import PiTaskView from "./component/task-view/index.vue";
|
||||
import PiStatusShow from "./component/status-show.vue";
|
||||
import VDraggable from "vuedraggable";
|
||||
import * as _ from "lodash-es";
|
||||
import { cloneDeep, merge, remove } from "lodash-es";
|
||||
import { message, Modal, notification } from "ant-design-vue";
|
||||
import { nanoid } from "nanoid";
|
||||
import { PipelineDetail, PipelineOptions, RunHistory } from "./type";
|
||||
@@ -299,9 +299,10 @@ import { useSettingStore } from "/@/store/settings";
|
||||
import { useUserStore } from "/@/store/user";
|
||||
import TaskShortcuts from "./component/shortcut/task-shortcuts.vue";
|
||||
import { eachSteps, findStep } from "../utils";
|
||||
import { PluginGroups, usePluginStore } from "/@/store/plugin";
|
||||
import { usePluginStore } from "/@/store/plugin";
|
||||
import { getCronNextTimes } from "/@/components/cron-editor/utils";
|
||||
import { useCertViewer } from "/@/views/certd/pipeline/use";
|
||||
import { useI18n } from "/@/locales";
|
||||
|
||||
export default defineComponent({
|
||||
name: "PipelineEdit",
|
||||
@@ -339,6 +340,7 @@ export default defineComponent({
|
||||
},
|
||||
emits: ["update:modelValue", "update:editMode"],
|
||||
setup(props, ctx) {
|
||||
const { t } = useI18n();
|
||||
const currentPipeline: Ref<any> = ref({});
|
||||
const pipeline: Ref<any> = ref({});
|
||||
|
||||
@@ -371,18 +373,20 @@ export default defineComponent({
|
||||
const loadCurrentHistoryDetail = async () => {
|
||||
const detail: RunHistory = await props.options?.getHistoryDetail({ historyId: currentHistory.value.id });
|
||||
currentHistory.value.logs = detail.logs;
|
||||
_.merge(currentHistory.value.pipeline, detail.pipeline);
|
||||
currentHistory.value.pipeline = detail.pipeline;
|
||||
currentHistory.value.status = detail.pipeline.status.result;
|
||||
};
|
||||
const changeCurrentHistory = async (history?: RunHistory) => {
|
||||
if (!history) {
|
||||
//取消历史记录查看模式
|
||||
currentHistory.value = null;
|
||||
pipeline.value = currentPipeline.value;
|
||||
pipeline.value = cloneDeep(currentPipeline.value);
|
||||
return;
|
||||
}
|
||||
currentHistory.value = history;
|
||||
pipeline.value = history.pipeline;
|
||||
await loadCurrentHistoryDetail();
|
||||
pipeline.value = currentHistory.value.pipeline;
|
||||
currentPipeline.value = currentHistory.value.pipeline;
|
||||
};
|
||||
|
||||
async function loadHistoryList(reload = false) {
|
||||
@@ -413,7 +417,8 @@ export default defineComponent({
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (historyList[0].pipeline?.version === pipeline.value.version) {
|
||||
//@ts-ignore
|
||||
if (historyList[0]?.version === pipeline.value.version) {
|
||||
await changeCurrentHistory(historyList[0]);
|
||||
}
|
||||
}
|
||||
@@ -435,8 +440,13 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
if (currentHistory.value != null) {
|
||||
if (currentHistory.value.pipeline?.status?.status === "start") {
|
||||
if (currentHistory.value.status === "start") {
|
||||
await loadCurrentHistoryDetail();
|
||||
pipeline.value = currentHistory.value.pipeline;
|
||||
// if (currentHistory.value.pipeline?.status?.status !== "start") {
|
||||
// 不传true好像不会刷新
|
||||
// await loadHistoryList(true);
|
||||
// }
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -477,7 +487,7 @@ export default defineComponent({
|
||||
return;
|
||||
}
|
||||
const detail: PipelineDetail = await props.options.getPipelineDetail({ pipelineId: value });
|
||||
currentPipeline.value = _.merge(
|
||||
currentPipeline.value = merge(
|
||||
{
|
||||
title: "新管道流程",
|
||||
stages: [],
|
||||
@@ -540,7 +550,7 @@ export default defineComponent({
|
||||
};
|
||||
|
||||
const taskCopy = (stage: any, stageIndex: number, task: any) => {
|
||||
task = _.cloneDeep(task);
|
||||
task = cloneDeep(task);
|
||||
task.id = nanoid();
|
||||
task.title = task.title + "_copy";
|
||||
for (const step of task.steps) {
|
||||
@@ -560,7 +570,7 @@ export default defineComponent({
|
||||
if (type === "delete") {
|
||||
stage.tasks.splice(taskIndex, 1);
|
||||
if (stage.tasks.length === 0) {
|
||||
_.remove(pipeline.value.stages, (item: Runnable) => {
|
||||
remove(pipeline.value.stages, (item: Runnable) => {
|
||||
return item.id === stage.id;
|
||||
});
|
||||
}
|
||||
@@ -666,9 +676,19 @@ export default defineComponent({
|
||||
notificationFormRef.value.notificationView(notification, (type: string, value: any) => {});
|
||||
}
|
||||
};
|
||||
const notificationDelete = (notification: any, index: any) => {
|
||||
Modal.confirm({
|
||||
title: t("certd.confirm"),
|
||||
content: t("certd.confirm_delete_trigger"),
|
||||
async onOk() {
|
||||
pipeline.value.notifications.splice(index, 1);
|
||||
},
|
||||
});
|
||||
};
|
||||
return {
|
||||
notificationAdd,
|
||||
notificationEdit,
|
||||
notificationDelete,
|
||||
notificationFormRef,
|
||||
};
|
||||
}
|
||||
@@ -788,7 +808,7 @@ export default defineComponent({
|
||||
currentPipeline.value = pipeline.value;
|
||||
|
||||
//移除空阶段
|
||||
_.remove(pipeline.value.stages, (item: Stage) => {
|
||||
remove(pipeline.value.stages, (item: Stage) => {
|
||||
return item.tasks.length === 0;
|
||||
});
|
||||
|
||||
@@ -802,12 +822,12 @@ export default defineComponent({
|
||||
}
|
||||
};
|
||||
const edit = () => {
|
||||
pipeline.value = _.cloneDeep(currentPipeline.value);
|
||||
pipeline.value = cloneDeep(currentPipeline.value);
|
||||
currentHistory.value = null;
|
||||
toggleEditMode(true);
|
||||
};
|
||||
const cancel = () => {
|
||||
pipeline.value = currentPipeline.value;
|
||||
pipeline.value = cloneDeep(currentPipeline.value);
|
||||
toggleEditMode(false);
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,12 @@
|
||||
<template #header>
|
||||
<div class="title">
|
||||
{{ 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>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding">
|
||||
|
||||
@@ -214,6 +214,7 @@ function transformStatusCount() {
|
||||
{ name: "error", label: "失败" },
|
||||
{ name: "canceled", label: "已取消" },
|
||||
{ name: null, label: "未执行" },
|
||||
{ name: "skip", label: "跳过" },
|
||||
];
|
||||
const result = [];
|
||||
for (const item of sorted) {
|
||||
|
||||
@@ -43,7 +43,7 @@ const slots = defineSlots();
|
||||
.data-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 180px;
|
||||
height: 188px;
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
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 { Modal, notification } from "ant-design-vue";
|
||||
import dayjs from "dayjs";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { computed } from "vue";
|
||||
|
||||
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const { t } = useI18n();
|
||||
@@ -26,7 +27,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
|
||||
const userStore = useUserStore();
|
||||
|
||||
const settingStore = useSettingStore();
|
||||
const userValidTimeEnabled = compute(() => {
|
||||
const userValidTimeEnabled = computed(() => {
|
||||
return settingStore.sysPublic.userValidTimeEnabled === true;
|
||||
});
|
||||
return {
|
||||
@@ -226,7 +227,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
|
||||
column: {
|
||||
align: "center",
|
||||
sorter: true,
|
||||
width: 100,
|
||||
width: 160,
|
||||
show: userValidTimeEnabled,
|
||||
cellRender({ value }) {
|
||||
if (value == null || value === 0) {
|
||||
|
||||
@@ -3,6 +3,44 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [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)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化流水线列表页面、详情页面性能,精简返回数据 ([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)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
20
packages/ui/certd-server/db/migration-mysql/v10027__auto.sql
Normal file
20
packages/ui/certd-server/db/migration-mysql/v10027__auto.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
DROP TABLE IF EXISTS `cd_domain`;
|
||||
CREATE TABLE `cd_domain`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint,
|
||||
`domain` varchar(512),
|
||||
challenge_type varchar(50),
|
||||
dns_provider_type varchar(50),
|
||||
dns_provider_access bigint,
|
||||
http_uploader_type varchar(50),
|
||||
http_uploader_access bigint,
|
||||
http_upload_root_dir varchar(512),
|
||||
`disabled` boolean NOT NULL DEFAULT false,
|
||||
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX `index_domain_user_id` ON `cd_domain` (`user_id`);
|
||||
CREATE INDEX `index_domain_domain` ON `cd_domain` (`domain`);
|
||||
|
||||
20
packages/ui/certd-server/db/migration-pg/v10027__auto.sql
Normal file
20
packages/ui/certd-server/db/migration-pg/v10027__auto.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
DROP TABLE IF EXISTS "cd_domain";
|
||||
CREATE TABLE "cd_domain"
|
||||
(
|
||||
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY NOT NULL,
|
||||
"user_id" bigint,
|
||||
"domain" varchar(512),
|
||||
challenge_type varchar(50),
|
||||
dns_provider_type varchar(50),
|
||||
dns_provider_access bigint,
|
||||
http_uploader_type varchar(50),
|
||||
http_uploader_access bigint,
|
||||
http_upload_root_dir varchar(512),
|
||||
"disabled" boolean NOT NULL DEFAULT (false),
|
||||
"create_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
|
||||
CREATE INDEX "index_domain_user_id" ON "cd_domain" ("user_id");
|
||||
CREATE INDEX "index_domain_domain" ON "cd_domain" ("domain");
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
DROP TABLE IF EXISTS "cd_domain";
|
||||
CREATE TABLE "cd_domain"
|
||||
(
|
||||
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"user_id" integer,
|
||||
"domain" varchar(1024),
|
||||
"domain" varchar(512),
|
||||
challenge_type varchar(50),
|
||||
dns_provider_type varchar(50),
|
||||
dns_provider_access bigint,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-server",
|
||||
"version": "1.36.5",
|
||||
"version": "1.36.10",
|
||||
"description": "fast-server base midway",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
@@ -42,20 +42,20 @@
|
||||
"@aws-sdk/client-cloudfront": "^3.699.0",
|
||||
"@aws-sdk/client-iam": "^3.699.0",
|
||||
"@aws-sdk/client-s3": "^3.705.0",
|
||||
"@certd/acme-client": "^1.36.5",
|
||||
"@certd/basic": "^1.36.5",
|
||||
"@certd/commercial-core": "^1.36.5",
|
||||
"@certd/acme-client": "^1.36.10",
|
||||
"@certd/basic": "^1.36.10",
|
||||
"@certd/commercial-core": "^1.36.10",
|
||||
"@certd/cv4pve-api-javascript": "^8.4.1",
|
||||
"@certd/jdcloud": "^1.36.5",
|
||||
"@certd/lib-huawei": "^1.36.5",
|
||||
"@certd/lib-k8s": "^1.36.5",
|
||||
"@certd/lib-server": "^1.36.5",
|
||||
"@certd/midway-flyway-js": "^1.36.5",
|
||||
"@certd/pipeline": "^1.36.5",
|
||||
"@certd/plugin-cert": "^1.36.5",
|
||||
"@certd/plugin-lib": "^1.36.5",
|
||||
"@certd/plugin-plus": "^1.36.5",
|
||||
"@certd/plus-core": "^1.36.5",
|
||||
"@certd/jdcloud": "^1.36.10",
|
||||
"@certd/lib-huawei": "^1.36.10",
|
||||
"@certd/lib-k8s": "^1.36.10",
|
||||
"@certd/lib-server": "^1.36.10",
|
||||
"@certd/midway-flyway-js": "^1.36.10",
|
||||
"@certd/pipeline": "^1.36.10",
|
||||
"@certd/plugin-cert": "^1.36.10",
|
||||
"@certd/plugin-lib": "^1.36.10",
|
||||
"@certd/plugin-plus": "^1.36.10",
|
||||
"@certd/plus-core": "^1.36.10",
|
||||
"@huaweicloud/huaweicloud-sdk-cdn": "^3.1.120",
|
||||
"@huaweicloud/huaweicloud-sdk-core": "^3.1.120",
|
||||
"@koa/cors": "^5.0.0",
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { ALL, Body, Controller, Get, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { CodeException, Constants, EncryptService } from '@certd/lib-server';
|
||||
import { CertInfoService } from '../../../modules/monitor/service/cert-info-service.js';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { OpenKey } from '../../../modules/open/service/open-key-service.js';
|
||||
import { BaseOpenController } from '../base-open-controller.js';
|
||||
import { ALL, Body, Controller, Get, Inject, Post, Provide, Query } from "@midwayjs/core";
|
||||
import { CodeException, Constants, EncryptService } from "@certd/lib-server";
|
||||
import { CertInfo } from "@certd/plugin-cert";
|
||||
import { OpenKey } from "../../../modules/open/service/open-key-service.js";
|
||||
import { BaseOpenController } from "../base-open-controller.js";
|
||||
import { CertInfoFacade } from "../../../modules/monitor/facade/cert-info-facade.js";
|
||||
import { merge } from "lodash-es";
|
||||
|
||||
export type CertGetReq = {
|
||||
domains?: string;
|
||||
certId: number;
|
||||
autoApply?:boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -16,7 +18,7 @@ export type CertGetReq = {
|
||||
@Controller('/api/v1/cert')
|
||||
export class OpenCertController extends BaseOpenController {
|
||||
@Inject()
|
||||
certInfoService: CertInfoService;
|
||||
certInfoFacade: CertInfoFacade;
|
||||
@Inject()
|
||||
encryptService: EncryptService;
|
||||
|
||||
@@ -29,10 +31,13 @@ export class OpenCertController extends BaseOpenController {
|
||||
throw new CodeException(Constants.res.openKeyError);
|
||||
}
|
||||
|
||||
const res: CertInfo = await this.certInfoService.getCertInfo({
|
||||
const req = merge({}, bean, query)
|
||||
|
||||
const res: CertInfo = await this.certInfoFacade.getCertInfo({
|
||||
userId,
|
||||
domains: bean.domains || query.domains,
|
||||
certId: bean.certId || query.certId,
|
||||
domains: req.domains,
|
||||
certId: req.certId,
|
||||
autoApply: req.autoApply??false,
|
||||
});
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import { ALL, Body, Controller, Get, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { CommonException, Constants, CrudController, PermissionException } from '@certd/lib-server';
|
||||
import { PipelineEntity } from '../../../modules/pipeline/entity/pipeline.js';
|
||||
import { HistoryService } from '../../../modules/pipeline/service/history-service.js';
|
||||
import { HistoryLogService } from '../../../modules/pipeline/service/history-log-service.js';
|
||||
import { HistoryEntity } from '../../../modules/pipeline/entity/history.js';
|
||||
import { HistoryLogEntity } from '../../../modules/pipeline/entity/history-log.js';
|
||||
import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js';
|
||||
import * as fs from 'fs';
|
||||
import { logger } from '@certd/basic';
|
||||
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
||||
import { SysSettingsService } from '@certd/lib-server';
|
||||
import { In } from 'typeorm';
|
||||
import { ALL, Body, Controller, Get, Inject, Post, Provide, Query } from "@midwayjs/core";
|
||||
import { CommonException, Constants, CrudController, PermissionException, SysSettingsService } from "@certd/lib-server";
|
||||
import { PipelineEntity } from "../../../modules/pipeline/entity/pipeline.js";
|
||||
import { HistoryService } from "../../../modules/pipeline/service/history-service.js";
|
||||
import { HistoryLogService } from "../../../modules/pipeline/service/history-log-service.js";
|
||||
import { HistoryEntity } from "../../../modules/pipeline/entity/history.js";
|
||||
import { HistoryLogEntity } from "../../../modules/pipeline/entity/history-log.js";
|
||||
import { PipelineService } from "../../../modules/pipeline/service/pipeline-service.js";
|
||||
import * as fs from "fs";
|
||||
import { logger } from "@certd/basic";
|
||||
import { AuthService } from "../../../modules/sys/authority/service/auth-service.js";
|
||||
import { In } from "typeorm";
|
||||
|
||||
/**
|
||||
* 证书
|
||||
@@ -88,11 +87,30 @@ export class HistoryController extends CrudController<HistoryService> {
|
||||
const buildQuery = qb => {
|
||||
qb.limit(20);
|
||||
};
|
||||
const withDetail = body.withDetail;
|
||||
delete body.withDetail;
|
||||
let select:any = null
|
||||
if (!withDetail) {
|
||||
select = {
|
||||
pipeline: true, // 后面这里改成false
|
||||
id: true,
|
||||
userId: true,
|
||||
pipelineId: true,
|
||||
status: true,
|
||||
// startTime: true,
|
||||
triggerType: true,
|
||||
endTime: true,
|
||||
createTime: true,
|
||||
updateTime: true
|
||||
};
|
||||
}
|
||||
const listRet = await this.getService().list({
|
||||
query: body,
|
||||
sort: { prop: 'id', asc: false },
|
||||
buildQuery,
|
||||
select
|
||||
});
|
||||
|
||||
for (const item of listRet) {
|
||||
if (!item.pipeline) {
|
||||
continue;
|
||||
@@ -100,7 +118,13 @@ export class HistoryController extends CrudController<HistoryService> {
|
||||
const json = JSON.parse(item.pipeline);
|
||||
delete json.stages;
|
||||
item.pipeline = json;
|
||||
|
||||
//@ts-ignore
|
||||
item.version = json.version;
|
||||
item.status = json.status.result
|
||||
delete item.pipeline;
|
||||
}
|
||||
|
||||
return this.ok(listRet);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { Autoload, Config, Init, Inject, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import { PipelineService } from '../pipeline/service/pipeline-service.js';
|
||||
import { logger } from '@certd/basic';
|
||||
import {Autoload, Config, Init, Inject, Scope, ScopeEnum} from '@midwayjs/core';
|
||||
import {PipelineService} from '../pipeline/service/pipeline-service.js';
|
||||
import {logger} from '@certd/basic';
|
||||
import {SysSettingsService, SysSiteInfo} from '@certd/lib-server';
|
||||
import { SiteInfoService } from '../monitor/index.js';
|
||||
import { Cron } from '../cron/cron.js';
|
||||
import {SiteInfoService} from '../monitor/index.js';
|
||||
import {Cron} from '../cron/cron.js';
|
||||
import {UserSettingsService} from "../mine/service/user-settings-service.js";
|
||||
import {UserSiteMonitorSetting} from "../mine/service/models.js";
|
||||
import {getPlusInfo} from "@certd/plus-core";
|
||||
import dayjs from "dayjs";
|
||||
import {NotificationService} from "../pipeline/service/notification-service.js";
|
||||
import {UserService} from "../sys/authority/service/user-service.js";
|
||||
import {Between} from "typeorm";
|
||||
|
||||
@Autoload()
|
||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||
@@ -58,6 +59,8 @@ export class AutoCRegisterCron {
|
||||
|
||||
|
||||
await this.registerPlusExpireCheckCron();
|
||||
|
||||
await this.registerUserExpireCheckCron()
|
||||
}
|
||||
|
||||
async registerSiteMonitorCron() {
|
||||
@@ -71,7 +74,7 @@ export class AutoCRegisterCron {
|
||||
}
|
||||
})
|
||||
for (const item of monitorSettingList) {
|
||||
const setting = item.setting ?? JSON.parse(item.setting)
|
||||
const setting = item.setting ? JSON.parse(item.setting):{}
|
||||
if(!setting?.cron){
|
||||
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
|
||||
subject: subject,
|
||||
text: email.content,
|
||||
html: email.html,
|
||||
attachments: email.attachments,
|
||||
};
|
||||
await transporter.sendMail(mailOptions);
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
}
|
||||
continue
|
||||
}
|
||||
const cnameRecord:CnameRecordEntity = cnameMap[mainDomain]
|
||||
const cnameRecord:CnameRecordEntity = cnameMap[domain]
|
||||
if (cnameRecord) {
|
||||
domainVerifiers[domain] = {
|
||||
domain,
|
||||
@@ -168,7 +168,7 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
}
|
||||
continue
|
||||
}
|
||||
const httpRecord = httpMap[mainDomain]
|
||||
const httpRecord = httpMap[domain]
|
||||
if (httpRecord) {
|
||||
domainVerifiers[domain] = {
|
||||
domain,
|
||||
|
||||
@@ -1,19 +1,27 @@
|
||||
import {Inject, Provide, Scope, ScopeEnum} from '@midwayjs/core';
|
||||
import {InjectEntityModel} from '@midwayjs/typeorm';
|
||||
import {Repository} from 'typeorm';
|
||||
import {AccessService, BaseService, PlusService, ValidateException} from '@certd/lib-server';
|
||||
import {CnameRecordEntity, CnameRecordStatusType} from '../entity/cname-record.js';
|
||||
import {createDnsProvider, IDnsProvider} from '@certd/plugin-cert';
|
||||
import {CnameProvider, CnameRecord} from '@certd/pipeline';
|
||||
import {cache, http, isDev, logger, utils} from '@certd/basic';
|
||||
import {getAuthoritativeDnsResolver, walkTxtRecord} from '@certd/acme-client';
|
||||
import {CnameProviderService} from './cname-provider-service.js';
|
||||
import {CnameProviderEntity} from '../entity/cname-provider.js';
|
||||
import {CommonDnsProvider} from './common-provider.js';
|
||||
import {DomainParser} from "@certd/plugin-cert/dist/dns-provider/domain-parser.js";
|
||||
import punycode from 'punycode.js'
|
||||
import {SubDomainService} from "../../pipeline/service/sub-domain-service.js";
|
||||
import {SubDomainsGetter} from "../../pipeline/service/getter/sub-domain-getter.js";
|
||||
import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core";
|
||||
import { InjectEntityModel } from "@midwayjs/typeorm";
|
||||
import { Repository } from "typeorm";
|
||||
import {
|
||||
AccessService,
|
||||
BaseService,
|
||||
PlusService,
|
||||
SysInstallInfo,
|
||||
SysSettingsService,
|
||||
ValidateException
|
||||
} from "@certd/lib-server";
|
||||
import { CnameRecordEntity, CnameRecordStatusType } from "../entity/cname-record.js";
|
||||
import { createDnsProvider, IDnsProvider } from "@certd/plugin-cert";
|
||||
import { CnameProvider, CnameRecord } from "@certd/pipeline";
|
||||
import { cache, http, isDev, logger, utils } from "@certd/basic";
|
||||
import { getAuthoritativeDnsResolver, walkTxtRecord } from "@certd/acme-client";
|
||||
import { CnameProviderService } from "./cname-provider-service.js";
|
||||
import { CnameProviderEntity } from "../entity/cname-provider.js";
|
||||
import { CommonDnsProvider } from "./common-provider.js";
|
||||
import { DomainParser } from "@certd/plugin-cert/dist/dns-provider/domain-parser.js";
|
||||
import punycode from "punycode.js";
|
||||
import { SubDomainService } from "../../pipeline/service/sub-domain-service.js";
|
||||
import { SubDomainsGetter } from "../../pipeline/service/getter/sub-domain-getter.js";
|
||||
|
||||
type CnameCheckCacheValue = {
|
||||
validating: boolean;
|
||||
pass: boolean;
|
||||
@@ -35,6 +43,8 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||
|
||||
@Inject()
|
||||
cnameProviderService: CnameProviderService;
|
||||
@Inject()
|
||||
sysSettingsService: SysSettingsService;
|
||||
|
||||
@Inject()
|
||||
accessService: AccessService;
|
||||
@@ -101,7 +111,17 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||
}
|
||||
param.hostRecord = hostRecord;
|
||||
|
||||
const cnameKey = utils.id.simpleNanoId().toLowerCase();
|
||||
const randomKey = utils.id.simpleNanoId(6).toLowerCase();
|
||||
|
||||
let userIdHash = ""
|
||||
if(param.cnameProviderId < 0){
|
||||
//公共cname服务
|
||||
userIdHash = utils.hash.md5(`userId${userId}_${randomKey}`).substring(0, 10)
|
||||
}else{
|
||||
const installInfo = await this.sysSettingsService.getSetting<SysInstallInfo>(SysInstallInfo)
|
||||
userIdHash = utils.hash.md5(`${installInfo.siteId}_${randomKey}`).substring(0, 10)
|
||||
}
|
||||
const cnameKey = `${userIdHash}-${randomKey}`;
|
||||
const safeDomain = param.domain.replaceAll('.', '-');
|
||||
param.recordValue = `${safeDomain}.${cnameKey}.${cnameProvider.domain}`;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core";
|
||||
import { CodeException, Constants } from "@certd/lib-server";
|
||||
import { CertInfoEntity } from "../entity/cert-info.js";
|
||||
import { utils } from "@certd/basic";
|
||||
import { PipelineService } from "../../pipeline/service/pipeline-service.js";
|
||||
import { UserSettingsService } from "../../mine/service/user-settings-service.js";
|
||||
import { UserEmailSetting } from "../../mine/service/models.js";
|
||||
import { PipelineEntity } from "../../pipeline/entity/pipeline.js";
|
||||
import { CertInfoService } from "../service/cert-info-service.js";
|
||||
import { DomainService } from "../../cert/service/domain-service.js";
|
||||
import { DomainVerifierGetter } from "../../pipeline/service/getter/domain-verifier-getter.js";
|
||||
|
||||
|
||||
@Provide("CertInfoFacade")
|
||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||
export class CertInfoFacade {
|
||||
|
||||
@Inject()
|
||||
pipelineService: PipelineService;
|
||||
|
||||
@Inject()
|
||||
certInfoService: CertInfoService ;
|
||||
|
||||
@Inject()
|
||||
domainService: DomainService
|
||||
|
||||
@Inject()
|
||||
userSettingsService : UserSettingsService
|
||||
|
||||
async getCertInfo(req: { domains?: string; certId?: number; userId: number,autoApply?:boolean }) {
|
||||
const { domains, certId, userId } = req;
|
||||
if (certId) {
|
||||
return await this.certInfoService.getCertInfoById({ id: certId, userId });
|
||||
}
|
||||
if (!domains) {
|
||||
throw new CodeException({
|
||||
...Constants.res.openParamError,
|
||||
message: "参数错误,certId和domains必须传一个",
|
||||
});
|
||||
}
|
||||
const domainArr = domains.split(',');
|
||||
|
||||
const matchedList = await this.certInfoService.getMatchCertList({domains:domainArr,userId})
|
||||
let matched: CertInfoEntity = null
|
||||
if (matchedList.length === 0 ) {
|
||||
if(req.autoApply === true){
|
||||
//自动申请,先创建自动申请流水线
|
||||
const pipeline:PipelineEntity = await this.createAutoPipeline({domains:domainArr,userId})
|
||||
await this.triggerApplyPipeline({pipelineId:pipeline.id})
|
||||
}else{
|
||||
throw new CodeException({
|
||||
...Constants.res.openCertNotFound,
|
||||
message:"在证书仓库中没有找到匹配域名的证书,请先创建证书流水线,或传入autoApply参数,自动创建"
|
||||
});
|
||||
}
|
||||
}
|
||||
matched = null;
|
||||
for (const item of matchedList) {
|
||||
if (item.expiresTime>0 && item.expiresTime > new Date().getTime()) {
|
||||
matched = item;
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!matched) {
|
||||
if(req.autoApply === true){
|
||||
//如果没有找到有效期内的证书,则自动触发一次申请
|
||||
const first = matchedList[0]
|
||||
await this.triggerApplyPipeline({pipelineId:first.pipelineId})
|
||||
return
|
||||
}else{
|
||||
throw new CodeException({
|
||||
...Constants.res.openCertNotFound,
|
||||
message:"证书已过期,请触发流水线申请,或者传入autoApply参数,自动触发"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return await this.certInfoService.getCertInfoById({ id: matched.id, userId: userId });
|
||||
}
|
||||
|
||||
async createAutoPipeline(req:{domains:string[],userId:number}){
|
||||
|
||||
const verifierGetter = new DomainVerifierGetter(req.userId, this.domainService)
|
||||
|
||||
const allDomains = []
|
||||
for (const item of req.domains) {
|
||||
allDomains.push(item.replaceAll("*.",""))
|
||||
}
|
||||
const verifiers = await verifierGetter.getVerifiers(allDomains)
|
||||
for (const item of allDomains) {
|
||||
if (!verifiers[item]){
|
||||
throw new CodeException({
|
||||
...Constants.res.openDomainNoVerifier,
|
||||
message:`域名${item}没有配置校验方式,请先在域名管理页面配置`,
|
||||
data:{
|
||||
domain:item
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const userEmailSetting = await this.userSettingsService.getSetting<UserEmailSetting>(req.userId,UserEmailSetting)
|
||||
if(!userEmailSetting.list){
|
||||
throw new CodeException(Constants.res.openEmailNotFound)
|
||||
}
|
||||
const email = userEmailSetting.list[0]
|
||||
|
||||
return await this.pipelineService.createAutoPipeline({
|
||||
domains: req.domains,
|
||||
email,
|
||||
userId: req.userId,
|
||||
from:"OpenAPI"
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
async triggerApplyPipeline(req:{pipelineId:number}){
|
||||
//查询流水线状态
|
||||
const status = await this.pipelineService.getStatus(req.pipelineId)
|
||||
if (status != 'running') {
|
||||
await this.pipelineService.trigger(req.pipelineId)
|
||||
await utils.sleep(1000)
|
||||
}
|
||||
const certInfo = await this.certInfoService.getByPipelineId(req.pipelineId)
|
||||
throw new CodeException({
|
||||
...Constants.res.openCertApplying,
|
||||
data:{
|
||||
pipelineId:req.pipelineId,
|
||||
certId:certInfo?.id
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import {Provide, Scope, ScopeEnum} from "@midwayjs/core";
|
||||
import {BaseService, CodeException, Constants, PageReq} from "@certd/lib-server";
|
||||
import {InjectEntityModel} from "@midwayjs/typeorm";
|
||||
import {MoreThan, Repository} from "typeorm";
|
||||
import {CertInfoEntity} from "../entity/cert-info.js";
|
||||
import {utils} from "@certd/basic";
|
||||
import {CertInfo, CertReader} from "@certd/plugin-cert";
|
||||
import { Provide, Scope, ScopeEnum } from "@midwayjs/core";
|
||||
import { BaseService, CodeException, Constants, PageReq } from "@certd/lib-server";
|
||||
import { InjectEntityModel } from "@midwayjs/typeorm";
|
||||
import { Repository } from "typeorm";
|
||||
import { CertInfoEntity } from "../entity/cert-info.js";
|
||||
import { utils } from "@certd/basic";
|
||||
import { CertInfo, CertReader } from "@certd/plugin-cert";
|
||||
|
||||
export type UploadCertReq = {
|
||||
id?: number;
|
||||
@@ -71,6 +71,7 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
||||
}
|
||||
|
||||
await this.addOrUpdate(bean);
|
||||
return bean.id
|
||||
}
|
||||
|
||||
async deleteByPipelineId(id: number) {
|
||||
@@ -82,44 +83,34 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
||||
});
|
||||
}
|
||||
|
||||
async getCertInfo(params: { domains?: string; certId?: number; userId: number }) {
|
||||
const { domains, certId, userId } = params;
|
||||
if (certId) {
|
||||
return await this.getCertInfoById({ id: certId, userId });
|
||||
}
|
||||
return await this.getCertInfoByDomains({
|
||||
domains,
|
||||
userId,
|
||||
});
|
||||
}
|
||||
|
||||
private async getCertInfoByDomains(params: { domains: string; userId: number }) {
|
||||
async getMatchCertList(params: { domains: string[]; userId: number }) {
|
||||
const { domains, userId } = params;
|
||||
if (!domains) {
|
||||
throw new CodeException(Constants.res.openCertNotFound);
|
||||
throw new CodeException({
|
||||
...Constants.res.openCertNotFound,
|
||||
message:"域名不能为空"
|
||||
});
|
||||
}
|
||||
const domainArr = domains.split(',');
|
||||
|
||||
const list = await this.find({
|
||||
select: {
|
||||
id: true,
|
||||
domains: true,
|
||||
expiresTime:true,
|
||||
pipelineId:true,
|
||||
},
|
||||
where: {
|
||||
userId,
|
||||
expiresTime: MoreThan(new Date().getTime())
|
||||
},
|
||||
order: {
|
||||
id: 'DESC',
|
||||
},
|
||||
});
|
||||
//遍历查找
|
||||
const matched = list.find(item => {
|
||||
return list.filter(item => {
|
||||
const itemDomains = item.domains.split(',');
|
||||
return utils.domain.match(domainArr, itemDomains);
|
||||
return utils.domain.match(domains, itemDomains);
|
||||
});
|
||||
if (!matched) {
|
||||
throw new CodeException(Constants.res.openCertNotFound);
|
||||
}
|
||||
|
||||
return await this.getCertInfoById({ id: matched.id, userId: userId });
|
||||
}
|
||||
|
||||
async getCertInfoById(req: { id: number; userId: number }) {
|
||||
@@ -176,4 +167,12 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
||||
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 ){
|
||||
//检查是否有变化
|
||||
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){
|
||||
//无变化
|
||||
hasChanged = false
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
import {IServiceGetter} from "@certd/pipeline";
|
||||
import {Inject, Provide, Scope, ScopeEnum} from "@midwayjs/core";
|
||||
import {AccessGetter, AccessService} from "@certd/lib-server";
|
||||
import {CnameProxyService} from "./cname-proxy-service.js";
|
||||
import {NotificationGetter} from "./notification-getter.js";
|
||||
import {NotificationService} from "../notification-service.js";
|
||||
import {CnameRecordService} from "../../../cname/service/cname-record-service.js";
|
||||
import {SubDomainsGetter} from './sub-domain-getter.js'
|
||||
import {DomainVerifierGetter} from "./domain-verifier-getter.js";
|
||||
import {Context} from "@midwayjs/koa";
|
||||
import {DomainService} from "../../../cert/service/domain-service.js";
|
||||
import {SubDomainService} from "../sub-domain-service.js";
|
||||
import { IServiceGetter } from "@certd/pipeline";
|
||||
import { ApplicationContext, IMidwayContainer, Provide, Scope, ScopeEnum } from "@midwayjs/core";
|
||||
import { AccessGetter, AccessService } from "@certd/lib-server";
|
||||
import { CnameProxyService } from "./cname-proxy-service.js";
|
||||
import { NotificationGetter } from "./notification-getter.js";
|
||||
import { NotificationService } from "../notification-service.js";
|
||||
import { CnameRecordService } from "../../../cname/service/cname-record-service.js";
|
||||
import { SubDomainsGetter } from "./sub-domain-getter.js";
|
||||
import { DomainVerifierGetter } from "./domain-verifier-getter.js";
|
||||
import { DomainService } from "../../../cert/service/domain-service.js";
|
||||
import { SubDomainService } from "../sub-domain-service.js";
|
||||
|
||||
export class TaskServiceGetter implements IServiceGetter{
|
||||
private userId: number;
|
||||
private ctx : Context;
|
||||
constructor(userId:number,ctx:Context) {
|
||||
private appCtx : IMidwayContainer;
|
||||
constructor(userId:number,appCtx:IMidwayContainer) {
|
||||
this.userId = userId;
|
||||
this.ctx = ctx
|
||||
this.appCtx = appCtx
|
||||
}
|
||||
async get<T>(serviceName: string): Promise<T> {
|
||||
|
||||
@@ -36,27 +35,27 @@ export class TaskServiceGetter implements IServiceGetter{
|
||||
}
|
||||
|
||||
async getSubDomainsGetter(): Promise<SubDomainsGetter> {
|
||||
const subDomainsService:SubDomainService = await this.ctx.requestContext.getAsync("subDomainService")
|
||||
const subDomainsService:SubDomainService = await this.appCtx.getAsync("subDomainService")
|
||||
return new SubDomainsGetter(this.userId, subDomainsService)
|
||||
}
|
||||
|
||||
async getAccessService(): Promise<AccessGetter> {
|
||||
const accessService:AccessService = await this.ctx.requestContext.getAsync("accessService")
|
||||
const accessService:AccessService = await this.appCtx.getAsync("accessService")
|
||||
return new AccessGetter(this.userId, accessService.getById.bind(accessService));
|
||||
}
|
||||
|
||||
async getCnameProxyService(): Promise<CnameProxyService> {
|
||||
const cnameRecordService:CnameRecordService = await this.ctx.requestContext.getAsync("cnameRecordService")
|
||||
const cnameRecordService:CnameRecordService = await this.appCtx.getAsync("cnameRecordService")
|
||||
return new CnameProxyService(this.userId, cnameRecordService.getWithAccessByDomain.bind(cnameRecordService));
|
||||
}
|
||||
|
||||
async getNotificationService(): Promise<NotificationGetter> {
|
||||
const notificationService:NotificationService = await this.ctx.requestContext.getAsync("notificationService")
|
||||
const notificationService:NotificationService = await this.appCtx.getAsync("notificationService")
|
||||
return new NotificationGetter(this.userId, notificationService);
|
||||
}
|
||||
|
||||
async getDomainVerifierGetter(): Promise<DomainVerifierGetter> {
|
||||
const domainService:DomainService = await this.ctx.requestContext.getAsync("domainService")
|
||||
const domainService:DomainService = await this.appCtx.getAsync("domainService")
|
||||
return new DomainVerifierGetter(this.userId, domainService);
|
||||
}
|
||||
}
|
||||
@@ -67,12 +66,12 @@ export type TaskServiceCreateReq = {
|
||||
@Provide()
|
||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||
export class TaskServiceBuilder {
|
||||
@Inject()
|
||||
ctx: Context;
|
||||
@ApplicationContext()
|
||||
appCtx: IMidwayContainer;
|
||||
|
||||
create(req:TaskServiceCreateReq){
|
||||
const userId = req.userId;
|
||||
return new TaskServiceGetter(userId,this.ctx)
|
||||
return new TaskServiceGetter(userId,this.appCtx)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {Config, Inject, Provide, Scope, ScopeEnum, sleep} from "@midwayjs/core";
|
||||
import {InjectEntityModel} from "@midwayjs/typeorm";
|
||||
import {In, MoreThan, Repository} from "typeorm";
|
||||
import { Config, Inject, Provide, Scope, ScopeEnum, sleep } from "@midwayjs/core";
|
||||
import { InjectEntityModel } from "@midwayjs/typeorm";
|
||||
import { In, MoreThan, Repository } from "typeorm";
|
||||
import {
|
||||
AccessService,
|
||||
BaseService,
|
||||
@@ -11,8 +11,8 @@ import {
|
||||
SysSettingsService,
|
||||
SysSiteInfo
|
||||
} from "@certd/lib-server";
|
||||
import {PipelineEntity} from "../entity/pipeline.js";
|
||||
import {PipelineDetail} from "../entity/vo/pipeline-detail.js";
|
||||
import { PipelineEntity } from "../entity/pipeline.js";
|
||||
import { PipelineDetail } from "../entity/vo/pipeline-detail.js";
|
||||
import {
|
||||
Executor,
|
||||
IAccessService,
|
||||
@@ -25,33 +25,32 @@ import {
|
||||
SysInfo,
|
||||
UserInfo
|
||||
} from "@certd/pipeline";
|
||||
import {DbStorage} from "./db-storage.js";
|
||||
import {StorageService} from "./storage-service.js";
|
||||
import {Cron} from "../../cron/cron.js";
|
||||
import {HistoryService} from "./history-service.js";
|
||||
import {HistoryEntity} from "../entity/history.js";
|
||||
import {HistoryLogEntity} from "../entity/history-log.js";
|
||||
import {HistoryLogService} from "./history-log-service.js";
|
||||
import {EmailService} from "../../basic/service/email-service.js";
|
||||
import {UserService} from "../../sys/authority/service/user-service.js";
|
||||
import {CnameRecordService} from "../../cname/service/cname-record-service.js";
|
||||
import {PluginConfigGetter} from "../../plugin/service/plugin-config-getter.js";
|
||||
import { DbStorage } from "./db-storage.js";
|
||||
import { StorageService } from "./storage-service.js";
|
||||
import { Cron } from "../../cron/cron.js";
|
||||
import { HistoryService } from "./history-service.js";
|
||||
import { HistoryEntity } from "../entity/history.js";
|
||||
import { HistoryLogEntity } from "../entity/history-log.js";
|
||||
import { HistoryLogService } from "./history-log-service.js";
|
||||
import { EmailService } from "../../basic/service/email-service.js";
|
||||
import { UserService } from "../../sys/authority/service/user-service.js";
|
||||
import { CnameRecordService } from "../../cname/service/cname-record-service.js";
|
||||
import { PluginConfigGetter } from "../../plugin/service/plugin-config-getter.js";
|
||||
import dayjs from "dayjs";
|
||||
import {DbAdapter} from "../../db/index.js";
|
||||
import {isComm, isPlus} from "@certd/plus-core";
|
||||
import {logger} from "@certd/basic";
|
||||
import {UrlService} from "./url-service.js";
|
||||
import {NotificationService} from "./notification-service.js";
|
||||
import {UserSuiteEntity, UserSuiteService} from "@certd/commercial-core";
|
||||
import {CertInfoService} from "../../monitor/service/cert-info-service.js";
|
||||
import {TaskServiceBuilder} from "./getter/task-service-getter.js";
|
||||
import {nanoid} from "nanoid";
|
||||
import {set} from "lodash-es";
|
||||
import { DbAdapter } from "../../db/index.js";
|
||||
import { isComm, isPlus } from "@certd/plus-core";
|
||||
import { logger } from "@certd/basic";
|
||||
import { UrlService } from "./url-service.js";
|
||||
import { NotificationService } from "./notification-service.js";
|
||||
import { UserSuiteEntity, UserSuiteService } from "@certd/commercial-core";
|
||||
import { CertInfoService } from "../../monitor/service/cert-info-service.js";
|
||||
import { TaskServiceBuilder } from "./getter/task-service-getter.js";
|
||||
import { nanoid } from "nanoid";
|
||||
import { set } from "lodash-es";
|
||||
|
||||
const runningTasks: Map<string | number, Executor> = new Map();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 证书申请
|
||||
*/
|
||||
@@ -91,7 +90,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
@Inject()
|
||||
cron: Cron;
|
||||
|
||||
@Config('certd')
|
||||
@Config("certd")
|
||||
private certdConfig: any;
|
||||
|
||||
@Inject()
|
||||
@@ -112,17 +111,35 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
}
|
||||
|
||||
async add(bean: PipelineEntity) {
|
||||
bean.status = ResultType.none
|
||||
bean.status = ResultType.none;
|
||||
await this.save(bean);
|
||||
return bean;
|
||||
}
|
||||
|
||||
async page(pageReq: PageReq<PipelineEntity>) {
|
||||
//模版流水线不要被查询出来
|
||||
set(pageReq,"query.isTemplate",false)
|
||||
set(pageReq, "query.isTemplate", false);
|
||||
const result = await super.page(pageReq);
|
||||
await this.fillLastVars(result.records);
|
||||
|
||||
for (const item of result.records) {
|
||||
if (!item.content) {
|
||||
continue;
|
||||
}
|
||||
const pipeline = JSON.parse(item.content);
|
||||
let stepCount = 0;
|
||||
if(pipeline.stages){
|
||||
RunnableCollection.each(pipeline.stages, (runnable: any) => {
|
||||
stepCount++;
|
||||
});
|
||||
}
|
||||
// @ts-ignore
|
||||
item.stepCount = stepCount;
|
||||
// @ts-ignore
|
||||
item.triggerCount = pipeline.triggers?.length;
|
||||
delete item.content;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -132,7 +149,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
for (const record of records) {
|
||||
pipelineIds.push(record.id);
|
||||
recordMap[record.id] = record;
|
||||
record.title = record.title + '';
|
||||
record.title = record.title + "";
|
||||
}
|
||||
if (pipelineIds?.length > 0) {
|
||||
const vars = await this.storageService.findPipelineVars(pipelineIds);
|
||||
@@ -153,17 +170,17 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
const info = await this.info(pipelineId);
|
||||
if (info && !info.disabled) {
|
||||
const pipeline = JSON.parse(info.content);
|
||||
this.registerTriggers(pipeline,false);
|
||||
this.registerTriggers(pipeline, false);
|
||||
}
|
||||
}
|
||||
|
||||
public async registerTrigger(info:PipelineEntity) {
|
||||
public async registerTrigger(info: PipelineEntity) {
|
||||
if (info == null) {
|
||||
return;
|
||||
}
|
||||
if (info && !info.disabled) {
|
||||
const pipeline = JSON.parse(info.content);
|
||||
this.registerTriggers(pipeline,false);
|
||||
this.registerTriggers(pipeline, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,12 +207,12 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
const isUpdate = bean.id > 0 && old != null;
|
||||
|
||||
|
||||
const pipeline = JSON.parse(bean.content || '{}');
|
||||
const pipeline = JSON.parse(bean.content || "{}");
|
||||
RunnableCollection.initPipelineRunnableType(pipeline);
|
||||
let domains = [];
|
||||
if (pipeline.stages) {
|
||||
RunnableCollection.each(pipeline.stages, (runnable: any) => {
|
||||
if (runnable.runnableType === 'step' && runnable.type.indexOf('CertApply')>=0) {
|
||||
if (runnable.runnableType === "step" && runnable.type.indexOf("CertApply") >= 0) {
|
||||
domains = runnable.input.domains || [];
|
||||
}
|
||||
});
|
||||
@@ -206,7 +223,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
await this.checkMaxPipelineCount(bean, pipeline, domains);
|
||||
}
|
||||
|
||||
if (!bean.status ){
|
||||
if (!bean.status) {
|
||||
bean.status = ResultType.none;
|
||||
}
|
||||
if (!isUpdate) {
|
||||
@@ -217,9 +234,11 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
await this.doUpdatePipelineJson(bean, pipeline);
|
||||
|
||||
//保存域名信息到certInfo表
|
||||
let fromType = 'pipeline';
|
||||
if (bean.type === 'cert_upload') {
|
||||
fromType = 'upload';
|
||||
let fromType = "pipeline";
|
||||
if (bean.type === "cert_upload") {
|
||||
fromType = "upload";
|
||||
}else if (bean.type === "cert_auto") {
|
||||
fromType = "auto";
|
||||
}
|
||||
await this.certInfoService.updateDomains(pipeline.id, pipeline.userId || bean.userId, domains, fromType);
|
||||
return bean;
|
||||
@@ -230,7 +249,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
* @param bean
|
||||
* @param pipeline
|
||||
*/
|
||||
async doUpdatePipelineJson(bean: PipelineEntity, pipeline:Pipeline) {
|
||||
async doUpdatePipelineJson(bean: PipelineEntity, pipeline: Pipeline) {
|
||||
await this.clearTriggers(bean);
|
||||
if (pipeline.title) {
|
||||
bean.title = pipeline.title;
|
||||
@@ -261,7 +280,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
throw new NeedSuiteException(`对不起,您最多只能添加${userSuite.domainCount.max}个域名,请购买或升级套餐`);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
//非商业版校验用户最大流水线数量
|
||||
const userId = bean.userId;
|
||||
const userIsAdmin = await this.userService.isAdmin(userId);
|
||||
@@ -280,12 +299,12 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
async foreachPipeline(callback: (pipeline: PipelineEntity) => void) {
|
||||
const idEntityList = await this.repository.find({
|
||||
select: {
|
||||
id: true,
|
||||
id: true
|
||||
},
|
||||
where: {
|
||||
disabled: false,
|
||||
templateId: 0,
|
||||
},
|
||||
templateId: 0
|
||||
}
|
||||
});
|
||||
const ids = idEntityList.map(item => {
|
||||
return item.id;
|
||||
@@ -305,7 +324,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
//分段加载记录
|
||||
for (const idArr of idsSpan) {
|
||||
const list = await this.repository.findBy({
|
||||
id: In(idArr),
|
||||
id: In(idArr)
|
||||
});
|
||||
|
||||
for (const entity of list) {
|
||||
@@ -330,14 +349,14 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
if (onlyAdminUser && entity.userId !== 1) {
|
||||
return;
|
||||
}
|
||||
const pipeline = JSON.parse(entity.content ?? '{}');
|
||||
const pipeline = JSON.parse(entity.content ?? "{}");
|
||||
try {
|
||||
await this.registerTriggers(pipeline, immediateTriggerOnce);
|
||||
} catch (e) {
|
||||
logger.error('加载定时trigger失败:', e);
|
||||
logger.error("加载定时trigger失败:", e);
|
||||
}
|
||||
});
|
||||
logger.info('定时器数量:', this.cron.getTaskSize());
|
||||
logger.info("定时器数量:", this.cron.getTaskSize());
|
||||
}
|
||||
|
||||
async registerTriggers(pipeline?: Pipeline, immediateTriggerOnce = false) {
|
||||
@@ -359,18 +378,18 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
if (isComm()) {
|
||||
await this.checkHasDeployCount(id, entity.userId);
|
||||
}
|
||||
await this.checkUserStatus(entity.userId)
|
||||
await this.checkUserStatus(entity.userId);
|
||||
this.cron.register({
|
||||
name: `pipeline.${id}.trigger.once`,
|
||||
cron: null,
|
||||
job: async () => {
|
||||
logger.info('用户手动启动job');
|
||||
logger.info("用户手动启动job");
|
||||
try {
|
||||
await this.doRun(entity, null, stepId);
|
||||
} catch (e) {
|
||||
logger.error('手动job执行失败:', e);
|
||||
logger.error("手动job执行失败:", e);
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -382,7 +401,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
logger.error(e.message);
|
||||
await this.update({
|
||||
id: pipelineId,
|
||||
status: 'no_deploy_count',
|
||||
status: "no_deploy_count"
|
||||
});
|
||||
}
|
||||
throw e;
|
||||
@@ -390,7 +409,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
async delete(id:any) {
|
||||
async delete(id: any) {
|
||||
await this.clearTriggers(id);
|
||||
//TODO 删除storage
|
||||
// const storage = new DbStorage(pipeline.userId, this.storageService);
|
||||
@@ -405,11 +424,11 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
if (id == null) {
|
||||
return;
|
||||
}
|
||||
let pipeline:PipelineEntity = null
|
||||
if (typeof id === 'number') {
|
||||
let pipeline: PipelineEntity = null;
|
||||
if (typeof id === "number") {
|
||||
pipeline = await this.info(id);
|
||||
}else{
|
||||
pipeline = id
|
||||
} else {
|
||||
pipeline = id;
|
||||
}
|
||||
if (!pipeline) {
|
||||
return;
|
||||
@@ -429,7 +448,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
|
||||
registerCron(pipelineId, trigger) {
|
||||
if (pipelineId == null) {
|
||||
logger.warn('pipelineId为空,无法注册定时任务');
|
||||
logger.warn("pipelineId为空,无法注册定时任务");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -438,11 +457,11 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
return;
|
||||
}
|
||||
cron = cron.trim();
|
||||
if (cron.startsWith('* *')) {
|
||||
cron = cron.replace('* *', '0 0');
|
||||
if (cron.startsWith("* *")) {
|
||||
cron = cron.replace("* *", "0 0");
|
||||
}
|
||||
if (cron.startsWith('*')) {
|
||||
cron = cron.replace('*', '0');
|
||||
if (cron.startsWith("*")) {
|
||||
cron = cron.replace("*", "0");
|
||||
}
|
||||
const triggerId = trigger.id;
|
||||
const name = this.buildCronKey(pipelineId, triggerId);
|
||||
@@ -451,19 +470,19 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
name,
|
||||
cron,
|
||||
job: async () => {
|
||||
logger.info('定时任务触发:', pipelineId, triggerId);
|
||||
logger.info("定时任务触发:", pipelineId, triggerId);
|
||||
if (pipelineId == null) {
|
||||
logger.warn('pipelineId为空,无法执行');
|
||||
logger.warn("pipelineId为空,无法执行");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await this.run(pipelineId, triggerId);
|
||||
} catch (e) {
|
||||
logger.error('定时job执行失败:', e);
|
||||
logger.error("定时job执行失败:", e);
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
logger.info('当前定时器数量:', this.cron.getTaskSize());
|
||||
logger.info("当前定时器数量:", this.cron.getTaskSize());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -483,11 +502,11 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
if (isComm()) {
|
||||
suite = await this.checkHasDeployCount(id, entity.userId);
|
||||
}
|
||||
try{
|
||||
await this.checkUserStatus(entity.userId)
|
||||
}catch (e) {
|
||||
logger.info(e.message)
|
||||
return
|
||||
try {
|
||||
await this.checkUserStatus(entity.userId);
|
||||
} catch (e) {
|
||||
logger.info(e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -505,7 +524,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (triggerType === 'timer') {
|
||||
if (triggerType === "timer") {
|
||||
if (entity.disabled) {
|
||||
return;
|
||||
}
|
||||
@@ -514,25 +533,25 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
const onChanged = async (history: RunHistory) => {
|
||||
//保存执行历史
|
||||
try {
|
||||
logger.info('保存执行历史:', history.id);
|
||||
logger.info("保存执行历史:", history.id);
|
||||
await this.saveHistory(history);
|
||||
} catch (e) {
|
||||
const pipelineEntity = new PipelineEntity();
|
||||
pipelineEntity.id = id;
|
||||
pipelineEntity.status = 'error';
|
||||
pipelineEntity.status = "error";
|
||||
pipelineEntity.lastHistoryTime = history.pipeline.status.startTime;
|
||||
await this.update(pipelineEntity);
|
||||
logger.error('保存执行历史失败:', e);
|
||||
logger.error("保存执行历史失败:", e);
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
const userId = entity.userId;
|
||||
const historyId = await this.historyService.start(entity,triggerType);
|
||||
const historyId = await this.historyService.start(entity, triggerType);
|
||||
const userIsAdmin = await this.userService.isAdmin(userId);
|
||||
const user: UserInfo = {
|
||||
id: userId,
|
||||
role: userIsAdmin ? 'admin' : 'user',
|
||||
role: userIsAdmin ? "admin" : "user"
|
||||
};
|
||||
|
||||
|
||||
@@ -543,11 +562,11 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
}
|
||||
|
||||
const taskServiceGetter = this.taskServiceBuilder.create({
|
||||
userId,
|
||||
})
|
||||
const accessGetter = await taskServiceGetter.get<IAccessService>("accessService")
|
||||
const notificationGetter =await taskServiceGetter.get<INotificationService>("notificationService")
|
||||
const cnameProxyService =await taskServiceGetter.get<ICnameProxyService>("cnameProxyService")
|
||||
userId
|
||||
});
|
||||
const accessGetter = await taskServiceGetter.get<IAccessService>("accessService");
|
||||
const notificationGetter = await taskServiceGetter.get<INotificationService>("notificationService");
|
||||
const cnameProxyService = await taskServiceGetter.get<ICnameProxyService>("cnameProxyService");
|
||||
const executor = new Executor({
|
||||
user,
|
||||
pipeline,
|
||||
@@ -561,7 +580,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
notificationService: notificationGetter,
|
||||
fileRootDir: this.certdConfig.fileRootDir,
|
||||
sysInfo,
|
||||
serviceGetter:taskServiceGetter
|
||||
serviceGetter: taskServiceGetter
|
||||
});
|
||||
try {
|
||||
runningTasks.set(historyId, executor);
|
||||
@@ -579,7 +598,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error('执行失败:', e);
|
||||
logger.error("执行失败:", e);
|
||||
// throw e;
|
||||
} finally {
|
||||
runningTasks.delete(historyId);
|
||||
@@ -603,7 +622,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
}
|
||||
|
||||
private getTriggerType(triggerId, pipeline) {
|
||||
let triggerType = 'user';
|
||||
let triggerType = "user";
|
||||
if (triggerId != null) {
|
||||
//如果不是手动触发
|
||||
//查找trigger
|
||||
@@ -613,8 +632,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
this.cron.remove(this.buildCronKey(pipeline.id, triggerId));
|
||||
triggerType = null;
|
||||
} else {
|
||||
logger.info('timer trigger:' + found.id, found.title, found.cron);
|
||||
triggerType = 'timer';
|
||||
logger.info("timer trigger:" + found.id, found.title, found.cron);
|
||||
triggerType = "timer";
|
||||
}
|
||||
}
|
||||
return triggerType;
|
||||
@@ -637,7 +656,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
//修改pipeline状态
|
||||
const pipelineEntity = new PipelineEntity();
|
||||
pipelineEntity.id = parseInt(history.pipeline.id);
|
||||
pipelineEntity.status = history.pipeline.status.status + '';
|
||||
pipelineEntity.status = history.pipeline.status.result + "";
|
||||
pipelineEntity.lastHistoryTime = history.pipeline.status.startTime;
|
||||
await this.update(pipelineEntity);
|
||||
|
||||
@@ -661,8 +680,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
async count(param: { userId?: any }) {
|
||||
const count = await this.repository.count({
|
||||
where: {
|
||||
userId: param.userId,
|
||||
},
|
||||
userId: param.userId
|
||||
}
|
||||
});
|
||||
return count;
|
||||
}
|
||||
@@ -670,12 +689,12 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
async statusCount(param: { userId?: any } = {}) {
|
||||
const statusCount = await this.repository
|
||||
.createQueryBuilder()
|
||||
.select('status')
|
||||
.addSelect('count(1)', 'count')
|
||||
.select("status")
|
||||
.addSelect("count(1)", "count")
|
||||
.where({
|
||||
userId: param.userId,
|
||||
userId: param.userId
|
||||
})
|
||||
.groupBy('status')
|
||||
.groupBy("status")
|
||||
.getRawMany();
|
||||
return statusCount;
|
||||
}
|
||||
@@ -685,11 +704,11 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
status: true,
|
||||
status: true
|
||||
},
|
||||
where: {
|
||||
userId,
|
||||
},
|
||||
userId
|
||||
}
|
||||
});
|
||||
await this.fillLastVars(list);
|
||||
list = list.filter(item => {
|
||||
@@ -703,16 +722,16 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
}
|
||||
|
||||
async createCountPerDay(param: { days: number } = { days: 7 }) {
|
||||
const todayEnd = dayjs().endOf('day');
|
||||
const todayEnd = dayjs().endOf("day");
|
||||
const result = await this.getRepository()
|
||||
.createQueryBuilder('main')
|
||||
.select(`${this.dbAdapter.date('main.createTime')} AS date`) // 将UNIX时间戳转换为日期
|
||||
.addSelect('COUNT(1) AS count')
|
||||
.createQueryBuilder("main")
|
||||
.select(`${this.dbAdapter.date("main.createTime")} AS date`) // 将UNIX时间戳转换为日期
|
||||
.addSelect("COUNT(1) AS count")
|
||||
.where({
|
||||
// 0点
|
||||
createTime: MoreThan(todayEnd.add(-param.days, 'day').toDate()),
|
||||
createTime: MoreThan(todayEnd.add(-param.days, "day").toDate())
|
||||
})
|
||||
.groupBy('date')
|
||||
.groupBy("date")
|
||||
.getRawMany();
|
||||
|
||||
return result;
|
||||
@@ -729,48 +748,48 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
await this.repository.update(
|
||||
{
|
||||
id: In(ids),
|
||||
userId,
|
||||
userId
|
||||
},
|
||||
{ groupId }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
async batchUpdateTrigger(ids: number[], trigger: any, userId: any){
|
||||
async batchUpdateTrigger(ids: number[], trigger: any, userId: any) {
|
||||
|
||||
const list = await this.find({
|
||||
where:{
|
||||
where: {
|
||||
id: In(ids),
|
||||
userId
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
for (const item of list) {
|
||||
const pipeline = JSON.parse(item.content);
|
||||
pipeline.triggers = [{
|
||||
id: nanoid(),
|
||||
title: '定时触发',
|
||||
title: "定时触发",
|
||||
...trigger
|
||||
}]
|
||||
await this.doUpdatePipelineJson(item,pipeline)
|
||||
}];
|
||||
await this.doUpdatePipelineJson(item, pipeline);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async batchUpdateNotifications(ids: number[], notification: Notification, userId: any){
|
||||
async batchUpdateNotifications(ids: number[], notification: Notification, userId: any) {
|
||||
|
||||
const list = await this.find({
|
||||
where:{
|
||||
where: {
|
||||
id: In(ids),
|
||||
userId
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
for (const item of list) {
|
||||
const pipeline = JSON.parse(item.content);
|
||||
pipeline.notifications = [{
|
||||
id: nanoid(),
|
||||
title: '通知',
|
||||
title: "通知",
|
||||
/**
|
||||
* type: NotificationType;
|
||||
* when: NotificationWhen[];
|
||||
@@ -781,44 +800,44 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
*/
|
||||
type: "other",
|
||||
...notification
|
||||
}]
|
||||
await this.doUpdatePipelineJson(item,pipeline)
|
||||
}];
|
||||
await this.doUpdatePipelineJson(item, pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
async batchRerun(ids: number[], userId: any) {
|
||||
if (!isPlus()){
|
||||
throw new NeedVIPException("此功能需要升级专业版")
|
||||
if (!isPlus()) {
|
||||
throw new NeedVIPException("此功能需要升级专业版");
|
||||
}
|
||||
|
||||
if (!userId || ids.length === 0) {
|
||||
return;
|
||||
}
|
||||
const list = await this.repository.find({
|
||||
select:{
|
||||
id:true
|
||||
select: {
|
||||
id: true
|
||||
},
|
||||
where:{
|
||||
where: {
|
||||
id: In(ids),
|
||||
userId
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
ids = list.map(item=>item.id)
|
||||
ids = list.map(item => item.id);
|
||||
|
||||
//异步执行
|
||||
this.startBatchRerun(ids)
|
||||
this.startBatchRerun(ids);
|
||||
}
|
||||
|
||||
async startBatchRerun(ids: number[]){
|
||||
async startBatchRerun(ids: number[]) {
|
||||
//20条一批
|
||||
const batchSize = 20;
|
||||
for (let i = 0; i < ids.length; i += batchSize) {
|
||||
const batchIds = ids.slice(i, i + batchSize);
|
||||
const batchPromises = batchIds.map(async (id)=>{
|
||||
await this.run(id,null,"ALL")
|
||||
const batchPromises = batchIds.map(async (id) => {
|
||||
await this.run(id, null, "ALL");
|
||||
});
|
||||
await Promise.all(batchPromises)
|
||||
await Promise.all(batchPromises);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -831,35 +850,132 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
return await this.repository.find({
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
title: true
|
||||
},
|
||||
where: {
|
||||
id: In(pipelineIds),
|
||||
userId,
|
||||
},
|
||||
userId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private async checkUserStatus(userId: number) {
|
||||
const userEntity = await this.userService.info(userId);
|
||||
if(userEntity == null){
|
||||
throw new Error('用户不存在');
|
||||
if (userEntity == null) {
|
||||
throw new Error("用户不存在");
|
||||
}
|
||||
if(userEntity.status === 0){
|
||||
const message = `账户${userId}已被禁用,禁止运行流水线`
|
||||
throw new Error(message)
|
||||
if (userEntity.status === 0) {
|
||||
const message = `账户${userId}已被禁用,禁止运行流水线`;
|
||||
throw new Error(message);
|
||||
}
|
||||
const sysPublic = await this.sysSettingsService.getPublicSettings()
|
||||
if(isPlus() && sysPublic.userValidTimeEnabled === true){
|
||||
const sysPublic = await this.sysSettingsService.getPublicSettings();
|
||||
if (isPlus() && sysPublic.userValidTimeEnabled === true) {
|
||||
//校验用户有效期是否设置
|
||||
if(userEntity.validTime!= null && userEntity.validTime > 0){
|
||||
if(userEntity.validTime < new Date().getTime()){
|
||||
if (userEntity.validTime != null && userEntity.validTime > 0) {
|
||||
if (userEntity.validTime < new Date().getTime()) {
|
||||
//用户已过期
|
||||
const message = `账户${userId}已过有效期,禁止运行流水线`
|
||||
throw new Error(message)
|
||||
const message = `账户${userId}已过有效期,禁止运行流水线`;
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async createAutoPipeline(req: { domains: string[]; email: string; userId: number ,from:string}) {
|
||||
|
||||
const randomHour = Math.floor(Math.random() * 6);
|
||||
const randomMin = Math.floor(Math.random() * 60);
|
||||
const randomCron = `0 ${randomMin} ${randomHour} * * *`;
|
||||
|
||||
let pipeline: any = {
|
||||
title: req.domains[0] + `证书自动申请【${req.from??"OpenAPI"}】`,
|
||||
runnableType: "pipeline",
|
||||
triggers: [
|
||||
{
|
||||
id: nanoid(),
|
||||
title: "定时触发",
|
||||
props:{
|
||||
cron: randomCron,
|
||||
},
|
||||
type: "timer"
|
||||
}
|
||||
],
|
||||
notifications: [
|
||||
{
|
||||
id: nanoid(),
|
||||
type: "custom",
|
||||
when: ["error", "turnToSuccess", "success"],
|
||||
notificationId: 0,
|
||||
title: "默认通知",
|
||||
}
|
||||
],
|
||||
stages: [
|
||||
{
|
||||
id: nanoid(),
|
||||
title: "证书申请阶段",
|
||||
maxTaskCount: 1,
|
||||
runnableType: "stage",
|
||||
tasks: [
|
||||
{
|
||||
id: nanoid(),
|
||||
title: "证书申请任务",
|
||||
runnableType: "task",
|
||||
steps: [
|
||||
{
|
||||
id: nanoid(),
|
||||
title: "申请证书",
|
||||
runnableType: "step",
|
||||
input: {
|
||||
renewDays: 35,
|
||||
domains: req.domains,
|
||||
email: req.email,
|
||||
"challengeType": "auto",
|
||||
"sslProvider": "letsencrypt",
|
||||
"privateKeyType": "rsa_2048",
|
||||
"certProfile": "classic",
|
||||
"useProxy": false,
|
||||
"skipLocalVerify": false,
|
||||
"maxCheckRetryCount": 20,
|
||||
"waitDnsDiffuseTime": 30,
|
||||
"pfxArgs": "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES",
|
||||
"successNotify": true
|
||||
},
|
||||
strategy: {
|
||||
runStrategy: 0 // 正常执行
|
||||
},
|
||||
type: "CertApply"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const bean = new PipelineEntity();
|
||||
bean.title = pipeline.title;
|
||||
bean.content = JSON.stringify(pipeline);
|
||||
bean.userId = req.userId;
|
||||
bean.status = "none";
|
||||
bean.type = "cert_auto";
|
||||
bean.disabled = false
|
||||
bean.keepHistoryCount = 30
|
||||
await this.save(bean)
|
||||
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
async getStatus(pipelineId: number) {
|
||||
const res = await this.repository.findOne({
|
||||
select: {
|
||||
status: true
|
||||
},
|
||||
where: {
|
||||
id: pipelineId
|
||||
}
|
||||
});
|
||||
return res?.status;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,4 +36,25 @@ export class SubDomainService extends BaseService<SubDomainEntity> {
|
||||
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)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { AliyunAccess } from '@certd/plugin-lib';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import {AliyunAccess, AliyunSslClient} from '@certd/plugin-lib';
|
||||
import {CertInfo, CertReader} from '@certd/plugin-cert';
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'DeployCertToAliyunOSS',
|
||||
@@ -82,11 +82,27 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
|
||||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: [...CertApplyPluginNames],
|
||||
from: [...CertApplyPluginNames,"uploadCertToAliyun"],
|
||||
},
|
||||
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({
|
||||
title: 'Access授权',
|
||||
@@ -103,12 +119,42 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
|
||||
async execute(): Promise<void> {
|
||||
this.logger.info('开始部署证书到阿里云OSS');
|
||||
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}`);
|
||||
const client = await this.getClient(access);
|
||||
await this.doRequest(client, {});
|
||||
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) {
|
||||
// @ts-ignore
|
||||
const OSS = await import('ali-oss');
|
||||
@@ -129,13 +175,24 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
|
||||
cname: '',
|
||||
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 = `
|
||||
<BucketCnameConfiguration>
|
||||
<Cname>
|
||||
<Domain>${this.domainName}</Domain>
|
||||
<CertificateConfiguration>
|
||||
<PrivateKey>${this.cert.key}</PrivateKey>
|
||||
<Certificate>${this.cert.crt}</Certificate>
|
||||
${certStr}
|
||||
<Force>true</Force>
|
||||
</CertificateConfiguration>
|
||||
</Cname>
|
||||
</BucketCnameConfiguration>`;
|
||||
|
||||
@@ -23,7 +23,7 @@ const regionDict = [
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: 'uploadCertToAliyun',
|
||||
title: '阿里云-上传证书到阿里云',
|
||||
title: '阿里云-上传证书到阿里云CAS',
|
||||
icon: 'svg:icon-aliyun',
|
||||
group: pluginGroups.aliyun.key,
|
||||
desc: '上传证书到阿里云数字证书管理服务(CAS),注意:不会部署到任何应用上;如果不想在阿里云上同一份证书上传多次,可以把此任务作为前置任务,其他阿里云任务证书那一项选择此任务的输出',
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './host-shell-execute/index.js';
|
||||
export * from './upload-to-host/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) {
|
||||
throw new Error('webhook地址不能为空');
|
||||
}
|
||||
/**
|
||||
*
|
||||
* "msgtype": "text",
|
||||
* "text": {
|
||||
* "content": "hello world"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
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})`,
|
||||
msgtype: 'text',
|
||||
text: {
|
||||
content: `${body.title}\n${body.content}\n查看详情: ${body.url}`,
|
||||
mentioned_list: this.mentionedList,
|
||||
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,
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,3 +2,4 @@ export * from './plugin-restart.js';
|
||||
export * from './plugin-script.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',
|
||||
title: '腾讯云-部署到腾讯云EO',
|
||||
icon: 'svg:icon-tencentcloud',
|
||||
desc: '腾讯云边缘安全加速平台EO,必须配置上传证书到腾讯云任务',
|
||||
desc: '腾讯云边缘安全加速平台EdgeOne(EO),必须配置上传证书到腾讯云任务',
|
||||
group: pluginGroups.tencent.key,
|
||||
default: {
|
||||
strategy: {
|
||||
|
||||
185
pnpm-lock.yaml
generated
185
pnpm-lock.yaml
generated
@@ -4,10 +4,16 @@ settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
overrides:
|
||||
'@certd/ui-server': link:packages/ui/certd-server
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
'@certd/ui-server':
|
||||
specifier: link:packages/ui/certd-server
|
||||
version: link:packages/ui/certd-server
|
||||
axios:
|
||||
specifier: ^1.7.7
|
||||
version: 1.9.0(debug@4.4.1)
|
||||
@@ -46,7 +52,7 @@ importers:
|
||||
packages/core/acme-client:
|
||||
dependencies:
|
||||
'@certd/basic':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../basic
|
||||
'@peculiar/x509':
|
||||
specifier: ^1.11.0
|
||||
@@ -207,11 +213,11 @@ importers:
|
||||
packages/core/pipeline:
|
||||
dependencies:
|
||||
'@certd/basic':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../basic
|
||||
'@certd/plus-core':
|
||||
specifier: ^1.36.1
|
||||
version: 1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../../pro/plus-core
|
||||
dayjs:
|
||||
specifier: ^1.11.7
|
||||
version: 1.11.13
|
||||
@@ -415,7 +421,7 @@ importers:
|
||||
packages/libs/lib-k8s:
|
||||
dependencies:
|
||||
'@certd/basic':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/basic
|
||||
'@kubernetes/client-node':
|
||||
specifier: 0.21.0
|
||||
@@ -455,17 +461,17 @@ importers:
|
||||
packages/libs/lib-server:
|
||||
dependencies:
|
||||
'@certd/acme-client':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/acme-client
|
||||
'@certd/basic':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/basic
|
||||
'@certd/pipeline':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/pipeline
|
||||
'@certd/plus-core':
|
||||
specifier: ^1.36.1
|
||||
version: 1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../../pro/plus-core
|
||||
'@midwayjs/cache':
|
||||
specifier: ~3.14.0
|
||||
version: 3.14.0
|
||||
@@ -607,16 +613,16 @@ importers:
|
||||
packages/plugins/plugin-cert:
|
||||
dependencies:
|
||||
'@certd/acme-client':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/acme-client
|
||||
'@certd/basic':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/basic
|
||||
'@certd/pipeline':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/pipeline
|
||||
'@certd/plugin-lib':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../plugin-lib
|
||||
'@google-cloud/publicca':
|
||||
specifier: ^1.3.0
|
||||
@@ -698,10 +704,10 @@ importers:
|
||||
specifier: ^3.787.0
|
||||
version: 3.810.0(aws-crt@1.26.2)
|
||||
'@certd/basic':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/basic
|
||||
'@certd/pipeline':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/pipeline
|
||||
'@kubernetes/client-node':
|
||||
specifier: 0.21.0
|
||||
@@ -789,19 +795,19 @@ importers:
|
||||
packages/pro/commercial-core:
|
||||
dependencies:
|
||||
'@certd/basic':
|
||||
specifier: ^1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/basic
|
||||
'@certd/lib-server':
|
||||
specifier: ^1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../../libs/lib-server
|
||||
'@certd/pipeline':
|
||||
specifier: ^1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/pipeline
|
||||
'@certd/plugin-plus':
|
||||
specifier: ^1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../plugin-plus
|
||||
'@certd/plus-core':
|
||||
specifier: ^1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../plus-core
|
||||
'@midwayjs/core':
|
||||
specifier: ~3.20.3
|
||||
@@ -886,22 +892,22 @@ importers:
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.3
|
||||
'@certd/basic':
|
||||
specifier: ^1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/basic
|
||||
'@certd/lib-k8s':
|
||||
specifier: ^1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../../libs/lib-k8s
|
||||
'@certd/pipeline':
|
||||
specifier: ^1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/pipeline
|
||||
'@certd/plugin-cert':
|
||||
specifier: ^1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../../plugins/plugin-cert
|
||||
'@certd/plugin-lib':
|
||||
specifier: ^1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../../plugins/plugin-lib
|
||||
'@certd/plus-core':
|
||||
specifier: ^1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../plus-core
|
||||
ali-oss:
|
||||
specifier: ^6.21.0
|
||||
@@ -1004,7 +1010,7 @@ importers:
|
||||
packages/pro/plus-core:
|
||||
dependencies:
|
||||
'@certd/basic':
|
||||
specifier: ^1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/basic
|
||||
dayjs:
|
||||
specifier: ^1.11.7
|
||||
@@ -1294,10 +1300,10 @@ importers:
|
||||
version: 0.1.3(zod@3.24.4)
|
||||
devDependencies:
|
||||
'@certd/lib-iframe':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../libs/lib-iframe
|
||||
'@certd/pipeline':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/pipeline
|
||||
'@rollup/plugin-commonjs':
|
||||
specifier: ^25.0.7
|
||||
@@ -1480,47 +1486,47 @@ importers:
|
||||
specifier: ^3.705.0
|
||||
version: 3.810.0(aws-crt@1.26.2)
|
||||
'@certd/acme-client':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/acme-client
|
||||
'@certd/basic':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/basic
|
||||
'@certd/commercial-core':
|
||||
specifier: ^1.36.1
|
||||
version: 1.36.1(better-sqlite3@11.10.0)(encoding@0.1.13)(mysql2@3.14.1)(pg@8.16.0)(reflect-metadata@0.2.2)(ts-node@10.9.2(@types/node@18.19.100)(typescript@5.8.3))
|
||||
specifier: ^1.36.5
|
||||
version: link:../../pro/commercial-core
|
||||
'@certd/cv4pve-api-javascript':
|
||||
specifier: ^8.4.1
|
||||
version: 8.4.1
|
||||
'@certd/jdcloud':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../libs/lib-jdcloud
|
||||
'@certd/lib-huawei':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../libs/lib-huawei
|
||||
'@certd/lib-k8s':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../libs/lib-k8s
|
||||
'@certd/lib-server':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../libs/lib-server
|
||||
'@certd/midway-flyway-js':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../libs/midway-flyway-js
|
||||
'@certd/pipeline':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../core/pipeline
|
||||
'@certd/plugin-cert':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../plugins/plugin-cert
|
||||
'@certd/plugin-lib':
|
||||
specifier: ^1.36.2
|
||||
specifier: ^1.36.5
|
||||
version: link:../../plugins/plugin-lib
|
||||
'@certd/plugin-plus':
|
||||
specifier: ^1.36.1
|
||||
version: 1.36.1(encoding@0.1.13)
|
||||
specifier: ^1.36.5
|
||||
version: link:../../pro/plugin-plus
|
||||
'@certd/plus-core':
|
||||
specifier: ^1.36.1
|
||||
version: 1.36.1
|
||||
specifier: ^1.36.5
|
||||
version: link:../../pro/plus-core
|
||||
'@huaweicloud/huaweicloud-sdk-cdn':
|
||||
specifier: ^3.1.120
|
||||
version: 3.1.149
|
||||
@@ -2760,18 +2766,9 @@ packages:
|
||||
'@better-scroll/zoom@2.5.1':
|
||||
resolution: {integrity: sha512-aGvFY5ooeZWS4RcxQLD+pGLpQHQxpPy0sMZV3yadcd2QK53PK9gS4Dp+BYfRv8lZ4/P2LoNEhr6Wq1DN6+uPlA==}
|
||||
|
||||
'@certd/commercial-core@1.36.1':
|
||||
resolution: {integrity: sha512-CpZ7K7s0JoXJ8MD3FyeryKnA62fvX3DKVQ7XkSSomaqgH/a8DgP4QrJGrt2ytIYtu2SzJvJsBfy14UhVM6174Q==}
|
||||
|
||||
'@certd/cv4pve-api-javascript@8.4.1':
|
||||
resolution: {integrity: sha512-jxlRieJmCA0Z9LnwX6Ra6ZekRGJEu8o8RGYoKU0Jjkhc9jm6ChEbVyfE7Iw49/hlpA+2yaHdAXb46au/afCISg==}
|
||||
|
||||
'@certd/plugin-plus@1.36.1':
|
||||
resolution: {integrity: sha512-Bd3tFwn/jDrpSWqUH9488YxFHnEIGI15NFoqQaLv58L+Ycm7mRbyTUC/S3xpiUkfhDI6wqvKL8SOtdpgo0IEzA==}
|
||||
|
||||
'@certd/plus-core@1.36.1':
|
||||
resolution: {integrity: sha512-TiRpqWCC7RGJxmVaDkSkMAFYe2zehRqZFKmNcfG8DZJTgKpQhd98HvXlyXCJD5qUtPmyvFoffTD1Q8bGqN84Vw==}
|
||||
|
||||
'@colors/colors@1.5.0':
|
||||
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
|
||||
engines: {node: '>=0.1.90'}
|
||||
@@ -15447,84 +15444,12 @@ snapshots:
|
||||
dependencies:
|
||||
'@better-scroll/core': 2.5.1
|
||||
|
||||
'@certd/commercial-core@1.36.1(better-sqlite3@11.10.0)(encoding@0.1.13)(mysql2@3.14.1)(pg@8.16.0)(reflect-metadata@0.2.2)(ts-node@10.9.2(@types/node@18.19.100)(typescript@5.8.3))':
|
||||
dependencies:
|
||||
'@certd/basic': link:packages/core/basic
|
||||
'@certd/lib-server': link:packages/libs/lib-server
|
||||
'@certd/pipeline': link:packages/core/pipeline
|
||||
'@certd/plugin-plus': 1.36.1(encoding@0.1.13)
|
||||
'@certd/plus-core': 1.36.1
|
||||
'@midwayjs/core': 3.20.4
|
||||
'@midwayjs/koa': 3.20.5
|
||||
'@midwayjs/logger': 3.4.2
|
||||
'@midwayjs/typeorm': 3.20.4
|
||||
alipay-sdk: 4.14.0
|
||||
dayjs: 1.11.13
|
||||
typeorm: 0.3.24(better-sqlite3@11.10.0)(mysql2@3.14.1)(pg@8.16.0)(reflect-metadata@0.2.2)(ts-node@10.9.2(@types/node@18.19.100)(typescript@5.8.3))
|
||||
wechatpay-node-v3: 2.2.1
|
||||
transitivePeerDependencies:
|
||||
- '@google-cloud/spanner'
|
||||
- '@sap/hana-client'
|
||||
- babel-plugin-macros
|
||||
- better-sqlite3
|
||||
- encoding
|
||||
- hdb-pool
|
||||
- ioredis
|
||||
- mongodb
|
||||
- mssql
|
||||
- mysql2
|
||||
- oracledb
|
||||
- pg
|
||||
- pg-native
|
||||
- pg-query-stream
|
||||
- proxy-agent
|
||||
- redis
|
||||
- reflect-metadata
|
||||
- sql.js
|
||||
- sqlite3
|
||||
- supports-color
|
||||
- ts-node
|
||||
- typeorm-aurora-data-api-driver
|
||||
|
||||
'@certd/cv4pve-api-javascript@8.4.1':
|
||||
dependencies:
|
||||
debug: 4.4.1(supports-color@8.1.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@certd/plugin-plus@1.36.1(encoding@0.1.13)':
|
||||
dependencies:
|
||||
'@alicloud/pop-core': 1.8.0
|
||||
'@baiducloud/sdk': 1.0.3
|
||||
'@certd/basic': link:packages/core/basic
|
||||
'@certd/lib-k8s': link:packages/libs/lib-k8s
|
||||
'@certd/pipeline': link:packages/core/pipeline
|
||||
'@certd/plugin-cert': link:packages/plugins/plugin-cert
|
||||
'@certd/plugin-lib': link:packages/plugins/plugin-lib
|
||||
'@certd/plus-core': 1.36.1
|
||||
ali-oss: 6.23.0
|
||||
baidu-aip-sdk: 4.16.16
|
||||
basic-ftp: 5.0.5
|
||||
cos-nodejs-sdk-v5: 2.14.7
|
||||
crypto-js: 4.2.0
|
||||
dayjs: 1.11.13
|
||||
form-data: 4.0.2
|
||||
https-proxy-agent: 7.0.6
|
||||
js-yaml: 4.1.0
|
||||
jsencrypt: 3.3.2
|
||||
jsrsasign: 11.1.0
|
||||
qiniu: 7.14.0
|
||||
tencentcloud-sdk-nodejs: 4.1.37(encoding@0.1.13)
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
- proxy-agent
|
||||
- supports-color
|
||||
|
||||
'@certd/plus-core@1.36.1':
|
||||
dependencies:
|
||||
'@certd/basic': link:packages/core/basic
|
||||
dayjs: 1.11.13
|
||||
|
||||
'@colors/colors@1.5.0':
|
||||
optional: true
|
||||
|
||||
@@ -21599,13 +21524,13 @@ snapshots:
|
||||
resolve: 1.22.10
|
||||
semver: 6.3.1
|
||||
|
||||
eslint-plugin-prettier@3.4.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@7.32.0)(prettier@2.8.8):
|
||||
eslint-plugin-prettier@3.4.1(eslint-config-prettier@8.10.0(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8):
|
||||
dependencies:
|
||||
eslint: 7.32.0
|
||||
prettier: 2.8.8
|
||||
prettier-linter-helpers: 1.0.0
|
||||
optionalDependencies:
|
||||
eslint-config-prettier: 8.10.0(eslint@8.57.0)
|
||||
eslint-config-prettier: 8.10.0(eslint@7.32.0)
|
||||
|
||||
eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8):
|
||||
dependencies:
|
||||
@@ -24313,7 +24238,7 @@ snapshots:
|
||||
eslint: 7.32.0
|
||||
eslint-config-prettier: 8.10.0(eslint@7.32.0)
|
||||
eslint-plugin-node: 11.1.0(eslint@7.32.0)
|
||||
eslint-plugin-prettier: 3.4.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@7.32.0)(prettier@2.8.8)
|
||||
eslint-plugin-prettier: 3.4.1(eslint-config-prettier@8.10.0(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8)
|
||||
execa: 5.1.1
|
||||
inquirer: 7.3.3
|
||||
json5: 2.2.3
|
||||
|
||||
Reference in New Issue
Block a user