Compare commits

...

41 Commits

Author SHA1 Message Date
xiaojunnuo 4fda6cbcde v1.38.8 2026-02-07 02:27:52 +08:00
xiaojunnuo 2bbba897ec build: prepare to build 2026-02-07 02:23:58 +08:00
xiaojunnuo 0cfb94b0ba perf: 支持设置默认的证书申请地址的反向代理 2026-02-07 02:20:27 +08:00
xiaojunnuo 3f7ac93932 perf: 子域名托管域名支持配置通配符 2026-02-07 00:03:37 +08:00
xiaojunnuo 96c36b4f6a chore: aliyun cdn log 2026-02-06 23:35:35 +08:00
xiaojunnuo febd6d32cf perf: 双重验证显示secret 2026-02-06 23:26:57 +08:00
xiaojunnuo cbd8699801 chore: 移除 github star 2026-02-06 23:04:39 +08:00
xiaojunnuo 74400aacc6 chore: 敏感数据隐藏输出 2026-02-06 16:49:19 +08:00
xiaojunnuo 9f55c3605a chore: 1 2026-02-06 16:36:57 +08:00
xiaojunnuo 8d61e8179f chore: 1 2026-02-06 16:29:53 +08:00
xiaojunnuo f250889c3e Merge branch 'v2-dev' of https://github.com/certd/certd into v2-dev 2026-02-06 16:26:32 +08:00
xiaojunnuo 00f67d86d6 perf: 优化申请证书最大超时时长 2026-02-06 16:26:26 +08:00
xiaojunnuo 5b580d2a17 build: release 2026-02-05 17:12:31 +08:00
xiaojunnuo 083dd7d1a3 build: publish 2026-02-05 16:32:10 +08:00
xiaojunnuo 03bd4755ce build: trigger build image 2026-02-05 16:31:58 +08:00
xiaojunnuo 29d37075dd v1.38.7 2026-02-05 16:30:37 +08:00
xiaojunnuo f311bac580 build: prepare to build 2026-02-05 16:26:01 +08:00
xiaojunnuo beb7a4c992 perf: 第三方登录支持Microsoft 2026-02-05 16:14:05 +08:00
xiaojunnuo 4d86fb319b perf: 优化zerossl申请证书稳定性 2026-02-05 12:22:55 +08:00
xiaojunnuo 5ea4f46de7 perf: eab从更多参数中挪到外面 2026-02-05 11:39:06 +08:00
xiaojunnuo 1d8d5251ae chore: domain-selector 优化 2026-02-05 11:29:10 +08:00
xiaojunnuo 54c8217808 fix: 修复有域名记录时,域名输入框无法关闭的bug 2026-02-05 11:27:32 +08:00
xiaojunnuo ba623903e0 chore: publish-atom.yaml 2026-02-05 02:05:04 +08:00
xiaojunnuo 907af3ae18 chore: publish 2026-02-05 02:03:57 +08:00
xiaojunnuo 24ae8a6b66 chore:2 2026-02-05 02:02:01 +08:00
xiaojunnuo 1646a5cdd2 chore: atom publish 2026-02-05 01:59:08 +08:00
xiaojunnuo 814f17d10b build: release 2026-02-05 01:33:21 +08:00
xiaojunnuo 40fe105903 build: release 2026-02-05 01:31:16 +08:00
xiaojunnuo 42a347d8b1 build: publish 2026-02-05 01:18:22 +08:00
xiaojunnuo 5450e5dac4 build: trigger build image 2026-02-05 01:18:09 +08:00
xiaojunnuo 1368259a1e v1.38.6 2026-02-05 01:16:39 +08:00
xiaojunnuo 81a495f267 build: prepare to build 2026-02-05 01:13:43 +08:00
xiaojunnuo 693a4a6633 perf: oauth支持github 和google, 修复头像显示问题 2026-02-05 01:10:01 +08:00
xiaojunnuo 82786c580a chore: tip 2026-02-05 00:42:25 +08:00
xiaojunnuo e19743f705 perf: count tip 2026-02-05 00:07:15 +08:00
xiaojunnuo 9166a57930 perf: 当域名管理中没有域名时,创建流水线时不展开域名选择框 2026-02-04 23:09:16 +08:00
xiaojunnuo bd511f97cb fix: 修复新网找错域名的bug 2026-02-03 18:28:41 +08:00
xiaojunnuo 560bf40e4b chore: 1 2026-02-03 16:28:11 +08:00
xiaojunnuo 4f4652c1cd docs: 1 2026-02-03 12:28:30 +08:00
xiaojunnuo 60e13c2a1d Merge branch 'v2-dev' of https://github.com/certd/certd into v2-dev 2026-02-03 09:50:29 +08:00
xiaojunnuo 1fe0dc4d16 chore: 1 2026-02-03 09:50:23 +08:00
86 changed files with 1359 additions and 279 deletions
+33
View File
@@ -3,6 +3,39 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.8](https://github.com/certd/certd/compare/v1.38.7...v1.38.8) (2026-02-06)
### Performance Improvements
* 双重验证显示secret ([febd6d3](https://github.com/certd/certd/commit/febd6d32cfe6d89ccecf26bf15141df7c456e5c6))
* 优化申请证书最大超时时长 ([00f67d8](https://github.com/certd/certd/commit/00f67d86d68f4f83cfafe2fbfeb4af0d86f9d20e))
* 支持设置默认的证书申请地址的反向代理 ([0cfb94b](https://github.com/certd/certd/commit/0cfb94b0ba6a6dc3bb0d0a81a1912068a4e6b6b6))
* 子域名托管域名支持配置通配符 ([3f7ac93](https://github.com/certd/certd/commit/3f7ac939326b0c7ec013a7534b6c0e58fb3e8cb4))
## [1.38.7](https://github.com/certd/certd/compare/v1.38.6...v1.38.7) (2026-02-05)
### Bug Fixes
* 修复有域名记录时,域名输入框无法关闭的bug ([54c8217](https://github.com/certd/certd/commit/54c8217808453b121abf646b004596f28932509f))
### Performance Improvements
* eab从更多参数中挪到外面 ([5ea4f46](https://github.com/certd/certd/commit/5ea4f46de7ae403a7a16e9488dc1d9c7523d019a))
* 第三方登录支持Microsoft ([beb7a4c](https://github.com/certd/certd/commit/beb7a4c99277262bb9681c5594cfcd3e36c52074))
* 优化zerossl申请证书稳定性 ([4d86fb3](https://github.com/certd/certd/commit/4d86fb319b81dbf6fa6485982105725b1b066593))
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
### Bug Fixes
* 修复新网找错域名的bug ([bd511f9](https://github.com/certd/certd/commit/bd511f97cb7fbdcaeff7ac899f0460a5c7b41826))
### Performance Improvements
* 当域名管理中没有域名时,创建流水线时不展开域名选择框 ([9166a57](https://github.com/certd/certd/commit/9166a579301a60750f0b72b6a42b0c8d730695fd))
* count tip ([e19743f](https://github.com/certd/certd/commit/e19743f70553700f1f91bff76f87370f749dd247))
* oauth支持github 和google 修复头像显示问题 ([693a4a6](https://github.com/certd/certd/commit/693a4a663385ced3176286bf4b5f3566da83d90e))
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
### Bug Fixes
+24
View File
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.7](https://github.com/certd/certd/compare/v1.38.6...v1.38.7) (2026-02-05)
### Bug Fixes
* 修复有域名记录时,域名输入框无法关闭的bug ([54c8217](https://github.com/certd/certd/commit/54c8217808453b121abf646b004596f28932509f))
### Performance Improvements
* eab从更多参数中挪到外面 ([5ea4f46](https://github.com/certd/certd/commit/5ea4f46de7ae403a7a16e9488dc1d9c7523d019a))
* 第三方登录支持Microsoft ([beb7a4c](https://github.com/certd/certd/commit/beb7a4c99277262bb9681c5594cfcd3e36c52074))
* 优化zerossl申请证书稳定性 ([4d86fb3](https://github.com/certd/certd/commit/4d86fb319b81dbf6fa6485982105725b1b066593))
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
### Bug Fixes
* 修复新网找错域名的bug ([bd511f9](https://github.com/certd/certd/commit/bd511f97cb7fbdcaeff7ac899f0460a5c7b41826))
### Performance Improvements
* 当域名管理中没有域名时,创建流水线时不展开域名选择框 ([9166a57](https://github.com/certd/certd/commit/9166a579301a60750f0b72b6a42b0c8d730695fd))
* count tip ([e19743f](https://github.com/certd/certd/commit/e19743f70553700f1f91bff76f87370f749dd247))
* oauth支持github 和google 修复头像显示问题 ([693a4a6](https://github.com/certd/certd/commit/693a4a663385ced3176286bf4b5f3566da83d90e))
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
### Bug Fixes
+24
View File
@@ -0,0 +1,24 @@
{
"notice": "永久专业版上线,新用户立减50,升级到最新版点击下方“立即赞助”按钮前往获取",
"plus": {
"name": "专业版",
"price": "89.9",
"price3": "199",
"tooltip": "开源需要您的赞助支持",
"priceText":"¥89.9/年",
"discountText":"永久专业版50优惠券立即领取"
},
"comm": {
"name": "商业版",
"price": "399",
"price3": "899",
"tooltip": "3年优惠300",
"priceText":"¥399/年",
"discountText":"¥899/3年(3年优惠300"
},
"app":{
"minVersion":"1.36.0",
"minVersionTip":"版本过低,为了您的数据安全,请尽快升级"
}
}
+1 -1
View File
@@ -5,7 +5,7 @@
| 序号 | 名称 | 说明 |
|-----|-----|-----|
| 1.| **证书申请(JS版)** | 免费通配符域名证书申请,支持多个域名打到同一个证书上 |
| 2.| **商用证书托管** | 手动上传自定义证书后,自动部署(每次证书有更新,都需要手动上传一次) |
| 2.| **已有证书托管** | 手动上传自定义证书后,自动部署(每次证书有更新,都需要手动上传一次) |
| 3.| **获取阿里云订阅证书** | 从阿里云拉取订阅模式的商用证书 |
| 4.| **证书申请(Lego** | 支持海量DNS解析提供商,推荐使用,一样的免费通配符域名证书申请,支持多个域名打到同一个证书上 |
## 2. 主机
+8
View File
@@ -52,3 +52,11 @@ service:
3. DNS 有其他平台申请过的_acme-challenge记录,删除即可
## 7. DNS problem: NXDOMAIN looking up TXT for _acme-challenge.xxx
`
DNS problem: NXDOMAIN looking up TXT for _acme-challenge.xxxxx - check that a DNS record exists for this domain
`
证书颁发机构向域名ns查询TXT验证记录失败,有以下几种可能
1、域名的ns服务器修改成别的了,但申请证书时的DNS提供商选择错误(检查确认,配置正确的DNS提供商)
2、证书颁发机构与ns域名服务器之间访问不通,无法查询到TXT记录(尝试更换证书颁发机构)
3、ns服务商解析值生效慢(尝试修改证书申请任务里面的等待生效时长600-1000s)
+1 -1
View File
@@ -9,5 +9,5 @@
}
},
"npmClient": "pnpm",
"version": "1.38.5"
"version": "1.38.8"
}
+17
View File
@@ -3,6 +3,23 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.8](https://github.com/publishlab/node-acme-client/compare/v1.38.7...v1.38.8) (2026-02-06)
### Performance Improvements
* 优化申请证书最大超时时长 ([00f67d8](https://github.com/publishlab/node-acme-client/commit/00f67d86d68f4f83cfafe2fbfeb4af0d86f9d20e))
* 支持设置默认的证书申请地址的反向代理 ([0cfb94b](https://github.com/publishlab/node-acme-client/commit/0cfb94b0ba6a6dc3bb0d0a81a1912068a4e6b6b6))
## [1.38.7](https://github.com/publishlab/node-acme-client/compare/v1.38.6...v1.38.7) (2026-02-05)
### Performance Improvements
* 优化zerossl申请证书稳定性 ([4d86fb3](https://github.com/publishlab/node-acme-client/commit/4d86fb319b81dbf6fa6485982105725b1b066593))
## [1.38.6](https://github.com/publishlab/node-acme-client/compare/v1.38.5...v1.38.6) (2026-02-04)
**Note:** Version bump only for package @certd/acme-client
## [1.38.5](https://github.com/publishlab/node-acme-client/compare/v1.38.4...v1.38.5) (2026-02-02)
### Bug Fixes
+3 -3
View File
@@ -3,7 +3,7 @@
"description": "Simple and unopinionated ACME client",
"private": false,
"author": "nmorsman",
"version": "1.38.5",
"version": "1.38.8",
"type": "module",
"module": "scr/index.js",
"main": "src/index.js",
@@ -18,7 +18,7 @@
"types"
],
"dependencies": {
"@certd/basic": "^1.38.5",
"@certd/basic": "^1.38.8",
"@peculiar/x509": "^1.11.0",
"asn1js": "^3.0.5",
"axios": "^1.9.0",
@@ -70,5 +70,5 @@
"bugs": {
"url": "https://github.com/publishlab/node-acme-client/issues"
},
"gitHead": "eeb1f27fa47ddc616451f3e5a8fb8d1de345d252"
"gitHead": "29d37075dd600fa4898c5e38611e09db522e32fc"
}
+5 -2
View File
@@ -600,8 +600,11 @@ class AcmeClient {
throw new Error(`[${d}] Unexpected item status: ${resp.data.status}`);
};
this.log(`[${d}] Waiting for valid status (等待valid状态): ${item.url}`, this.backoffOpts);
return util.retry(verifyFn, this.backoffOpts);
this.log(`[${d}] Waiting for valid status (等待valid状态): ${item.url}`, JSON.stringify(this.backoffOpts));
const log = (...args)=>{
this.logger.info(...args)
}
return util.retry(verifyFn, this.backoffOpts,log);
}
/**
+26
View File
@@ -57,6 +57,32 @@ export function getDirectoryUrl(opts) {
return list.production
}
export function getAllSslProviderDomains() {
const list = Object.values(directory).map((item) => {
let url = item.production.replace('https://', '')
url = url.substring(0, url.indexOf('/'))
return url
})
return list
}
let sslProviderReverseProxies = {}
function initSslProviderReverseProxies() {
for (const sslProvider of getAllSslProviderDomains()) {
sslProviderReverseProxies[sslProvider] = ""
}
}
initSslProviderReverseProxies()
export function getSslProviderReverseProxies() {
return sslProviderReverseProxies
}
export function setSslProviderReverseProxies(reverseProxies) {
Object.assign(sslProviderReverseProxies, reverseProxies)
}
/**
* Crypto
*/
+8 -2
View File
@@ -52,11 +52,17 @@ async function retryPromise(fn, attempts, backoff, logger = log) {
let aborted = false;
try {
const data = await fn(() => { aborted = true; });
const setAbort = () => { aborted = true; }
const data = await fn(setAbort);
return data;
}
catch (e) {
if (aborted || ((backoff.attempts + 1) >= attempts)) {
if (aborted){
logger(`用户取消重试`);
throw e;
}
if ( ((backoff.attempts + 1) >= attempts)) {
logger(`重试次数超过${attempts}`);
throw e;
}
+3
View File
@@ -118,6 +118,9 @@ export const directory: {
};
export function getDirectoryUrl(opts:{sslProvider:string, pkType: string}): string;
export function getAllSslProviderDomains(): string[];
export function getSslProviderReverseProxies(): Record<string, string>;
export function setSslProviderReverseProxies(reverseProxies: Record<string, string>): void;
/**
* Crypto
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.8](https://github.com/certd/certd/compare/v1.38.7...v1.38.8) (2026-02-06)
**Note:** Version bump only for package @certd/basic
## [1.38.7](https://github.com/certd/certd/compare/v1.38.6...v1.38.7) (2026-02-05)
**Note:** Version bump only for package @certd/basic
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
**Note:** Version bump only for package @certd/basic
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
**Note:** Version bump only for package @certd/basic
+1 -1
View File
@@ -1 +1 @@
23:59
02:23
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/basic",
"private": false,
"version": "1.38.5",
"version": "1.38.8",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
@@ -47,5 +47,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "eeb1f27fa47ddc616451f3e5a8fb8d1de345d252"
"gitHead": "29d37075dd600fa4898c5e38611e09db522e32fc"
}
+7 -1
View File
@@ -18,7 +18,7 @@ export function resetLogConfigure() {
});
}
resetLogConfigure();
export const logger = log4js.getLogger("default");
export const logger: ILogger = log4js.getLogger("default") as any;
export function resetLogFilePath(filePath: string) {
logFilePath = filePath;
@@ -77,6 +77,8 @@ export type ILogger = {
fatal(message: any, ...args: any[]): void;
mark(message: any, ...args: any[]): void;
addSecret(secret: string): void;
};
const locale = Intl.DateTimeFormat().resolvedOptions().locale;
@@ -106,10 +108,14 @@ export class PipelineLogger implements ILogger {
constructor(name: string, write: (text: string) => void) {
this.customWriter = write;
//@ts-ignore
this.logger = log4js.getLogger(name);
}
addSecret(secret: string) {
if (!secret) {
return;
}
this._secrets.push(secret);
}
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.8](https://github.com/certd/certd/compare/v1.38.7...v1.38.8) (2026-02-06)
**Note:** Version bump only for package @certd/pipeline
## [1.38.7](https://github.com/certd/certd/compare/v1.38.6...v1.38.7) (2026-02-05)
**Note:** Version bump only for package @certd/pipeline
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
**Note:** Version bump only for package @certd/pipeline
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
**Note:** Version bump only for package @certd/pipeline
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/pipeline",
"private": false,
"version": "1.38.5",
"version": "1.38.8",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
@@ -18,8 +18,8 @@
"compile": "tsc --skipLibCheck --watch"
},
"dependencies": {
"@certd/basic": "^1.38.5",
"@certd/plus-core": "^1.38.5",
"@certd/basic": "^1.38.8",
"@certd/plus-core": "^1.38.8",
"dayjs": "^1.11.7",
"lodash-es": "^4.17.21",
"reflect-metadata": "^0.1.13"
@@ -45,5 +45,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "eeb1f27fa47ddc616451f3e5a8fb8d1de345d252"
"gitHead": "29d37075dd600fa4898c5e38611e09db522e32fc"
}
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.8](https://github.com/certd/certd/compare/v1.38.7...v1.38.8) (2026-02-06)
**Note:** Version bump only for package @certd/lib-huawei
## [1.38.7](https://github.com/certd/certd/compare/v1.38.6...v1.38.7) (2026-02-05)
**Note:** Version bump only for package @certd/lib-huawei
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
**Note:** Version bump only for package @certd/lib-huawei
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
**Note:** Version bump only for package @certd/lib-huawei
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/lib-huawei",
"private": false,
"version": "1.38.5",
"version": "1.38.8",
"main": "./dist/bundle.js",
"module": "./dist/bundle.js",
"types": "./dist/d/index.d.ts",
@@ -24,5 +24,5 @@
"prettier": "^2.8.8",
"tslib": "^2.8.1"
},
"gitHead": "eeb1f27fa47ddc616451f3e5a8fb8d1de345d252"
"gitHead": "29d37075dd600fa4898c5e38611e09db522e32fc"
}
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.8](https://github.com/certd/certd/compare/v1.38.7...v1.38.8) (2026-02-06)
**Note:** Version bump only for package @certd/lib-iframe
## [1.38.7](https://github.com/certd/certd/compare/v1.38.6...v1.38.7) (2026-02-05)
**Note:** Version bump only for package @certd/lib-iframe
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
**Note:** Version bump only for package @certd/lib-iframe
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
**Note:** Version bump only for package @certd/lib-iframe
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/lib-iframe",
"private": false,
"version": "1.38.5",
"version": "1.38.8",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
@@ -31,5 +31,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "eeb1f27fa47ddc616451f3e5a8fb8d1de345d252"
"gitHead": "29d37075dd600fa4898c5e38611e09db522e32fc"
}
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.8](https://github.com/certd/certd/compare/v1.38.7...v1.38.8) (2026-02-06)
**Note:** Version bump only for package @certd/jdcloud
## [1.38.7](https://github.com/certd/certd/compare/v1.38.6...v1.38.7) (2026-02-05)
**Note:** Version bump only for package @certd/jdcloud
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
**Note:** Version bump only for package @certd/jdcloud
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
**Note:** Version bump only for package @certd/jdcloud
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@certd/jdcloud",
"version": "1.38.5",
"version": "1.38.8",
"description": "jdcloud openApi sdk",
"main": "./dist/bundle.js",
"module": "./dist/bundle.js",
@@ -56,5 +56,5 @@
"fetch"
]
},
"gitHead": "eeb1f27fa47ddc616451f3e5a8fb8d1de345d252"
"gitHead": "29d37075dd600fa4898c5e38611e09db522e32fc"
}
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.8](https://github.com/certd/certd/compare/v1.38.7...v1.38.8) (2026-02-06)
**Note:** Version bump only for package @certd/lib-k8s
## [1.38.7](https://github.com/certd/certd/compare/v1.38.6...v1.38.7) (2026-02-05)
**Note:** Version bump only for package @certd/lib-k8s
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
**Note:** Version bump only for package @certd/lib-k8s
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
**Note:** Version bump only for package @certd/lib-k8s
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/lib-k8s",
"private": false,
"version": "1.38.5",
"version": "1.38.8",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
@@ -17,7 +17,7 @@
"pub": "npm publish"
},
"dependencies": {
"@certd/basic": "^1.38.5",
"@certd/basic": "^1.38.8",
"@kubernetes/client-node": "0.21.0"
},
"devDependencies": {
@@ -32,5 +32,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "eeb1f27fa47ddc616451f3e5a8fb8d1de345d252"
"gitHead": "29d37075dd600fa4898c5e38611e09db522e32fc"
}
+14
View File
@@ -3,6 +3,20 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.8](https://github.com/certd/certd/compare/v1.38.7...v1.38.8) (2026-02-06)
### Performance Improvements
* 支持设置默认的证书申请地址的反向代理 ([0cfb94b](https://github.com/certd/certd/commit/0cfb94b0ba6a6dc3bb0d0a81a1912068a4e6b6b6))
## [1.38.7](https://github.com/certd/certd/compare/v1.38.6...v1.38.7) (2026-02-05)
**Note:** Version bump only for package @certd/lib-server
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
**Note:** Version bump only for package @certd/lib-server
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
### Performance Improvements
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@certd/lib-server",
"version": "1.38.5",
"version": "1.38.8",
"description": "midway with flyway, sql upgrade way ",
"private": false,
"type": "module",
@@ -28,11 +28,11 @@
],
"license": "AGPL",
"dependencies": {
"@certd/acme-client": "^1.38.5",
"@certd/basic": "^1.38.5",
"@certd/pipeline": "^1.38.5",
"@certd/plugin-lib": "^1.38.5",
"@certd/plus-core": "^1.38.5",
"@certd/acme-client": "^1.38.8",
"@certd/basic": "^1.38.8",
"@certd/pipeline": "^1.38.8",
"@certd/plugin-lib": "^1.38.8",
"@certd/plus-core": "^1.38.8",
"@midwayjs/cache": "3.14.0",
"@midwayjs/core": "3.20.11",
"@midwayjs/i18n": "3.20.13",
@@ -64,5 +64,5 @@
"typeorm": "^0.3.11",
"typescript": "^5.4.2"
},
"gitHead": "eeb1f27fa47ddc616451f3e5a8fb8d1de345d252"
"gitHead": "29d37075dd600fa4898c5e38611e09db522e32fc"
}
@@ -76,6 +76,9 @@ export class SysPrivateSettings extends BaseSettings {
httpsProxy? = '';
httpProxy? = '';
reverseProxies?: Record<string, string> = {};
dnsResultOrder? = '';
commonCnameEnabled?: boolean = true;
@@ -4,10 +4,10 @@ import { Repository } from 'typeorm';
import { SysSettingsEntity } from '../entity/sys-settings.js';
import { BaseSettings, SysInstallInfo, SysPrivateSettings, SysPublicSettings, SysSecret, SysSecretBackup } from './models.js';
import { BaseService } from '../../../basic/index.js';
import { cache, logger, setGlobalProxy } from '@certd/basic';
import { getAllSslProviderDomains, setSslProviderReverseProxies } from '@certd/acme-client';
import { cache, logger, mergeUtils, setGlobalProxy } from '@certd/basic';
import * as dns from 'node:dns';
import {mergeUtils} from "@certd/basic";
import { BaseService } from '../../../basic/index.js';
import { executorQueue } from '../../basic/service/executor-queue.js';
const {merge} = mergeUtils;
/**
@@ -120,7 +120,14 @@ export class SysSettingsService extends BaseService<SysSettingsEntity> {
}
async getPrivateSettings(): Promise<SysPrivateSettings> {
return await this.getSetting(SysPrivateSettings);
const res = await this.getSetting<SysPrivateSettings>(SysPrivateSettings);
const sslProviderDomains = getAllSslProviderDomains();
for (const domain of sslProviderDomains) {
if (!res.reverseProxies[domain]) {
res.reverseProxies[domain] = "";
}
}
return res
}
async savePrivateSettings(bean: SysPrivateSettings) {
@@ -145,6 +152,8 @@ export class SysSettingsService extends BaseService<SysSettingsEntity> {
if (bean.pipelineMaxRunningCount){
executorQueue.setMaxRunningCount(bean.pipelineMaxRunningCount);
}
setSslProviderReverseProxies(bean.reverseProxies);
}
async updateByKey(key: string, setting: any) {
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.8](https://github.com/certd/certd/compare/v1.38.7...v1.38.8) (2026-02-06)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.38.7](https://github.com/certd/certd/compare/v1.38.6...v1.38.7) (2026-02-05)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
**Note:** Version bump only for package @certd/midway-flyway-js
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@certd/midway-flyway-js",
"version": "1.38.5",
"version": "1.38.8",
"description": "midway with flyway, sql upgrade way ",
"private": false,
"type": "module",
@@ -46,5 +46,5 @@
"typeorm": "^0.3.11",
"typescript": "^5.4.2"
},
"gitHead": "eeb1f27fa47ddc616451f3e5a8fb8d1de345d252"
"gitHead": "29d37075dd600fa4898c5e38611e09db522e32fc"
}
+14
View File
@@ -3,6 +3,20 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.8](https://github.com/certd/certd/compare/v1.38.7...v1.38.8) (2026-02-06)
**Note:** Version bump only for package @certd/plugin-cert
## [1.38.7](https://github.com/certd/certd/compare/v1.38.6...v1.38.7) (2026-02-05)
### Performance Improvements
* eab从更多参数中挪到外面 ([5ea4f46](https://github.com/certd/certd/commit/5ea4f46de7ae403a7a16e9488dc1d9c7523d019a))
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
**Note:** Version bump only for package @certd/plugin-cert
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
**Note:** Version bump only for package @certd/plugin-cert
+6 -6
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/plugin-cert",
"private": false,
"version": "1.38.5",
"version": "1.38.8",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -17,10 +17,10 @@
"compile": "tsc --skipLibCheck --watch"
},
"dependencies": {
"@certd/acme-client": "^1.38.5",
"@certd/basic": "^1.38.5",
"@certd/pipeline": "^1.38.5",
"@certd/plugin-lib": "^1.38.5",
"@certd/acme-client": "^1.38.8",
"@certd/basic": "^1.38.8",
"@certd/pipeline": "^1.38.8",
"@certd/plugin-lib": "^1.38.8",
"psl": "^1.9.0",
"punycode.js": "^2.3.1"
},
@@ -38,5 +38,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "eeb1f27fa47ddc616451f3e5a8fb8d1de345d252"
"gitHead": "29d37075dd600fa4898c5e38611e09db522e32fc"
}
+1 -1
View File
@@ -1 +1 @@
export * from "@certd/plugin-lib";
export * from "@certd/plugin-lib";
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.8](https://github.com/certd/certd/compare/v1.38.7...v1.38.8) (2026-02-06)
**Note:** Version bump only for package @certd/plugin-lib
## [1.38.7](https://github.com/certd/certd/compare/v1.38.6...v1.38.7) (2026-02-05)
**Note:** Version bump only for package @certd/plugin-lib
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
**Note:** Version bump only for package @certd/plugin-lib
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
**Note:** Version bump only for package @certd/plugin-lib
+6 -6
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/plugin-lib",
"private": false,
"version": "1.38.5",
"version": "1.38.8",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -22,10 +22,10 @@
"@alicloud/pop-core": "^1.7.10",
"@alicloud/tea-util": "^1.4.11",
"@aws-sdk/client-s3": "^3.964.0",
"@certd/acme-client": "^1.38.5",
"@certd/basic": "^1.38.5",
"@certd/pipeline": "^1.38.5",
"@certd/plus-core": "^1.38.5",
"@certd/acme-client": "^1.38.8",
"@certd/basic": "^1.38.8",
"@certd/pipeline": "^1.38.8",
"@certd/plus-core": "^1.38.8",
"@kubernetes/client-node": "0.21.0",
"ali-oss": "^6.22.0",
"basic-ftp": "^5.0.5",
@@ -57,5 +57,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "eeb1f27fa47ddc616451f3e5a8fb8d1de345d252"
"gitHead": "29d37075dd600fa4898c5e38611e09db522e32fc"
}
+26
View File
@@ -3,6 +3,32 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.8](https://github.com/certd/certd/compare/v1.38.7...v1.38.8) (2026-02-06)
### Performance Improvements
* 双重验证显示secret ([febd6d3](https://github.com/certd/certd/commit/febd6d32cfe6d89ccecf26bf15141df7c456e5c6))
* 支持设置默认的证书申请地址的反向代理 ([0cfb94b](https://github.com/certd/certd/commit/0cfb94b0ba6a6dc3bb0d0a81a1912068a4e6b6b6))
* 子域名托管域名支持配置通配符 ([3f7ac93](https://github.com/certd/certd/commit/3f7ac939326b0c7ec013a7534b6c0e58fb3e8cb4))
## [1.38.7](https://github.com/certd/certd/compare/v1.38.6...v1.38.7) (2026-02-05)
### Bug Fixes
* 修复有域名记录时,域名输入框无法关闭的bug ([54c8217](https://github.com/certd/certd/commit/54c8217808453b121abf646b004596f28932509f))
### Performance Improvements
* eab从更多参数中挪到外面 ([5ea4f46](https://github.com/certd/certd/commit/5ea4f46de7ae403a7a16e9488dc1d9c7523d019a))
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
### Performance Improvements
* 当域名管理中没有域名时,创建流水线时不展开域名选择框 ([9166a57](https://github.com/certd/certd/commit/9166a579301a60750f0b72b6a42b0c8d730695fd))
* count tip ([e19743f](https://github.com/certd/certd/commit/e19743f70553700f1f91bff76f87370f749dd247))
* oauth支持github 和google 修复头像显示问题 ([693a4a6](https://github.com/certd/certd/commit/693a4a663385ced3176286bf4b5f3566da83d90e))
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
### Bug Fixes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@certd/ui-client",
"version": "1.38.5",
"version": "1.38.8",
"private": true,
"scripts": {
"dev": "vite --open",
@@ -106,8 +106,8 @@
"zod-defaults": "^0.1.3"
},
"devDependencies": {
"@certd/lib-iframe": "^1.38.5",
"@certd/pipeline": "^1.38.5",
"@certd/lib-iframe": "^1.38.8",
"@certd/pipeline": "^1.38.8",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"@types/chai": "^4.3.12",
@@ -3,6 +3,7 @@
<div class="flex flex-row">
<a-select
class="domain-select-input"
:popup-class-name="popupClassName"
:dropdown-style="dropdownStyle"
show-search
:filter-option="filterOption"
@@ -55,12 +56,12 @@
</div>
</template>
<script setup lang="ts">
import { computed, defineComponent, ref, Ref, useAttrs } from "vue";
import { request } from "/@/api/service";
import { Dicts } from "../lib/dicts";
import { computed, defineComponent, onMounted, ref, Ref, useAttrs } from "vue";
import { useRouter } from "vue-router";
import { useDomainImport, useDomainImportManage } from "/@/views/certd/cert/domain/use";
import { Dicts } from "../lib/dicts";
import { request } from "/@/api/service";
import { openRouteInNewWindow } from "/@/vben/utils";
import { useDomainImportManage } from "/@/views/certd/cert/domain/use";
defineOptions({
name: "DomainSelector",
@@ -90,6 +91,15 @@ const emit = defineEmits<{
const attrs = useAttrs();
const hasOptions: Ref = ref(null);
const popupClassName = computed(() => {
if (!hasOptions.value) {
return "hidden-important";
}
return "";
});
const searchKeyRef = ref("");
const optionsRef = ref([]);
const message = ref("");
@@ -143,6 +153,14 @@ const getOptions = async () => {
}
optionsRef.value = options;
if (hasOptions.value == null) {
//
if (options.length > 0) {
hasOptions.value = true;
} else {
hasOptions.value = false;
}
}
pagerRef.value.total = list.length;
if (props.pager) {
if (res.total != null) {
@@ -205,6 +223,10 @@ function openDomainImportDialog() {
const dropdownStyle = ref({
zIndex: 2000,
});
onMounted(() => {
refreshOptions();
});
</script>
<style lang="less"></style>
@@ -1,8 +1,8 @@
<template>
<div class="params-show">
<a-tag type="primary" color="green" v-for="item of params" :key="item.value" class="item">
<a-tag v-for="item of params" :key="item.value" type="primary" color="green" class="item">
<span class="label">{{ item.label }}=</span>
<fs-copyable :modelValue="`\$\{${item.value}\}`" :button="{show:false}" :inline="true"></fs-copyable>
<fs-copyable :model-value="`\$\{${item.value}\}`" :button="{ show: false }" :inline="true"></fs-copyable>
</a-tag>
</div>
</template>
@@ -161,27 +161,30 @@ function openStarModal(vipType: string) {
return;
}
Modal.destroyAll();
const goGithub = () => {
window.open("https://github.com/certd/certd/");
};
modal.confirm({
title: t("vip.get_7_day_pro_trial"),
okText: t("vip.star_now"),
onOk() {
goGithub();
openTrialModal(vipType);
},
width: 600,
content: () => {
return (
<div class="flex mt-10 mb-10">
<div>{t("vip.please_help_star")}</div>
<img class="ml-5" src="https://img.shields.io/github/stars/certd/certd?logo=github" />
</div>
);
},
});
openTrialModal(vipType);
// const goGithub = () => {
// window.open("https://github.com/certd/certd/");
// };
// modal.confirm({
// title: t("vip.get_7_day_pro_trial"),
// okText: t("vip.star_now"),
// onOk() {
// goGithub();
// openTrialModal(vipType);
// },
// width: 600,
// content: () => {
// return (
// <div class="flex mt-10 mb-10">
// <div>{t("vip.please_help_star")}</div>
// <img class="ml-5" src="https://img.shields.io/github/stars/certd/certd?logo=github" />
// </div>
// );
// },
// });
}
function openUpgrade() {
@@ -8,9 +8,20 @@
<div class="flex flex-col order-count-text weight-bold">
<div class="count-text ml-4 flex items-center">
<fs-icon icon="noto:fire" class="fs-20 mr-2"></fs-icon>
<span> 今日赞助 </span>
<span class="count-number color-red font-bold text-2xl ml-1 mr-1"> {{ stage.orderCount }} </span>
<span> {{ stage.title }} </span>
<template v-if="stage.vipTotal > 0">
<span> 已有 </span>
<span class="count-number color-red font-bold text-2xl ml-1 mr-1"> {{ stage.vipTotal }} </span> 位小伙伴赞助
<span>
{{ stage.title }}
</span>
</template>
<template v-else>
<span> 今日赞助 </span>
<span class="count-number color-red font-bold text-2xl ml-1 mr-1"> {{ stage.orderCount }} </span>
<span>
{{ stage.title }}
</span>
</template>
</div>
</div>
</div>
@@ -109,14 +120,13 @@
</template>
<script lang="ts" setup>
import { computed, nextTick, onMounted, reactive, Ref, ref } from "vue";
import { message, Modal } from "ant-design-vue";
import dayjs from "dayjs";
import { computed, nextTick, onMounted, onUnmounted, reactive, Ref, ref } from "vue";
import { useI18n } from "vue-i18n";
import { useRouter } from "vue-router";
import { useSettingStore } from "/@/store/settings";
import * as api from "./api";
import { utils } from "/@/utils";
import { useSettingStore } from "/@/store/settings";
const { t } = useI18n();
const router = useRouter();
@@ -230,12 +240,13 @@ const vipTypeDefine: any = {
},
};
const TodayVipOrderCountRef: Ref = ref({});
const TodayVipOrderCountRef: Ref = ref({ enabled: false, current: 0, stages: [] });
async function getTodayVipOrderCount() {
const res = await api.getTodayVipOrderCount();
if (res) {
TodayVipOrderCountRef.value = res;
TodayVipOrderCountRef.value.current = 0;
}
}
@@ -248,31 +259,50 @@ const todayOrderCount = computed(() => {
}
const lastStage = countInfo?.stages?.[countInfo?.stages?.length - 1] || {};
lastStage.orderCount = orderCount;
const stages: any = [];
stages.push({
title: countInfo.title,
vipTotal: countInfo?.vipTotal || 0,
orderCount: orderCount,
bg: lastStage.bg,
});
if (lastStage.orderCount > 0) {
stages.push(lastStage);
}
return {
enabled: enabled,
orderCount: orderCount,
title: lastStage.title || "",
stages: countInfo?.stages,
stages: stages,
};
});
async function scrollOrderCount() {
const stages = todayOrderCount.value.stages;
if (!stages.length) {
if (stages.length === 0) {
return;
}
let index = 0;
for (const stage of stages) {
const doScroll = () => {
TodayVipOrderCountRef.value.current = index;
await utils.sleep(500);
index++;
}
if (index >= stages.length) {
index = 0;
}
};
doScroll();
scrollOrderCountIntervalRef.value = setInterval(doScroll, 7000);
}
const scrollOrderCountIntervalRef: Ref = ref(null);
onMounted(async () => {
await getTodayVipOrderCount();
await nextTick();
await scrollOrderCount();
});
onUnmounted(() => {
clearInterval(scrollOrderCountIntervalRef.value);
});
</script>
<style lang="less">
@@ -35,7 +35,13 @@ const menus = computed(() => [
const avatar = computed(() => {
const avt = userStore.getUserInfo?.avatar;
return avt ? `/api/basic/file/download?key=${avt}` : "";
if (!avt) {
return "";
}
if (avt.startsWith("http")) {
return avt;
}
return `/api/basic/file/download?key=${avt}`;
});
async function handleLogout() {
@@ -511,6 +511,7 @@ export default {
selectRecordFirst: "Please select records first",
subdomainHosted: "Hosted Subdomain",
subdomainHelpText: "If you don't understand what subdomain hosting is,Do not set it randomly, as it may result in the inability to apply for the certificate. please refer to the documentation ",
subdomainHelpSupportStart: "Supports * wildcard, indicating that all subdomains of the domain are hosted (free subdomains)",
subdomainManagement: "Subdomain Management",
isDisabled: "Is Disabled",
enabled: "Enabled",
@@ -784,6 +785,7 @@ export default {
captchaSetting: "Captcha Setting",
pipelineSetting: "Pipeline Settings",
oauthSetting: "OAuth2 Settings",
networkSetting: "Network Settings",
showRunStrategy: "Show RunStrategy",
showRunStrategyHelper: "Allow modify the run strategy of the task",
@@ -835,6 +837,11 @@ export default {
notice: "System Notice",
noticeHelper: "System notice, will be displayed on the login page",
noticePlaceholder: "System notice",
reverseProxy: "Reverse Proxy List",
reverseProxyHelper: "Reverse proxy for ACME address, used when applying for certificate",
reverseProxyPlaceholder: "http://le.px.handfree.work",
reverseProxyEmpty: "No reverse proxy list configured",
},
},
modal: {
@@ -120,7 +120,7 @@ export default {
},
customPipeline: "自定义流水线",
createCertdPipeline: "创建证书流水线",
commercialCertHosting: "商用证书托管",
commercialCertHosting: "已有证书托管",
tooltip: {
manualUploadOwnCert: "手动上传自有证书,执行自动部署",
noAutoApplyCommercialCert: "并不能自动申请商业证书",
@@ -521,6 +521,7 @@ export default {
selectRecordFirst: "请先勾选记录",
subdomainHosted: "托管的子域名",
subdomainHelpText: "如果您不理解什么是子域托管,请不要随意设置(可能导致证书无法申请,以前设置过的cname记录也需要重新配置),可以参考文档",
subdomainHelpSupportStart: "支持*号通配符,表示该域名下的子域名都是托管的(免费子域名)",
subdomainManagement: "子域管理",
isDisabled: "是否禁用",
enabled: "启用",
@@ -791,6 +792,7 @@ export default {
captchaSetting: "验证码设置",
pipelineSetting: "流水线设置",
oauthSetting: "第三方登录",
networkSetting: "网络设置",
showRunStrategy: "显示运行策略选择",
showRunStrategyHelper: "任务设置中是否允许选择运行策略",
@@ -850,6 +852,11 @@ export default {
notice: "系统公告",
noticeHelper: "系统公告,将在首页显示",
noticePlaceholder: "系统公告",
reverseProxy: "反向代理列表",
reverseProxyHelper: "证书颁发机构ACME地址的反向代理,在申请证书时自动使用",
reverseProxyPlaceholder: "http://le.px.handfree.work",
reverseProxyEmpty: "未配置反向代理",
},
},
modal: {
@@ -93,6 +93,7 @@ export type SuiteSetting = {
export type SysPrivateSetting = {
httpProxy?: string;
httpsProxy?: string;
reverseProxies?: any;
dnsResultOrder?: string;
commonCnameEnabled?: boolean;
// 同一个用户同时最大运行流水线数量
@@ -372,6 +372,13 @@ h6 {
border-spacing: 0;
overflow: auto;
&.cd-table-none-border {
border: 0 !important;
td, th {
border: 0 !important;
}
}
.fs-loading {
position: absolute;
left: 0;
@@ -476,4 +483,10 @@ h6 {
.fs-icon{
margin-right: 5px;
}
}
.hidden-important {
display: none !important;
visibility: hidden !important;
}
@@ -28,7 +28,7 @@ export async function TwoFactorAuthenticatorGet() {
url: apiPrefix + "/twoFactor/authenticator/qrcode",
method: "post",
});
return res as string; //base64
return res as { qrcode: string; link: string; secret: string }; //base64
}
export async function TwoFactorAuthenticatorSave(req: AuthenticatorSaveReq) {
@@ -57,6 +57,17 @@
<div class="ml-20">
<img class="full-w" :src="authenticatorForm.qrcodeSrc" />
</div>
<div class="ml-20 mt-5">
<div>您也可以手动添加</div>
<div class="flex mt-5">
<a-tag type="primary" color="green" class="mr-2">Secret</a-tag>
<fs-copyable :model-value="authenticatorForm.secret" />
</div>
<div class="flex mt-5">
<a-tag type="primary" color="green" class="mr-2">Link</a-tag>
<fs-copyable :model-value="authenticatorForm.link" />
</div>
</div>
</div>
<h3 class="font-bold m-10">{{ t("certd.step3") }}</h3>
<div class="ml-20">
@@ -97,6 +108,8 @@ const formState = reactive<Partial<UserTwoFactorSetting>>({
const authenticatorForm = reactive({
qrcodeSrc: "",
verifyCode: "",
link: "",
secret: "",
open: false,
});
@@ -110,9 +123,14 @@ watch(
async open => {
if (open) {
//base64
authenticatorForm.qrcodeSrc = await api.TwoFactorAuthenticatorGet();
const { qrcode, link, secret } = await api.TwoFactorAuthenticatorGet();
authenticatorForm.qrcodeSrc = qrcode;
authenticatorForm.link = link;
authenticatorForm.secret = secret;
} else {
authenticatorForm.qrcodeSrc = "";
authenticatorForm.link = "";
authenticatorForm.secret = "";
authenticatorForm.verifyCode = "";
}
}
@@ -8,7 +8,7 @@
<a-descriptions-item :label="t('authentication.username')">{{ userInfo.username }}</a-descriptions-item>
<a-descriptions-item :label="t('authentication.nickName')">{{ userInfo.nickName }}</a-descriptions-item>
<a-descriptions-item :label="t('authentication.avatar')">
<a-avatar v-if="userInfo.avatar" size="large" :src="'api/basic/file/download?&key=' + userInfo.avatar" style="background-color: #eee"> </a-avatar>
<a-avatar v-if="userInfo.avatar" size="large" :src="userAvatar" style="background-color: #eee"> </a-avatar>
<a-avatar v-else size="large" style="background-color: #00b4f5">
{{ userInfo.username }}
</a-avatar>
@@ -108,6 +108,17 @@ async function bind(type: string) {
window.location.href = loginUrl;
}
const userAvatar = computed(() => {
if (isEmpty(userInfo.value.avatar)) {
return "";
}
if (userInfo.value.avatar.startsWith("http")) {
return userInfo.value.avatar;
}
return "api/basic/file/download?&key=" + userInfo.value.avatar;
});
onMounted(async () => {
await getUserInfo();
await loadOauthBounds();
@@ -1065,7 +1065,7 @@ export default defineComponent({
}
.layout-right {
width: 364px;
width: 368px;
height: 100%;
max-width: 90vw;
}
@@ -1292,7 +1292,7 @@ export default defineComponent({
.layout-right {
position: relative;
&.collapsed {
margin-right: max(-364px, -90vw);
margin-right: max(-368px, -90vw);
}
.collapse-toggle {
@@ -80,10 +80,13 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
render() {
return (
<div>
{t("certd.subdomainHelpText")}
<a href={"https://help.aliyun.com/zh/dns/subdomain-management"} target={"_blank"}>
{t("certd.subdomainManagement")}
</a>
<div>
1. {t("certd.subdomainHelpText")}
<a href={"https://help.aliyun.com/zh/dns/subdomain-management"} target={"_blank"}>
{t("certd.subdomainManagement")}
</a>
</div>
<div>2. {t("certd.subdomainHelpSupportStart")}</div>
</div>
);
},
@@ -26,6 +26,9 @@
<a-tab-pane key="pipeline" :tab="t('certd.sys.setting.pipelineSetting')">
<SettingPipeline v-if="activeKey === 'pipeline'" />
</a-tab-pane>
<a-tab-pane key="network" :tab="t('certd.sys.setting.networkSetting')">
<SettingNetwork v-if="activeKey === 'network'" />
</a-tab-pane>
</a-tabs>
</div>
</fs-page>
@@ -39,6 +42,7 @@ import SettingSafe from "/@/views/sys/settings/tabs/safe.vue";
import SettingCaptcha from "/@/views/sys/settings/tabs/captcha.vue";
import SettingPipeline from "/@/views/sys/settings/tabs/pipeline.vue";
import SettingOauth from "/@/views/sys/settings/tabs/oauth.vue";
import SettingNetwork from "/@/views/sys/settings/tabs/network.vue";
import { useRoute, useRouter } from "vue-router";
import { ref } from "vue";
import { useSettingStore } from "/@/store/settings";
@@ -15,33 +15,6 @@
<a-switch v-model:checked="formState.public.robots" />
</a-form-item>
<a-form-item :label="t('certd.httpProxy')" :name="['private', 'httpProxy']" :rules="urlRules">
<a-input v-model:value="formState.private.httpProxy" :placeholder="t('certd.httpProxyPlaceholder')" />
<div class="helper">{{ t("certd.httpProxyHelper") }}</div>
</a-form-item>
<a-form-item :label="t('certd.httpsProxy')" :name="['private', 'httpsProxy']" :rules="urlRules">
<div class="flex">
<a-input v-model:value="formState.private.httpsProxy" :placeholder="t('certd.httpsProxyPlaceholder')" />
<a-button class="ml-5" type="primary" :loading="testProxyLoading" :title="t('certd.saveThenTestTitle')" @click="testProxy">{{ t("certd.testButton") }}</a-button>
</div>
<div class="helper">{{ t("certd.httpsProxyHelper") }}</div>
</a-form-item>
<a-form-item :label="t('certd.dualStackNetwork')" :name="['private', 'dnsResultOrder']">
<a-select v-model:value="formState.private.dnsResultOrder">
<a-select-option value="verbatim">{{ t("certd.default") }}</a-select-option>
<a-select-option value="ipv4first">{{ t("certd.ipv4Priority") }}</a-select-option>
<a-select-option value="ipv6first">{{ t("certd.ipv6Priority") }}</a-select-option>
</a-select>
<div class="helper">{{ t("certd.dualStackNetworkHelper") }}, <a href="https://certd.docmirror.cn/guide/use/setting/ipv6.html" target="_blank">{{ t("certd.helpDocLink") }}</a></div>
</a-form-item>
<a-form-item :label="t('certd.sys.setting.showRunStrategy')" :name="['public', 'showRunStrategy']">
<a-switch v-model:checked="formState.public.showRunStrategy" />
<div class="helper">{{ t("certd.sys.setting.showRunStrategyHelper") }}</div>
</a-form-item>
<a-form-item :label="t('certd.enableCommonCnameService')" :name="['private', 'commonCnameEnabled']">
<a-switch v-model:checked="formState.private.commonCnameEnabled" />
<div class="helper" v-html="t('certd.commonCnameHelper')"></div>
@@ -60,16 +33,14 @@
</template>
<script setup lang="tsx">
import { reactive, ref } from "vue";
import { SysSettings } from "/@/views/sys/settings/api";
import * as api from "/@/views/sys/settings/api";
import { merge } from "lodash-es";
import { useSettingStore } from "/@/store/settings";
import { notification } from "ant-design-vue";
import { util } from "/@/utils";
import { merge } from "lodash-es";
import { reactive, ref } from "vue";
import { useSettingStore } from "/@/store/settings";
import * as api from "/@/views/sys/settings/api";
import { SysSettings } from "/@/views/sys/settings/api";
import { useI18n } from "/src/locales";
import AddonSelector from "../../../certd/addon/addon-selector/index.vue";
import CaptchaInput from "/@/components/captcha/captcha-input.vue";
const { t } = useI18n();
defineOptions({
@@ -84,11 +55,6 @@ const formState = reactive<Partial<SysSettings>>({
private: {},
});
const urlRules = ref({
type: "url",
message: "请输入正确的URL",
});
async function loadSysSettings() {
const data: any = await api.SysSettingsGet();
merge(formState, data);
@@ -110,43 +76,6 @@ const onFinish = async (form: any) => {
saveLoading.value = false;
}
};
const testProxyLoading = ref(false);
async function testProxy() {
testProxyLoading.value = true;
try {
const res = await api.TestProxy();
let success = true;
if (res.google !== true || res.baidu !== true) {
success = false;
}
const content = () => {
return (
<div>
<div>
{t("certd.google")}: {res.google === true ? t("certd.success") : util.maxLength(res.google)}
</div>
<div>
{t("certd.baidu")}: {res.baidu === true ? t("certd.success") : util.maxLength(res.baidu)}
</div>
</div>
);
};
if (!success) {
notification.error({
message: t("certd.testFailed"),
description: content,
});
return;
}
notification.success({
message: t("certd.testCompleted"),
description: content,
});
} finally {
testProxyLoading.value = false;
}
}
</script>
<style lang="less">
.sys-settings-base {
@@ -0,0 +1,127 @@
<template>
<div class="sys-settings-form sys-settings-network">
<a-form :model="formState" name="basic" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }" autocomplete="off" @finish="onFinish">
<a-form-item :label="t('certd.httpProxy')" :name="['private', 'httpProxy']" :rules="urlRules">
<a-input v-model:value="formState.private.httpProxy" :placeholder="t('certd.httpProxyPlaceholder')" />
<div class="helper">{{ t("certd.httpProxyHelper") }}</div>
</a-form-item>
<a-form-item :label="t('certd.httpsProxy')" :name="['private', 'httpsProxy']" :rules="urlRules">
<div class="flex">
<a-input v-model:value="formState.private.httpsProxy" :placeholder="t('certd.httpsProxyPlaceholder')" />
<a-button class="ml-5" type="primary" :loading="testProxyLoading" :title="t('certd.saveThenTestTitle')" @click="testProxy">{{ t("certd.testButton") }}</a-button>
</div>
<div class="helper">{{ t("certd.httpsProxyHelper") }}</div>
</a-form-item>
<a-form-item :label="t('certd.dualStackNetwork')" :name="['private', 'dnsResultOrder']">
<a-select v-model:value="formState.private.dnsResultOrder">
<a-select-option value="verbatim">{{ t("certd.default") }}</a-select-option>
<a-select-option value="ipv4first">{{ t("certd.ipv4Priority") }}</a-select-option>
<a-select-option value="ipv6first">{{ t("certd.ipv6Priority") }}</a-select-option>
</a-select>
<div class="helper">
{{ t("certd.dualStackNetworkHelper") }}, <a href="https://certd.docmirror.cn/guide/use/setting/ipv6.html" target="_blank">{{ t("certd.helpDocLink") }}</a>
</div>
</a-form-item>
<a-form-item :label="t('certd.sys.setting.reverseProxy')" :name="['private', 'reverseProxy']">
<div class="mt-5">
<div v-for="(value, key) in formState.private.reverseProxies" :key="key" class="flex items-center p-2 border-b border-gray-300">
<span class="flex-1">{{ key }}</span>
<span class="flex-1 ml-5"><a-input v-model:value="formState.private.reverseProxies[key]" placeholder="proxy.xxxx.com" allow-clear /></span>
</div>
</div>
<div class="helper">{{ t("certd.sys.setting.reverseProxyHelper") }}</div>
</a-form-item>
<a-form-item label=" " :colon="false" :wrapper-col="{ span: 8 }">
<a-button :loading="saveLoading" type="primary" html-type="submit">{{ t("certd.saveButton") }}</a-button>
</a-form-item>
</a-form>
</div>
</template>
<script setup lang="tsx">
import { proxyRefs, reactive, ref } from "vue";
import { SysSettings } from "/@/views/sys/settings/api";
import * as api from "/@/views/sys/settings/api";
import { merge } from "lodash-es";
import { useSettingStore } from "/@/store/settings";
import { message, notification } from "ant-design-vue";
import { useI18n } from "/src/locales";
const { t } = useI18n();
import { util } from "/@/utils";
defineOptions({
name: "SettingNetwork",
});
const formState = reactive<Partial<SysSettings>>({
public: {},
private: {},
});
const urlRules = ref({
type: "url",
message: "请输入正确的URL",
});
async function loadSysSettings() {
const data: any = await api.SysSettingsGet();
merge(formState, data);
}
const saveLoading = ref(false);
loadSysSettings();
const settingsStore = useSettingStore();
const onFinish = async (form: any) => {
try {
saveLoading.value = true;
form.private.reverseProxies = formState.private.reverseProxies;
await api.SysSettingsSave(form);
await settingsStore.loadSysSettings();
notification.success({
message: t("certd.saveSuccess"),
});
} finally {
saveLoading.value = false;
}
};
const testProxyLoading = ref(false);
async function testProxy() {
testProxyLoading.value = true;
try {
const res = await api.TestProxy();
let success = true;
if (res.google !== true || res.baidu !== true) {
success = false;
}
const content = () => {
return (
<div>
<div>
{t("certd.google")}: {res.google === true ? t("certd.success") : util.maxLength(res.google)}
</div>
<div>
{t("certd.baidu")}: {res.baidu === true ? t("certd.success") : util.maxLength(res.baidu)}
</div>
</div>
);
};
if (!success) {
notification.error({
message: t("certd.testFailed"),
description: content,
});
return;
}
notification.success({
message: t("certd.testCompleted"),
description: content,
});
} finally {
testProxyLoading.value = false;
}
}
</script>
<style lang="less"></style>
@@ -8,6 +8,10 @@
<a-input-number v-model:value="formState.public.limitUserPipelineCount" />
<div class="helper">{{ t("certd.limitUserPipelineCountHelper") }}</div>
</a-form-item>
<a-form-item :label="t('certd.sys.setting.showRunStrategy')" :name="['public', 'showRunStrategy']">
<a-switch v-model:checked="formState.public.showRunStrategy" />
<div class="helper">{{ t("certd.sys.setting.showRunStrategyHelper") }}</div>
</a-form-item>
<a-form-item :label="t('certd.sys.setting.pipelineValidTimeEnabled')" :name="['public', 'pipelineValidTimeEnabled']">
<div class="flex items-center">
<a-switch v-model:checked="formState.public.pipelineValidTimeEnabled" :disabled="!settingsStore.isPlus" />
+27
View File
@@ -3,6 +3,33 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.8](https://github.com/certd/certd/compare/v1.38.7...v1.38.8) (2026-02-06)
### Performance Improvements
* 双重验证显示secret ([febd6d3](https://github.com/certd/certd/commit/febd6d32cfe6d89ccecf26bf15141df7c456e5c6))
* 优化申请证书最大超时时长 ([00f67d8](https://github.com/certd/certd/commit/00f67d86d68f4f83cfafe2fbfeb4af0d86f9d20e))
* 支持设置默认的证书申请地址的反向代理 ([0cfb94b](https://github.com/certd/certd/commit/0cfb94b0ba6a6dc3bb0d0a81a1912068a4e6b6b6))
* 子域名托管域名支持配置通配符 ([3f7ac93](https://github.com/certd/certd/commit/3f7ac939326b0c7ec013a7534b6c0e58fb3e8cb4))
## [1.38.7](https://github.com/certd/certd/compare/v1.38.6...v1.38.7) (2026-02-05)
### Performance Improvements
* eab从更多参数中挪到外面 ([5ea4f46](https://github.com/certd/certd/commit/5ea4f46de7ae403a7a16e9488dc1d9c7523d019a))
* 第三方登录支持Microsoft ([beb7a4c](https://github.com/certd/certd/commit/beb7a4c99277262bb9681c5594cfcd3e36c52074))
* 优化zerossl申请证书稳定性 ([4d86fb3](https://github.com/certd/certd/commit/4d86fb319b81dbf6fa6485982105725b1b066593))
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
### Bug Fixes
* 修复新网找错域名的bug ([bd511f9](https://github.com/certd/certd/commit/bd511f97cb7fbdcaeff7ac899f0460a5c7b41826))
### Performance Improvements
* oauth支持github 和google 修复头像显示问题 ([693a4a6](https://github.com/certd/certd/commit/693a4a663385ced3176286bf4b5f3566da83d90e))
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
### Bug Fixes
@@ -22,7 +22,9 @@ input:
component:
name: api-test
action: TestRequest
helper: 点击测试接口是否正常
helper: |-
测试前请务必先在新网后台关闭异地登录保护、关闭动态口令验证
如果提示需要短信验证码,请等几个小时后再试
pluginType: access
type: builtIn
scriptFilePath: /plugins/plugin-xinnet/access.js
@@ -0,0 +1,19 @@
addonType: oauth
name: github
title: GitHub认证
desc: GitHub OAuth2登录
icon: simple-icons:github
showTest: false
input:
clientId:
title: ClientId
helper: '[GitHub Developer Settings](https://github.com/settings/developers)创建应用后获取'
required: true
clientSecretKey:
title: ClientSecretKey
component:
placeholder: ClientSecretKey / appSecretKey
required: true
pluginType: addon
type: builtIn
scriptFilePath: /plugins/plugin-oauth/oauth2/plugin-github.js
@@ -0,0 +1,21 @@
addonType: oauth
name: google
title: Google认证
desc: Google OAuth2登录
icon: simple-icons:google
showTest: false
input:
clientId:
title: ClientId
helper: >-
[Google Cloud
Console](https://console.cloud.google.com/apis/credentials)创建应用后获取
required: true
clientSecretKey:
title: ClientSecretKey
component:
placeholder: ClientSecretKey / appSecretKey
required: true
pluginType: addon
type: builtIn
scriptFilePath: /plugins/plugin-oauth/oauth2/plugin-google.js
@@ -0,0 +1,26 @@
addonType: oauth
name: microsoft
title: Microsoft认证
desc: Microsoft OAuth2登录
icon: simple-icons:microsoft
showTest: false
input:
clientId:
title: ClientId
helper: '[Azure Portal](https://portal.azure.com/)创建应用后获取'
required: true
clientSecretKey:
title: ClientSecretKey
component:
placeholder: ClientSecretKey / appSecretKey
required: true
tenantId:
title: TenantId
helper: 租户ID,留空使用/common端点(需要应用配置为多租户)
component:
placeholder: common 或 租户ID
value: common
required: false
pluginType: addon
type: builtIn
scriptFilePath: /plugins/plugin-oauth/oauth2/plugin-microsoft.js
@@ -215,7 +215,7 @@ input:
component:
name: access-selector
type: eab
maybeNeed: true
maybeNeed: false
required: false
helper: >-
需要提供EAB授权
@@ -246,7 +246,7 @@ input:
component:
name: access-selector
type: google
maybeNeed: true
maybeNeed: false
required: false
helper: >-
google服务账号授权与EAB授权选填其中一个,[服务账号授权获取方法](https://certd.docmirror.cn/guide/use/google/)
@@ -4,7 +4,7 @@ default:
runStrategy: 0
name: CertApplyUpload
icon: ph:certificate
title: 商用证书托管
title: 已有证书托管
group: cert
desc: 手动上传自定义证书后,自动部署(每次证书有更新,都需要手动上传一次)
shortcut:
+14 -14
View File
@@ -1,6 +1,6 @@
{
"name": "@certd/ui-server",
"version": "1.38.5",
"version": "1.38.8",
"description": "fast-server base midway",
"private": true,
"type": "module",
@@ -48,20 +48,20 @@
"@aws-sdk/client-iam": "^3.964.0",
"@aws-sdk/client-route-53": "^3.964.0",
"@aws-sdk/client-s3": "^3.964.0",
"@certd/acme-client": "^1.38.5",
"@certd/basic": "^1.38.5",
"@certd/commercial-core": "^1.38.5",
"@certd/acme-client": "^1.38.8",
"@certd/basic": "^1.38.8",
"@certd/commercial-core": "^1.38.8",
"@certd/cv4pve-api-javascript": "^8.4.2",
"@certd/jdcloud": "^1.38.5",
"@certd/lib-huawei": "^1.38.5",
"@certd/lib-k8s": "^1.38.5",
"@certd/lib-server": "^1.38.5",
"@certd/midway-flyway-js": "^1.38.5",
"@certd/pipeline": "^1.38.5",
"@certd/plugin-cert": "^1.38.5",
"@certd/plugin-lib": "^1.38.5",
"@certd/plugin-plus": "^1.38.5",
"@certd/plus-core": "^1.38.5",
"@certd/jdcloud": "^1.38.8",
"@certd/lib-huawei": "^1.38.8",
"@certd/lib-k8s": "^1.38.8",
"@certd/lib-server": "^1.38.8",
"@certd/midway-flyway-js": "^1.38.8",
"@certd/pipeline": "^1.38.8",
"@certd/plugin-cert": "^1.38.8",
"@certd/plugin-lib": "^1.38.8",
"@certd/plugin-plus": "^1.38.8",
"@certd/plus-core": "^1.38.8",
"@google-cloud/publicca": "^1.3.0",
"@huaweicloud/huaweicloud-sdk-cdn": "^3.1.185",
"@huaweicloud/huaweicloud-sdk-core": "^3.1.185",
@@ -48,8 +48,8 @@ export class UserTwoFactorSettingController extends BaseController {
@Post("/authenticator/qrcode", { summary: Constants.per.authOnly })
async authenticatorQrcode() {
const userId = this.getUserId();
const qrcode = await this.twoFactorService.getAuthenticatorQrCode(userId);
return this.ok(qrcode);
const {qrcode,link,secret} = await this.twoFactorService.getAuthenticatorQrCode(userId);
return this.ok({qrcode,link,secret});
}
@Post("/authenticator/save", { summary: Constants.per.authOnly })
@@ -9,6 +9,7 @@ import { Application } from '@midwayjs/koa';
import { httpsServer, HttpsServerOptions } from './https/server.js';
import { UserService } from '../sys/authority/service/user-service.js';
import { UserSettingsService } from '../mine/service/user-settings-service.js';
import { startProxyServer } from './proxy/server.js';
@Autoload()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
@@ -37,6 +38,7 @@ export class AutoZPrint {
async init() {
//监听https
this.startHttpsServer();
// this.startProxyServer();
logger.info("ENV:", process.env.NODE_ENV);
if (isDev()) {
this.startHeapLog();
@@ -97,4 +99,8 @@ export class AutoZPrint {
hostname: this.httpsConfig.hostname || this.koaConfig.hostname,
});
}
startProxyServer() {
startProxyServer({port: 7003});
}
}
@@ -0,0 +1,92 @@
// proxy-server.js
import http from 'http';
import https from 'https';
import url from 'url';
import net from 'net';
import { logger } from '@certd/basic';
export function startProxyServer(opts:{port:number}) {
const {port} = opts;
// 创建 HTTP 代理服务器
const proxyServer = http.createServer((clientReq, clientRes) => {
logger.log(`[proxy] 收到请求: ${clientReq.method} ${clientReq.url}`);
// 解析请求的 URL
const parsedUrl = url.parse(clientReq.url);
const options = {
hostname: parsedUrl.hostname,
port: parsedUrl.port || (parsedUrl.protocol === 'https:' ? 443 : 80),
path: parsedUrl.path,
method: clientReq.method,
headers: clientReq.headers
};
// 根据协议选择不同的模块
const protocol = parsedUrl.protocol === 'https:' ? https : http;
// 移除可能会引起问题的 headers
delete options.headers['proxy-connection'];
delete options.headers['connection'];
delete options.headers['keep-alive'];
// 创建到目标服务器的请求
const proxyReq = protocol.request(options, (proxyRes) => {
// 将目标服务器的响应返回给客户端
clientRes.writeHead(proxyRes.statusCode, proxyRes.headers);
proxyRes.pipe(clientRes);
});
proxyReq.on('error', (err) => {
logger.error('[proxy] 代理请求错误:', err);
clientRes.writeHead(500);
clientRes.end('代理服务器错误');
});
// 将客户端请求体转发到目标服务器
clientReq.pipe(proxyReq);
});
// 处理 CONNECT 方法(HTTPS 代理)
proxyServer.on('connect', (req, clientSocket, head) => {
logger.log(`[proxy] HTTPS 连接请求: ${req.url}`);
const [hostname, port] = req.url.split(':');
const portNum = parseInt(port) || 443;
// 连接到目标服务器
const serverSocket = net.connect(portNum, hostname, () => {
// 告诉客户端连接已建立
clientSocket.write('HTTP/1.1 200 Connection Established\r\n' +
'Proxy-agent: Node.js-Proxy\r\n' +
'\r\n');
// 建立双向数据流
serverSocket.write(head);
serverSocket.pipe(clientSocket);
clientSocket.pipe(serverSocket);
});
serverSocket.on('error', (err) => {
logger.error('[proxy] HTTPS 代理错误:', err);
clientSocket.end();
});
clientSocket.on('error', (err) => {
logger.error('[proxy] 客户端 socket 错误:', err);
serverSocket.end();
});
});
// 监听端口
proxyServer.listen(port, () => {
logger.info(`[proxy] 正向代理服务器运行在 http://0.0.0.0:${port}`);
});
proxyServer.close(() => {
logger.info('[proxy] 正向代理服务器已关闭');
});
return proxyServer
}
@@ -33,7 +33,8 @@ export class TwoFactorService {
//生成qrcode base64
const qrcode = await import("qrcode");
return await qrcode.toDataURL(qrcodeContent);
const qrcodeBase64 = await qrcode.toDataURL(qrcodeContent);
return {qrcode:qrcodeBase64,link:qrcodeContent,secret}
}
@@ -1,5 +1,5 @@
import {ISubDomainsGetter} from "@certd/plugin-cert";
import {SubDomainService} from "../sub-domain-service.js";
import { ISubDomainsGetter } from "@certd/plugin-cert";
import { SubDomainService } from "../sub-domain-service.js";
import { DomainService } from "../../../cert/service/domain-service.js";
export class SubDomainsGetter implements ISubDomainsGetter {
@@ -18,18 +18,39 @@ export class SubDomainsGetter implements ISubDomainsGetter {
}
async hasSubDomain(fullDomain: string) {
let arr = fullDomain.split(".")
const subDomains = await this.getSubDomains()
if (subDomains && subDomains.length > 0) {
if (subDomains && subDomains.length > 0) {
const fullDomainDot = "." + fullDomain;
for (const subDomain of subDomains) {
if (fullDomainDot.endsWith("." + subDomain)) {
//找到子域名托管
return subDomain;
}
if (subDomain.startsWith("*.")) {
//如果子域名配置的是泛域名,说明这一层及以下的子域名都是托管的
//以fullDomain在这一层的子域名作为返回值
const nonStarDomain = subDomain.slice(1)
if (fullDomainDot.endsWith(nonStarDomain)) {
//提取fullDomain在这一层的子域名
const fullArr = arr.reverse()
const subArr = subDomain.split(".").reverse()
let strBuilder = ""
for (let i =0 ;i<subArr.length;i++) {
if (strBuilder) {
strBuilder = fullArr[i] + "." + strBuilder
} else {
strBuilder = fullArr[i]
}
}
return strBuilder
}
}
}
}
let arr = fullDomain.split(".")
while(arr.length>0){
while (arr.length > 0) {
const subDomain = arr.join(".")
const domain = await this.domainService.findOne({
where: {
@@ -38,10 +59,10 @@ export class SubDomainsGetter implements ISubDomainsGetter {
challengeType: "dns",
}
})
if(domain){
if (domain) {
return subDomain
}
arr = arr.slice(1)
arr = arr.slice(1)
}
return null
}
@@ -113,6 +113,9 @@ export class PipelineService extends BaseService<PipelineEntity> {
async add(bean: PipelineEntity) {
bean.status = ResultType.none;
if (bean.order == null) {
bean.order = 0;
}
await this.save(bean);
return bean;
}
@@ -243,6 +246,9 @@ export class PipelineService extends BaseService<PipelineEntity> {
if (!bean.status) {
bean.status = ResultType.none;
}
if (bean.order == null) {
bean.order = 0;
}
if (!isUpdate) {
//如果是添加,先保存一下,获取到id,更新pipeline.id
await this.addOrUpdate(bean);
@@ -151,6 +151,7 @@ export class DeployCertToAliyunCDN extends AbstractTaskPlugin {
}
async SetCdnDomainSSLCertificate(client: any, params: { CertId: number; DomainName: string,CertName:string,CertRegion:string }) {
this.logger.info('设置CDN: ',JSON.stringify(params));
const requestOption = {
method: 'POST',
formatParams: false,
@@ -1,13 +1,12 @@
// @ts-ignore
import * as acme from "@certd/acme-client";
import { ClientExternalAccountBindingOptions, UrlMapping } from "@certd/acme-client";
import * as _ from "lodash-es";
import { Challenge } from "@certd/acme-client/types/rfc8555.js";
import { IContext } from "@certd/pipeline";
import { ILogger, utils } from "@certd/basic";
import { IContext } from "@certd/pipeline";
import { IDnsProvider, IDomainParser } from "@certd/plugin-lib";
import punycode from "punycode.js";
import { IOssClient } from "../../../plugin-lib/index.js";
import { IDnsProvider, IDomainParser } from "@certd/plugin-lib";
export type CnameVerifyPlan = {
type?: string;
domain: string;
@@ -112,11 +111,26 @@ export class AcmeService {
}
async getAcmeClient(email: string): Promise<acme.Client> {
const mappings = {};
if (this.sslProvider === "letsencrypt") {
mappings["acme-v02.api.letsencrypt.org"] = this.options.reverseProxy || "le.px.certd.handfree.work";
} else if (this.sslProvider === "google") {
mappings["dv.acme-v02.api.pki.goog"] = this.options.reverseProxy || "gg.px.certd.handfree.work";
const directoryUrl = acme.getDirectoryUrl({ sslProvider: this.sslProvider, pkType: this.options.privateKeyType });
let targetUrl = directoryUrl.replace("https://", "");
targetUrl = targetUrl.substring(0, targetUrl.indexOf("/"));
const mappings = {
"acme-v02.api.letsencrypt.org": "le.px.certd.handfree.work",
"dv.acme-v02.api.pki.goog": "gg.px.certd.handfree.work",
};
const reverseProxies = acme.getSslProviderReverseProxies();
if (reverseProxies) {
for (const key in reverseProxies) {
const value = reverseProxies[key];
if (value) {
mappings[key] = value;
}
}
}
if (this.options.reverseProxy && targetUrl) {
mappings[targetUrl] = this.options.reverseProxy;
}
const urlMapping: UrlMapping = {
enabled: false,
@@ -128,7 +142,7 @@ export class AcmeService {
await this.saveAccountConfig(email, conf);
this.logger.info(`创建新的Accountkey:${email}`);
}
const directoryUrl = acme.getDirectoryUrl({ sslProvider: this.sslProvider, pkType: this.options.privateKeyType });
if (this.options.useMappingProxy) {
urlMapping.enabled = true;
} else {
@@ -147,7 +161,7 @@ export class AcmeService {
externalAccountBinding: this.eab,
backoffAttempts: this.options.maxCheckRetryCount || 20,
backoffMin: 5000,
backoffMax: 10000,
backoffMax: 30 * 1000,
urlMapping,
signal: this.options.signal,
logger: this.logger,
@@ -434,11 +448,7 @@ export class AcmeService {
if (domains.length === 0) {
throw new Error("domain can not be empty");
}
// const commonName = domains[0];
// let altNames: undefined | string[] = undefined;
// if (domains.length > 1) {
// altNames = _.slice(domains, 1);
// }
return {
// commonName,
altNames: domains,
@@ -264,7 +264,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
name: "access-selector",
type: "eab",
},
maybeNeed: true,
maybeNeed: false,
required: false,
helper:
"需要提供EAB授权" +
@@ -291,7 +291,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
name: "access-selector",
type: "google",
},
maybeNeed: true,
maybeNeed: false,
required: false,
helper: "google服务账号授权与EAB授权选填其中一个,[服务账号授权获取方法](https://certd.docmirror.cn/guide/use/google/)\n服务账号授权需要配置代理或者服务器本身在海外",
mergeScript: `
@@ -458,6 +458,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
this.eab = eab;
const subDomainsGetter = await this.ctx.serviceGetter.get<ISubDomainsGetter>("subDomainsGetter");
const domainParser = new DomainParser(subDomainsGetter, this.logger);
this.acme = new AcmeService({
userId: this.ctx.user.id,
userContext: this.userContext,
@@ -673,6 +674,12 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
},
};
}
async onGetReverseProxyList() {
const sysSettingsService:any = await this.ctx.serviceGetter.get("sysSettingsService");
const sysSettings = await sysSettingsService.getPrivateSettings();
return sysSettings.reverseProxyList || []
}
}
new CertApplyPlugin();
@@ -60,6 +60,7 @@ export abstract class CertApplyBasePlugin extends CertApplyBaseConvertPlugin {
abstract doCertApply(): Promise<CertReader>;
async execute(): Promise<string | void> {
this.logger.addSecret(this.pfxPassword);
const oldCert = await this.condition();
if (oldCert != null) {
await this.output(oldCert, false);
@@ -6,7 +6,7 @@ import dayjs from "dayjs";
@IsTaskPlugin({
name: "CertApplyUpload",
icon: "ph:certificate",
title: "商用证书托管",
title: "已有证书托管",
group: pluginGroups.cert.key,
desc: "手动上传自定义证书后,自动部署(每次证书有更新,都需要手动上传一次)",
default: {
@@ -2,4 +2,7 @@ export * from './api.js'
export * from './oidc/plugin-oidc.js'
export * from './wx/plugin-wx.js'
export * from './oauth2/plugin-gitee.js'
export * from './oauth2/plugin-clogin.js'
export * from './oauth2/plugin-clogin.js'
export * from './oauth2/plugin-github.js'
export * from './oauth2/plugin-google.js'
export * from './oauth2/plugin-microsoft.js'
@@ -0,0 +1,103 @@
import { AddonInput, BaseAddon, IsAddon } from "@certd/lib-server";
import { BuildLoginUrlReq, BuildLogoutUrlReq, IOauthProvider, OnCallbackReq } from "../api.js";
@IsAddon({
addonType: "oauth",
name: 'github',
title: 'GitHub认证',
desc: 'GitHub OAuth2登录',
icon:"simple-icons:github",
showTest: false,
})
export class GithubOauthProvider extends BaseAddon implements IOauthProvider {
@AddonInput({
title: "ClientId",
helper: "[GitHub Developer Settings](https://github.com/settings/developers)创建应用后获取",
required: true,
})
clientId = "";
@AddonInput({
title: "ClientSecretKey",
component: {
placeholder: "ClientSecretKey / appSecretKey",
},
required: true,
})
clientSecretKey = "";
async buildLoginUrl(params: BuildLoginUrlReq) {
let scope = "user:email" // Scope of the access request
let state:any = {
forType: params.forType || 'login',
}
state = this.ctx.utils.hash.base64(JSON.stringify(state))
const authorizeEndpoint = "https://github.com/login/oauth/authorize"
const redirectUrl = encodeURIComponent(params.redirectUri)
const loginUrl = `${authorizeEndpoint}?client_id=${this.clientId}&redirect_uri=${redirectUrl}&response_type=code&scope=${scope}&state=${state}`
return {
loginUrl,
ticketValue: {
state,
},
};
}
async onCallback(req: OnCallbackReq) {
const code = req.code || ""
const tokenEndpoint = "https://github.com/login/oauth/access_token"
const uri = new URL(req.currentURL)
const redirectUri = `${uri.origin}${uri.pathname}`
const res = await this.ctx.utils.http.request( {
url: tokenEndpoint,
method: "post",
headers: {
"Accept": "application/json"
},
data:{
client_id: this.clientId,
client_secret: this.clientSecretKey,
code,
redirect_uri: redirectUri
}
})
const tokens = res
const userInfoEndpoint = "https://api.github.com/user"
// 获取用户信息
const userInfoRes = await this.ctx.utils.http.request( {
url: userInfoEndpoint,
method: "get",
headers: {
"Authorization": `Bearer ${tokens.access_token}`,
"Accept": "application/json"
}
})
const userInfo = userInfoRes
return {
token:{
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
expiresIn: tokens.expires_in,
},
userInfo: {
openId: userInfo.id,
nickName: userInfo.login || userInfo.name || "",
avatar: userInfo.avatar_url,
},
}
};
async buildLogoutUrl(params: BuildLogoutUrlReq) {
return {};
}
}
@@ -0,0 +1,103 @@
import { AddonInput, BaseAddon, IsAddon } from "@certd/lib-server";
import { BuildLoginUrlReq, BuildLogoutUrlReq, IOauthProvider, OnCallbackReq } from "../api.js";
@IsAddon({
addonType: "oauth",
name: 'google',
title: 'Google认证',
desc: 'Google OAuth2登录',
icon:"simple-icons:google",
showTest: false,
})
export class GoogleOauthProvider extends BaseAddon implements IOauthProvider {
@AddonInput({
title: "ClientId",
helper: "[Google Cloud Console](https://console.cloud.google.com/apis/credentials)创建应用后获取",
required: true,
})
clientId = "";
@AddonInput({
title: "ClientSecretKey",
component: {
placeholder: "ClientSecretKey / appSecretKey",
},
required: true,
})
clientSecretKey = "";
async buildLoginUrl(params: BuildLoginUrlReq) {
let scope = "email profile" // Scope of the access request
let state:any = {
forType: params.forType || 'login',
}
state = this.ctx.utils.hash.base64(JSON.stringify(state))
const authorizeEndpoint = "https://accounts.google.com/o/oauth2/auth"
const redirectUrl = encodeURIComponent(params.redirectUri)
const loginUrl = `${authorizeEndpoint}?client_id=${this.clientId}&redirect_uri=${redirectUrl}&response_type=code&scope=${scope}&state=${state}`
return {
loginUrl,
ticketValue: {
state,
},
};
}
async onCallback(req: OnCallbackReq) {
const code = req.code || ""
const tokenEndpoint = "https://oauth2.googleapis.com/token"
const uri = new URL(req.currentURL)
const redirectUri = `${uri.origin}${uri.pathname}`
const res = await this.ctx.utils.http.request( {
url: tokenEndpoint,
method: "post",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
data:{
client_id: this.clientId,
client_secret: this.clientSecretKey,
code,
redirect_uri: redirectUri,
grant_type: "authorization_code"
}
})
const tokens = res
const userInfoEndpoint = "https://www.googleapis.com/oauth2/v3/userinfo"
// 获取用户信息
const userInfoRes = await this.ctx.utils.http.request( {
url: userInfoEndpoint,
method: "get",
headers: {
"Authorization": `Bearer ${tokens.access_token}`
}
})
const userInfo = userInfoRes
return {
token:{
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
expiresIn: tokens.expires_in,
},
userInfo: {
openId: userInfo.sub,
nickName: userInfo.name || userInfo.email || "",
avatar: userInfo.picture,
},
}
};
async buildLogoutUrl(params: BuildLogoutUrlReq) {
return {};
}
}
@@ -0,0 +1,122 @@
import { AddonInput, BaseAddon, IsAddon } from "@certd/lib-server";
import { BuildLoginUrlReq, BuildLogoutUrlReq, IOauthProvider, OnCallbackReq } from "../api.js";
@IsAddon({
addonType: "oauth",
name: 'microsoft',
title: 'Microsoft认证',
desc: 'Microsoft OAuth2登录',
icon:"simple-icons:microsoft",
showTest: false,
})
export class MicrosoftOauthProvider extends BaseAddon implements IOauthProvider {
@AddonInput({
title: "ClientId",
helper: "[Azure Portal](https://portal.azure.com/)创建应用后获取",
required: true,
})
clientId = "";
@AddonInput({
title: "ClientSecretKey",
component: {
placeholder: "ClientSecretKey / appSecretKey",
},
required: true,
})
clientSecretKey = "";
@AddonInput({
title: "TenantId",
helper: "租户ID,留空使用/common端点(需要应用配置为多租户)",
component: {
placeholder: "common 或 租户ID",
},
value: "common",
required: false,
})
tenantId = "common";
async buildLoginUrl(params: BuildLoginUrlReq) {
let scope = "openid profile email User.Read" // Scope of the access request
let state:any = {
forType: params.forType || 'login',
}
state = this.ctx.utils.hash.base64(JSON.stringify(state))
const authorizeEndpoint = `https://login.microsoftonline.com/${this.tenantId}/oauth2/v2.0/authorize`
const redirectUrl = encodeURIComponent(params.redirectUri)
const loginUrl = `${authorizeEndpoint}?client_id=${this.clientId}&redirect_uri=${redirectUrl}&response_type=code&scope=${scope}&state=${state}`
return {
loginUrl,
ticketValue: {
state,
},
};
}
async onCallback(req: OnCallbackReq) {
const code = req.code || ""
if (!code) {
throw new Error("Missing code parameter");
}
const tokenEndpoint = `https://login.microsoftonline.com/${this.tenantId}/oauth2/v2.0/token`
const uri = new URL(req.currentURL)
const redirectUri = `${uri.origin}${uri.pathname}`
// 构建 form-urlencoded 格式的数据
const formData = new URLSearchParams();
formData.append('client_id', this.clientId);
formData.append('client_secret', this.clientSecretKey);
formData.append('code', code);
formData.append('redirect_uri', redirectUri);
formData.append('grant_type', 'authorization_code');
const res = await this.ctx.utils.http.request( {
url: tokenEndpoint,
method: "post",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json"
},
data: formData.toString()
})
const tokens = res
const userInfoEndpoint = "https://graph.microsoft.com/v1.0/me"
// 获取用户信息
const userInfoRes = await this.ctx.utils.http.request( {
url: userInfoEndpoint,
method: "get",
headers: {
"Authorization": `Bearer ${tokens.access_token}`,
"Accept": "application/json"
}
})
const userInfo = userInfoRes
return {
token:{
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
expiresIn: tokens.expires_in,
},
userInfo: {
openId: userInfo.id,
nickName: userInfo.displayName || userInfo.userPrincipalName || "",
avatar: userInfo.avatar || "",
},
}
};
async buildLogoutUrl(params: BuildLogoutUrlReq) {
return {};
}
}
@@ -44,7 +44,7 @@ export class XinnetAccess extends BaseAccess {
name: "api-test",
action: "TestRequest"
},
helper: "点击测试接口是否正常"
helper: "测试前请务必先在新网后台关闭异地登录保护、关闭动态口令验证\n如果提示需要短信验证码,请等几个小时后再试"
})
testRequest = true;
@@ -57,7 +57,19 @@ export class XinnetProvider extends AbstractDnsProvider<XinnetRecord> {
if (!res.list || res.list.length == 0) {
throw new Error("域名不存在");
}
const serviceCode = res.list[0].serviceCode;
let list = res.list.map((item) => ({
domainName: item.domainName,
serviceCode: item.serviceCode
}));
this.logger.info("域名列表:", JSON.stringify(list));
const domainItem = list.find((item) => item.domainName === domain);
if (!domainItem) {
throw new Error("域名(" + domain + ")不存在");
}
const serviceCode = domainItem.serviceCode;
const dcpCookie = await client.getDcpCookie({
serviceCode
+44 -44
View File
@@ -49,7 +49,7 @@ importers:
packages/core/acme-client:
dependencies:
'@certd/basic':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../basic
'@peculiar/x509':
specifier: ^1.11.0
@@ -213,10 +213,10 @@ importers:
packages/core/pipeline:
dependencies:
'@certd/basic':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../basic
'@certd/plus-core':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../pro/plus-core
dayjs:
specifier: ^1.11.7
@@ -412,7 +412,7 @@ importers:
packages/libs/lib-k8s:
dependencies:
'@certd/basic':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/basic
'@kubernetes/client-node':
specifier: 0.21.0
@@ -452,19 +452,19 @@ importers:
packages/libs/lib-server:
dependencies:
'@certd/acme-client':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/acme-client
'@certd/basic':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/basic
'@certd/pipeline':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/pipeline
'@certd/plugin-lib':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../plugins/plugin-lib
'@certd/plus-core':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../pro/plus-core
'@midwayjs/cache':
specifier: 3.14.0
@@ -610,16 +610,16 @@ importers:
packages/plugins/plugin-cert:
dependencies:
'@certd/acme-client':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/acme-client
'@certd/basic':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/basic
'@certd/pipeline':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/pipeline
'@certd/plugin-lib':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../plugin-lib
psl:
specifier: ^1.9.0
@@ -683,16 +683,16 @@ importers:
specifier: ^3.964.0
version: 3.964.0(aws-crt@1.26.2)
'@certd/acme-client':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/acme-client
'@certd/basic':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/basic
'@certd/pipeline':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/pipeline
'@certd/plus-core':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../pro/plus-core
'@kubernetes/client-node':
specifier: 0.21.0
@@ -783,16 +783,16 @@ importers:
packages/pro/commercial-core:
dependencies:
'@certd/basic':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/basic
'@certd/lib-server':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../libs/lib-server
'@certd/pipeline':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/pipeline
'@certd/plus-core':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../plus-core
'@midwayjs/core':
specifier: 3.20.11
@@ -865,16 +865,16 @@ importers:
packages/pro/plugin-plus:
dependencies:
'@certd/basic':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/basic
'@certd/pipeline':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/pipeline
'@certd/plugin-lib':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../plugins/plugin-lib
'@certd/plus-core':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../plus-core
crypto-js:
specifier: ^4.2.0
@@ -950,7 +950,7 @@ importers:
packages/pro/plus-core:
dependencies:
'@certd/basic':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/basic
dayjs:
specifier: ^1.11.7
@@ -1246,10 +1246,10 @@ importers:
version: 0.1.3(zod@3.24.4)
devDependencies:
'@certd/lib-iframe':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../libs/lib-iframe
'@certd/pipeline':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/pipeline
'@rollup/plugin-commonjs':
specifier: ^25.0.7
@@ -1438,46 +1438,46 @@ importers:
specifier: ^3.964.0
version: 3.964.0(aws-crt@1.26.2)
'@certd/acme-client':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/acme-client
'@certd/basic':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/basic
'@certd/commercial-core':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../pro/commercial-core
'@certd/cv4pve-api-javascript':
specifier: ^8.4.2
version: 8.4.2
'@certd/jdcloud':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../libs/lib-jdcloud
'@certd/lib-huawei':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../libs/lib-huawei
'@certd/lib-k8s':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../libs/lib-k8s
'@certd/lib-server':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../libs/lib-server
'@certd/midway-flyway-js':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../libs/midway-flyway-js
'@certd/pipeline':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../core/pipeline
'@certd/plugin-cert':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../plugins/plugin-cert
'@certd/plugin-lib':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../plugins/plugin-lib
'@certd/plugin-plus':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../pro/plugin-plus
'@certd/plus-core':
specifier: ^1.38.3
specifier: ^1.38.5
version: link:../../pro/plus-core
'@google-cloud/publicca':
specifier: ^1.3.0
@@ -19971,13 +19971,13 @@ snapshots:
resolve: 1.22.10
semver: 6.3.1
eslint-plugin-prettier@3.4.1(eslint-config-prettier@8.10.0(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8):
eslint-plugin-prettier@3.4.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@7.32.0)(prettier@2.8.8):
dependencies:
eslint: 7.32.0
prettier: 2.8.8
prettier-linter-helpers: 1.0.0
optionalDependencies:
eslint-config-prettier: 8.10.0(eslint@7.32.0)
eslint-config-prettier: 8.10.0(eslint@8.57.0)
eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8):
dependencies:
@@ -22377,7 +22377,7 @@ snapshots:
eslint: 7.32.0
eslint-config-prettier: 8.10.0(eslint@7.32.0)
eslint-plugin-node: 11.1.0(eslint@7.32.0)
eslint-plugin-prettier: 3.4.1(eslint-config-prettier@8.10.0(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8)
eslint-plugin-prettier: 3.4.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@7.32.0)(prettier@2.8.8)
execa: 5.1.1
inquirer: 7.3.3
json5: 2.2.3
+1 -1
View File
@@ -1 +1 @@
00:04
16:31
+1 -1
View File
@@ -1 +1 @@
11
16
+1 -1
View File
@@ -1 +1 @@
00:18
17:12