Merge branch 'v2-dev' into v2-dev-buy

# Conflicts:
#	packages/core/basic/src/utils/util.hash.ts
This commit is contained in:
xiaojunnuo
2025-09-24 01:58:11 +08:00
56 changed files with 869 additions and 246 deletions
+9
View File
@@ -3,6 +3,15 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.22](https://github.com/certd/certd/compare/v1.36.21...v1.36.22) (2025-09-23)
### Performance Improvements
* 7001绑定::地址 ([7188997](https://github.com/certd/certd/commit/7188997dd1979f1c10fa29b30221015e0bd5fe9e))
* 公共cname支持权限校验 ([9cc5f0f](https://github.com/certd/certd/commit/9cc5f0f889d4362ff36e7a1f0e448e02d32ecee7))
* dns支持新网域名解析 ([cf3a78e](https://github.com/certd/certd/commit/cf3a78e1145ff0505c87fbc485d9e731b1aa88a8))
* gcore flush plugin ssl_id改为必填项 ([4b90972](https://github.com/certd/certd/commit/4b909723411c57505aa13b07d8699fb9ac77c937))
## [1.36.21](https://github.com/certd/certd/compare/v1.36.20...v1.36.21) (2025-09-15)
**Note:** Version bump only for package @certd/ui-server
+14 -14
View File
@@ -1,6 +1,6 @@
{
"name": "@certd/ui-server",
"version": "1.36.21",
"version": "1.36.22",
"description": "fast-server base midway",
"private": true,
"type": "module",
@@ -43,20 +43,20 @@
"@aws-sdk/client-cloudfront": "^3.699.0",
"@aws-sdk/client-iam": "^3.699.0",
"@aws-sdk/client-s3": "^3.705.0",
"@certd/acme-client": "^1.36.21",
"@certd/basic": "^1.36.21",
"@certd/commercial-core": "^1.36.21",
"@certd/acme-client": "^1.36.22",
"@certd/basic": "^1.36.22",
"@certd/commercial-core": "^1.36.22",
"@certd/cv4pve-api-javascript": "^8.4.2",
"@certd/jdcloud": "^1.36.21",
"@certd/lib-huawei": "^1.36.21",
"@certd/lib-k8s": "^1.36.21",
"@certd/lib-server": "^1.36.21",
"@certd/midway-flyway-js": "^1.36.21",
"@certd/pipeline": "^1.36.21",
"@certd/plugin-cert": "^1.36.21",
"@certd/plugin-lib": "^1.36.21",
"@certd/plugin-plus": "^1.36.21",
"@certd/plus-core": "^1.36.21",
"@certd/jdcloud": "^1.36.22",
"@certd/lib-huawei": "^1.36.22",
"@certd/lib-k8s": "^1.36.22",
"@certd/lib-server": "^1.36.22",
"@certd/midway-flyway-js": "^1.36.22",
"@certd/pipeline": "^1.36.22",
"@certd/plugin-cert": "^1.36.22",
"@certd/plugin-lib": "^1.36.22",
"@certd/plugin-plus": "^1.36.22",
"@certd/plus-core": "^1.36.22",
"@huaweicloud/huaweicloud-sdk-cdn": "^3.1.120",
"@huaweicloud/huaweicloud-sdk-core": "^3.1.120",
"@koa/cors": "^5.0.0",
@@ -21,6 +21,7 @@ import { DomainParser } from "@certd/plugin-cert/dist/dns-provider/domain-parser
import punycode from "punycode.js";
import { SubDomainService } from "../../pipeline/service/sub-domain-service.js";
import { SubDomainsGetter } from "../../pipeline/service/getter/sub-domain-getter.js";
import { TaskServiceBuilder } from "../../pipeline/service/getter/task-service-getter.js";
type CnameCheckCacheValue = {
validating: boolean;
@@ -55,6 +56,10 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
@Inject()
subDomainService: SubDomainService;
@Inject()
taskServiceBuilder: TaskServiceBuilder;
//@ts-ignore
getRepository() {
return this.repository;
@@ -250,8 +255,9 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
});
}
const serviceGetter = this.taskServiceBuilder.create({userId:cnameProvider.userId})
const access = await this.accessService.getById(cnameProvider.accessId, cnameProvider.userId);
const context = {access, logger, http, utils, domainParser};
const context = {access, logger, http, utils, domainParser,serviceGetter};
const dnsProvider: IDnsProvider = await createDnsProvider({
dnsProviderType: cnameProvider.dnsProviderType,
context,
@@ -10,6 +10,9 @@ import { DomainVerifierGetter } from "./domain-verifier-getter.js";
import { DomainService } from "../../../cert/service/domain-service.js";
import { SubDomainService } from "../sub-domain-service.js";
const serviceNames = [
'ocrService',
]
export class TaskServiceGetter implements IServiceGetter{
private userId: number;
private appCtx : IMidwayContainer;
@@ -29,8 +32,14 @@ export class TaskServiceGetter implements IServiceGetter{
return await this.getNotificationService() as T
} else if (serviceName === 'domainVerifierGetter') {
return await this.getDomainVerifierGetter() as T
}else{
throw new Error(`service ${serviceName} not found`)
} else{
if(!serviceNames.includes(serviceName)){
throw new Error(`${serviceName} not in whitelist`)
}
const service = await this.appCtx.getAsync(serviceName)
if (! service){
throw new Error(`${serviceName} not found`)
}
}
}
@@ -36,3 +36,4 @@ export * from './plugin-apisix/index.js'
export * from './plugin-dokploy/index.js'
export * from './plugin-godaddy/index.js'
export * from './plugin-captcha/index.js'
export * from './plugin-xinnet/index.js'
@@ -0,0 +1,79 @@
import { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline";
import { XinnetClient } from "@certd/plugin-plus";
/**
* 这个注解将注册一个授权配置
* 在certd的后台管理系统中,用户可以选择添加此类型的授权
*/
@IsAccess({
name: "xinnet",
title: "新网授权",
icon: "lsicon:badge-new-filled",
desc: ""
})
export class XinnetAccess extends BaseAccess {
/**
* 授权属性配置
*/
@AccessInput({
title: "用户名",
component: {
placeholder: "手机号/用户名"
},
required: true,
encrypt: true
})
username = "";
@AccessInput({
title: "登录密码",
component: {
name: "a-input-password",
vModel: "value",
placeholder: "登录密码"
},
required: true,
encrypt: true
})
password = "";
@AccessInput({
title: "测试",
component: {
name: "api-test",
action: "TestRequest"
},
helper: "点击测试接口是否正常"
})
testRequest = true;
async onTestRequest() {
const client = new XinnetClient({
access: this,
logger: this.ctx.logger,
http: this.ctx.http
});
await client.getDomainList({ pageNo: 1, pageSize: 1 });
return "ok";
}
getCacheKey () {
let hashStr = ""
for (const key in this) {
if (Object.prototype.hasOwnProperty.call(this, key)) {
const element = this[key];
hashStr += element;
}
}
const hashCode = this.ctx.utils.hash.sha256(hashStr);
return `xinnet-${hashCode}`;
}
}
new XinnetAccess();
@@ -0,0 +1,110 @@
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from "@certd/plugin-cert";
import { XinnetAccess } from "./access.js";
import { XinnetClient } from "@certd/plugin-plus";
export type XinnetRecord = {
recordId: number;
recordFullName: string;
recordValue: string;
type: string;
serviceCode: string;
dcpCookie: string;
};
// 这里通过IsDnsProvider注册一个dnsProvider
@IsDnsProvider({
name: "xinnet",
title: "新网",
desc: "新网域名解析",
icon: "lsicon:badge-new-filled",
// 这里是对应的 cloudflare的access类型名称
accessType: "xinnet",
order: 7
})
export class XinnetProvider extends AbstractDnsProvider<XinnetRecord> {
access!: XinnetAccess;
async onInstance() {
//一些初始化的操作
// 也可以通过ctx成员变量传递context
this.access = this.ctx.access as XinnetAccess;
}
/**
* 创建dns解析记录,用于验证域名所有权
*/
async createRecord(options: CreateRecordOptions): Promise<XinnetRecord> {
/**
* fullRecord: '_acme-challenge.test.example.com',
* value: 一串uuid
* type: 'TXT',
* domain: 'example.com'
*/
const { fullRecord, hostRecord, value, type, domain } = options;
this.logger.info("添加域名解析:", fullRecord, value, type, domain);
const client = new XinnetClient({
logger: this.logger,
access: this.access,
http: this.http
});
const res = await client.getDomainList({
searchKey: domain
});
if (!res.list || res.list.length == 0) {
throw new Error("域名不存在");
}
const serviceCode = res.list[0].serviceCode;
const dcpCookie = await client.getDcpCookie({
serviceCode
});
const recordRes = await client.addDomainDnsRecord({
recordName: hostRecord,
type: type,
recordValue: value
}, {
dcpCookie,
serviceCode
});
return {
...recordRes,
serviceCode,
dcpCookie
};
}
/**
* 删除dns解析记录,清理申请痕迹
* @param options
*/
async removeRecord(options: RemoveRecordOptions<XinnetRecord>): Promise<void> {
const client = new XinnetClient({
logger: this.logger,
access: this.access,
http: this.http
});
const recordRes = options.recordRes;
let dcpCookie = recordRes.dcpCookie;
if (!dcpCookie) {
dcpCookie = await client.getDcpCookie({
serviceCode: recordRes.serviceCode
});
}
await client.deleteDomainDnsRecord(recordRes, {
dcpCookie,
serviceCode: recordRes.serviceCode
});
}
}
//实例化这个provider,将其自动注册到系统中
new XinnetProvider();
@@ -0,0 +1,2 @@
export * from './dns-provider.js';
export * from './access.js';