Compare commits

...

13 Commits

Author SHA1 Message Date
xiaojunnuo 55d2a1f09b v1.37.7 2025-11-13 01:15:01 +08:00
xiaojunnuo e3a5bcb907 build: prepare to build 2025-11-13 01:12:01 +08:00
xiaojunnuo d56567c9de chore: teo dns 测试成功 2025-11-13 01:11:04 +08:00
xiaojunnuo d7c381e05d chore: 1 2025-11-13 00:50:40 +08:00
xiaojunnuo 1d23dd2426 perf: 支持腾讯云teo dns解析 2025-11-13 00:45:05 +08:00
xiaojunnuo 86ce00adf9 perf: 支持使用letencrypt测试环境申请ip证书 2025-11-12 23:56:02 +08:00
xiaojunnuo e1eef013a8 fix: 修复点击立即触发运行报错的bug 2025-11-12 22:15:17 +08:00
xiaojunnuo c31bfd8b94 docs: 1 2025-11-11 16:03:40 +08:00
xiaojunnuo f443675f4f docs: 1 2025-11-11 16:03:19 +08:00
xiaojunnuo a44bd8849d chore: 1 2025-11-11 13:29:38 +08:00
xiaojunnuo 274c887140 chore: nslookup 改成dig命令 2025-11-11 11:41:36 +08:00
xiaojunnuo 44973ebd00 fix: 账号绑定页面某些情况下打不开的bug 2025-11-11 11:05:34 +08:00
xiaojunnuo 88f74163ff build: release 2025-11-11 01:16:32 +08:00
48 changed files with 444 additions and 129 deletions
+5 -1
View File
@@ -4,5 +4,9 @@
"typescript.tsc.autoDetect": "watch", "typescript.tsc.autoDetect": "watch",
"git.scanRepositories": [ "git.scanRepositories": [
"./packages/pro" "./packages/pro"
] ],
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"[typescript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
}
} }
+12
View File
@@ -3,6 +3,18 @@
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.37.7](https://github.com/certd/certd/compare/v1.37.6...v1.37.7) (2025-11-12)
### Bug Fixes
* 修复点击立即触发运行报错的bug ([e1eef01](https://github.com/certd/certd/commit/e1eef013a856d26fe80a05d9ec6e505e2e31e5f9))
* 账号绑定页面某些情况下打不开的bug ([44973eb](https://github.com/certd/certd/commit/44973ebd00e89c0fee8f3b91174157757ce0160f))
### Performance Improvements
* 支持使用letencrypt测试环境申请ip证书 ([86ce00a](https://github.com/certd/certd/commit/86ce00adf92ff98fead87a3eaaa6631036708f47))
* 支持腾讯云teo dns解析 ([1d23dd2](https://github.com/certd/certd/commit/1d23dd2426bd1e4c4dfea0a9e561d665e045ba9d))
## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10) ## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10)
### Bug Fixes ### Bug Fixes
+5 -3
View File
@@ -152,8 +152,11 @@ https://certd.handfree.work/
## 八、捐赠 ## 八、捐赠
************************ ************************
支持开源,为爱发电,我已入驻爱发电 开源为什么要做专业版收费?
https://afdian.com/a/greper 1. 纯靠为爱发电不可持续(比如:我的dev-sidecar项目即便是拥有20K+star,也差点凉凉,幸亏有另外大佬接手用爱发电)
2. 没有赞助的项目,作者不会用心倾听用户的心声,不顾用户体验(比如:下意识拒绝需求、频繁破坏性变更升级、全盘推倒重来之类的)
3. 没有赞助的项目,交流群的戾气有时候比较重,容易起冲突
发电权益: 发电权益:
1. 可加入发电专属群,可以获得作者一对一技术支持 1. 可加入发电专属群,可以获得作者一对一技术支持
@@ -173,7 +176,6 @@ https://afdian.com/a/greper
************************ ************************
************************
## 九、贡献代码 ## 九、贡献代码
+1 -1
View File
@@ -9,5 +9,5 @@
} }
}, },
"npmClient": "pnpm", "npmClient": "pnpm",
"version": "1.37.6" "version": "1.37.7"
} }
+7
View File
@@ -3,6 +3,13 @@
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.37.7](https://github.com/publishlab/node-acme-client/compare/v1.37.6...v1.37.7) (2025-11-12)
### Performance Improvements
* 支持使用letencrypt测试环境申请ip证书 ([86ce00a](https://github.com/publishlab/node-acme-client/commit/86ce00adf92ff98fead87a3eaaa6631036708f47))
* 支持腾讯云teo dns解析 ([1d23dd2](https://github.com/publishlab/node-acme-client/commit/1d23dd2426bd1e4c4dfea0a9e561d665e045ba9d))
## [1.37.6](https://github.com/publishlab/node-acme-client/compare/v1.37.5...v1.37.6) (2025-11-10) ## [1.37.6](https://github.com/publishlab/node-acme-client/compare/v1.37.5...v1.37.6) (2025-11-10)
### Performance Improvements ### Performance Improvements
+2 -2
View File
@@ -3,7 +3,7 @@
"description": "Simple and unopinionated ACME client", "description": "Simple and unopinionated ACME client",
"private": false, "private": false,
"author": "nmorsman", "author": "nmorsman",
"version": "1.37.6", "version": "1.37.7",
"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.37.6", "@certd/basic": "^1.37.7",
"@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",
+18 -3
View File
@@ -4,6 +4,9 @@
import { readCsrDomains } from "./crypto/index.js"; import { readCsrDomains } from "./crypto/index.js";
import { wait } from "./wait.js"; import { wait } from "./wait.js";
import { CancelError } from "./error.js"; import { CancelError } from "./error.js";
import { domainUtils } from '@certd/basic';
const defaultOpts = { const defaultOpts = {
@@ -65,7 +68,7 @@ export default async (client, userOpts) => {
* Parse domains from CSR * Parse domains from CSR
*/ */
log("[auto] Parsing domains from Certificate Signing Request "); log("[auto] Parsing domains from Certificate Signing Request");
const { commonName, altNames } = readCsrDomains(opts.csr); const { commonName, altNames } = readCsrDomains(opts.csr);
const uniqueDomains = Array.from(new Set([commonName].concat(altNames).filter((d) => d))); const uniqueDomains = Array.from(new Set([commonName].concat(altNames).filter((d) => d)));
@@ -76,9 +79,21 @@ export default async (client, userOpts) => {
*/ */
log("[auto] Placing new certificate order with ACME provider"); log("[auto] Placing new certificate order with ACME provider");
const orderPayload = { identifiers: uniqueDomains.map((d) => ({ type: "dns", value: d })) };
if (opts.profile && client.sslProvider === 'letsencrypt' ){ let hasIp = false
const orderPayload = { identifiers: uniqueDomains.map((d) =>{
// 判断是否为IP(v4或v6),否则按域名处理
const type = domainUtils.isIp(d) ? 'ip' : 'dns';
if(type === 'ip'){
hasIp = true
}
return { type, value: d }
}) };
if (opts.profile && client.sslProvider.startsWith("letsencrypt") ){
orderPayload.profile = opts.profile; orderPayload.profile = opts.profile;
if(hasIp){
orderPayload.profile = "shortlived"
}
} }
const order = await client.createOrder(orderPayload); const order = await client.createOrder(orderPayload);
const authorizations = await client.getAuthorizations(order); const authorizations = await client.getAuthorizations(order);
+10 -2
View File
@@ -7,7 +7,7 @@ import { createHash } from 'crypto';
import { getPemBodyAsB64u } from './crypto/index.js'; import { getPemBodyAsB64u } from './crypto/index.js';
import HttpClient from './http.js'; import HttpClient from './http.js';
import AcmeApi from './api.js'; import AcmeApi from './api.js';
import verify from './verify.js'; import {createChallengeFn} from './verify.js';
import * as util from './util.js'; import * as util from './util.js';
import auto from './auto.js'; import auto from './auto.js';
import { CancelError } from './error.js'; import { CancelError } from './error.js';
@@ -492,6 +492,9 @@ class AcmeClient {
throw new Error('Unable to verify ACME challenge, URL not found'); throw new Error('Unable to verify ACME challenge, URL not found');
} }
const {challenges} = createChallengeFn({logger:this.logger});
const verify = challenges
if (typeof verify[challenge.type] === 'undefined') { if (typeof verify[challenge.type] === 'undefined') {
throw new Error(`Unable to verify ACME challenge, unknown type: ${challenge.type}`); throw new Error(`Unable to verify ACME challenge, unknown type: ${challenge.type}`);
} }
@@ -507,7 +510,12 @@ class AcmeClient {
}; };
this.log('Waiting for ACME challenge verification(等待ACME检查验证)'); this.log('Waiting for ACME challenge verification(等待ACME检查验证)');
return util.retry(verifyFn, this.backoffOpts);
const log = (...args)=>{
this.logger.info(...args)
}
return util.retry(verifyFn, this.backoffOpts,log);
} }
/** /**
+18 -18
View File
@@ -48,7 +48,7 @@ class Backoff {
* @returns {Promise} * @returns {Promise}
*/ */
async function retryPromise(fn, attempts, backoff) { async function retryPromise(fn, attempts, backoff, logger = log) {
let aborted = false; let aborted = false;
try { try {
@@ -60,12 +60,12 @@ async function retryPromise(fn, attempts, backoff) {
throw e; throw e;
} }
log(`Promise rejected: ${e.message}`); logger(`Promise rejected: ${e.message}`);
const duration = backoff.duration(); const duration = backoff.duration();
log(`Promise rejected attempt #${backoff.attempts}, ${duration}ms 后重试: ${e.message}`); logger(`Promise rejected attempt #${backoff.attempts}, ${duration}ms 后重试: ${e.message}`);
await new Promise((resolve) => { setTimeout(resolve, duration); }); await new Promise((resolve) => { setTimeout(resolve, duration); });
return retryPromise(fn, attempts, backoff); return retryPromise(fn, attempts, backoff, logger);
} }
} }
@@ -80,9 +80,9 @@ async function retryPromise(fn, attempts, backoff) {
* @returns {Promise} * @returns {Promise}
*/ */
function retry(fn, { attempts = 5, min = 5000, max = 30000 } = {}) { function retry(fn, { attempts = 5, min = 5000, max = 30000 } = {}, logger = log) {
const backoff = new Backoff({ min, max }); const backoff = new Backoff({ min, max });
return retryPromise(fn, attempts, backoff); return retryPromise(fn, attempts, backoff, logger);
} }
/** /**
@@ -216,21 +216,21 @@ function formatResponseError(resp) {
* @returns {Promise<string>} Root domain name * @returns {Promise<string>} Root domain name
*/ */
async function resolveDomainBySoaRecord(recordName) { async function resolveDomainBySoaRecord(recordName, logger = log) {
try { try {
await dns.resolveSoa(recordName); await dns.resolveSoa(recordName);
log(`找到${recordName}的SOA记录`); logger(`找到${recordName}的SOA记录`);
return recordName; return recordName;
} }
catch (e) { catch (e) {
log(`找不到${recordName}的SOA记录,继续往主域名查找`); logger(`找不到${recordName}的SOA记录,继续往主域名查找`);
const parentRecordName = recordName.split('.').slice(1).join('.'); const parentRecordName = recordName.split('.').slice(1).join('.');
if (!parentRecordName.includes('.')) { if (!parentRecordName.includes('.')) {
throw new Error('SOA record查找失败'); throw new Error('SOA record查找失败');
} }
return resolveDomainBySoaRecord(parentRecordName); return resolveDomainBySoaRecord(parentRecordName,logger);
} }
} }
@@ -241,18 +241,18 @@ async function resolveDomainBySoaRecord(recordName) {
* @returns {Promise<dns.Resolver>} DNS resolver * @returns {Promise<dns.Resolver>} DNS resolver
*/ */
async function getAuthoritativeDnsResolver(recordName) { async function getAuthoritativeDnsResolver(recordName, logger = log) {
log(`获取域名${recordName}的权威NS服务器: `); logger(`获取域名${recordName}的权威NS服务器: `);
const resolver = new dns.Resolver(); const resolver = new dns.Resolver();
try { try {
/* Resolve root domain by SOA */ /* Resolve root domain by SOA */
const domain = await resolveDomainBySoaRecord(recordName); const domain = await resolveDomainBySoaRecord(recordNam,logger);
/* Resolve authoritative NS addresses */ /* Resolve authoritative NS addresses */
log(`获取到权威NS服务器name: ${domain}`); logger(`获取到权威NS服务器name: ${domain}`);
const nsRecords = await dns.resolveNs(domain); const nsRecords = await dns.resolveNs(domain);
log(`域名权威NS服务器:${nsRecords}`); logger(`域名权威NS服务器:${nsRecords}`);
const nsAddrArray = await Promise.all(nsRecords.map(async (r) => dns.resolve4(r))); const nsAddrArray = await Promise.all(nsRecords.map(async (r) => dns.resolve4(r)));
const nsAddresses = [].concat(...nsAddrArray).filter((a) => a); const nsAddresses = [].concat(...nsAddrArray).filter((a) => a);
@@ -261,16 +261,16 @@ async function getAuthoritativeDnsResolver(recordName) {
} }
/* Authoritative NS success */ /* Authoritative NS success */
log(`Found ${nsAddresses.length} authoritative NS addresses for domain: ${domain}`); logger(`Found ${nsAddresses.length} authoritative NS addresses for domain: ${domain}`);
resolver.setServers(nsAddresses); resolver.setServers(nsAddresses);
} }
catch (e) { catch (e) {
log(`Authoritative NS lookup error(获取权威NS服务器地址失败): ${e.message}`); logger(`Authoritative NS lookup error(获取权威NS服务器地址失败): ${e.message}`);
} }
/* Return resolver */ /* Return resolver */
const addresses = resolver.getServers(); const addresses = resolver.getServers();
log(`DNS resolver addresses(域名的权威NS服务器地址): ${addresses.join(', ')}`); logger(`DNS resolver addresses(域名的权威NS服务器地址): ${addresses.join(', ')}`);
return resolver; return resolver;
} }
+23 -13
View File
@@ -4,14 +4,22 @@
import dnsSdk from "dns" import dnsSdk from "dns"
import https from 'https' import https from 'https'
import {log} from './logger.js' import {log as defaultLog} from './logger.js'
import axios from './axios.js' import axios from './axios.js'
import * as util from './util.js' import * as util from './util.js'
import {isAlpnCertificateAuthorizationValid} from './crypto/index.js' import {isAlpnCertificateAuthorizationValid} from './crypto/index.js'
const dns = dnsSdk.promises const dns = dnsSdk.promises
/**
export function createChallengeFn(opts = {}){
const logger = opts?.logger || {info:defaultLog,error:defaultLog,warn:defaultLog,debug:defaultLog}
const log = function(...args){
logger.info(...args)
}
/**
* Verify ACME HTTP challenge * Verify ACME HTTP challenge
* *
* https://datatracker.ietf.org/doc/html/rfc8555#section-8.3 * https://datatracker.ietf.org/doc/html/rfc8555#section-8.3
@@ -112,7 +120,7 @@ async function walkDnsChallengeRecord(recordName, resolver = dns,deep = 0) {
return records return records
} }
export async function walkTxtRecord(recordName,deep = 0) { async function walkTxtRecord(recordName,deep = 0) {
if(deep >5){ if(deep >5){
log(`walkTxtRecord too deep (#${deep}) , skip walk`) log(`walkTxtRecord too deep (#${deep}) , skip walk`)
return [] return []
@@ -136,7 +144,7 @@ export async function walkTxtRecord(recordName,deep = 0) {
try{ try{
/* Authoritative DNS resolver */ /* Authoritative DNS resolver */
log(`从域名权威服务器获取TXT解析记录`); log(`从域名权威服务器获取TXT解析记录`);
const authoritativeResolver = await util.getAuthoritativeDnsResolver(recordName); const authoritativeResolver = await util.getAuthoritativeDnsResolver(recordName,log);
const res = await walkDnsChallengeRecord(recordName, authoritativeResolver,deep); const res = await walkDnsChallengeRecord(recordName, authoritativeResolver,deep);
if (res && res.length > 0) { if (res && res.length > 0) {
for (const item of res) { for (const item of res) {
@@ -173,7 +181,8 @@ async function verifyDnsChallenge(authz, challenge, keyAuthorization, prefix = '
recordValues = [...new Set(recordValues)]; recordValues = [...new Set(recordValues)];
log(`DNS查询成功, 找到 ${recordValues.length} 条TXT记录:${recordValues}`); log(`DNS查询成功, 找到 ${recordValues.length} 条TXT记录:${recordValues}`);
if (!recordValues.length || !recordValues.includes(keyAuthorization)) { if (!recordValues.length || !recordValues.includes(keyAuthorization)) {
throw new Error(`没有找到需要的DNS TXT记录: ${recordName},期望:${keyAuthorization},结果:${recordValues}`); const err = `没有找到需要的DNS TXT记录: ${recordName},期望:${keyAuthorization},结果:${recordValues}`
throw new Error(err);
} }
log(`关键授权匹配成功(${challenge.type}/${recordName}:${keyAuthorization},校验成功, ACME challenge verified`); log(`关键授权匹配成功(${challenge.type}/${recordName}:${keyAuthorization},校验成功, ACME challenge verified`);
@@ -207,12 +216,13 @@ async function verifyTlsAlpnChallenge(authz, challenge, keyAuthorization) {
return true; return true;
} }
/** return {
* Export API challenges:{
*/ 'http-01': verifyHttpChallenge,
'dns-01': verifyDnsChallenge,
'tls-alpn-01': verifyTlsAlpnChallenge,
},
walkTxtRecord,
}
export default { }
'http-01': verifyHttpChallenge,
'dns-01': verifyDnsChallenge,
'tls-alpn-01': verifyTlsAlpnChallenge,
};
+2 -1
View File
@@ -207,7 +207,8 @@ 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 createChallengeFn(opts?: {logger?:any}): any;
// export function walkTxtRecord(record: any): Promise<string[]>;
export function getAuthoritativeDnsResolver(record:string): Promise<any>; export function getAuthoritativeDnsResolver(record:string): Promise<any>;
export const CancelError: typeof CancelError; export const CancelError: typeof CancelError;
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.7](https://github.com/certd/certd/compare/v1.37.6...v1.37.7) (2025-11-12)
### Performance Improvements
* 支持使用letencrypt测试环境申请ip证书 ([86ce00a](https://github.com/certd/certd/commit/86ce00adf92ff98fead87a3eaaa6631036708f47))
## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10) ## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10)
**Note:** Version bump only for package @certd/basic **Note:** Version bump only for package @certd/basic
+1 -1
View File
@@ -1 +1 @@
00:42 01:12
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@certd/basic", "name": "@certd/basic",
"private": false, "private": false,
"version": "1.37.6", "version": "1.37.7",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
+33 -7
View File
@@ -7,29 +7,29 @@ function match(targetDomains: string | string[], inDomains: string[]) {
return false; return false;
} }
if (typeof targetDomains === 'string') { if (typeof targetDomains === "string") {
targetDomains = [targetDomains]; targetDomains = [targetDomains];
} }
for (let targetDomain of targetDomains) { for (let targetDomain of targetDomains) {
let matched = false; let matched = false;
if (targetDomain.startsWith('.')) { if (targetDomain.startsWith(".")) {
targetDomain = '*' + targetDomain; targetDomain = "*" + targetDomain;
} }
for (let inDomain of inDomains) { for (let inDomain of inDomains) {
if (inDomain.startsWith('.')) { if (inDomain.startsWith(".")) {
inDomain = '*' + inDomain; inDomain = "*" + inDomain;
} }
if (targetDomain === inDomain) { if (targetDomain === inDomain) {
matched = true; matched = true;
break; break;
} }
if (!inDomain.startsWith('*.')) { if (!inDomain.startsWith("*.")) {
//不可能匹配 //不可能匹配
continue; continue;
} }
//子域名匹配通配符即可 //子域名匹配通配符即可
const firstDotIndex = targetDomain.indexOf('.'); const firstDotIndex = targetDomain.indexOf(".");
const targetDomainSuffix = targetDomain.substring(firstDotIndex + 1); const targetDomainSuffix = targetDomain.substring(firstDotIndex + 1);
if (targetDomainSuffix === inDomain.substring(2)) { if (targetDomainSuffix === inDomain.substring(2)) {
matched = true; matched = true;
@@ -46,6 +46,32 @@ function match(targetDomains: string | string[], inDomains: string[]) {
return true; return true;
} }
function isIpv4(d: string) {
if (!d) {
return false;
}
const isIPv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
return isIPv4Regex.test(d);
}
function isIpv6(d: string) {
if (!d) {
return false;
}
const isIPv6Regex = /^([\da-f]{1,4}:){2,7}[\da-f]{1,4}$/i;
return isIPv6Regex.test(d);
}
function isIp(d: string) {
if (!d) {
return false;
}
return isIpv4(d) || isIpv6(d);
}
export const domainUtils = { export const domainUtils = {
match, match,
isIpv4,
isIpv6,
isIp,
}; };
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.7](https://github.com/certd/certd/compare/v1.37.6...v1.37.7) (2025-11-12)
**Note:** Version bump only for package @certd/pipeline
## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10) ## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10)
**Note:** Version bump only for package @certd/pipeline **Note:** Version bump only for package @certd/pipeline
+3 -3
View File
@@ -1,7 +1,7 @@
{ {
"name": "@certd/pipeline", "name": "@certd/pipeline",
"private": false, "private": false,
"version": "1.37.6", "version": "1.37.7",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
@@ -18,8 +18,8 @@
"compile": "tsc --skipLibCheck --watch" "compile": "tsc --skipLibCheck --watch"
}, },
"dependencies": { "dependencies": {
"@certd/basic": "^1.37.6", "@certd/basic": "^1.37.7",
"@certd/plus-core": "^1.37.6", "@certd/plus-core": "^1.37.7",
"dayjs": "^1.11.7", "dayjs": "^1.11.7",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"reflect-metadata": "^0.1.13" "reflect-metadata": "^0.1.13"
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.7](https://github.com/certd/certd/compare/v1.37.6...v1.37.7) (2025-11-12)
**Note:** Version bump only for package @certd/lib-huawei
## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10) ## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10)
**Note:** Version bump only for package @certd/lib-huawei **Note:** Version bump only for package @certd/lib-huawei
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@certd/lib-huawei", "name": "@certd/lib-huawei",
"private": false, "private": false,
"version": "1.37.6", "version": "1.37.7",
"main": "./dist/bundle.js", "main": "./dist/bundle.js",
"module": "./dist/bundle.js", "module": "./dist/bundle.js",
"types": "./dist/d/index.d.ts", "types": "./dist/d/index.d.ts",
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.7](https://github.com/certd/certd/compare/v1.37.6...v1.37.7) (2025-11-12)
**Note:** Version bump only for package @certd/lib-iframe
## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10) ## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10)
**Note:** Version bump only for package @certd/lib-iframe **Note:** Version bump only for package @certd/lib-iframe
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@certd/lib-iframe", "name": "@certd/lib-iframe",
"private": false, "private": false,
"version": "1.37.6", "version": "1.37.7",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.7](https://github.com/certd/certd/compare/v1.37.6...v1.37.7) (2025-11-12)
**Note:** Version bump only for package @certd/jdcloud
## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10) ## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10)
**Note:** Version bump only for package @certd/jdcloud **Note:** Version bump only for package @certd/jdcloud
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@certd/jdcloud", "name": "@certd/jdcloud",
"version": "1.37.6", "version": "1.37.7",
"description": "jdcloud openApi sdk", "description": "jdcloud openApi sdk",
"main": "./dist/bundle.js", "main": "./dist/bundle.js",
"module": "./dist/bundle.js", "module": "./dist/bundle.js",
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.7](https://github.com/certd/certd/compare/v1.37.6...v1.37.7) (2025-11-12)
**Note:** Version bump only for package @certd/lib-k8s
## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10) ## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10)
**Note:** Version bump only for package @certd/lib-k8s **Note:** Version bump only for package @certd/lib-k8s
+2 -2
View File
@@ -1,7 +1,7 @@
{ {
"name": "@certd/lib-k8s", "name": "@certd/lib-k8s",
"private": false, "private": false,
"version": "1.37.6", "version": "1.37.7",
"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.37.6", "@certd/basic": "^1.37.7",
"@kubernetes/client-node": "0.21.0" "@kubernetes/client-node": "0.21.0"
}, },
"devDependencies": { "devDependencies": {
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.7](https://github.com/certd/certd/compare/v1.37.6...v1.37.7) (2025-11-12)
**Note:** Version bump only for package @certd/lib-server
## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10) ## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10)
**Note:** Version bump only for package @certd/lib-server **Note:** Version bump only for package @certd/lib-server
+6 -6
View File
@@ -1,6 +1,6 @@
{ {
"name": "@certd/lib-server", "name": "@certd/lib-server",
"version": "1.37.6", "version": "1.37.7",
"description": "midway with flyway, sql upgrade way ", "description": "midway with flyway, sql upgrade way ",
"private": false, "private": false,
"type": "module", "type": "module",
@@ -28,11 +28,11 @@
], ],
"license": "AGPL", "license": "AGPL",
"dependencies": { "dependencies": {
"@certd/acme-client": "^1.37.6", "@certd/acme-client": "^1.37.7",
"@certd/basic": "^1.37.6", "@certd/basic": "^1.37.7",
"@certd/pipeline": "^1.37.6", "@certd/pipeline": "^1.37.7",
"@certd/plugin-lib": "^1.37.6", "@certd/plugin-lib": "^1.37.7",
"@certd/plus-core": "^1.37.6", "@certd/plus-core": "^1.37.7",
"@midwayjs/cache": "3.14.0", "@midwayjs/cache": "3.14.0",
"@midwayjs/core": "3.20.11", "@midwayjs/core": "3.20.11",
"@midwayjs/i18n": "3.20.13", "@midwayjs/i18n": "3.20.13",
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.7](https://github.com/certd/certd/compare/v1.37.6...v1.37.7) (2025-11-12)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10) ## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10)
**Note:** Version bump only for package @certd/midway-flyway-js **Note:** Version bump only for package @certd/midway-flyway-js
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@certd/midway-flyway-js", "name": "@certd/midway-flyway-js",
"version": "1.37.6", "version": "1.37.7",
"description": "midway with flyway, sql upgrade way ", "description": "midway with flyway, sql upgrade way ",
"private": false, "private": false,
"type": "module", "type": "module",
@@ -3,6 +3,13 @@
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.37.7](https://github.com/certd/certd/compare/v1.37.6...v1.37.7) (2025-11-12)
### Performance Improvements
* 支持使用letencrypt测试环境申请ip证书 ([86ce00a](https://github.com/certd/certd/commit/86ce00adf92ff98fead87a3eaaa6631036708f47))
* 支持腾讯云teo dns解析 ([1d23dd2](https://github.com/certd/certd/commit/1d23dd2426bd1e4c4dfea0a9e561d665e045ba9d))
## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10) ## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10)
### Performance Improvements ### Performance Improvements
+5 -5
View File
@@ -1,7 +1,7 @@
{ {
"name": "@certd/plugin-cert", "name": "@certd/plugin-cert",
"private": false, "private": false,
"version": "1.37.6", "version": "1.37.7",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@@ -17,10 +17,10 @@
"compile": "tsc --skipLibCheck --watch" "compile": "tsc --skipLibCheck --watch"
}, },
"dependencies": { "dependencies": {
"@certd/acme-client": "^1.37.6", "@certd/acme-client": "^1.37.7",
"@certd/basic": "^1.37.6", "@certd/basic": "^1.37.7",
"@certd/pipeline": "^1.37.6", "@certd/pipeline": "^1.37.7",
"@certd/plugin-lib": "^1.37.6", "@certd/plugin-lib": "^1.37.7",
"@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",
@@ -337,7 +337,7 @@ export class AcmeService {
domains = encodingDomains; domains = encodingDomains;
/* Create CSR */ /* Create CSR */
const { commonName, altNames } = this.buildCommonNameByDomains(domains); const { altNames } = this.buildCommonNameByDomains(domains);
let privateKey = null; let privateKey = null;
const privateKeyType = options.privateKeyType || "rsa_2048"; const privateKeyType = options.privateKeyType || "rsa_2048";
const privateKeyArr = privateKeyType.split("_"); const privateKeyArr = privateKeyType.split("_");
@@ -364,15 +364,13 @@ export class AcmeService {
//兼容老版本 //兼容老版本
createCsr = acme.forge.createCsr; createCsr = acme.forge.createCsr;
} }
const [key, csr] = await createCsr( const csrData: any = {
{ // commonName,
commonName, ...csrInfo,
...csrInfo, altNames,
altNames, // emailAddress: email,
// emailAddress: email, };
}, const [key, csr] = await createCsr(csrData, privateKey);
privateKey
);
if (dnsProvider == null && domainsVerifyPlan == null) { if (dnsProvider == null && domainsVerifyPlan == null) {
throw new Error("dnsProvider 、 domainsVerifyPlan不能都为空"); throw new Error("dnsProvider 、 domainsVerifyPlan不能都为空");
@@ -417,7 +415,7 @@ export class AcmeService {
} }
buildCommonNameByDomains(domains: string | string[]): { buildCommonNameByDomains(domains: string | string[]): {
commonName: string; commonName?: string;
altNames: string[] | undefined; altNames: string[] | undefined;
} { } {
if (typeof domains === "string") { if (typeof domains === "string") {
@@ -426,14 +424,14 @@ export class AcmeService {
if (domains.length === 0) { if (domains.length === 0) {
throw new Error("domain can not be empty"); throw new Error("domain can not be empty");
} }
const commonName = domains[0]; // const commonName = domains[0];
let altNames: undefined | string[] = undefined; // let altNames: undefined | string[] = undefined;
if (domains.length > 1) { // if (domains.length > 1) {
altNames = _.slice(domains, 1); // altNames = _.slice(domains, 1);
} // }
return { return {
commonName, // commonName,
altNames, altNames: domains,
}; };
} }
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.7](https://github.com/certd/certd/compare/v1.37.6...v1.37.7) (2025-11-12)
### Performance Improvements
* 支持腾讯云teo dns解析 ([1d23dd2](https://github.com/certd/certd/commit/1d23dd2426bd1e4c4dfea0a9e561d665e045ba9d))
## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10) ## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10)
**Note:** Version bump only for package @certd/plugin-lib **Note:** Version bump only for package @certd/plugin-lib
+3 -3
View File
@@ -1,7 +1,7 @@
{ {
"name": "@certd/plugin-lib", "name": "@certd/plugin-lib",
"private": false, "private": false,
"version": "1.37.6", "version": "1.37.7",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@@ -22,8 +22,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.37.6", "@certd/basic": "^1.37.7",
"@certd/pipeline": "^1.37.6", "@certd/pipeline": "^1.37.7",
"@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",
@@ -64,4 +64,8 @@ export class TencentAccess extends BaseAccess {
intlDomain() { intlDomain() {
return this.isIntl() ? "intl." : ""; return this.isIntl() ? "intl." : "";
} }
buildEndpoint(endpoint: string) {
return `${this.intlDomain()}${endpoint}`;
}
} }
+7
View File
@@ -3,6 +3,13 @@
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.37.7](https://github.com/certd/certd/compare/v1.37.6...v1.37.7) (2025-11-12)
### Bug Fixes
* 修复点击立即触发运行报错的bug ([e1eef01](https://github.com/certd/certd/commit/e1eef013a856d26fe80a05d9ec6e505e2e31e5f9))
* 账号绑定页面某些情况下打不开的bug ([44973eb](https://github.com/certd/certd/commit/44973ebd00e89c0fee8f3b91174157757ce0160f))
## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10) ## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10)
### Bug Fixes ### Bug Fixes
+3 -3
View File
@@ -1,6 +1,6 @@
{ {
"name": "@certd/ui-client", "name": "@certd/ui-client",
"version": "1.37.6", "version": "1.37.7",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite --open", "dev": "vite --open",
@@ -106,8 +106,8 @@
"zod-defaults": "^0.1.3" "zod-defaults": "^0.1.3"
}, },
"devDependencies": { "devDependencies": {
"@certd/lib-iframe": "^1.37.6", "@certd/lib-iframe": "^1.37.7",
"@certd/pipeline": "^1.37.6", "@certd/pipeline": "^1.37.7",
"@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",
@@ -6,7 +6,12 @@
<div>1. 解析记录应该添加在{{ record.domain }}域名下</div> <div>1. 解析记录应该添加在{{ record.domain }}域名下</div>
<div>2. 要添加的是CNAME类型的记录不是TXT</div> <div>2. 要添加的是CNAME类型的记录不是TXT</div>
<div>3. 核对记录值是否是:{{ record.recordValue }}</div> <div>3. 核对记录值是否是:{{ record.recordValue }}</div>
<div>4. 运行下面的命令,查看解析是否正确 <fs-copyable :style="{ color: '#52c41a' }" :model-value="nslookupCmd"></fs-copyable></div> <div>
4. 在验证中状态下运行下面的命令,查看cname和txt解析是否正确
<fs-copyable :style="{ color: '#52c41a' }" :model-value="nslookupCmd"></fs-copyable>
或者
<fs-copyable :style="{ color: '#52c41a' }" :model-value="digCmd"></fs-copyable>
</div>
<div>5. 如果以上检查都没有问题则可能是DNS解析生效时间比较慢某些提供商延迟可能高达几个小时</div> <div>5. 如果以上检查都没有问题则可能是DNS解析生效时间比较慢某些提供商延迟可能高达几个小时</div>
</div> </div>
</template> </template>
@@ -23,4 +28,8 @@ const props = defineProps<{
const nslookupCmd = computed(() => { const nslookupCmd = computed(() => {
return `nslookup -q=txt _acme-challenge.${props.record.domain}`; return `nslookup -q=txt _acme-challenge.${props.record.domain}`;
}); });
const digCmd = computed(() => {
return `dig _acme-challenge.${props.record.domain}`;
});
</script> </script>
@@ -97,6 +97,6 @@ export default {
already_comm: "已经是商业版了,不能降级为专业版", already_comm: "已经是商业版了,不能降级为专业版",
already_perpetual_plus: "您已经是永久专业版了,无法继续升级", already_perpetual_plus: "您已经是永久专业版了,无法继续升级",
confirm: "确认", confirm: "确认",
not_effective: "没有生效?", not_effective: "VIP没有生效?",
learn_more: "更多特权(加VIP群等)", learn_more: "更多特权(加VIP群等)",
}; };
@@ -20,8 +20,8 @@ defineOptions({
name: "PipelineDetail", name: "PipelineDetail",
}); });
const route = useRoute(); const route = useRoute();
const pipelineId: Ref = ref(route.query.id); const pipelineId: Ref = ref(parseInt((route.query.id as string) || "0"));
const historyId = ref(route.query.historyId as string); const historyId: Ref = ref(parseInt((route.query.historyId as string) || "0"));
const pluginStore = usePluginStore(); const pluginStore = usePluginStore();
const pipelineOptions: PipelineOptions = { const pipelineOptions: PipelineOptions = {
async getPipelineDetail({ pipelineId }) { async getPipelineDetail({ pipelineId }) {
@@ -327,11 +327,11 @@ export default defineComponent({
}, },
props: { props: {
pipelineId: { pipelineId: {
type: [Number, String], type: Number,
default: 0, default: 0,
}, },
historyId: { historyId: {
type: [Number, String], type: Number,
default: 0, default: 0,
}, },
editMode: { editMode: {
@@ -348,6 +348,7 @@ export default defineComponent({
emits: ["update:modelValue", "update:editMode"], emits: ["update:modelValue", "update:editMode"],
setup(props, ctx) { setup(props, ctx) {
const { t } = useI18n(); const { t } = useI18n();
//pipeline
const currentPipeline: Ref<any> = ref({}); const currentPipeline: Ref<any> = ref({});
const pipeline: Ref<any> = ref({}); const pipeline: Ref<any> = ref({});
const pipelineEntity: Ref<any> = ref({}); const pipelineEntity: Ref<any> = ref({});
@@ -399,7 +400,7 @@ export default defineComponent({
currentPipeline.value = currentHistory.value.pipeline; currentPipeline.value = currentHistory.value.pipeline;
}; };
async function loadHistoryList(reload = false) { async function loadHistoryList(reload = false, historyId: number) {
if (props.editMode) { if (props.editMode) {
return; return;
} }
@@ -416,11 +417,11 @@ export default defineComponent({
histories.value = historyList; histories.value = historyList;
if (historyList.length > 0) { if (historyList.length > 0) {
//@ts-ignore if (historyId > 0) {
if (props.historyId > 0) { //history
const found = historyList.find(item => { const found = histories.value.find(item => {
//==int //==int
return item.id == props.historyId; return item.id == historyId;
}); });
if (found) { if (found) {
await changeCurrentHistory(found); await changeCurrentHistory(found);
@@ -428,7 +429,8 @@ export default defineComponent({
} }
} }
//@ts-ignore //@ts-ignore
if (historyList[0]?.version === pipeline.value.version) { if (historyList[0]?.version === pipeline.value?.version) {
//线current
await changeCurrentHistory(historyList[0]); await changeCurrentHistory(historyList[0]);
} }
} }
@@ -482,7 +484,7 @@ export default defineComponent({
if (editMode) { if (editMode) {
changeCurrentHistory(); changeCurrentHistory();
} else if (histories.value.length > 0) { } else if (histories.value.length > 0) {
if (histories.value[0].pipeline.version === pipeline.value.version) { if (histories.value[0].pipeline?.version === pipeline.value?.version) {
changeCurrentHistory(histories.value[0]); changeCurrentHistory(histories.value[0]);
} }
} }
@@ -508,7 +510,7 @@ export default defineComponent({
detail.pipeline detail.pipeline
); );
pipeline.value = currentPipeline.value; pipeline.value = currentPipeline.value;
await loadHistoryList(true); await loadHistoryList(true, props.historyId);
}, },
{ {
immediate: true, immediate: true,
@@ -740,7 +742,11 @@ export default defineComponent({
//@ts-ignore //@ts-ignore
await changeCurrentHistory(null); await changeCurrentHistory(null);
if (histories.value.length > 0) { if (histories.value.length > 0) {
pipeline.value = histories.value[0].pipeline; //pipeline
if (pipeline.value?.version !== histories.value[0].pipeline?.version) {
const detail: PipelineDetail = await props.options.getPipelineDetail({ pipelineId: pipeline.value.id });
pipeline.value = detail.pipeline;
}
} }
await props.options.doTrigger({ pipelineId: pipeline.value.id, stepId: stepId }); await props.options.doTrigger({ pipelineId: pipeline.value.id, stepId: stepId });
@@ -31,7 +31,8 @@ const iframeSrcRef = computed(() => {
if (!settingStore.installInfo.accountServerBaseUrl) { if (!settingStore.installInfo.accountServerBaseUrl) {
return "#/app/certd/home"; return "#/app/certd/home";
} }
return `${settingStore.installInfo.accountServerBaseUrl}/#/app/certd/home`; const timestamp = Date.now();
return `${settingStore.installInfo.accountServerBaseUrl}/#/app/certd/home?t=${timestamp}`;
}); });
type SubjectInfo = { type SubjectInfo = {
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.7](https://github.com/certd/certd/compare/v1.37.6...v1.37.7) (2025-11-12)
### Performance Improvements
* 支持腾讯云teo dns解析 ([1d23dd2](https://github.com/certd/certd/commit/1d23dd2426bd1e4c4dfea0a9e561d665e045ba9d))
## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10) ## [1.37.6](https://github.com/certd/certd/compare/v1.37.5...v1.37.6) (2025-11-10)
### Performance Improvements ### Performance Improvements
+14 -14
View File
@@ -1,6 +1,6 @@
{ {
"name": "@certd/ui-server", "name": "@certd/ui-server",
"version": "1.37.6", "version": "1.37.7",
"description": "fast-server base midway", "description": "fast-server base midway",
"private": true, "private": true,
"type": "module", "type": "module",
@@ -45,20 +45,20 @@
"@aws-sdk/client-cloudfront": "^3.699.0", "@aws-sdk/client-cloudfront": "^3.699.0",
"@aws-sdk/client-iam": "^3.699.0", "@aws-sdk/client-iam": "^3.699.0",
"@aws-sdk/client-s3": "^3.705.0", "@aws-sdk/client-s3": "^3.705.0",
"@certd/acme-client": "^1.37.6", "@certd/acme-client": "^1.37.7",
"@certd/basic": "^1.37.6", "@certd/basic": "^1.37.7",
"@certd/commercial-core": "^1.37.6", "@certd/commercial-core": "^1.37.7",
"@certd/cv4pve-api-javascript": "^8.4.2", "@certd/cv4pve-api-javascript": "^8.4.2",
"@certd/jdcloud": "^1.37.6", "@certd/jdcloud": "^1.37.7",
"@certd/lib-huawei": "^1.37.6", "@certd/lib-huawei": "^1.37.7",
"@certd/lib-k8s": "^1.37.6", "@certd/lib-k8s": "^1.37.7",
"@certd/lib-server": "^1.37.6", "@certd/lib-server": "^1.37.7",
"@certd/midway-flyway-js": "^1.37.6", "@certd/midway-flyway-js": "^1.37.7",
"@certd/pipeline": "^1.37.6", "@certd/pipeline": "^1.37.7",
"@certd/plugin-cert": "^1.37.6", "@certd/plugin-cert": "^1.37.7",
"@certd/plugin-lib": "^1.37.6", "@certd/plugin-lib": "^1.37.7",
"@certd/plugin-plus": "^1.37.6", "@certd/plugin-plus": "^1.37.7",
"@certd/plus-core": "^1.37.6", "@certd/plus-core": "^1.37.7",
"@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",
@@ -13,7 +13,7 @@ import { CnameRecordEntity, CnameRecordStatusType } from "../entity/cname-record
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 { getAuthoritativeDnsResolver, walkTxtRecord } from "@certd/acme-client"; import { getAuthoritativeDnsResolver, createChallengeFn } 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";
@@ -241,6 +241,8 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
* @param id * @param id
*/ */
async verify(id: number) { async verify(id: number) {
const {walkTxtRecord} = createChallengeFn({logger});
const bean = await this.info(id); const bean = await this.info(id);
if (!bean) { if (!bean) {
throw new ValidateException(`CnameRecord:${id} 不存在`); throw new ValidateException(`CnameRecord:${id} 不存在`);
@@ -416,6 +418,7 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
async checkRepeatAcmeChallengeRecords(acmeRecordDomain: string, targetCnameDomain: string) { async checkRepeatAcmeChallengeRecords(acmeRecordDomain: string, targetCnameDomain: string) {
let dnsResolver = null; let dnsResolver = null;
try { try {
dnsResolver = await getAuthoritativeDnsResolver(acmeRecordDomain); dnsResolver = await getAuthoritativeDnsResolver(acmeRecordDomain);
@@ -460,6 +463,9 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
//如果权威服务器中查不到txt,无需继续检查 //如果权威服务器中查不到txt,无需继续检查
return; return;
} }
const {walkTxtRecord} = createChallengeFn({logger});
if (cnameRecords.length > 0) { if (cnameRecords.length > 0) {
// 从cname记录中获取txt记录 // 从cname记录中获取txt记录
// 对比是否存在,如果不存在于cname中获取的txt中,说明本体有创建多余的txt记录 // 对比是否存在,如果不存在于cname中获取的txt中,说明本体有创建多余的txt记录
@@ -1,2 +1,3 @@
import './dnspod-dns-provider.js'; import './dnspod-dns-provider.js';
import './tencent-dns-provider.js'; import './tencent-dns-provider.js';
import './teo-dns-provider.js';
@@ -0,0 +1,145 @@
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from '@certd/plugin-cert';
import { TencentAccess } from '@certd/plugin-lib';
@IsDnsProvider({
name: 'tencent-eo',
title: '腾讯云EO DNS',
desc: '腾讯云EO DNS解析提供者',
accessType: 'tencent',
icon: 'svg:icon-tencentcloud',
})
export class TencentEoDnsProvider extends AbstractDnsProvider {
access!: TencentAccess;
client!: any;
async onInstance() {
this.access = this.ctx.access as TencentAccess
const clientConfig = {
credential: this.access,
region: '',
profile: {
httpProfile: {
endpoint: this.access.buildEndpoint("teo.tencentcloudapi.com"),
},
},
};
const teosdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/teo/v20220901/index.js');
const TeoClient = teosdk.v20220901.Client;
// 实例化要请求产品的client对象,clientProfile是可选的
this.client = new TeoClient(clientConfig);
}
async getZoneId(domain: string) {
const params = {
"Filters": [
{
"Name": "zone-name",
"Values": [
domain
]
}
]
};
const res = await this.client.DescribeZones(params);
if (res.Zones && res.Zones.length > 0) {
return res.Zones[0].ZoneId;
}
throw new Error('未找到对应的ZoneId');
}
async createRecord(options: CreateRecordOptions): Promise<any> {
const { fullRecord, value, type, domain } = options;
this.logger.info('添加域名解析:', fullRecord, value);
const zoneId = await this.getZoneId(domain);
const params = {
"ZoneId": zoneId,
"Name": fullRecord,
"Type": type,
"Content": value,
"TTL": 60,
};
try {
const ret = await this.client.CreateDnsRecord(params);
this.logger.info('添加域名解析成功:', fullRecord, value, JSON.stringify(ret));
/*
{
"RecordId": 162,
"RequestId": "ab4f1426-ea15-42ea-8183-dc1b44151166"
}
*/
return {
RecordId: ret.RecordId,
ZoneId: zoneId,
};
} catch (e: any) {
if (e?.code === 'ResourceInUse.DuplicateName') {
this.logger.info('域名解析已存在,无需重复添加:', fullRecord, value);
return await this.findRecord({
...options,
zoneId,
});
}
throw e;
}
}
async findRecord(options: CreateRecordOptions & { zoneId: string }): Promise<any> {
const { zoneId } = options;
const params = {
"ZoneId": zoneId,
"Filters": [
{
"Name": "name",
"Values": [
options.fullRecord
]
},
{
"Name": "content",
"Values": [
options.value
]
},
{
"Name": "type",
"Values": [
options.type
]
}
]
};
const ret = await this.client.DescribeRecordFilterList(params);
if (ret.DnsRecords && ret.DnsRecords.length > 0) {
this.logger.info('已存在解析记录:', ret.DnsRecords);
return ret.DnsRecords[0];
}
return {};
}
async removeRecord(options: RemoveRecordOptions<any>) {
const { fullRecord, value } = options.recordReq;
const record = options.recordRes;
if (!record) {
this.logger.info('解析记录recordId为空,不执行删除', fullRecord, value);
}
const params = {
"ZoneId": record.ZoneId,
"RecordIds": [
record.RecordId
]
};
const ret = await this.client.DeleteDnsRecords(params);
this.logger.info('删除域名解析成功:', fullRecord, value);
return ret;
}
}
new TencentEoDnsProvider();
+1 -1
View File
@@ -1 +1 @@
05:19 01:16