Merge branch 'v2-dev' into v2

This commit is contained in:
xiaojunnuo
2025-11-13 01:17:55 +08:00
47 changed files with 460 additions and 144 deletions
+7
View File
@@ -3,6 +3,13 @@
All notable changes to this project will be documented in this file.
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)
### Bug Fixes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@certd/ui-client",
"version": "1.37.6",
"version": "1.37.7",
"private": true,
"scripts": {
"dev": "vite --open",
@@ -106,8 +106,8 @@
"zod-defaults": "^0.1.3"
},
"devDependencies": {
"@certd/lib-iframe": "^1.37.6",
"@certd/pipeline": "^1.37.6",
"@certd/lib-iframe": "^1.37.7",
"@certd/pipeline": "^1.37.7",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"@types/chai": "^4.3.12",
@@ -97,6 +97,6 @@ export default {
already_comm: "已经是商业版了,不能降级为专业版",
already_perpetual_plus: "您已经是永久专业版了,无法继续升级",
confirm: "确认",
not_effective: "没有生效?",
not_effective: "VIP没有生效?",
learn_more: "更多特权(加VIP群等)",
};
@@ -20,8 +20,8 @@ defineOptions({
name: "PipelineDetail",
});
const route = useRoute();
const pipelineId: Ref = ref(route.query.id);
const historyId = ref(route.query.historyId as string);
const pipelineId: Ref = ref(parseInt((route.query.id as string) || "0"));
const historyId: Ref = ref(parseInt((route.query.historyId as string) || "0"));
const pluginStore = usePluginStore();
const pipelineOptions: PipelineOptions = {
async getPipelineDetail({ pipelineId }) {
@@ -327,11 +327,11 @@ export default defineComponent({
},
props: {
pipelineId: {
type: [Number, String],
type: Number,
default: 0,
},
historyId: {
type: [Number, String],
type: Number,
default: 0,
},
editMode: {
@@ -348,6 +348,7 @@ export default defineComponent({
emits: ["update:modelValue", "update:editMode"],
setup(props, ctx) {
const { t } = useI18n();
//右侧选中的pipeline
const currentPipeline: Ref<any> = ref({});
const pipeline: Ref<any> = ref({});
const pipelineEntity: Ref<any> = ref({});
@@ -399,7 +400,7 @@ export default defineComponent({
currentPipeline.value = currentHistory.value.pipeline;
};
async function loadHistoryList(reload = false) {
async function loadHistoryList(reload = false, historyId: number) {
if (props.editMode) {
return;
}
@@ -416,11 +417,11 @@ export default defineComponent({
histories.value = historyList;
if (historyList.length > 0) {
//@ts-ignore
if (props.historyId > 0) {
const found = historyList.find(item => {
if (historyId > 0) {
//如果传递了history,优先显示历史记录作为当前
const found = histories.value.find(item => {
//字符串==int
return item.id == props.historyId;
return item.id == historyId;
});
if (found) {
await changeCurrentHistory(found);
@@ -428,7 +429,8 @@ export default defineComponent({
}
}
//@ts-ignore
if (historyList[0]?.version === pipeline.value.version) {
if (historyList[0]?.version === pipeline.value?.version) {
//如果当前的流水线版本与历史记录最后一条一致,则将该记录设置为current
await changeCurrentHistory(historyList[0]);
}
}
@@ -482,7 +484,7 @@ export default defineComponent({
if (editMode) {
changeCurrentHistory();
} 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]);
}
}
@@ -508,7 +510,7 @@ export default defineComponent({
detail.pipeline
);
pipeline.value = currentPipeline.value;
await loadHistoryList(true);
await loadHistoryList(true, props.historyId);
},
{
immediate: true,
@@ -740,7 +742,11 @@ export default defineComponent({
//@ts-ignore
await changeCurrentHistory(null);
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 });
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
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)
### Performance Improvements
+14 -14
View File
@@ -1,6 +1,6 @@
{
"name": "@certd/ui-server",
"version": "1.37.6",
"version": "1.37.7",
"description": "fast-server base midway",
"private": true,
"type": "module",
@@ -45,20 +45,20 @@
"@aws-sdk/client-cloudfront": "^3.699.0",
"@aws-sdk/client-iam": "^3.699.0",
"@aws-sdk/client-s3": "^3.705.0",
"@certd/acme-client": "^1.37.6",
"@certd/basic": "^1.37.6",
"@certd/commercial-core": "^1.37.6",
"@certd/acme-client": "^1.37.7",
"@certd/basic": "^1.37.7",
"@certd/commercial-core": "^1.37.7",
"@certd/cv4pve-api-javascript": "^8.4.2",
"@certd/jdcloud": "^1.37.6",
"@certd/lib-huawei": "^1.37.6",
"@certd/lib-k8s": "^1.37.6",
"@certd/lib-server": "^1.37.6",
"@certd/midway-flyway-js": "^1.37.6",
"@certd/pipeline": "^1.37.6",
"@certd/plugin-cert": "^1.37.6",
"@certd/plugin-lib": "^1.37.6",
"@certd/plugin-plus": "^1.37.6",
"@certd/plus-core": "^1.37.6",
"@certd/jdcloud": "^1.37.7",
"@certd/lib-huawei": "^1.37.7",
"@certd/lib-k8s": "^1.37.7",
"@certd/lib-server": "^1.37.7",
"@certd/midway-flyway-js": "^1.37.7",
"@certd/pipeline": "^1.37.7",
"@certd/plugin-cert": "^1.37.7",
"@certd/plugin-lib": "^1.37.7",
"@certd/plugin-plus": "^1.37.7",
"@certd/plus-core": "^1.37.7",
"@huaweicloud/huaweicloud-sdk-cdn": "^3.1.120",
"@huaweicloud/huaweicloud-sdk-core": "^3.1.120",
"@koa/cors": "^5.0.0",
@@ -13,7 +13,7 @@ import { CnameRecordEntity, CnameRecordStatusType } from "../entity/cname-record
import { createDnsProvider, IDnsProvider } from "@certd/plugin-cert";
import { CnameProvider, CnameRecord } from "@certd/pipeline";
import { cache, http, isDev, logger, utils } from "@certd/basic";
import { getAuthoritativeDnsResolver, walkTxtRecord } from "@certd/acme-client";
import { getAuthoritativeDnsResolver, createChallengeFn } from "@certd/acme-client";
import { CnameProviderService } from "./cname-provider-service.js";
import { CnameProviderEntity } from "../entity/cname-provider.js";
import { CommonDnsProvider } from "./common-provider.js";
@@ -241,6 +241,8 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
* @param id
*/
async verify(id: number) {
const {walkTxtRecord} = createChallengeFn({logger});
const bean = await this.info(id);
if (!bean) {
throw new ValidateException(`CnameRecord:${id} 不存在`);
@@ -416,6 +418,7 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
async checkRepeatAcmeChallengeRecords(acmeRecordDomain: string, targetCnameDomain: string) {
let dnsResolver = null;
try {
dnsResolver = await getAuthoritativeDnsResolver(acmeRecordDomain);
@@ -460,6 +463,9 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
//如果权威服务器中查不到txt,无需继续检查
return;
}
const {walkTxtRecord} = createChallengeFn({logger});
if (cnameRecords.length > 0) {
// 从cname记录中获取txt记录
// 对比是否存在,如果不存在于cname中获取的txt中,说明本体有创建多余的txt记录
@@ -1,2 +1,3 @@
import './dnspod-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();