mirror of https://github.com/certd/certd
Merge branch 'v2-dev' into v2
commit
1bbed351ba
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -3,6 +3,24 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复用户最大流水线数量校验的问题 ([919f70a](https://github.com/certd/certd/commit/919f70a5fd2842ca69f96f1659bb5a7ba3f73776))
|
||||||
|
* 修复中文域名使用cname方式校验无法通过的问题 ([f7d5baa](https://github.com/certd/certd/commit/f7d5baa6d04cb83c572b06e62f885890cfa0143a))
|
||||||
|
* 修复cv4pve sdk (proxmox插件连接失败时无法正常结束任务的bug) ([49f26b4](https://github.com/certd/certd/commit/49f26b4049a0549b0270395157e96e8f04a68bc4))
|
||||||
|
* 修复flexcdn部署证书的顶级CA名称显示 ([6467edb](https://github.com/certd/certd/commit/6467edb84324d7c80a85212675dbacedc459df83))
|
||||||
|
* 修复flexcdn证书commonNames错误的问题 ([ace363f](https://github.com/certd/certd/commit/ace363fa355436e769b27f71cc487d30d6441780))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 分组选择支持清空选项 ([03e2e99](https://github.com/certd/certd/commit/03e2e9949837b34eb3ea56d14a9e8a5dabc96063))
|
||||||
|
* 优化cname检查,当有冲突的cname记录时,给出提示 ([e639a8f](https://github.com/certd/certd/commit/e639a8f9f12640ffcca69f1a6a0324459924afbd))
|
||||||
|
* 增加下载日志按钮 ([6ff509d](https://github.com/certd/certd/commit/6ff509d263c0182645b4692c10b5fedb192db964))
|
||||||
|
* 站点监控支持批量导入域名和ip ([2d7729d](https://github.com/certd/certd/commit/2d7729dbe98f29088f5f317db2b52cc1ede223a6))
|
||||||
|
* 支持设置用户有效期 ([6ac3bc5](https://github.com/certd/certd/commit/6ac3bc564f407dad2cd0b0b0744e887387aa5da3))
|
||||||
|
|
||||||
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
|
@ -168,7 +168,11 @@ https://afdian.com/a/greper
|
||||||
1. 可以调整开源协议以使其更严格或更宽松。
|
1. 可以调整开源协议以使其更严格或更宽松。
|
||||||
2. 可以用于商业用途。
|
2. 可以用于商业用途。
|
||||||
|
|
||||||
|
感谢以下贡献者做出的贡献。
|
||||||
|
|
||||||
|
<a href="https://github.com/certd/certd/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=certd/certd" />
|
||||||
|
</a>
|
||||||
|
|
||||||
## 九、 开源许可
|
## 九、 开源许可
|
||||||
* 本项目遵循 GNU Affero General Public License(AGPL)开源协议。
|
* 本项目遵循 GNU Affero General Public License(AGPL)开源协议。
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
23:57
|
23:51
|
||||||
|
|
|
@ -3,6 +3,24 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复用户最大流水线数量校验的问题 ([919f70a](https://github.com/certd/certd/commit/919f70a5fd2842ca69f96f1659bb5a7ba3f73776))
|
||||||
|
* 修复中文域名使用cname方式校验无法通过的问题 ([f7d5baa](https://github.com/certd/certd/commit/f7d5baa6d04cb83c572b06e62f885890cfa0143a))
|
||||||
|
* 修复cv4pve sdk (proxmox插件连接失败时无法正常结束任务的bug) ([49f26b4](https://github.com/certd/certd/commit/49f26b4049a0549b0270395157e96e8f04a68bc4))
|
||||||
|
* 修复flexcdn部署证书的顶级CA名称显示 ([6467edb](https://github.com/certd/certd/commit/6467edb84324d7c80a85212675dbacedc459df83))
|
||||||
|
* 修复flexcdn证书commonNames错误的问题 ([ace363f](https://github.com/certd/certd/commit/ace363fa355436e769b27f71cc487d30d6441780))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 分组选择支持清空选项 ([03e2e99](https://github.com/certd/certd/commit/03e2e9949837b34eb3ea56d14a9e8a5dabc96063))
|
||||||
|
* 优化cname检查,当有冲突的cname记录时,给出提示 ([e639a8f](https://github.com/certd/certd/commit/e639a8f9f12640ffcca69f1a6a0324459924afbd))
|
||||||
|
* 增加下载日志按钮 ([6ff509d](https://github.com/certd/certd/commit/6ff509d263c0182645b4692c10b5fedb192db964))
|
||||||
|
* 站点监控支持批量导入域名和ip ([2d7729d](https://github.com/certd/certd/commit/2d7729dbe98f29088f5f317db2b52cc1ede223a6))
|
||||||
|
* 支持设置用户有效期 ([6ac3bc5](https://github.com/certd/certd/commit/6ac3bc564f407dad2cd0b0b0744e887387aa5da3))
|
||||||
|
|
||||||
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
|
@ -9,5 +9,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npmClient": "pnpm",
|
"npmClient": "pnpm",
|
||||||
"version": "1.34.10"
|
"version": "1.34.11"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,16 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/publishlab/node-acme-client/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复中文域名使用cname方式校验无法通过的问题 ([f7d5baa](https://github.com/publishlab/node-acme-client/commit/f7d5baa6d04cb83c572b06e62f885890cfa0143a))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化cname检查,当有冲突的cname记录时,给出提示 ([e639a8f](https://github.com/publishlab/node-acme-client/commit/e639a8f9f12640ffcca69f1a6a0324459924afbd))
|
||||||
|
|
||||||
## [1.34.10](https://github.com/publishlab/node-acme-client/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/publishlab/node-acme-client/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/acme-client
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"description": "Simple and unopinionated ACME client",
|
"description": "Simple and unopinionated ACME client",
|
||||||
"private": false,
|
"private": false,
|
||||||
"author": "nmorsman",
|
"author": "nmorsman",
|
||||||
"version": "1.34.10",
|
"version": "1.34.11",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"module": "scr/index.js",
|
"module": "scr/index.js",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
"types"
|
"types"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.34.10",
|
"@certd/basic": "^1.34.11",
|
||||||
"@peculiar/x509": "^1.11.0",
|
"@peculiar/x509": "^1.11.0",
|
||||||
"asn1js": "^3.0.5",
|
"asn1js": "^3.0.5",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
"https-proxy-agent": "^7.0.5",
|
"https-proxy-agent": "^7.0.5",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"node-forge": "^1.3.1",
|
"node-forge": "^1.3.1",
|
||||||
"punycode": "^2.3.1"
|
"punycode.js": "^2.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.14.10",
|
"@types/node": "^20.14.10",
|
||||||
|
@ -69,5 +69,5 @@
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||||
},
|
},
|
||||||
"gitHead": "a4b6580247efabe948507c771a177d4f75670bc2"
|
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,6 +203,7 @@ export const agents: any;
|
||||||
export function setLogger(fn: (message: any, ...args: any[]) => void): void;
|
export function setLogger(fn: (message: any, ...args: any[]) => void): void;
|
||||||
|
|
||||||
export function walkTxtRecord(record: any): Promise<string[]>;
|
export function walkTxtRecord(record: any): Promise<string[]>;
|
||||||
|
export function getAuthoritativeDnsResolver(record:string): Promise<any>;
|
||||||
|
|
||||||
export const CancelError: typeof CancelError;
|
export const CancelError: typeof CancelError;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
23:54
|
23:48
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@certd/basic",
|
"name": "@certd/basic",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.34.10",
|
"version": "1.34.11",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
|
@ -45,5 +45,5 @@
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "a4b6580247efabe948507c771a177d4f75670bc2"
|
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@certd/pipeline",
|
"name": "@certd/pipeline",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.34.10",
|
"version": "1.34.11",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
|
@ -17,8 +17,8 @@
|
||||||
"pub": "npm publish"
|
"pub": "npm publish"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.34.10",
|
"@certd/basic": "^1.34.11",
|
||||||
"@certd/plus-core": "^1.34.10",
|
"@certd/plus-core": "^1.34.11",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"reflect-metadata": "^0.1.13"
|
"reflect-metadata": "^0.1.13"
|
||||||
|
@ -44,5 +44,5 @@
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "a4b6580247efabe948507c771a177d4f75670bc2"
|
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-huawei
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@certd/lib-huawei",
|
"name": "@certd/lib-huawei",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.34.10",
|
"version": "1.34.11",
|
||||||
"main": "./dist/bundle.js",
|
"main": "./dist/bundle.js",
|
||||||
"module": "./dist/bundle.js",
|
"module": "./dist/bundle.js",
|
||||||
"types": "./dist/d/index.d.ts",
|
"types": "./dist/d/index.d.ts",
|
||||||
|
@ -24,5 +24,5 @@
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
"tslib": "^2.8.1"
|
"tslib": "^2.8.1"
|
||||||
},
|
},
|
||||||
"gitHead": "a4b6580247efabe948507c771a177d4f75670bc2"
|
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-iframe
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@certd/lib-iframe",
|
"name": "@certd/lib-iframe",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.34.10",
|
"version": "1.34.11",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
|
@ -31,5 +31,5 @@
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "a4b6580247efabe948507c771a177d4f75670bc2"
|
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/jdcloud
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@certd/jdcloud",
|
"name": "@certd/jdcloud",
|
||||||
"version": "1.34.10",
|
"version": "1.34.11",
|
||||||
"description": "jdcloud openApi sdk",
|
"description": "jdcloud openApi sdk",
|
||||||
"main": "./dist/bundle.js",
|
"main": "./dist/bundle.js",
|
||||||
"module": "./dist/bundle.js",
|
"module": "./dist/bundle.js",
|
||||||
|
@ -61,5 +61,5 @@
|
||||||
"fetch"
|
"fetch"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"gitHead": "a4b6580247efabe948507c771a177d4f75670bc2"
|
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-k8s
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@certd/lib-k8s",
|
"name": "@certd/lib-k8s",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.34.10",
|
"version": "1.34.11",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
"pub": "npm publish"
|
"pub": "npm publish"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.34.10",
|
"@certd/basic": "^1.34.11",
|
||||||
"@kubernetes/client-node": "0.21.0"
|
"@kubernetes/client-node": "0.21.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -32,5 +32,5 @@
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "a4b6580247efabe948507c771a177d4f75670bc2"
|
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,12 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持设置用户有效期 ([6ac3bc5](https://github.com/certd/certd/commit/6ac3bc564f407dad2cd0b0b0744e887387aa5da3))
|
||||||
|
|
||||||
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-server
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@certd/lib-server",
|
"name": "@certd/lib-server",
|
||||||
"version": "1.34.10",
|
"version": "1.34.11",
|
||||||
"description": "midway with flyway, sql upgrade way ",
|
"description": "midway with flyway, sql upgrade way ",
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
@ -27,10 +27,10 @@
|
||||||
],
|
],
|
||||||
"license": "AGPL",
|
"license": "AGPL",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/acme-client": "^1.34.10",
|
"@certd/acme-client": "^1.34.11",
|
||||||
"@certd/basic": "^1.34.10",
|
"@certd/basic": "^1.34.11",
|
||||||
"@certd/pipeline": "^1.34.10",
|
"@certd/pipeline": "^1.34.11",
|
||||||
"@certd/plus-core": "^1.34.10",
|
"@certd/plus-core": "^1.34.11",
|
||||||
"@midwayjs/cache": "~3.14.0",
|
"@midwayjs/cache": "~3.14.0",
|
||||||
"@midwayjs/core": "~3.20.3",
|
"@midwayjs/core": "~3.20.3",
|
||||||
"@midwayjs/i18n": "~3.20.3",
|
"@midwayjs/i18n": "~3.20.3",
|
||||||
|
@ -61,5 +61,5 @@
|
||||||
"typeorm": "^0.3.11",
|
"typeorm": "^0.3.11",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "a4b6580247efabe948507c771a177d4f75670bc2"
|
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ export class SysPublicSettings extends BaseSettings {
|
||||||
static __access__ = 'public';
|
static __access__ = 'public';
|
||||||
|
|
||||||
registerEnabled = false;
|
registerEnabled = false;
|
||||||
|
userValidTimeEnabled?:boolean = false;
|
||||||
passwordLoginEnabled = true;
|
passwordLoginEnabled = true;
|
||||||
usernameRegisterEnabled = true;
|
usernameRegisterEnabled = true;
|
||||||
mobileRegisterEnabled = false;
|
mobileRegisterEnabled = false;
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@certd/midway-flyway-js",
|
"name": "@certd/midway-flyway-js",
|
||||||
"version": "1.34.10",
|
"version": "1.34.11",
|
||||||
"description": "midway with flyway, sql upgrade way ",
|
"description": "midway with flyway, sql upgrade way ",
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
@ -46,5 +46,5 @@
|
||||||
"typeorm": "^0.3.11",
|
"typeorm": "^0.3.11",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "a4b6580247efabe948507c771a177d4f75670bc2"
|
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,12 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复中文域名使用cname方式校验无法通过的问题 ([f7d5baa](https://github.com/certd/certd/commit/f7d5baa6d04cb83c572b06e62f885890cfa0143a))
|
||||||
|
|
||||||
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/plugin-cert
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@certd/plugin-cert",
|
"name": "@certd/plugin-cert",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.34.10",
|
"version": "1.34.11",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
|
@ -16,16 +16,16 @@
|
||||||
"pub": "npm publish"
|
"pub": "npm publish"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/acme-client": "^1.34.10",
|
"@certd/acme-client": "^1.34.11",
|
||||||
"@certd/basic": "^1.34.10",
|
"@certd/basic": "^1.34.11",
|
||||||
"@certd/pipeline": "^1.34.10",
|
"@certd/pipeline": "^1.34.11",
|
||||||
"@certd/plugin-lib": "^1.34.10",
|
"@certd/plugin-lib": "^1.34.11",
|
||||||
"@google-cloud/publicca": "^1.3.0",
|
"@google-cloud/publicca": "^1.3.0",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"psl": "^1.9.0",
|
"psl": "^1.9.0",
|
||||||
"punycode": "^2.3.1",
|
"punycode.js": "^2.3.1",
|
||||||
"rimraf": "^5.0.5"
|
"rimraf": "^5.0.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -43,5 +43,5 @@
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "a4b6580247efabe948507c771a177d4f75670bc2"
|
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,25 @@ export type DnsProviderContext = {
|
||||||
|
|
||||||
export interface IDnsProvider<T = any> {
|
export interface IDnsProvider<T = any> {
|
||||||
onInstance(): Promise<void>;
|
onInstance(): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中文转英文
|
||||||
|
* @param domain
|
||||||
|
*/
|
||||||
|
punyCodeEncode(domain: string): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转中文域名
|
||||||
|
* @param domain
|
||||||
|
*/
|
||||||
|
punyCodeDecode(domain: string): string;
|
||||||
|
|
||||||
createRecord(options: CreateRecordOptions): Promise<T>;
|
createRecord(options: CreateRecordOptions): Promise<T>;
|
||||||
|
|
||||||
removeRecord(options: RemoveRecordOptions<T>): Promise<void>;
|
removeRecord(options: RemoveRecordOptions<T>): Promise<void>;
|
||||||
|
|
||||||
setCtx(ctx: DnsProviderContext): void;
|
setCtx(ctx: DnsProviderContext): void;
|
||||||
|
|
||||||
//中文域名是否需要punycode转码,如果返回True,则使用punycode来添加解析记录,否则使用中文域名添加解析记录
|
//中文域名是否需要punycode转码,如果返回True,则使用punycode来添加解析记录,否则使用中文域名添加解析记录
|
||||||
usePunyCode(): boolean;
|
usePunyCode(): boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { CreateRecordOptions, DnsProviderContext, DnsProviderDefine, IDnsProvider, RemoveRecordOptions } from "./api.js";
|
import { CreateRecordOptions, DnsProviderContext, DnsProviderDefine, IDnsProvider, RemoveRecordOptions } from "./api.js";
|
||||||
import { dnsProviderRegistry } from "./registry.js";
|
import { dnsProviderRegistry } from "./registry.js";
|
||||||
import { HttpClient, ILogger } from "@certd/basic";
|
import { HttpClient, ILogger } from "@certd/basic";
|
||||||
|
import punycode from "punycode.js";
|
||||||
export abstract class AbstractDnsProvider<T = any> implements IDnsProvider<T> {
|
export abstract class AbstractDnsProvider<T = any> implements IDnsProvider<T> {
|
||||||
ctx!: DnsProviderContext;
|
ctx!: DnsProviderContext;
|
||||||
http!: HttpClient;
|
http!: HttpClient;
|
||||||
|
@ -13,6 +13,22 @@ export abstract class AbstractDnsProvider<T = any> implements IDnsProvider<T> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中文转英文
|
||||||
|
* @param domain
|
||||||
|
*/
|
||||||
|
punyCodeEncode(domain: string) {
|
||||||
|
return punycode.toASCII(domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转中文域名
|
||||||
|
* @param domain
|
||||||
|
*/
|
||||||
|
punyCodeDecode(domain: string) {
|
||||||
|
return punycode.toUnicode(domain);
|
||||||
|
}
|
||||||
|
|
||||||
setCtx(ctx: DnsProviderContext) {
|
setCtx(ctx: DnsProviderContext) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
this.logger = ctx.logger;
|
this.logger = ctx.logger;
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { Challenge } from "@certd/acme-client/types/rfc8555";
|
||||||
import { IContext } from "@certd/pipeline";
|
import { IContext } from "@certd/pipeline";
|
||||||
import { ILogger, utils } from "@certd/basic";
|
import { ILogger, utils } from "@certd/basic";
|
||||||
import { IDnsProvider, IDomainParser } from "../../dns-provider/index.js";
|
import { IDnsProvider, IDomainParser } from "../../dns-provider/index.js";
|
||||||
import punycode from "node:punycode";
|
import punycode from "punycode.js";
|
||||||
import { IOssClient } from "@certd/plugin-lib";
|
import { IOssClient } from "@certd/plugin-lib";
|
||||||
export type CnameVerifyPlan = {
|
export type CnameVerifyPlan = {
|
||||||
type?: string;
|
type?: string;
|
||||||
|
@ -233,16 +233,18 @@ export class AcmeService {
|
||||||
let dnsProvider = providers.dnsProvider;
|
let dnsProvider = providers.dnsProvider;
|
||||||
let fullRecord = `_acme-challenge.${fullDomain}`;
|
let fullRecord = `_acme-challenge.${fullDomain}`;
|
||||||
|
|
||||||
|
const origDomain = punycode.toUnicode(domain);
|
||||||
|
const origFullDomain = punycode.toUnicode(fullDomain);
|
||||||
if (providers.domainsVerifyPlan) {
|
if (providers.domainsVerifyPlan) {
|
||||||
//按照计划执行
|
//按照计划执行
|
||||||
const domainVerifyPlan = providers.domainsVerifyPlan[domain];
|
const domainVerifyPlan = providers.domainsVerifyPlan[origDomain];
|
||||||
if (domainVerifyPlan) {
|
if (domainVerifyPlan) {
|
||||||
if (domainVerifyPlan.type === "dns") {
|
if (domainVerifyPlan.type === "dns") {
|
||||||
dnsProvider = domainVerifyPlan.dnsProvider;
|
dnsProvider = domainVerifyPlan.dnsProvider;
|
||||||
} else if (domainVerifyPlan.type === "cname") {
|
} else if (domainVerifyPlan.type === "cname") {
|
||||||
const cnameVerifyPlan = domainVerifyPlan.cnameVerifyPlan;
|
const cnameVerifyPlan = domainVerifyPlan.cnameVerifyPlan;
|
||||||
if (cnameVerifyPlan) {
|
if (cnameVerifyPlan) {
|
||||||
const cname = cnameVerifyPlan[fullDomain];
|
const cname = cnameVerifyPlan[origFullDomain];
|
||||||
if (cname) {
|
if (cname) {
|
||||||
dnsProvider = cname.dnsProvider;
|
dnsProvider = cname.dnsProvider;
|
||||||
domain = await this.options.domainParser.parse(cname.domain);
|
domain = await this.options.domainParser.parse(cname.domain);
|
||||||
|
|
|
@ -5,6 +5,7 @@ import path from "path";
|
||||||
import { CertificateInfo, crypto } from "@certd/acme-client";
|
import { CertificateInfo, crypto } from "@certd/acme-client";
|
||||||
import { ILogger } from "@certd/basic";
|
import { ILogger } from "@certd/basic";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
import { uniq } from "lodash-es";
|
||||||
|
|
||||||
export type CertReaderHandleContext = {
|
export type CertReaderHandleContext = {
|
||||||
reader: CertReader;
|
reader: CertReader;
|
||||||
|
@ -90,7 +91,8 @@ export class CertReader {
|
||||||
const { detail } = this.getCrtDetail();
|
const { detail } = this.getCrtDetail();
|
||||||
const domains = [detail.domains.commonName];
|
const domains = [detail.domains.commonName];
|
||||||
domains.push(...detail.domains.altNames);
|
domains.push(...detail.domains.altNames);
|
||||||
return domains;
|
//去重
|
||||||
|
return uniq(domains);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAltNames() {
|
getAltNames() {
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|
||||||
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@certd/plugin-lib",
|
"name": "@certd/plugin-lib",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.34.10",
|
"version": "1.34.11",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
|
@ -20,8 +20,8 @@
|
||||||
"@alicloud/pop-core": "^1.7.10",
|
"@alicloud/pop-core": "^1.7.10",
|
||||||
"@alicloud/tea-util": "^1.4.10",
|
"@alicloud/tea-util": "^1.4.10",
|
||||||
"@aws-sdk/client-s3": "^3.787.0",
|
"@aws-sdk/client-s3": "^3.787.0",
|
||||||
"@certd/basic": "^1.34.10",
|
"@certd/basic": "^1.34.11",
|
||||||
"@certd/pipeline": "^1.34.10",
|
"@certd/pipeline": "^1.34.11",
|
||||||
"@kubernetes/client-node": "0.21.0",
|
"@kubernetes/client-node": "0.21.0",
|
||||||
"ali-oss": "^6.22.0",
|
"ali-oss": "^6.22.0",
|
||||||
"basic-ftp": "^5.0.5",
|
"basic-ftp": "^5.0.5",
|
||||||
|
@ -52,5 +52,5 @@
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "a4b6580247efabe948507c771a177d4f75670bc2"
|
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,21 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复中文域名使用cname方式校验无法通过的问题 ([f7d5baa](https://github.com/certd/certd/commit/f7d5baa6d04cb83c572b06e62f885890cfa0143a))
|
||||||
|
* 修复flexcdn部署证书的顶级CA名称显示 ([6467edb](https://github.com/certd/certd/commit/6467edb84324d7c80a85212675dbacedc459df83))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 分组选择支持清空选项 ([03e2e99](https://github.com/certd/certd/commit/03e2e9949837b34eb3ea56d14a9e8a5dabc96063))
|
||||||
|
* 优化cname检查,当有冲突的cname记录时,给出提示 ([e639a8f](https://github.com/certd/certd/commit/e639a8f9f12640ffcca69f1a6a0324459924afbd))
|
||||||
|
* 增加下载日志按钮 ([6ff509d](https://github.com/certd/certd/commit/6ff509d263c0182645b4692c10b5fedb192db964))
|
||||||
|
* 站点监控支持批量导入域名和ip ([2d7729d](https://github.com/certd/certd/commit/2d7729dbe98f29088f5f317db2b52cc1ede223a6))
|
||||||
|
* 支持设置用户有效期 ([6ac3bc5](https://github.com/certd/certd/commit/6ac3bc564f407dad2cd0b0b0744e887387aa5da3))
|
||||||
|
|
||||||
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@certd/ui-client",
|
"name": "@certd/ui-client",
|
||||||
"version": "1.34.10",
|
"version": "1.34.11",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --open",
|
"dev": "vite --open",
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
"debug": "vite --mode debug --open",
|
"debug": "vite --mode debug --open",
|
||||||
"debug:pm": "vite --mode debugpm",
|
"debug:pm": "vite --mode debugpm",
|
||||||
"debug:force": "vite --force --mode debug",
|
"debug:force": "vite --force --mode debug",
|
||||||
"build": "cross-env NODE_OPTIONS=--max-old-space-size=32768 vite build ",
|
"build": "cross-env NODE_OPTIONS=--max-old-space-size=40960 vite build ",
|
||||||
"dev-build": "echo 1",
|
"dev-build": "echo 1",
|
||||||
"test:unit": "vitest",
|
"test:unit": "vitest",
|
||||||
"serve": "vite preview",
|
"serve": "vite preview",
|
||||||
|
@ -102,8 +102,8 @@
|
||||||
"zod-defaults": "^0.1.3"
|
"zod-defaults": "^0.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@certd/lib-iframe": "^1.34.10",
|
"@certd/lib-iframe": "^1.34.11",
|
||||||
"@certd/pipeline": "^1.34.10",
|
"@certd/pipeline": "^1.34.11",
|
||||||
"@rollup/plugin-commonjs": "^25.0.7",
|
"@rollup/plugin-commonjs": "^25.0.7",
|
||||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||||
"@types/chai": "^4.3.12",
|
"@types/chai": "^4.3.12",
|
||||||
|
|
|
@ -15,6 +15,7 @@ import PemInput from "./pem-input.vue";
|
||||||
import { defineAsyncComponent } from "vue";
|
import { defineAsyncComponent } from "vue";
|
||||||
import NotificationSelector from "../views/certd/notification/notification-selector/index.vue";
|
import NotificationSelector from "../views/certd/notification/notification-selector/index.vue";
|
||||||
import EmailSelector from "./email-selector/index.vue";
|
import EmailSelector from "./email-selector/index.vue";
|
||||||
|
import ValidTimeFormat from "./valid-time-format.vue";
|
||||||
export default {
|
export default {
|
||||||
install(app: any) {
|
install(app: any) {
|
||||||
app.component(
|
app.component(
|
||||||
|
@ -27,6 +28,7 @@ export default {
|
||||||
app.component("TextEditable", TextEditable);
|
app.component("TextEditable", TextEditable);
|
||||||
app.component("FileInput", FileInput);
|
app.component("FileInput", FileInput);
|
||||||
app.component("PemInput", PemInput);
|
app.component("PemInput", PemInput);
|
||||||
|
app.component("ValidTimeFormat", ValidTimeFormat);
|
||||||
// app.component("CodeEditor", CodeEditor);
|
// app.component("CodeEditor", CodeEditor);
|
||||||
|
|
||||||
app.component("CronLight", CronLight);
|
app.component("CronLight", CronLight);
|
||||||
|
|
|
@ -8,6 +8,7 @@ export type CnameRecord = {
|
||||||
status?: string;
|
status?: string;
|
||||||
hostRecord?: string;
|
hostRecord?: string;
|
||||||
recordValue?: string;
|
recordValue?: string;
|
||||||
|
error?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DomainGroupItem = {
|
export type DomainGroupItem = {
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
</td>
|
</td>
|
||||||
<td class="status center flex-center">
|
<td class="status center flex-center">
|
||||||
<fs-values-format v-model="cnameRecord.status" :dict="statusDict" />
|
<fs-values-format v-model="cnameRecord.status" :dict="statusDict" />
|
||||||
|
<a-tooltip v-if="cnameRecord.error" :title="cnameRecord.error">
|
||||||
|
<fs-icon class="ml-5 color-red" icon="ion:warning-outline"></fs-icon>
|
||||||
|
</a-tooltip>
|
||||||
</td>
|
</td>
|
||||||
<td class="center">
|
<td class="center">
|
||||||
<template v-if="cnameRecord.status !== 'valid'">
|
<template v-if="cnameRecord.status !== 'valid'">
|
||||||
|
|
|
@ -21,7 +21,7 @@ import CnameRecordInfo from "/@/components/plugins/cert/domains-verify-plan-edit
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "CnameVerifyPlan"
|
name: "CnameVerifyPlan",
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(["update:modelValue", "change"]);
|
const emit = defineEmits(["update:modelValue", "change"]);
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div v-if="item.type === 'http'" class="plan-http">
|
<div v-if="item.type === 'http'" class="plan-http">
|
||||||
<http-verify-plan v-model="item.httpVerifyPlan" @change="onPlanChanged" />
|
<http-verify-plan v-model="item.httpVerifyPlan" @change="onPlanChanged" />
|
||||||
|
<div class="helper">证书颁发机构将请求 https://yourdomain/.well-known/acme-challenge/xxxxxx 来验证域名所有权。</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<template>
|
||||||
|
<div class="valid-time-format">
|
||||||
|
<a-tag v-if="isExpired" color="red">{{ prefix || "" }}已过期</a-tag>
|
||||||
|
<a-tag v-if="isValid" color="green" :title="date">
|
||||||
|
<fs-time-humanize v-if="humanize" :model-value="modelValue" :options="{ largest: 1, units: ['y', 'd', 'h'] }" :use-format-greater="30000000000" />
|
||||||
|
<template v-else> {{ prefix || "" }}{{ date }} </template>
|
||||||
|
</a-tag>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from "vue";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
modelValue: number;
|
||||||
|
humanize?: boolean;
|
||||||
|
prefix?: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const date = computed(() => {
|
||||||
|
return dayjs(props.modelValue || 0).format("YYYY-MM-DD");
|
||||||
|
});
|
||||||
|
|
||||||
|
const isValid = computed(() => {
|
||||||
|
return props.modelValue > 0 && props.modelValue > new Date().getTime();
|
||||||
|
});
|
||||||
|
|
||||||
|
const isExpired = computed(() => {
|
||||||
|
return props.modelValue > 0 && props.modelValue < new Date().getTime();
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -233,13 +233,13 @@ function openUpgrade() {
|
||||||
desc: "社区免费版",
|
desc: "社区免费版",
|
||||||
type: "free",
|
type: "free",
|
||||||
icon: "lucide:package-open",
|
icon: "lucide:package-open",
|
||||||
privilege: ["证书申请无限制", "域名数量无限制", "证书流水线数量无限制", "常用的主机、云平台、cdn等部署插件", "邮件、webhook通知方式"],
|
privilege: ["证书申请无限制", "域名数量无限制", "证书流水线数量无限制", "常用的主机、云平台、cdn、宝塔、1Panel等部署插件", "邮件、webhook通知方式"],
|
||||||
},
|
},
|
||||||
plus: {
|
plus: {
|
||||||
title: "专业版",
|
title: "专业版",
|
||||||
desc: "开源需要您的赞助支持",
|
desc: "开源需要您的赞助支持",
|
||||||
type: "plus",
|
type: "plus",
|
||||||
privilege: ["可加VIP群,您的需求将优先实现", "站点证书监控无限制", "更多通知方式", "插件全开放,更多强大的部署插件,宝塔、群晖、1Panel等"],
|
privilege: ["可加VIP群,您的需求将优先实现", "站点证书监控无限制", "更多通知方式", "插件全开放,群辉等更多插件"],
|
||||||
trial: {
|
trial: {
|
||||||
title: "点击获取7天试用",
|
title: "点击获取7天试用",
|
||||||
click: () => {
|
click: () => {
|
||||||
|
|
|
@ -120,10 +120,10 @@ function install(app: App, options: any = {}) {
|
||||||
rowHandle: {
|
rowHandle: {
|
||||||
fixed: "right",
|
fixed: "right",
|
||||||
buttons: {
|
buttons: {
|
||||||
view: { type: "link", text: null, icon: "ion:eye-outline" },
|
view: { type: "link", text: null, icon: "ion:eye-outline", tooltip: { title: "查看" } },
|
||||||
copy: { show: true, type: "link", text: null, icon: "ion:copy-outline" },
|
copy: { show: true, type: "link", text: null, icon: "ion:copy-outline", tooltip: { title: "复制" } },
|
||||||
edit: { type: "link", text: null, icon: "ion:create-outline" },
|
edit: { type: "link", text: null, icon: "ion:create-outline", tooltip: { title: "编辑" } },
|
||||||
remove: { type: "link", style: { color: "red" }, text: null, icon: "ion:trash-outline" },
|
remove: { type: "link", style: { color: "red" }, text: null, icon: "ion:trash-outline", tooltip: { title: "删除" } },
|
||||||
},
|
},
|
||||||
dropdown: {
|
dropdown: {
|
||||||
more: {
|
more: {
|
||||||
|
|
|
@ -122,7 +122,7 @@ export const certdResources = [
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: "OpenKey",
|
title: "开放接口密钥",
|
||||||
name: "OpenKey",
|
name: "OpenKey",
|
||||||
path: "/certd/open/openkey",
|
path: "/certd/open/openkey",
|
||||||
component: "/certd/open/openkey/index.vue",
|
component: "/certd/open/openkey/index.vue",
|
||||||
|
|
|
@ -30,6 +30,7 @@ export type PlusInfo = {
|
||||||
};
|
};
|
||||||
export type SysPublicSetting = {
|
export type SysPublicSetting = {
|
||||||
registerEnabled?: boolean;
|
registerEnabled?: boolean;
|
||||||
|
userValidTimeEnabled?: boolean;
|
||||||
usernameRegisterEnabled?: boolean;
|
usernameRegisterEnabled?: boolean;
|
||||||
mobileRegisterEnabled?: boolean;
|
mobileRegisterEnabled?: boolean;
|
||||||
emailRegisterEnabled?: boolean;
|
emailRegisterEnabled?: boolean;
|
||||||
|
|
|
@ -27,6 +27,8 @@ export interface UserInfoRes {
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
roleIds: number[];
|
roleIds: number[];
|
||||||
isWeak?: boolean;
|
isWeak?: boolean;
|
||||||
|
validTime?: number;
|
||||||
|
status?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LoginRes {
|
export interface LoginRes {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as api from "./api";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { Ref, ref } from "vue";
|
import { Ref, ref } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
import { useUserStore } from "/@/store/user";
|
import { useUserStore } from "/@/store/user";
|
||||||
import { useSettingStore } from "/@/store/settings";
|
import { useSettingStore } from "/@/store/settings";
|
||||||
import { message } from "ant-design-vue";
|
import { message } from "ant-design-vue";
|
||||||
|
@ -31,7 +31,15 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
const settingStore = useSettingStore();
|
const settingStore = useSettingStore();
|
||||||
const selectedRowKeys: Ref<any[]> = ref([]);
|
const selectedRowKeys: Ref<any[]> = ref([]);
|
||||||
context.selectedRowKeys = selectedRowKeys;
|
context.selectedRowKeys = selectedRowKeys;
|
||||||
|
const dictRef = dict({
|
||||||
|
data: [
|
||||||
|
{ label: "待设置CNAME", value: "cname", color: "warning" },
|
||||||
|
{ label: "验证中", value: "validating", color: "blue" },
|
||||||
|
{ label: "验证成功", value: "valid", color: "green" },
|
||||||
|
{ label: "验证失败", value: "failed", color: "red" },
|
||||||
|
{ label: "验证超时", value: "timeout", color: "red" },
|
||||||
|
],
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
settings: {
|
settings: {
|
||||||
|
@ -174,21 +182,25 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
status: {
|
status: {
|
||||||
title: "状态",
|
title: "状态",
|
||||||
type: "dict-select",
|
type: "dict-select",
|
||||||
dict: dict({
|
dict: dictRef,
|
||||||
data: [
|
|
||||||
{ label: "待设置CNAME", value: "cname", color: "warning" },
|
|
||||||
{ label: "验证中", value: "validating", color: "blue" },
|
|
||||||
{ label: "验证成功", value: "valid", color: "green" },
|
|
||||||
{ label: "验证失败", value: "failed", color: "red" },
|
|
||||||
{ label: "验证超时", value: "timeout", color: "red" },
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
addForm: {
|
addForm: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 120,
|
width: 120,
|
||||||
align: "center",
|
align: "center",
|
||||||
|
cellRender({ value, row }) {
|
||||||
|
return (
|
||||||
|
<div class={"flex flex-center"}>
|
||||||
|
<fs-values-format modelValue={value} dict={dictRef}></fs-values-format>
|
||||||
|
{row.error && (
|
||||||
|
<a-tooltip title={row.error}>
|
||||||
|
<fs-icon class={"ml-5 color-red"} icon="ion:warning-outline"></fs-icon>
|
||||||
|
</a-tooltip>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
triggerValidate: {
|
triggerValidate: {
|
||||||
|
|
|
@ -6,7 +6,7 @@ export async function GetList(query: any) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/page",
|
url: apiPrefix + "/page",
|
||||||
method: "post",
|
method: "post",
|
||||||
data: query
|
data: query,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ export async function AddObj(obj: any) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/add",
|
url: apiPrefix + "/add",
|
||||||
method: "post",
|
method: "post",
|
||||||
data: obj
|
data: obj,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ export async function UpdateObj(obj: any) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/update",
|
url: apiPrefix + "/update",
|
||||||
method: "post",
|
method: "post",
|
||||||
data: obj
|
data: obj,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ export async function DelObj(id: any) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/delete",
|
url: apiPrefix + "/delete",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: { id }
|
params: { id },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ export async function GetObj(id: any) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/info",
|
url: apiPrefix + "/info",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: { id }
|
params: { id },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ export async function GetDetail(id: any) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/detail",
|
url: apiPrefix + "/detail",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: { id }
|
params: { id },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,6 @@ export async function DeleteBatch(ids: any[]) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/deleteByIds",
|
url: apiPrefix + "/deleteByIds",
|
||||||
method: "post",
|
method: "post",
|
||||||
data: { ids }
|
data: { ids },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,14 @@ export const siteInfoApi = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async Import(form: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/import",
|
||||||
|
method: "post",
|
||||||
|
data: form,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
async DisabledChange(id: number, disabled: boolean) {
|
async DisabledChange(id: number, disabled: boolean) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/disabledChange",
|
url: apiPrefix + "/disabledChange",
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { useSettingStore } from "/@/store/settings";
|
||||||
import { mySuiteApi } from "/@/views/certd/suite/mine/api";
|
import { mySuiteApi } from "/@/views/certd/suite/mine/api";
|
||||||
import { mitter } from "/@/utils/util.mitt";
|
import { mitter } from "/@/utils/util.mitt";
|
||||||
import { useSiteIpMonitor } from "./ip/use";
|
import { useSiteIpMonitor } from "./ip/use";
|
||||||
|
import { useSiteImport } from "/@/views/certd/monitor/site/use";
|
||||||
|
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -44,6 +45,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
});
|
});
|
||||||
|
|
||||||
const { openSiteIpMonitorDialog } = useSiteIpMonitor();
|
const { openSiteIpMonitorDialog } = useSiteIpMonitor();
|
||||||
|
const { openSiteImportDialog } = useSiteImport();
|
||||||
return {
|
return {
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
request: {
|
request: {
|
||||||
|
@ -97,6 +99,19 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
await crudExpose.openAdd({});
|
await crudExpose.openAdd({});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
//导入按钮
|
||||||
|
import: {
|
||||||
|
show: true,
|
||||||
|
text: "批量导入",
|
||||||
|
type: "primary",
|
||||||
|
async click() {
|
||||||
|
openSiteImportDialog({
|
||||||
|
afterSubmit() {
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
rowHandle: {
|
rowHandle: {
|
||||||
|
@ -235,7 +250,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<a-popover placement="left" v-slots={slots} overlayStyle={{ maxWidth: "30%" }}>
|
<a-popover placement={"left"} v-slots={slots} overlayStyle={{ maxWidth: "30%" }}>
|
||||||
{row.certDomains}
|
{row.certDomains}
|
||||||
</a-popover>
|
</a-popover>
|
||||||
);
|
);
|
||||||
|
|
|
@ -68,4 +68,11 @@ export const siteIpApi = {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
async Import(form: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/import",
|
||||||
|
method: "post",
|
||||||
|
data: form,
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,13 +4,11 @@ import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, Edi
|
||||||
import { siteIpApi } from "./api";
|
import { siteIpApi } from "./api";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { Modal, notification } from "ant-design-vue";
|
import { Modal, notification } from "ant-design-vue";
|
||||||
import { useSettingStore } from "/@/store/settings";
|
import { useSiteIpMonitor } from "/@/views/certd/monitor/site/ip/use";
|
||||||
|
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { t } = useI18n();
|
|
||||||
const api = siteIpApi;
|
const api = siteIpApi;
|
||||||
|
|
||||||
const { crudBinding } = crudExpose;
|
|
||||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
if (!query.query) {
|
if (!query.query) {
|
||||||
query.query = {};
|
query.query = {};
|
||||||
|
@ -36,8 +34,6 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
const settingsStore = useSettingStore();
|
|
||||||
|
|
||||||
const checkStatusDict = dict({
|
const checkStatusDict = dict({
|
||||||
data: [
|
data: [
|
||||||
{ label: "成功", value: "ok", color: "green" },
|
{ label: "成功", value: "ok", color: "green" },
|
||||||
|
@ -45,6 +41,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
{ label: "异常", value: "error", color: "red" },
|
{ label: "异常", value: "error", color: "red" },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
const { openSiteIpImportDialog } = useSiteIpMonitor();
|
||||||
return {
|
return {
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
request: {
|
request: {
|
||||||
|
@ -75,6 +72,19 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
await crudExpose.openAdd({});
|
await crudExpose.openAdd({});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
import: {
|
||||||
|
show: true,
|
||||||
|
text: "批量导入",
|
||||||
|
type: "primary",
|
||||||
|
async click() {
|
||||||
|
openSiteIpImportDialog({
|
||||||
|
siteId: context.props.siteId,
|
||||||
|
afterSubmit() {
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
load: {
|
load: {
|
||||||
text: "同步IP",
|
text: "同步IP",
|
||||||
type: "primary",
|
type: "primary",
|
||||||
|
@ -295,6 +305,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
data: [
|
data: [
|
||||||
{ label: "同步", value: "sync", color: "green" },
|
{ label: "同步", value: "sync", color: "green" },
|
||||||
{ label: "手动", value: "manual", color: "blue" },
|
{ label: "手动", value: "manual", color: "blue" },
|
||||||
|
{ label: "导入", value: "import", color: "blue" },
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
form: {
|
form: {
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import { useFormWrapper } from "@fast-crud/fast-crud";
|
import { useFormWrapper } from "@fast-crud/fast-crud";
|
||||||
import { useRouter } from "vue-router";
|
|
||||||
|
|
||||||
import SiteIpCertMonitor from "./index.vue";
|
import SiteIpCertMonitor from "./index.vue";
|
||||||
|
import { siteIpApi } from "/@/views/certd/monitor/site/ip/api";
|
||||||
|
|
||||||
export function useSiteIpMonitor() {
|
export function useSiteIpMonitor() {
|
||||||
const { openDialog } = useFormWrapper();
|
const { openDialog, openCrudFormDialog } = useFormWrapper();
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
async function openSiteIpMonitorDialog(opts: { siteId: number }) {
|
async function openSiteIpMonitorDialog(opts: { siteId: number }) {
|
||||||
await openDialog({
|
await openDialog({
|
||||||
|
@ -34,7 +33,42 @@ export function useSiteIpMonitor() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function openSiteIpImportDialog(opts: { afterSubmit: any; siteId: any }) {
|
||||||
|
const { afterSubmit } = opts;
|
||||||
|
await openCrudFormDialog<any>({
|
||||||
|
crudOptions: {
|
||||||
|
columns: {
|
||||||
|
text: {
|
||||||
|
type: "textarea",
|
||||||
|
title: "IP列表",
|
||||||
|
form: {
|
||||||
|
helper: "IP或者CNAME域名,一行一个",
|
||||||
|
rules: [{ required: true, message: "请输入要导入的IP或域名" }],
|
||||||
|
component: {
|
||||||
|
placeholder: "192.168.1.2\ncname.foo.com",
|
||||||
|
rows: 8,
|
||||||
|
},
|
||||||
|
col: {
|
||||||
|
span: 24,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
async doSubmit({ form }) {
|
||||||
|
return siteIpApi.Import({
|
||||||
|
...form,
|
||||||
|
siteId: opts.siteId,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
afterSubmit,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
openSiteIpMonitorDialog,
|
openSiteIpMonitorDialog,
|
||||||
|
openSiteIpImportDialog,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { useFormWrapper } from "@fast-crud/fast-crud";
|
||||||
|
import { siteInfoApi } from "./api";
|
||||||
|
|
||||||
|
export function useSiteImport() {
|
||||||
|
const { openCrudFormDialog } = useFormWrapper();
|
||||||
|
|
||||||
|
async function openSiteImportDialog(opts: { afterSubmit: any }) {
|
||||||
|
const { afterSubmit } = opts;
|
||||||
|
await openCrudFormDialog<any>({
|
||||||
|
crudOptions: {
|
||||||
|
columns: {
|
||||||
|
text: {
|
||||||
|
type: "textarea",
|
||||||
|
title: "域名列表",
|
||||||
|
form: {
|
||||||
|
helper: "格式【域名:端口:名称】,一行一个,其中端口、名称可以省略\n比如:\nwww.baidu.com:443:百度\nwww.taobao.com::淘宝\nwww.google.com",
|
||||||
|
rules: [{ required: true, message: "请输入要导入的域名" }],
|
||||||
|
component: {
|
||||||
|
placeholder: "www.baidu.com:443:百度\nwww.taobao.com::淘宝\nwww.google.com\n",
|
||||||
|
rows: 8,
|
||||||
|
},
|
||||||
|
col: {
|
||||||
|
span: 24,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
async doSubmit({ form }) {
|
||||||
|
return siteInfoApi.Import(form);
|
||||||
|
},
|
||||||
|
afterSubmit,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
openSiteImportDialog,
|
||||||
|
};
|
||||||
|
}
|
|
@ -223,6 +223,7 @@ export default function ({ crudExpose, context: { groupDictRef, selectedRowKeys
|
||||||
play: {
|
play: {
|
||||||
order: -999,
|
order: -999,
|
||||||
title: "运行流水线",
|
title: "运行流水线",
|
||||||
|
tooltip: { title: "运行流水线" },
|
||||||
type: "link",
|
type: "link",
|
||||||
icon: "ant-design:play-circle-outlined",
|
icon: "ant-design:play-circle-outlined",
|
||||||
click({ row }) {
|
click({ row }) {
|
||||||
|
@ -276,6 +277,7 @@ export default function ({ crudExpose, context: { groupDictRef, selectedRowKeys
|
||||||
viewCert: {
|
viewCert: {
|
||||||
order: 3,
|
order: 3,
|
||||||
title: "查看证书",
|
title: "查看证书",
|
||||||
|
tooltip: { title: "查看证书" },
|
||||||
type: "link",
|
type: "link",
|
||||||
icon: "ph:certificate",
|
icon: "ph:certificate",
|
||||||
async click({ row }) {
|
async click({ row }) {
|
||||||
|
@ -286,6 +288,7 @@ export default function ({ crudExpose, context: { groupDictRef, selectedRowKeys
|
||||||
order: 4,
|
order: 4,
|
||||||
type: "link",
|
type: "link",
|
||||||
title: "下载证书",
|
title: "下载证书",
|
||||||
|
tooltip: { title: "下载证书" },
|
||||||
icon: "ant-design:download-outlined",
|
icon: "ant-design:download-outlined",
|
||||||
async click({ row }) {
|
async click({ row }) {
|
||||||
await downloadCert(row);
|
await downloadCert(row);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="pi-group-selector flex full-w">
|
<div class="pi-group-selector flex full-w">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<fs-dict-select :value="modelValue" :dict="groupDictRef" @update:value="doUpdate"></fs-dict-select>
|
<fs-dict-select :value="modelValue" :dict="groupDictRef" :allow-clear="true" @update:value="doUpdate"></fs-dict-select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<fs-table-select
|
<fs-table-select
|
||||||
|
|
|
@ -23,14 +23,11 @@
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<a-tooltip title="AI分析异常">
|
<fs-button v-if="settingsStore.sysPublic.aiChatEnabled !== false" key="aiChat" :tooltip="{ title: 'AI分析异常' }" type="primary" icon="ion:color-wand-outline" @click="taskModal.onAiChat">AI分析</fs-button>
|
||||||
<fs-button v-if="settingsStore.sysPublic.aiChatEnabled !== false" key="aiChat" type="primary" icon="ion:color-wand-outline" @click="taskModal.onAiChat">AI分析</fs-button>
|
<fs-button key="rerun" type="primary" :tooltip="{ title: '强制重新执行此步骤' }" text="重新运行" icon="icon-park-outline:replay-music" @click="triggerRun(activeKey)"></fs-button>
|
||||||
</a-tooltip>
|
<fs-button key="downloadLogs" type="primary" :tooltip="{ title: '当前任务日志下载' }" icon="ion:arrow-down-circle-outline" @click="taskModal.onDownloadLogs">下载日志</fs-button>
|
||||||
<a-tooltip title="强制重新执行此步骤">
|
<fs-button key="cancel" :tooltip="{ title: '关闭窗口' }" icon="ion:close-circle-outline" @click="taskModal.onOk">关闭</fs-button>
|
||||||
<fs-button key="rerun" type="primary" text="重新运行" icon="icon-park-outline:replay-music" @click="triggerRun(activeKey)"></fs-button>
|
<!-- <fs-button key="submit" :tooltip="{ title: '关闭窗口' }" icon="ion:checkmark-circle-outline" type="primary" @click="taskModal.onOk">确定</fs-button>-->
|
||||||
</a-tooltip>
|
|
||||||
<fs-button key="cancel" icon="ion:close-circle-outline" @click="taskModal.onOk">关闭</fs-button>
|
|
||||||
<fs-button key="submit" icon="ion:checkmark-circle-outline" type="primary" @click="taskModal.onOk">确定</fs-button>
|
|
||||||
</template>
|
</template>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
@ -41,6 +38,7 @@ import { RunHistory } from "../../type";
|
||||||
import PiStatusShow from "/@/views/certd/pipeline/pipeline/component/status-show.vue";
|
import PiStatusShow from "/@/views/certd/pipeline/pipeline/component/status-show.vue";
|
||||||
import { usePreferences } from "/@/vben/preferences";
|
import { usePreferences } from "/@/vben/preferences";
|
||||||
import { useSettingStore } from "/@/store/settings/index";
|
import { useSettingStore } from "/@/store/settings/index";
|
||||||
|
import { notification } from "ant-design-vue";
|
||||||
export default {
|
export default {
|
||||||
name: "PiTaskView",
|
name: "PiTaskView",
|
||||||
components: { PiStatusShow },
|
components: { PiStatusShow },
|
||||||
|
@ -56,6 +54,22 @@ export default {
|
||||||
onAiChat() {
|
onAiChat() {
|
||||||
onAiChat();
|
onAiChat();
|
||||||
},
|
},
|
||||||
|
onDownloadLogs() {
|
||||||
|
const logs = currentHistory.value?.logs[activeKey.value];
|
||||||
|
if (!logs || logs.length === 0) {
|
||||||
|
notification.warning({
|
||||||
|
message: "没有日志",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const logText = logs.join("");
|
||||||
|
const blob = new Blob([logText], { type: "text/plain;charset=utf-8" });
|
||||||
|
const a = document.createElement("a");
|
||||||
|
a.href = URL.createObjectURL(blob);
|
||||||
|
a.download = "certd-task-log.txt";
|
||||||
|
a.click();
|
||||||
|
URL.revokeObjectURL(a.href);
|
||||||
|
},
|
||||||
cancelText: "关闭",
|
cancelText: "关闭",
|
||||||
});
|
});
|
||||||
const { isMobile } = usePreferences();
|
const { isMobile } = usePreferences();
|
||||||
|
|
|
@ -35,6 +35,10 @@
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
<suite-card class="m-0"></suite-card>
|
<suite-card class="m-0"></suite-card>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="settingsStore.isPlus && settingsStore.sysPublic.userValidTimeEnabled === true && userInfo.validTime">
|
||||||
|
<a-divider type="vertical" />
|
||||||
|
<valid-time-format class="flex-o" prefix="账户有效期:" :model-value="userInfo.validTime" />
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import * as api from "./api";
|
import * as api from "./api";
|
||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
import { useUserStore } from "/@/store/user";
|
import { useUserStore } from "/@/store/user";
|
||||||
import { Modal, notification } from "ant-design-vue";
|
import { Modal, notification } from "ant-design-vue";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { useSettingStore } from "/@/store/settings";
|
||||||
|
|
||||||
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
|
@ -21,6 +23,10 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
const userValidTimeEnabled = compute(() => {
|
||||||
|
return settingStore.sysPublic.userValidTimeEnabled === true;
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
request: {
|
request: {
|
||||||
|
@ -210,6 +216,43 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
|
||||||
width: 100,
|
width: 100,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
validTime: {
|
||||||
|
title: "有效期",
|
||||||
|
type: "date",
|
||||||
|
form: {
|
||||||
|
show: userValidTimeEnabled,
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
align: "center",
|
||||||
|
sorter: true,
|
||||||
|
width: 100,
|
||||||
|
show: userValidTimeEnabled,
|
||||||
|
cellRender({ value }) {
|
||||||
|
if (value == null || value === 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (value < dayjs().valueOf()) {
|
||||||
|
return <a-tag color={"red"}>已过期</a-tag>;
|
||||||
|
}
|
||||||
|
const date = dayjs(value).format("YYYY-MM-DD");
|
||||||
|
return (
|
||||||
|
<a-tag color={"green"} title={date}>
|
||||||
|
<fs-time-humanize modelValue={value} options={{ largest: 1, units: ["y", "d", "h"] }} useFormatGreater={30000000000} />
|
||||||
|
</a-tag>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valueBuilder({ value, row, key }) {
|
||||||
|
if (value != null) {
|
||||||
|
row[key] = dayjs(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
valueResolve({ value, row, key }) {
|
||||||
|
if (value != null) {
|
||||||
|
row[key] = value.valueOf();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
remark: {
|
remark: {
|
||||||
title: "备注",
|
title: "备注",
|
||||||
type: "text",
|
type: "text",
|
||||||
|
|
|
@ -11,6 +11,13 @@
|
||||||
<a-form-item label="开启自助注册" :name="['public', 'registerEnabled']">
|
<a-form-item label="开启自助注册" :name="['public', 'registerEnabled']">
|
||||||
<a-switch v-model:checked="formState.public.registerEnabled" />
|
<a-switch v-model:checked="formState.public.registerEnabled" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label="开启用户有效期" :name="['public', 'userValidTimeEnabled']">
|
||||||
|
<div class="flex-o">
|
||||||
|
<a-switch v-model:checked="formState.public.userValidTimeEnabled" :disabled="!settingsStore.isPlus" />
|
||||||
|
<vip-button class="ml-5" mode="button"></vip-button>
|
||||||
|
</div>
|
||||||
|
<div class="helper">有效期内用户可正常使用,失效后流水线将被停用</div>
|
||||||
|
</a-form-item>
|
||||||
<template v-if="formState.public.registerEnabled">
|
<template v-if="formState.public.registerEnabled">
|
||||||
<a-form-item label="开启用户名注册" :name="['public', 'usernameRegisterEnabled']">
|
<a-form-item label="开启用户名注册" :name="['public', 'usernameRegisterEnabled']">
|
||||||
<a-switch v-model:checked="formState.public.usernameRegisterEnabled" />
|
<a-switch v-model:checked="formState.public.usernameRegisterEnabled" />
|
||||||
|
@ -154,6 +161,14 @@ async function loadSysSettings() {
|
||||||
if (data?.private.sms?.type) {
|
if (data?.private.sms?.type) {
|
||||||
await loadTypeDefine(data.private.sms.type);
|
await loadTypeDefine(data.private.sms.type);
|
||||||
}
|
}
|
||||||
|
if (!settingsStore.isPlus) {
|
||||||
|
formState.public.userValidTimeEnabled = false;
|
||||||
|
formState.public.emailRegisterEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!settingsStore.isComm) {
|
||||||
|
formState.public.smsLoginEnabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveLoading = ref(false);
|
const saveLoading = ref(false);
|
||||||
|
|
|
@ -9,6 +9,6 @@ typeorm:
|
||||||
port: 3309
|
port: 3309
|
||||||
username: root
|
username: root
|
||||||
password: root
|
password: root
|
||||||
database: certd2
|
database: certd
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,23 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复用户最大流水线数量校验的问题 ([919f70a](https://github.com/certd/certd/commit/919f70a5fd2842ca69f96f1659bb5a7ba3f73776))
|
||||||
|
* 修复中文域名使用cname方式校验无法通过的问题 ([f7d5baa](https://github.com/certd/certd/commit/f7d5baa6d04cb83c572b06e62f885890cfa0143a))
|
||||||
|
* 修复cv4pve sdk (proxmox插件连接失败时无法正常结束任务的bug) ([49f26b4](https://github.com/certd/certd/commit/49f26b4049a0549b0270395157e96e8f04a68bc4))
|
||||||
|
* 修复flexcdn部署证书的顶级CA名称显示 ([6467edb](https://github.com/certd/certd/commit/6467edb84324d7c80a85212675dbacedc459df83))
|
||||||
|
* 修复flexcdn证书commonNames错误的问题 ([ace363f](https://github.com/certd/certd/commit/ace363fa355436e769b27f71cc487d30d6441780))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 分组选择支持清空选项 ([03e2e99](https://github.com/certd/certd/commit/03e2e9949837b34eb3ea56d14a9e8a5dabc96063))
|
||||||
|
* 优化cname检查,当有冲突的cname记录时,给出提示 ([e639a8f](https://github.com/certd/certd/commit/e639a8f9f12640ffcca69f1a6a0324459924afbd))
|
||||||
|
* 站点监控支持批量导入域名和ip ([2d7729d](https://github.com/certd/certd/commit/2d7729dbe98f29088f5f317db2b52cc1ede223a6))
|
||||||
|
* 支持设置用户有效期 ([6ac3bc5](https://github.com/certd/certd/commit/6ac3bc564f407dad2cd0b0b0744e887387aa5da3))
|
||||||
|
|
||||||
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
ALTER TABLE cd_cname_record ADD COLUMN `error` varchar(4096);
|
||||||
|
ALTER TABLE sys_user ADD COLUMN `valid_time` bigint;
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
ALTER TABLE cd_cname_record ADD COLUMN "error" varchar(4096);
|
||||||
|
ALTER TABLE sys_user ADD COLUMN "valid_time" bigint;
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
ALTER TABLE cd_cname_record ADD COLUMN "error" varchar(4096);
|
||||||
|
ALTER TABLE sys_user ADD COLUMN "valid_time" integer;
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@certd/ui-server",
|
"name": "@certd/ui-server",
|
||||||
"version": "1.34.10",
|
"version": "1.34.11",
|
||||||
"description": "fast-server base midway",
|
"description": "fast-server base midway",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
@ -42,20 +42,20 @@
|
||||||
"@aws-sdk/client-iam": "^3.699.0",
|
"@aws-sdk/client-iam": "^3.699.0",
|
||||||
"@aws-sdk/client-cloudfront": "^3.699.0",
|
"@aws-sdk/client-cloudfront": "^3.699.0",
|
||||||
"@aws-sdk/client-s3": "^3.705.0",
|
"@aws-sdk/client-s3": "^3.705.0",
|
||||||
"@certd/acme-client": "^1.34.10",
|
"@certd/acme-client": "^1.34.11",
|
||||||
"@certd/basic": "^1.34.10",
|
"@certd/basic": "^1.34.11",
|
||||||
"@certd/commercial-core": "^1.34.10",
|
"@certd/commercial-core": "^1.34.11",
|
||||||
"@certd/jdcloud": "^1.34.10",
|
"@certd/cv4pve-api-javascript": "^8.4.1",
|
||||||
"@certd/lib-huawei": "^1.34.10",
|
"@certd/jdcloud": "^1.34.11",
|
||||||
"@certd/lib-k8s": "^1.34.10",
|
"@certd/lib-huawei": "^1.34.11",
|
||||||
"@certd/lib-server": "^1.34.10",
|
"@certd/lib-k8s": "^1.34.11",
|
||||||
"@certd/midway-flyway-js": "^1.34.10",
|
"@certd/lib-server": "^1.34.11",
|
||||||
"@certd/pipeline": "^1.34.10",
|
"@certd/midway-flyway-js": "^1.34.11",
|
||||||
"@certd/plugin-cert": "^1.34.10",
|
"@certd/pipeline": "^1.34.11",
|
||||||
"@certd/plugin-lib": "^1.34.10",
|
"@certd/plugin-cert": "^1.34.11",
|
||||||
"@certd/plugin-plus": "^1.34.10",
|
"@certd/plugin-lib": "^1.34.11",
|
||||||
"@certd/plus-core": "^1.34.10",
|
"@certd/plugin-plus": "^1.34.11",
|
||||||
"@corsinvest/cv4pve-api-javascript": "^8.3.0",
|
"@certd/plus-core": "^1.34.11",
|
||||||
"@huaweicloud/huaweicloud-sdk-cdn": "^3.1.120",
|
"@huaweicloud/huaweicloud-sdk-cdn": "^3.1.120",
|
||||||
"@huaweicloud/huaweicloud-sdk-core": "^3.1.120",
|
"@huaweicloud/huaweicloud-sdk-core": "^3.1.120",
|
||||||
"@koa/cors": "^5.0.0",
|
"@koa/cors": "^5.0.0",
|
||||||
|
@ -105,6 +105,7 @@
|
||||||
"otplib": "^12.0.1",
|
"otplib": "^12.0.1",
|
||||||
"pg": "^8.12.0",
|
"pg": "^8.12.0",
|
||||||
"psl": "^1.9.0",
|
"psl": "^1.9.0",
|
||||||
|
"punycode.js": "^2.3.1",
|
||||||
"qiniu": "^7.12.0",
|
"qiniu": "^7.12.0",
|
||||||
"qrcode": "^1.5.4",
|
"qrcode": "^1.5.4",
|
||||||
"qs": "^6.13.1",
|
"qs": "^6.13.1",
|
||||||
|
|
|
@ -105,6 +105,17 @@ export class SiteInfoController extends CrudController<SiteInfoService> {
|
||||||
await this.service.checkAllByUsers(userId);
|
await this.service.checkAllByUsers(userId);
|
||||||
return this.ok();
|
return this.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post('/import', { summary: Constants.per.authOnly })
|
||||||
|
async doImport(@Body(ALL) body: any) {
|
||||||
|
const userId = this.getUserId();
|
||||||
|
await this.service.doImport({
|
||||||
|
text:body.text,
|
||||||
|
userId
|
||||||
|
})
|
||||||
|
return this.ok();
|
||||||
|
}
|
||||||
|
|
||||||
@Post('/ipCheckChange', { summary: Constants.per.authOnly })
|
@Post('/ipCheckChange', { summary: Constants.per.authOnly })
|
||||||
async ipCheckChange(@Body(ALL) bean: any) {
|
async ipCheckChange(@Body(ALL) bean: any) {
|
||||||
const userId = this.getUserId();
|
const userId = this.getUserId();
|
||||||
|
|
|
@ -111,5 +111,16 @@ export class SiteInfoController extends CrudController<SiteIpService> {
|
||||||
return this.ok();
|
return this.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post('/import', { summary: Constants.per.authOnly })
|
||||||
|
async doImport(@Body(ALL) body: any) {
|
||||||
|
const userId = this.getUserId();
|
||||||
|
await this.service.doImport({
|
||||||
|
text:body.text,
|
||||||
|
userId,
|
||||||
|
siteId:body.siteId
|
||||||
|
})
|
||||||
|
return this.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,9 @@ export class CnameRecordEntity {
|
||||||
@Column({ comment: '验证状态', length: 20 })
|
@Column({ comment: '验证状态', length: 20 })
|
||||||
status: string;
|
status: string;
|
||||||
|
|
||||||
|
@Column({ comment: '错误信息' })
|
||||||
|
error: string
|
||||||
|
|
||||||
@Column({
|
@Column({
|
||||||
comment: '创建时间',
|
comment: '创建时间',
|
||||||
name: 'create_time',
|
name: 'create_time',
|
||||||
|
|
|
@ -6,13 +6,13 @@ import {CnameRecordEntity, CnameRecordStatusType} from '../entity/cname-record.j
|
||||||
import {createDnsProvider, IDnsProvider} from '@certd/plugin-cert';
|
import {createDnsProvider, IDnsProvider} from '@certd/plugin-cert';
|
||||||
import {CnameProvider, CnameRecord} from '@certd/pipeline';
|
import {CnameProvider, CnameRecord} from '@certd/pipeline';
|
||||||
import {cache, http, isDev, logger, utils} from '@certd/basic';
|
import {cache, http, isDev, logger, utils} from '@certd/basic';
|
||||||
import {walkTxtRecord} from '@certd/acme-client';
|
import {getAuthoritativeDnsResolver, walkTxtRecord} from '@certd/acme-client';
|
||||||
import {CnameProviderService} from './cname-provider-service.js';
|
import {CnameProviderService} from './cname-provider-service.js';
|
||||||
import {CnameProviderEntity} from '../entity/cname-provider.js';
|
import {CnameProviderEntity} from '../entity/cname-provider.js';
|
||||||
import {CommonDnsProvider} from './common-provider.js';
|
import {CommonDnsProvider} from './common-provider.js';
|
||||||
import {SubDomainService, SubDomainsGetter} from "../../pipeline/service/sub-domain-service.js";
|
import {SubDomainService, SubDomainsGetter} from "../../pipeline/service/sub-domain-service.js";
|
||||||
import {DomainParser} from "@certd/plugin-cert/dist/dns-provider/domain-parser.js";
|
import {DomainParser} from "@certd/plugin-cert/dist/dns-provider/domain-parser.js";
|
||||||
|
import punycode from 'punycode.js'
|
||||||
type CnameCheckCacheValue = {
|
type CnameCheckCacheValue = {
|
||||||
validating: boolean;
|
validating: boolean;
|
||||||
pass: boolean;
|
pass: boolean;
|
||||||
|
@ -22,11 +22,12 @@ type CnameCheckCacheValue = {
|
||||||
intervalId?: NodeJS.Timeout;
|
intervalId?: NodeJS.Timeout;
|
||||||
dnsProvider?: IDnsProvider;
|
dnsProvider?: IDnsProvider;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 授权
|
* 授权
|
||||||
*/
|
*/
|
||||||
@Provide()
|
@Provide()
|
||||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
@Scope(ScopeEnum.Request, {allowDowngrade: true})
|
||||||
export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||||
@InjectEntityModel(CnameRecordEntity)
|
@InjectEntityModel(CnameRecordEntity)
|
||||||
repository: Repository<CnameRecordEntity>;
|
repository: Repository<CnameRecordEntity>;
|
||||||
|
@ -47,6 +48,7 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||||
getRepository() {
|
getRepository() {
|
||||||
return this.repository;
|
return this.repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增
|
* 新增
|
||||||
* @param param 数据
|
* @param param 数据
|
||||||
|
@ -62,7 +64,7 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||||
param.domain = param.domain.substring(2);
|
param.domain = param.domain.substring(2);
|
||||||
}
|
}
|
||||||
param.domain = param.domain.trim()
|
param.domain = param.domain.trim()
|
||||||
const info = await this.getRepository().findOne({ where: { domain: param.domain,userId: param.userId } });
|
const info = await this.getRepository().findOne({where: {domain: param.domain, userId: param.userId}});
|
||||||
if (info) {
|
if (info) {
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
@ -77,14 +79,14 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||||
} else {
|
} else {
|
||||||
cnameProvider = await this.cnameProviderService.info(param.cnameProviderId);
|
cnameProvider = await this.cnameProviderService.info(param.cnameProviderId);
|
||||||
}
|
}
|
||||||
await this.cnameProviderChanged(param.userId,param, cnameProvider);
|
await this.cnameProviderChanged(param.userId, param, cnameProvider);
|
||||||
|
|
||||||
param.status = 'cname';
|
param.status = 'cname';
|
||||||
const { id } = await super.add(param);
|
const {id} = await super.add(param);
|
||||||
return await this.info(id);
|
return await this.info(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async cnameProviderChanged(userId:number,param: any, cnameProvider: CnameProviderEntity) {
|
private async cnameProviderChanged(userId: number, param: any, cnameProvider: CnameProviderEntity) {
|
||||||
param.cnameProviderId = cnameProvider.id;
|
param.cnameProviderId = cnameProvider.id;
|
||||||
|
|
||||||
const subDomainGetter = new SubDomainsGetter(userId, this.subDomainService)
|
const subDomainGetter = new SubDomainsGetter(userId, this.subDomainService)
|
||||||
|
@ -117,7 +119,7 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||||
}
|
}
|
||||||
if (old.cnameProviderId !== param.cnameProviderId) {
|
if (old.cnameProviderId !== param.cnameProviderId) {
|
||||||
const cnameProvider = await this.cnameProviderService.info(param.cnameProviderId);
|
const cnameProvider = await this.cnameProviderService.info(param.cnameProviderId);
|
||||||
await this.cnameProviderChanged(old.userId,param, cnameProvider);
|
await this.cnameProviderChanged(old.userId, param, cnameProvider);
|
||||||
param.status = 'cname';
|
param.status = 'cname';
|
||||||
}
|
}
|
||||||
return await super.update(param);
|
return await super.update(param);
|
||||||
|
@ -157,10 +159,10 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
throw new ValidateException('userId不能为空');
|
throw new ValidateException('userId不能为空');
|
||||||
}
|
}
|
||||||
let record = await this.getRepository().findOne({ where: { domain, userId } });
|
let record = await this.getRepository().findOne({where: {domain, userId}});
|
||||||
if (record == null) {
|
if (record == null) {
|
||||||
if (createOnNotFound) {
|
if (createOnNotFound) {
|
||||||
record = await this.add({ domain, userId });
|
record = await this.add({domain, userId});
|
||||||
} else {
|
} else {
|
||||||
throw new ValidateException(`找不到${domain}的CNAME记录`);
|
throw new ValidateException(`找不到${domain}的CNAME记录`);
|
||||||
}
|
}
|
||||||
|
@ -208,7 +210,7 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||||
if (isDev()) {
|
if (isDev()) {
|
||||||
ttl = 30 * 1000;
|
ttl = 30 * 1000;
|
||||||
}
|
}
|
||||||
const testRecordValue = 'certd-cname-verify';
|
const testRecordValue = `certd-cname-verify-${bean.id}`;
|
||||||
|
|
||||||
const buildDnsProvider = async () => {
|
const buildDnsProvider = async () => {
|
||||||
const cnameProvider = await this.cnameProviderService.info(bean.cnameProviderId);
|
const cnameProvider = await this.cnameProviderService.info(bean.cnameProviderId);
|
||||||
|
@ -228,7 +230,7 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const access = await this.accessService.getById(cnameProvider.accessId, cnameProvider.userId);
|
const access = await this.accessService.getById(cnameProvider.accessId, cnameProvider.userId);
|
||||||
const context = { access, logger, http, utils,domainParser };
|
const context = {access, logger, http, utils, domainParser};
|
||||||
const dnsProvider: IDnsProvider = await createDnsProvider({
|
const dnsProvider: IDnsProvider = await createDnsProvider({
|
||||||
dnsProviderType: cnameProvider.dnsProviderType,
|
dnsProviderType: cnameProvider.dnsProviderType,
|
||||||
context,
|
context,
|
||||||
|
@ -239,7 +241,7 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||||
const clearVerifyRecord = async () => {
|
const clearVerifyRecord = async () => {
|
||||||
cache.delete(cacheKey);
|
cache.delete(cacheKey);
|
||||||
try {
|
try {
|
||||||
let dnsProvider =value.dnsProvider
|
let dnsProvider = value.dnsProvider
|
||||||
if (!dnsProvider) {
|
if (!dnsProvider) {
|
||||||
dnsProvider = await buildDnsProvider();
|
dnsProvider = await buildDnsProvider();
|
||||||
}
|
}
|
||||||
|
@ -271,6 +273,9 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||||
|
|
||||||
logger.info(`检查CNAME配置 ${fullDomain} ${testRecordValue}`);
|
logger.info(`检查CNAME配置 ${fullDomain} ${testRecordValue}`);
|
||||||
|
|
||||||
|
//检查是否有重复的acme配置
|
||||||
|
await this.checkRepeatAcmeChallengeRecords(fullDomain,bean.recordValue)
|
||||||
|
|
||||||
// const txtRecords = await dns.promises.resolveTxt(fullDomain);
|
// const txtRecords = await dns.promises.resolveTxt(fullDomain);
|
||||||
// if (txtRecords.length) {
|
// if (txtRecords.length) {
|
||||||
// records = [].concat(...txtRecords);
|
// records = [].concat(...txtRecords);
|
||||||
|
@ -286,7 +291,7 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||||
if (success) {
|
if (success) {
|
||||||
clearInterval(value.intervalId);
|
clearInterval(value.intervalId);
|
||||||
logger.info(`检测到CNAME配置,修改状态 ${fullDomain} ${testRecordValue}`);
|
logger.info(`检测到CNAME配置,修改状态 ${fullDomain} ${testRecordValue}`);
|
||||||
await this.updateStatus(bean.id, 'valid');
|
await this.updateStatus(bean.id, 'valid', "");
|
||||||
value.pass = true;
|
value.pass = true;
|
||||||
await clearVerifyRecord()
|
await clearVerifyRecord()
|
||||||
return success;
|
return success;
|
||||||
|
@ -312,24 +317,102 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||||
type: 'TXT',
|
type: 'TXT',
|
||||||
value: testRecordValue,
|
value: testRecordValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
const dnsProvider = await buildDnsProvider();
|
const dnsProvider = await buildDnsProvider();
|
||||||
|
if(dnsProvider.usePunyCode()){
|
||||||
|
//是否需要中文转英文
|
||||||
|
req.domain = dnsProvider.punyCodeEncode(req.domain)
|
||||||
|
req.fullRecord = dnsProvider.punyCodeEncode(req.fullRecord)
|
||||||
|
req.hostRecord = dnsProvider.punyCodeEncode(req.hostRecord)
|
||||||
|
req.value = dnsProvider.punyCodeEncode(req.value)
|
||||||
|
}
|
||||||
const recordRes = await dnsProvider.createRecord(req);
|
const recordRes = await dnsProvider.createRecord(req);
|
||||||
value.dnsProvider = dnsProvider;
|
value.dnsProvider = dnsProvider;
|
||||||
value.validating = true;
|
value.validating = true;
|
||||||
value.recordReq = req;
|
value.recordReq = req;
|
||||||
value.recordRes = recordRes;
|
value.recordRes = recordRes;
|
||||||
await this.updateStatus(bean.id, 'validating');
|
await this.updateStatus(bean.id, 'validating', "");
|
||||||
|
|
||||||
value.intervalId = setInterval(async () => {
|
value.intervalId = setInterval(async () => {
|
||||||
try {
|
try {
|
||||||
await checkRecordValue();
|
await checkRecordValue();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error('检查cname出错:', e);
|
logger.error('检查cname出错:', e);
|
||||||
|
await this.updateError(bean.id, e.message);
|
||||||
}
|
}
|
||||||
}, 10000);
|
}, 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateStatus(id: number, status: CnameRecordStatusType) {
|
async updateStatus(id: number, status: CnameRecordStatusType, error?: string) {
|
||||||
await this.getRepository().update(id, { status });
|
const updated: any = {status}
|
||||||
|
if (error != null) {
|
||||||
|
updated.error = error
|
||||||
|
}
|
||||||
|
await this.getRepository().update(id, updated);
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateError(id: number, error: string) {
|
||||||
|
await this.getRepository().update(id, {error});
|
||||||
|
}
|
||||||
|
|
||||||
|
async checkRepeatAcmeChallengeRecords(acmeRecordDomain: string,targetCnameDomain:string) {
|
||||||
|
|
||||||
|
let dnsResolver = null
|
||||||
|
try{
|
||||||
|
dnsResolver = await getAuthoritativeDnsResolver(acmeRecordDomain)
|
||||||
|
}catch (e) {
|
||||||
|
logger.error(`获取${acmeRecordDomain}的权威DNS服务器失败,${e.message}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let cnameRecords = []
|
||||||
|
try{
|
||||||
|
cnameRecords = await dnsResolver.resolveCname(acmeRecordDomain);
|
||||||
|
}catch (e) {
|
||||||
|
logger.error(`查询CNAME记录失败:${e.message}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
targetCnameDomain = targetCnameDomain.toLowerCase()
|
||||||
|
targetCnameDomain = punycode.toASCII(targetCnameDomain)
|
||||||
|
if (cnameRecords.length > 0) {
|
||||||
|
for (const cnameRecord of cnameRecords) {
|
||||||
|
if(cnameRecord.toLowerCase() !== targetCnameDomain){
|
||||||
|
//确保只有一个cname记录
|
||||||
|
throw new Error(`${acmeRecordDomain}存在多个CNAME记录,请删除多余的CNAME记录:${cnameRecord}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保权威服务器里面没有纯粹的TXT记录
|
||||||
|
let txtRecords = []
|
||||||
|
try{
|
||||||
|
const txtRecordRes = await dnsResolver.resolveTxt(acmeRecordDomain);
|
||||||
|
|
||||||
|
if (txtRecordRes && txtRecordRes.length > 0) {
|
||||||
|
logger.info(`找到 ${txtRecordRes.length} 条 TXT记录( ${acmeRecordDomain})`);
|
||||||
|
logger.info(`TXT records: ${JSON.stringify(txtRecords)}`);
|
||||||
|
txtRecords = txtRecords.concat(...txtRecordRes);
|
||||||
|
}
|
||||||
|
}catch (e) {
|
||||||
|
logger.error(`查询Txt记录失败:${e.message}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txtRecords.length === 0) {
|
||||||
|
//如果权威服务器中查不到txt,无需继续检查
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (cnameRecords.length > 0) {
|
||||||
|
// 从cname记录中获取txt记录
|
||||||
|
// 对比是否存在,如果不存在于cname中获取的txt中,说明本体有创建多余的txt记录
|
||||||
|
const res = await walkTxtRecord(cnameRecords[0]);
|
||||||
|
if (res.length > 0) {
|
||||||
|
for (const txtRecord of txtRecords) {
|
||||||
|
if (!res.includes(txtRecord)) {
|
||||||
|
throw new Error(`${acmeRecordDomain}存在多个TXT记录,请删除多余的TXT记录:${txtRecord}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {CreateRecordOptions, DnsProviderContext, IDnsProvider, RemoveRecordOptions} from '@certd/plugin-cert';
|
import {CreateRecordOptions, DnsProviderContext, IDnsProvider, RemoveRecordOptions} from '@certd/plugin-cert';
|
||||||
import {PlusService} from '@certd/lib-server';
|
import {PlusService} from '@certd/lib-server';
|
||||||
|
import punycode from 'punycode.js'
|
||||||
export type CommonCnameProvider = {
|
export type CommonCnameProvider = {
|
||||||
id: number;
|
id: number;
|
||||||
domain: string;
|
domain: string;
|
||||||
|
@ -24,6 +24,23 @@ export class CommonDnsProvider implements IDnsProvider {
|
||||||
this.plusService = opts.plusService;
|
this.plusService = opts.plusService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中文转英文
|
||||||
|
* @param domain
|
||||||
|
*/
|
||||||
|
punyCodeEncode(domain: string) {
|
||||||
|
return punycode.encode(domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转中文域名
|
||||||
|
* @param domain
|
||||||
|
*/
|
||||||
|
punyCodeDecode(domain: string) {
|
||||||
|
return punycode.decode(domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
usePunyCode(): boolean {
|
usePunyCode(): boolean {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core";
|
||||||
import { BaseService, NeedSuiteException, NeedVIPException, SysSettingsService } from '@certd/lib-server';
|
import { BaseService, NeedSuiteException, NeedVIPException, SysSettingsService } from "@certd/lib-server";
|
||||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
import { InjectEntityModel } from "@midwayjs/typeorm";
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from "typeorm";
|
||||||
import { SiteInfoEntity } from '../entity/site-info.js';
|
import { SiteInfoEntity } from "../entity/site-info.js";
|
||||||
import { siteTester } from './site-tester.js';
|
import { siteTester } from "./site-tester.js";
|
||||||
import dayjs from 'dayjs';
|
import dayjs from "dayjs";
|
||||||
import { logger, utils } from '@certd/basic';
|
import { logger, utils } from "@certd/basic";
|
||||||
import { PeerCertificate } from 'tls';
|
import { PeerCertificate } from "tls";
|
||||||
import { NotificationService } from '../../pipeline/service/notification-service.js';
|
import { NotificationService } from "../../pipeline/service/notification-service.js";
|
||||||
import { isComm, isPlus } from '@certd/plus-core';
|
import { isComm, isPlus } from "@certd/plus-core";
|
||||||
import { UserSuiteService } from '@certd/commercial-core';
|
import { UserSuiteService } from "@certd/commercial-core";
|
||||||
import { UserSettingsService } from "../../mine/service/user-settings-service.js";
|
import { UserSettingsService } from "../../mine/service/user-settings-service.js";
|
||||||
import { UserSiteMonitorSetting } from "../../mine/service/models.js";
|
import { UserSiteMonitorSetting } from "../../mine/service/models.js";
|
||||||
import {SiteIpService} from "./site-ip-service.js";
|
import { SiteIpService } from "./site-ip-service.js";
|
||||||
import {SiteIpEntity} from "../entity/site-ip.js";
|
import { SiteIpEntity } from "../entity/site-ip.js";
|
||||||
|
|
||||||
@Provide()
|
@Provide()
|
||||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||||
|
@ -43,7 +43,7 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||||
|
|
||||||
async add(data: SiteInfoEntity) {
|
async add(data: SiteInfoEntity) {
|
||||||
if (!data.userId) {
|
if (!data.userId) {
|
||||||
throw new Error('userId is required');
|
throw new Error("userId is required");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isComm()) {
|
if (isComm()) {
|
||||||
|
@ -51,25 +51,34 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||||
if (suiteSetting.enabled) {
|
if (suiteSetting.enabled) {
|
||||||
const userSuite = await this.userSuiteService.getMySuiteDetail(data.userId);
|
const userSuite = await this.userSuiteService.getMySuiteDetail(data.userId);
|
||||||
if (userSuite.monitorCount.max != -1 && userSuite.monitorCount.max <= userSuite.monitorCount.used) {
|
if (userSuite.monitorCount.max != -1 && userSuite.monitorCount.max <= userSuite.monitorCount.used) {
|
||||||
throw new NeedSuiteException('站点监控数量已达上限,请购买或升级套餐');
|
throw new NeedSuiteException("站点监控数量已达上限,请购买或升级套餐");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else if (!isPlus()) {
|
} else if (!isPlus()) {
|
||||||
const count = await this.getUserMonitorCount(data.userId);
|
const count = await this.getUserMonitorCount(data.userId);
|
||||||
if (count >= 1) {
|
if (count >= 1) {
|
||||||
throw new NeedVIPException('站点监控数量已达上限,请升级专业版');
|
throw new NeedVIPException("站点监控数量已达上限,请升级专业版");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
data.disabled = false;
|
data.disabled = false;
|
||||||
|
|
||||||
|
const found = await this.repository.findOne({
|
||||||
|
where: {
|
||||||
|
domain: data.domain,
|
||||||
|
userId: data.userId,
|
||||||
|
httpsPort: data.httpsPort || 443
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (found) {
|
||||||
|
return { id: found.id };
|
||||||
|
}
|
||||||
|
|
||||||
return await super.add(data);
|
return await super.add(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(data: any) {
|
async update(data: any) {
|
||||||
if (!data.id) {
|
if (!data.id) {
|
||||||
throw new Error('id is required');
|
throw new Error("id is required");
|
||||||
}
|
}
|
||||||
delete data.userId;
|
delete data.userId;
|
||||||
await super.update(data);
|
await super.update(data);
|
||||||
|
@ -77,10 +86,10 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||||
|
|
||||||
async getUserMonitorCount(userId: number) {
|
async getUserMonitorCount(userId: number) {
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
throw new Error('userId is required');
|
throw new Error("userId is required");
|
||||||
}
|
}
|
||||||
return await this.repository.count({
|
return await this.repository.count({
|
||||||
where: { userId },
|
where: { userId }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,26 +101,26 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||||
*/
|
*/
|
||||||
async doCheck(site: SiteInfoEntity, notify = true, retryTimes = 3) {
|
async doCheck(site: SiteInfoEntity, notify = true, retryTimes = 3) {
|
||||||
if (!site?.domain) {
|
if (!site?.domain) {
|
||||||
throw new Error('站点域名不能为空');
|
throw new Error("站点域名不能为空");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await this.update({
|
await this.update({
|
||||||
id: site.id,
|
id: site.id,
|
||||||
checkStatus: 'checking',
|
checkStatus: "checking",
|
||||||
lastCheckTime: dayjs().valueOf(),
|
lastCheckTime: dayjs().valueOf()
|
||||||
});
|
});
|
||||||
const res = await siteTester.test({
|
const res = await siteTester.test({
|
||||||
host: site.domain,
|
host: site.domain,
|
||||||
port: site.httpsPort,
|
port: site.httpsPort,
|
||||||
retryTimes,
|
retryTimes
|
||||||
});
|
});
|
||||||
|
|
||||||
const certi: PeerCertificate = res.certificate;
|
const certi: PeerCertificate = res.certificate;
|
||||||
if (!certi) {
|
if (!certi) {
|
||||||
throw new Error('没有发现证书');
|
throw new Error("没有发现证书");
|
||||||
}
|
}
|
||||||
const expires = certi.valid_to;
|
const expires = certi.valid_to;
|
||||||
const allDomains = certi.subjectaltname?.replaceAll('DNS:', '').split(',') ||[];
|
const allDomains = certi.subjectaltname?.replaceAll("DNS:", "").split(",") || [];
|
||||||
const mainDomain = certi.subject?.CN;
|
const mainDomain = certi.subject?.CN;
|
||||||
let domains = allDomains;
|
let domains = allDomains;
|
||||||
if (!allDomains.includes(mainDomain)) {
|
if (!allDomains.includes(mainDomain)) {
|
||||||
|
@ -119,23 +128,26 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||||
}
|
}
|
||||||
const issuer = `${certi.issuer.O}<${certi.issuer.CN}>`;
|
const issuer = `${certi.issuer.O}<${certi.issuer.CN}>`;
|
||||||
const isExpired = dayjs().valueOf() > dayjs(expires).valueOf();
|
const isExpired = dayjs().valueOf() > dayjs(expires).valueOf();
|
||||||
const status = isExpired ? 'expired' : 'ok';
|
const status = isExpired ? "expired" : "ok";
|
||||||
const updateData = {
|
const updateData = {
|
||||||
id: site.id,
|
id: site.id,
|
||||||
certDomains: domains.join(','),
|
certDomains: domains.join(","),
|
||||||
certStatus: status,
|
certStatus: status,
|
||||||
certProvider: issuer,
|
certProvider: issuer,
|
||||||
certExpiresTime: dayjs(expires).valueOf(),
|
certExpiresTime: dayjs(expires).valueOf(),
|
||||||
lastCheckTime: dayjs().valueOf(),
|
lastCheckTime: dayjs().valueOf(),
|
||||||
error: null,
|
error: null,
|
||||||
checkStatus: 'ok',
|
checkStatus: "ok"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (site.ipCheck) {
|
||||||
|
delete updateData.checkStatus
|
||||||
|
}
|
||||||
await this.update(updateData);
|
await this.update(updateData);
|
||||||
|
|
||||||
|
|
||||||
//检查ip
|
//检查ip
|
||||||
await this.checkAllIp(site)
|
await this.checkAllIp(site);
|
||||||
|
|
||||||
if (!notify) {
|
if (!notify) {
|
||||||
return;
|
return;
|
||||||
|
@ -143,15 +155,15 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||||
try {
|
try {
|
||||||
await this.sendExpiresNotify(site);
|
await this.sendExpiresNotify(site);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error('send notify error', e);
|
logger.error("send notify error", e);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error('check site error', e);
|
logger.error("check site error", e);
|
||||||
await this.update({
|
await this.update({
|
||||||
id: site.id,
|
id: site.id,
|
||||||
checkStatus: 'error',
|
checkStatus: "error",
|
||||||
lastCheckTime: dayjs().valueOf(),
|
lastCheckTime: dayjs().valueOf(),
|
||||||
error: e.message,
|
error: e.message
|
||||||
});
|
});
|
||||||
if (!notify) {
|
if (!notify) {
|
||||||
return;
|
return;
|
||||||
|
@ -159,49 +171,56 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||||
try {
|
try {
|
||||||
await this.sendCheckErrorNotify(site);
|
await this.sendCheckErrorNotify(site);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error('send notify error', e);
|
logger.error("send notify error", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkAllIp(site:SiteInfoEntity){
|
async checkAllIp(site: SiteInfoEntity) {
|
||||||
if( !site.ipCheck){
|
if (!site.ipCheck) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const certExpiresTime = site.certExpiresTime;
|
const certExpiresTime = site.certExpiresTime;
|
||||||
const onFinished = async (list:SiteIpEntity[])=>{
|
const onFinished = async (list: SiteIpEntity[]) => {
|
||||||
let errorCount = 0
|
let errorCount = 0;
|
||||||
let errorMessage = ""
|
let errorMessage = "";
|
||||||
for (const item of list) {
|
for (const item of list) {
|
||||||
if (!item) {
|
if (!item) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
errorCount++
|
errorCount++;
|
||||||
if(item.error){
|
if (item.error) {
|
||||||
errorMessage += `${item.ipAddress}:${item.error}; \n`
|
errorMessage += `${item.ipAddress}:${item.error}; \n`;
|
||||||
}else if(item.certExpiresTime!==certExpiresTime){
|
} else if (item.certExpiresTime !== certExpiresTime) {
|
||||||
errorMessage += `${item.ipAddress}:与主站证书过期时间不一致; \n`
|
errorMessage += `${item.ipAddress}:与主站证书过期时间不一致; \n`;
|
||||||
}else{
|
} else {
|
||||||
errorCount--
|
errorCount--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (errorCount<=0){
|
if (errorCount <= 0) {
|
||||||
return
|
//检查正常
|
||||||
|
await this.update({
|
||||||
|
id: site.id,
|
||||||
|
checkStatus: "ok",
|
||||||
|
error: "",
|
||||||
|
ipErrorCount: 0
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
await this.update({
|
await this.update({
|
||||||
id: site.id,
|
id: site.id,
|
||||||
checkStatus: 'error',
|
checkStatus: "error",
|
||||||
error: errorMessage,
|
error: errorMessage,
|
||||||
ipErrorCount: errorCount,
|
ipErrorCount: errorCount
|
||||||
})
|
});
|
||||||
try {
|
try {
|
||||||
site = await this.info(site.id)
|
site = await this.info(site.id);
|
||||||
await this.sendCheckErrorNotify(site,true);
|
await this.sendCheckErrorNotify(site, true);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error('send notify error', e);
|
logger.error("send notify error", e);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
await this.siteIpService.checkAll(site,onFinished)
|
await this.siteIpService.checkAll(site, onFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -213,13 +232,13 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||||
async check(id: number, notify = false, retryTimes = 3) {
|
async check(id: number, notify = false, retryTimes = 3) {
|
||||||
const site = await this.info(id);
|
const site = await this.info(id);
|
||||||
if (!site) {
|
if (!site) {
|
||||||
throw new Error('站点不存在');
|
throw new Error("站点不存在");
|
||||||
}
|
}
|
||||||
return await this.doCheck(site, notify, retryTimes);
|
return await this.doCheck(site, notify, retryTimes);
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendCheckErrorNotify(site: SiteInfoEntity,fromIpCheck=false) {
|
async sendCheckErrorNotify(site: SiteInfoEntity, fromIpCheck = false) {
|
||||||
const url = await this.notificationService.getBindUrl('#/certd/monitor/site');
|
const url = await this.notificationService.getBindUrl("#/certd/monitor/site");
|
||||||
// 发邮件
|
// 发邮件
|
||||||
await this.notificationService.send(
|
await this.notificationService.send(
|
||||||
{
|
{
|
||||||
|
@ -227,22 +246,23 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||||
logger: logger,
|
logger: logger,
|
||||||
body: {
|
body: {
|
||||||
url,
|
url,
|
||||||
title: `站点证书${fromIpCheck?"(IP)":""}检查出错<${site.name}>`,
|
title: `站点证书${fromIpCheck ? "(IP)" : ""}检查出错<${site.name}>`,
|
||||||
content: `站点名称: ${site.name} \n站点域名: ${site.domain} \n错误信息:${site.error}`,
|
content: `站点名称: ${site.name} \n站点域名: ${site.domain} \n错误信息:${site.error}`,
|
||||||
errorMessage: site.error,
|
errorMessage: site.error
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
site.userId
|
site.userId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendExpiresNotify(site: SiteInfoEntity) {
|
async sendExpiresNotify(site: SiteInfoEntity) {
|
||||||
|
|
||||||
const tipDays = 10
|
const tipDays = 10;
|
||||||
|
|
||||||
const expires = site.certExpiresTime;
|
const expires = site.certExpiresTime;
|
||||||
const validDays = dayjs(expires).diff(dayjs(), 'day');
|
const validDays = dayjs(expires).diff(dayjs(), "day");
|
||||||
const url = await this.notificationService.getBindUrl('#/certd/monitor/site');
|
const url = await this.notificationService.getBindUrl("#/certd/monitor/site");
|
||||||
const content = `站点名称: ${site.name} \n站点域名: ${site.domain} \n证书域名: ${site.certDomains} \n颁发机构: ${site.certProvider} \n过期时间: ${dayjs(site.certExpiresTime).format('YYYY-MM-DD')} \n`;
|
const content = `站点名称: ${site.name} \n站点域名: ${site.domain} \n证书域名: ${site.certDomains} \n颁发机构: ${site.certProvider} \n过期时间: ${dayjs(site.certExpiresTime).format("YYYY-MM-DD")} \n`;
|
||||||
if (validDays >= 0 && validDays < tipDays) {
|
if (validDays >= 0 && validDays < tipDays) {
|
||||||
// 发通知
|
// 发通知
|
||||||
await this.notificationService.send(
|
await this.notificationService.send(
|
||||||
|
@ -252,8 +272,8 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||||
body: {
|
body: {
|
||||||
title: `站点证书即将过期,剩余${validDays}天,<${site.name}>`,
|
title: `站点证书即将过期,剩余${validDays}天,<${site.name}>`,
|
||||||
content,
|
content,
|
||||||
url,
|
url
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
site.userId
|
site.userId
|
||||||
);
|
);
|
||||||
|
@ -268,7 +288,7 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||||
content,
|
content,
|
||||||
url,
|
url,
|
||||||
errorMessage: "站点证书已过期"
|
errorMessage: "站点证书已过期"
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
site.userId
|
site.userId
|
||||||
);
|
);
|
||||||
|
@ -277,10 +297,10 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||||
|
|
||||||
async checkAllByUsers(userId: any) {
|
async checkAllByUsers(userId: any) {
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
throw new Error('userId is required');
|
throw new Error("userId is required");
|
||||||
}
|
}
|
||||||
const sites = await this.repository.find({
|
const sites = await this.repository.find({
|
||||||
where: { userId },
|
where: { userId }
|
||||||
});
|
});
|
||||||
this.checkList(sites);
|
this.checkList(sites);
|
||||||
}
|
}
|
||||||
|
@ -294,7 +314,7 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSetting(userId: number){
|
async getSetting(userId: number) {
|
||||||
return await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId, UserSiteMonitorSetting);
|
return await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId, UserSiteMonitorSetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,26 +322,78 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||||
await this.userSettingsService.saveSetting(userId, bean);
|
await this.userSettingsService.saveSetting(userId, bean);
|
||||||
}
|
}
|
||||||
|
|
||||||
async ipCheckChange(req: {id: any; ipCheck: any}) {
|
async ipCheckChange(req: { id: any; ipCheck: any }) {
|
||||||
|
|
||||||
await this.update({
|
await this.update({
|
||||||
id: req.id,
|
id: req.id,
|
||||||
ipCheck: req.ipCheck,
|
ipCheck: req.ipCheck
|
||||||
});
|
});
|
||||||
if(req.ipCheck){
|
if (req.ipCheck) {
|
||||||
const site = await this.info(req.id);
|
const site = await this.info(req.id);
|
||||||
await this.siteIpService.sync(site)
|
await this.siteIpService.sync(site);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async disabledChange(req: { disabled: any; id: any }) {
|
async disabledChange(req: { disabled: any; id: any }) {
|
||||||
await this.update({
|
await this.update({
|
||||||
id: req.id,
|
id: req.id,
|
||||||
disabled: req.disabled,
|
disabled: req.disabled
|
||||||
});
|
});
|
||||||
if(!req.disabled){
|
if (!req.disabled) {
|
||||||
const site = await this.info(req.id);
|
const site = await this.info(req.id);
|
||||||
await this.doCheck(site)
|
await this.doCheck(site);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async doImport(req: { text: string; userId: number }) {
|
||||||
|
if (!req.text) {
|
||||||
|
throw new Error("text is required");
|
||||||
|
}
|
||||||
|
if (!req.userId) {
|
||||||
|
throw new Error("userId is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = req.text.split("\n");
|
||||||
|
|
||||||
|
const list = [];
|
||||||
|
for (const item of rows) {
|
||||||
|
if (!item) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const arr = item.trim().split(":");
|
||||||
|
if (arr.length === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const domain = arr[0];
|
||||||
|
let port = 443;
|
||||||
|
let name = domain;
|
||||||
|
if (arr.length > 1) {
|
||||||
|
try {
|
||||||
|
port = parseInt(arr[1] || "443");
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`${item}格式错误`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (arr.length > 2) {
|
||||||
|
name = arr[2] || domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.push({
|
||||||
|
domain,
|
||||||
|
name,
|
||||||
|
httpsPort: port,
|
||||||
|
userId: req.userId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const batchAdd = async (list: any[]) => {
|
||||||
|
for (const item of list) {
|
||||||
|
await this.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// await this.checkAllByUsers(req.userId);
|
||||||
|
};
|
||||||
|
await batchAdd(list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,7 +182,7 @@ export class SiteIpService extends BaseService<SiteIpEntity> {
|
||||||
const finished = res.filter(item=>{
|
const finished = res.filter(item=>{
|
||||||
return item!=null
|
return item!=null
|
||||||
})
|
})
|
||||||
if (finished.length > 0) {
|
if (onFinish) {
|
||||||
onFinish && onFinish(finished)
|
onFinish && onFinish(finished)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -232,4 +232,50 @@ export class SiteIpService extends BaseService<SiteIpEntity> {
|
||||||
ipCount:count
|
ipCount:count
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async doImport(req: { text: string; userId:number, siteId:number }) {
|
||||||
|
if (!req.text) {
|
||||||
|
throw new Error("text is required");
|
||||||
|
}
|
||||||
|
if (!req.siteId) {
|
||||||
|
throw new Error("siteId is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
const siteEntity = await this.siteInfoRepository.findOne({
|
||||||
|
where: {
|
||||||
|
id: req.siteId,
|
||||||
|
userId:req.userId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!siteEntity) {
|
||||||
|
throw new Error(`站点${req.siteId}不存在`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const userId = siteEntity.userId;
|
||||||
|
|
||||||
|
const rows = req.text.split("\n");
|
||||||
|
|
||||||
|
const list = [];
|
||||||
|
for (const item of rows) {
|
||||||
|
if (!item) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
list.push({
|
||||||
|
ipAddress:item,
|
||||||
|
userId: userId,
|
||||||
|
siteId: req.siteId,
|
||||||
|
from: "import",
|
||||||
|
disabled:false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const batchAdd = async (list: any[]) => {
|
||||||
|
for (const item of list) {
|
||||||
|
await this.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// await this.checkAllByUsers(req.userId);
|
||||||
|
};
|
||||||
|
await batchAdd(list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,8 +233,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||||
throw new NeedSuiteException(`对不起,您最多只能添加${userSuite.domainCount.max}个域名,请购买或升级套餐`);
|
throw new NeedSuiteException(`对不起,您最多只能添加${userSuite.domainCount.max}个域名,请购买或升级套餐`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}else{
|
||||||
|
//非商业版校验用户最大流水线数量
|
||||||
const userId = bean.userId;
|
const userId = bean.userId;
|
||||||
const userIsAdmin = await this.userService.isAdmin(userId);
|
const userIsAdmin = await this.userService.isAdmin(userId);
|
||||||
if (!userIsAdmin) {
|
if (!userIsAdmin) {
|
||||||
|
@ -247,6 +247,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async foreachPipeline(callback: (pipeline: PipelineEntity) => void) {
|
async foreachPipeline(callback: (pipeline: PipelineEntity) => void) {
|
||||||
const idEntityList = await this.repository.find({
|
const idEntityList = await this.repository.find({
|
||||||
|
@ -329,6 +330,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||||
if (isComm()) {
|
if (isComm()) {
|
||||||
await this.checkHasDeployCount(id, entity.userId);
|
await this.checkHasDeployCount(id, entity.userId);
|
||||||
}
|
}
|
||||||
|
await this.checkUserStatus(entity.userId)
|
||||||
this.cron.register({
|
this.cron.register({
|
||||||
name: `pipeline.${id}.trigger.once`,
|
name: `pipeline.${id}.trigger.once`,
|
||||||
cron: null,
|
cron: null,
|
||||||
|
@ -446,6 +448,13 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||||
if (isComm()) {
|
if (isComm()) {
|
||||||
suite = await this.checkHasDeployCount(id, entity.userId);
|
suite = await this.checkHasDeployCount(id, entity.userId);
|
||||||
}
|
}
|
||||||
|
try{
|
||||||
|
await this.checkUserStatus(entity.userId)
|
||||||
|
}catch (e) {
|
||||||
|
logger.info(e.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const pipeline = JSON.parse(entity.content);
|
const pipeline = JSON.parse(entity.content);
|
||||||
if (!pipeline.id) {
|
if (!pipeline.id) {
|
||||||
|
@ -745,5 +754,25 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async checkUserStatus(userId: number) {
|
||||||
|
const userEntity = await this.userService.info(userId);
|
||||||
|
if(userEntity == null){
|
||||||
|
throw new Error('用户不存在');
|
||||||
|
}
|
||||||
|
if(userEntity.status === 0){
|
||||||
|
const message = `账户${userId}已被禁用,禁止运行流水线`
|
||||||
|
throw new Error(message)
|
||||||
|
}
|
||||||
|
const sysPublic = await this.sysSettingsService.getPublicSettings()
|
||||||
|
if(isPlus() && sysPublic.userValidTimeEnabled === true){
|
||||||
|
//校验用户有效期是否设置
|
||||||
|
if(userEntity.validTime!= null && userEntity.validTime > 0){
|
||||||
|
if(userEntity.validTime < new Date().getTime()){
|
||||||
|
//用户已过期
|
||||||
|
const message = `账户${userId}已过有效期,禁止运行流水线`
|
||||||
|
throw new Error(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,10 @@ export class UserEntity {
|
||||||
|
|
||||||
@Column({ comment: '状态 0:禁用 1:启用', default: 1 })
|
@Column({ comment: '状态 0:禁用 1:启用', default: 1 })
|
||||||
status: number;
|
status: number;
|
||||||
|
|
||||||
|
@Column({ name: 'valid_time', comment: '有效期', nullable: true })
|
||||||
|
validTime: number;
|
||||||
|
|
||||||
@Column({
|
@Column({
|
||||||
name: 'create_time',
|
name: 'create_time',
|
||||||
comment: '创建时间',
|
comment: '创建时间',
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||||
title: '阿里云-部署证书至OSS',
|
title: '阿里云-部署证书至OSS',
|
||||||
icon: 'svg:icon-aliyun',
|
icon: 'svg:icon-aliyun',
|
||||||
group: pluginGroups.aliyun.key,
|
group: pluginGroups.aliyun.key,
|
||||||
desc: '自动部署域名证书至阿里云OSS',
|
desc: '部署域名证书至阿里云OSS自定义域名,不是上传到阿里云oss',
|
||||||
default: {
|
default: {
|
||||||
strategy: {
|
strategy: {
|
||||||
runStrategy: RunStrategy.SkipWhenSucceed,
|
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||||
|
|
|
@ -26,6 +26,11 @@ export type CloudflareRecord = {
|
||||||
})
|
})
|
||||||
export class CloudflareDnsProvider extends AbstractDnsProvider<CloudflareRecord> {
|
export class CloudflareDnsProvider extends AbstractDnsProvider<CloudflareRecord> {
|
||||||
access!: CloudflareAccess;
|
access!: CloudflareAccess;
|
||||||
|
usePunyCode(): boolean {
|
||||||
|
//是否使用punycode来添加解析记录
|
||||||
|
//默认都使用原始中文域名来添加
|
||||||
|
return true;
|
||||||
|
}
|
||||||
async onInstance() {
|
async onInstance() {
|
||||||
//一些初始化的操作
|
//一些初始化的操作
|
||||||
// 也可以通过ctx成员变量传递context
|
// 也可以通过ctx成员变量传递context
|
||||||
|
|
|
@ -91,8 +91,9 @@ export class FlexCDNRefreshCert extends AbstractTaskPlugin {
|
||||||
* timeEndAt: Math.floor((new Date(currentInfo.validTo)).getTime() / 1000),
|
* timeEndAt: Math.floor((new Date(currentInfo.validTo)).getTime() / 1000),
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const commonNames =[ certReader.getMainDomain()]
|
const topCrt = CertReader.readCertDetail(certReader.cert.ic)
|
||||||
const dnsNames = certReader.getAltNames()
|
const commonNames =[ topCrt.detail.issuer.commonName]
|
||||||
|
const dnsNames = certReader.getAllDomains()
|
||||||
const timeBeginAt = Math.floor(certReader.detail.notBefore.getTime() / 1000);
|
const timeBeginAt = Math.floor(certReader.detail.notBefore.getTime() / 1000);
|
||||||
const timeEndAt = Math.floor(certReader.detail.notAfter.getTime() / 1000);
|
const timeEndAt = Math.floor(certReader.detail.notAfter.getTime() / 1000);
|
||||||
const body = {
|
const body = {
|
||||||
|
|
|
@ -77,7 +77,13 @@ export class GithubCheckRelease extends AbstractTaskPlugin {
|
||||||
this.logger.info(`有更新,${lastVersion??"0"}->${res.tag_name}`)
|
this.logger.info(`有更新,${lastVersion??"0"}->${res.tag_name}`)
|
||||||
this.lastVersion = res.tag_name;
|
this.lastVersion = res.tag_name;
|
||||||
|
|
||||||
const body = res.body.replaceAll("* ","- ")
|
// const body = res.body.replaceAll("* ","- ")
|
||||||
|
//仅每行开头的* 替换成 -, *号前面可以有空格
|
||||||
|
const body = res.body.replace(/^(\s*)\* /gm, "$1- ")
|
||||||
|
|
||||||
|
if (this.notificationIds == null){
|
||||||
|
this.notificationIds = [0]
|
||||||
|
}
|
||||||
//发送通知
|
//发送通知
|
||||||
for (const notificationId of this.notificationIds) {
|
for (const notificationId of this.notificationIds) {
|
||||||
await this.ctx.notificationService.send({
|
await this.ctx.notificationService.send({
|
||||||
|
|
|
@ -23,6 +23,11 @@ export class NamesiloDnsProvider extends AbstractDnsProvider<NamesiloRecord> {
|
||||||
// 也可以通过ctx成员变量传递context
|
// 也可以通过ctx成员变量传递context
|
||||||
this.access = this.ctx.access as NamesiloAccess;
|
this.access = this.ctx.access as NamesiloAccess;
|
||||||
}
|
}
|
||||||
|
usePunyCode(): boolean {
|
||||||
|
//是否使用punycode来添加解析记录
|
||||||
|
//默认都使用原始中文域名来添加
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private async doRequest(url: string, params: any = null) {
|
private async doRequest(url: string, params: any = null) {
|
||||||
params = merge(
|
params = merge(
|
||||||
|
|
|
@ -93,7 +93,7 @@ export class ProxmoxUploadCert extends AbstractPlusTaskPlugin {
|
||||||
|
|
||||||
async getClient() {
|
async getClient() {
|
||||||
const access: ProxmoxAccess = await this.getAccess<ProxmoxAccess>(this.accessId);
|
const access: ProxmoxAccess = await this.getAccess<ProxmoxAccess>(this.accessId);
|
||||||
const pve = await import('@corsinvest/cv4pve-api-javascript');
|
const pve = await import('@certd/cv4pve-api-javascript');
|
||||||
const client = new pve.PveClient(access.host, access.port);
|
const client = new pve.PveClient(access.host, access.port);
|
||||||
const login = await client.login(access.username, access.password, access.realm || 'pam');
|
const login = await client.login(access.username, access.password, access.realm || 'pam');
|
||||||
if (!login) {
|
if (!login) {
|
||||||
|
|
118
pnpm-lock.yaml
118
pnpm-lock.yaml
|
@ -46,7 +46,7 @@ importers:
|
||||||
packages/core/acme-client:
|
packages/core/acme-client:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@certd/basic':
|
'@certd/basic':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../basic
|
version: link:../basic
|
||||||
'@peculiar/x509':
|
'@peculiar/x509':
|
||||||
specifier: ^1.11.0
|
specifier: ^1.11.0
|
||||||
|
@ -72,7 +72,7 @@ importers:
|
||||||
node-forge:
|
node-forge:
|
||||||
specifier: ^1.3.1
|
specifier: ^1.3.1
|
||||||
version: 1.3.1
|
version: 1.3.1
|
||||||
punycode:
|
punycode.js:
|
||||||
specifier: ^2.3.1
|
specifier: ^2.3.1
|
||||||
version: 2.3.1
|
version: 2.3.1
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
@ -207,10 +207,10 @@ importers:
|
||||||
packages/core/pipeline:
|
packages/core/pipeline:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@certd/basic':
|
'@certd/basic':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../basic
|
version: link:../basic
|
||||||
'@certd/plus-core':
|
'@certd/plus-core':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../pro/plus-core
|
version: link:../../pro/plus-core
|
||||||
dayjs:
|
dayjs:
|
||||||
specifier: ^1.11.7
|
specifier: ^1.11.7
|
||||||
|
@ -415,7 +415,7 @@ importers:
|
||||||
packages/libs/lib-k8s:
|
packages/libs/lib-k8s:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@certd/basic':
|
'@certd/basic':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/basic
|
version: link:../../core/basic
|
||||||
'@kubernetes/client-node':
|
'@kubernetes/client-node':
|
||||||
specifier: 0.21.0
|
specifier: 0.21.0
|
||||||
|
@ -455,16 +455,16 @@ importers:
|
||||||
packages/libs/lib-server:
|
packages/libs/lib-server:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@certd/acme-client':
|
'@certd/acme-client':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/acme-client
|
version: link:../../core/acme-client
|
||||||
'@certd/basic':
|
'@certd/basic':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/basic
|
version: link:../../core/basic
|
||||||
'@certd/pipeline':
|
'@certd/pipeline':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/pipeline
|
version: link:../../core/pipeline
|
||||||
'@certd/plus-core':
|
'@certd/plus-core':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../pro/plus-core
|
version: link:../../pro/plus-core
|
||||||
'@midwayjs/cache':
|
'@midwayjs/cache':
|
||||||
specifier: ~3.14.0
|
specifier: ~3.14.0
|
||||||
|
@ -607,16 +607,16 @@ importers:
|
||||||
packages/plugins/plugin-cert:
|
packages/plugins/plugin-cert:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@certd/acme-client':
|
'@certd/acme-client':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/acme-client
|
version: link:../../core/acme-client
|
||||||
'@certd/basic':
|
'@certd/basic':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/basic
|
version: link:../../core/basic
|
||||||
'@certd/pipeline':
|
'@certd/pipeline':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/pipeline
|
version: link:../../core/pipeline
|
||||||
'@certd/plugin-lib':
|
'@certd/plugin-lib':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../plugin-lib
|
version: link:../plugin-lib
|
||||||
'@google-cloud/publicca':
|
'@google-cloud/publicca':
|
||||||
specifier: ^1.3.0
|
specifier: ^1.3.0
|
||||||
|
@ -633,7 +633,7 @@ importers:
|
||||||
psl:
|
psl:
|
||||||
specifier: ^1.9.0
|
specifier: ^1.9.0
|
||||||
version: 1.15.0
|
version: 1.15.0
|
||||||
punycode:
|
punycode.js:
|
||||||
specifier: ^2.3.1
|
specifier: ^2.3.1
|
||||||
version: 2.3.1
|
version: 2.3.1
|
||||||
rimraf:
|
rimraf:
|
||||||
|
@ -682,9 +682,6 @@ importers:
|
||||||
|
|
||||||
packages/plugins/plugin-lib:
|
packages/plugins/plugin-lib:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@alicloud/credentials':
|
|
||||||
specifier: ^2.4.3
|
|
||||||
version: 2.4.3
|
|
||||||
'@alicloud/openapi-client':
|
'@alicloud/openapi-client':
|
||||||
specifier: ^0.4.14
|
specifier: ^0.4.14
|
||||||
version: 0.4.14
|
version: 0.4.14
|
||||||
|
@ -698,10 +695,10 @@ importers:
|
||||||
specifier: ^3.787.0
|
specifier: ^3.787.0
|
||||||
version: 3.810.0(aws-crt@1.26.2)
|
version: 3.810.0(aws-crt@1.26.2)
|
||||||
'@certd/basic':
|
'@certd/basic':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/basic
|
version: link:../../core/basic
|
||||||
'@certd/pipeline':
|
'@certd/pipeline':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/pipeline
|
version: link:../../core/pipeline
|
||||||
'@kubernetes/client-node':
|
'@kubernetes/client-node':
|
||||||
specifier: 0.21.0
|
specifier: 0.21.0
|
||||||
|
@ -789,19 +786,19 @@ importers:
|
||||||
packages/pro/commercial-core:
|
packages/pro/commercial-core:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@certd/basic':
|
'@certd/basic':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/basic
|
version: link:../../core/basic
|
||||||
'@certd/lib-server':
|
'@certd/lib-server':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../libs/lib-server
|
version: link:../../libs/lib-server
|
||||||
'@certd/pipeline':
|
'@certd/pipeline':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/pipeline
|
version: link:../../core/pipeline
|
||||||
'@certd/plugin-plus':
|
'@certd/plugin-plus':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../plugin-plus
|
version: link:../plugin-plus
|
||||||
'@certd/plus-core':
|
'@certd/plus-core':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../plus-core
|
version: link:../plus-core
|
||||||
'@midwayjs/core':
|
'@midwayjs/core':
|
||||||
specifier: ~3.20.3
|
specifier: ~3.20.3
|
||||||
|
@ -886,22 +883,22 @@ importers:
|
||||||
specifier: ^1.0.2
|
specifier: ^1.0.2
|
||||||
version: 1.0.3
|
version: 1.0.3
|
||||||
'@certd/basic':
|
'@certd/basic':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/basic
|
version: link:../../core/basic
|
||||||
'@certd/lib-k8s':
|
'@certd/lib-k8s':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../libs/lib-k8s
|
version: link:../../libs/lib-k8s
|
||||||
'@certd/pipeline':
|
'@certd/pipeline':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/pipeline
|
version: link:../../core/pipeline
|
||||||
'@certd/plugin-cert':
|
'@certd/plugin-cert':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../plugins/plugin-cert
|
version: link:../../plugins/plugin-cert
|
||||||
'@certd/plugin-lib':
|
'@certd/plugin-lib':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../plugins/plugin-lib
|
version: link:../../plugins/plugin-lib
|
||||||
'@certd/plus-core':
|
'@certd/plus-core':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../plus-core
|
version: link:../plus-core
|
||||||
ali-oss:
|
ali-oss:
|
||||||
specifier: ^6.21.0
|
specifier: ^6.21.0
|
||||||
|
@ -1004,7 +1001,7 @@ importers:
|
||||||
packages/pro/plus-core:
|
packages/pro/plus-core:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@certd/basic':
|
'@certd/basic':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/basic
|
version: link:../../core/basic
|
||||||
dayjs:
|
dayjs:
|
||||||
specifier: ^1.11.7
|
specifier: ^1.11.7
|
||||||
|
@ -1294,10 +1291,10 @@ importers:
|
||||||
version: 0.1.3(zod@3.24.4)
|
version: 0.1.3(zod@3.24.4)
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@certd/lib-iframe':
|
'@certd/lib-iframe':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../libs/lib-iframe
|
version: link:../../libs/lib-iframe
|
||||||
'@certd/pipeline':
|
'@certd/pipeline':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/pipeline
|
version: link:../../core/pipeline
|
||||||
'@rollup/plugin-commonjs':
|
'@rollup/plugin-commonjs':
|
||||||
specifier: ^25.0.7
|
specifier: ^25.0.7
|
||||||
|
@ -1477,47 +1474,47 @@ importers:
|
||||||
specifier: ^3.705.0
|
specifier: ^3.705.0
|
||||||
version: 3.810.0(aws-crt@1.26.2)
|
version: 3.810.0(aws-crt@1.26.2)
|
||||||
'@certd/acme-client':
|
'@certd/acme-client':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/acme-client
|
version: link:../../core/acme-client
|
||||||
'@certd/basic':
|
'@certd/basic':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/basic
|
version: link:../../core/basic
|
||||||
'@certd/commercial-core':
|
'@certd/commercial-core':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../pro/commercial-core
|
version: link:../../pro/commercial-core
|
||||||
|
'@certd/cv4pve-api-javascript':
|
||||||
|
specifier: ^8.4.1
|
||||||
|
version: 8.4.1
|
||||||
'@certd/jdcloud':
|
'@certd/jdcloud':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../libs/lib-jdcloud
|
version: link:../../libs/lib-jdcloud
|
||||||
'@certd/lib-huawei':
|
'@certd/lib-huawei':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../libs/lib-huawei
|
version: link:../../libs/lib-huawei
|
||||||
'@certd/lib-k8s':
|
'@certd/lib-k8s':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../libs/lib-k8s
|
version: link:../../libs/lib-k8s
|
||||||
'@certd/lib-server':
|
'@certd/lib-server':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../libs/lib-server
|
version: link:../../libs/lib-server
|
||||||
'@certd/midway-flyway-js':
|
'@certd/midway-flyway-js':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../libs/midway-flyway-js
|
version: link:../../libs/midway-flyway-js
|
||||||
'@certd/pipeline':
|
'@certd/pipeline':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../core/pipeline
|
version: link:../../core/pipeline
|
||||||
'@certd/plugin-cert':
|
'@certd/plugin-cert':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../plugins/plugin-cert
|
version: link:../../plugins/plugin-cert
|
||||||
'@certd/plugin-lib':
|
'@certd/plugin-lib':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../plugins/plugin-lib
|
version: link:../../plugins/plugin-lib
|
||||||
'@certd/plugin-plus':
|
'@certd/plugin-plus':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../pro/plugin-plus
|
version: link:../../pro/plugin-plus
|
||||||
'@certd/plus-core':
|
'@certd/plus-core':
|
||||||
specifier: ^1.34.7
|
specifier: ^1.34.10
|
||||||
version: link:../../pro/plus-core
|
version: link:../../pro/plus-core
|
||||||
'@corsinvest/cv4pve-api-javascript':
|
|
||||||
specifier: ^8.3.0
|
|
||||||
version: 8.4.0
|
|
||||||
'@huaweicloud/huaweicloud-sdk-cdn':
|
'@huaweicloud/huaweicloud-sdk-cdn':
|
||||||
specifier: ^3.1.120
|
specifier: ^3.1.120
|
||||||
version: 3.1.149
|
version: 3.1.149
|
||||||
|
@ -1665,6 +1662,9 @@ importers:
|
||||||
psl:
|
psl:
|
||||||
specifier: ^1.9.0
|
specifier: ^1.9.0
|
||||||
version: 1.15.0
|
version: 1.15.0
|
||||||
|
punycode.js:
|
||||||
|
specifier: ^2.3.1
|
||||||
|
version: 2.3.1
|
||||||
qiniu:
|
qiniu:
|
||||||
specifier: ^7.12.0
|
specifier: ^7.12.0
|
||||||
version: 7.14.0
|
version: 7.14.0
|
||||||
|
@ -2659,13 +2659,13 @@ packages:
|
||||||
'@better-scroll/zoom@2.5.1':
|
'@better-scroll/zoom@2.5.1':
|
||||||
resolution: {integrity: sha512-aGvFY5ooeZWS4RcxQLD+pGLpQHQxpPy0sMZV3yadcd2QK53PK9gS4Dp+BYfRv8lZ4/P2LoNEhr6Wq1DN6+uPlA==}
|
resolution: {integrity: sha512-aGvFY5ooeZWS4RcxQLD+pGLpQHQxpPy0sMZV3yadcd2QK53PK9gS4Dp+BYfRv8lZ4/P2LoNEhr6Wq1DN6+uPlA==}
|
||||||
|
|
||||||
|
'@certd/cv4pve-api-javascript@8.4.1':
|
||||||
|
resolution: {integrity: sha512-jxlRieJmCA0Z9LnwX6Ra6ZekRGJEu8o8RGYoKU0Jjkhc9jm6ChEbVyfE7Iw49/hlpA+2yaHdAXb46au/afCISg==}
|
||||||
|
|
||||||
'@colors/colors@1.5.0':
|
'@colors/colors@1.5.0':
|
||||||
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
|
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
|
||||||
engines: {node: '>=0.1.90'}
|
engines: {node: '>=0.1.90'}
|
||||||
|
|
||||||
'@corsinvest/cv4pve-api-javascript@8.4.0':
|
|
||||||
resolution: {integrity: sha512-SDL+Y+t+/NkXmfOnRgil2ujMv/gfnah88n4+rMFBLv3qYjSy5uNetoeMmtLoR1wSlJmOvktzxQjsBl0TZt0gCw==}
|
|
||||||
|
|
||||||
'@cspotcode/source-map-support@0.8.1':
|
'@cspotcode/source-map-support@0.8.1':
|
||||||
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
@ -14881,15 +14881,15 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@better-scroll/core': 2.5.1
|
'@better-scroll/core': 2.5.1
|
||||||
|
|
||||||
'@colors/colors@1.5.0':
|
'@certd/cv4pve-api-javascript@8.4.1':
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@corsinvest/cv4pve-api-javascript@8.4.0':
|
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.4.1(supports-color@8.1.1)
|
debug: 4.4.1(supports-color@8.1.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
'@colors/colors@1.5.0':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@cspotcode/source-map-support@0.8.1':
|
'@cspotcode/source-map-support@0.8.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/trace-mapping': 0.3.9
|
'@jridgewell/trace-mapping': 0.3.9
|
||||||
|
@ -20740,13 +20740,13 @@ snapshots:
|
||||||
resolve: 1.22.10
|
resolve: 1.22.10
|
||||||
semver: 6.3.1
|
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:
|
dependencies:
|
||||||
eslint: 7.32.0
|
eslint: 7.32.0
|
||||||
prettier: 2.8.8
|
prettier: 2.8.8
|
||||||
prettier-linter-helpers: 1.0.0
|
prettier-linter-helpers: 1.0.0
|
||||||
optionalDependencies:
|
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):
|
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:
|
dependencies:
|
||||||
|
@ -23454,7 +23454,7 @@ snapshots:
|
||||||
eslint: 7.32.0
|
eslint: 7.32.0
|
||||||
eslint-config-prettier: 8.10.0(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-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
|
execa: 5.1.1
|
||||||
inquirer: 7.3.3
|
inquirer: 7.3.3
|
||||||
json5: 2.2.3
|
json5: 2.2.3
|
||||||
|
|
Loading…
Reference in New Issue