diff --git a/packages/core/pipeline/src/context/index.ts b/packages/core/pipeline/src/context/index.ts index 0dd6b147..2d987bc0 100644 --- a/packages/core/pipeline/src/context/index.ts +++ b/packages/core/pipeline/src/context/index.ts @@ -21,9 +21,9 @@ export type PageRes = { export class Pager { pageNo: number; pageSize: number; - constructor(req: PageSearch) { - this.pageNo = req.pageNo ?? 1; - this.pageSize = req.pageSize || 50; + constructor(req?: PageSearch) { + this.pageNo = req?.pageNo ?? 1; + this.pageSize = req?.pageSize || 50; } getOffset() { diff --git a/packages/ui/certd-server/db/migration/v10028__fix_suite.sql b/packages/ui/certd-server/db/migration/v10028__fix_suite.sql index 521d76e8..e69de29b 100644 --- a/packages/ui/certd-server/db/migration/v10028__fix_suite.sql +++ b/packages/ui/certd-server/db/migration/v10028__fix_suite.sql @@ -1 +0,0 @@ -update cd_user_suite set is_empty = false where is_empty is null; diff --git a/packages/ui/certd-server/src/plugins/index.ts b/packages/ui/certd-server/src/plugins/index.ts index 8157b61d..92da08bc 100644 --- a/packages/ui/certd-server/src/plugins/index.ts +++ b/packages/ui/certd-server/src/plugins/index.ts @@ -34,3 +34,4 @@ export * from './plugin-admin/index.js' export * from './plugin-ksyun/index.js' export * from './plugin-apisix/index.js' export * from './plugin-dokploy/index.js' +export * from './plugin-godaddy/index.js' diff --git a/packages/ui/certd-server/src/plugins/plugin-godaddy/access.ts b/packages/ui/certd-server/src/plugins/plugin-godaddy/access.ts new file mode 100644 index 00000000..45f41ff7 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-godaddy/access.ts @@ -0,0 +1,96 @@ +import {AccessInput, BaseAccess, IsAccess, Pager, PageSearch} from '@certd/pipeline'; +import {HttpRequestConfig} from "@certd/basic"; + +/** + * 这个注解将注册一个授权配置 + * 在certd的后台管理系统中,用户可以选择添加此类型的授权 + */ +@IsAccess({ + name: 'godaddy', + title: 'godaddy授权', + icon: 'arcticons:dns-changer-3', + desc: '', +}) +export class GodaddyAccess extends BaseAccess { + /** + * 授权属性配置 + */ + @AccessInput({ + title: 'Key', + component: { + placeholder: '授权key', + }, + helper:"[https://developer.godaddy.com/keys](https://developer.godaddy.com/keys),创建key(选择product,不要选择ote)", + required: true, + encrypt: false, + }) + key = ''; + + @AccessInput({ + title: 'Secret', + component: { + name:"a-input-password", + vModel:"value", + }, + required: true, + encrypt: true, + }) + secret = ''; + + @AccessInput({ + title: 'HTTP代理', + component: { + placeholder: 'http://xxxxx:xx', + }, + helper: '使用https_proxy', + required: false, + }) + httpProxy = ''; + + @AccessInput({ + title: "测试", + component: { + name: "api-test", + action: "TestRequest" + }, + helper: "点击测试接口是否正常(注意账号中必须要有50个域名才能使用API接口)" + }) + testRequest = true; + + async onTestRequest() { + const res = await this.getDomainList({pageSize:1}); + this.ctx.logger.info(res) + return "ok" + } + + + async getDomainList(opts?: PageSearch){ + + const pager = new Pager(opts); + const req = { + url :`/v1/domains?limit=${pager.pageSize}`, + method: "get", + } + return await this.doRequest(req); + } + + + async doRequest(req: HttpRequestConfig){ + const headers = { + "Authorization": `sso-key ${this.key}:${this.secret}`, + ...req.headers + }; + return await this.ctx.http.request({ + headers, + baseURL: "https://api.godaddy.com", + ...req, + logRes: true, + httpProxy: this.httpProxy, + }); + } + + + +} + +new GodaddyAccess(); diff --git a/packages/ui/certd-server/src/plugins/plugin-godaddy/dns-provider.ts b/packages/ui/certd-server/src/plugins/plugin-godaddy/dns-provider.ts new file mode 100644 index 00000000..f8bcc972 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-godaddy/dns-provider.ts @@ -0,0 +1,90 @@ +import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from "@certd/plugin-cert"; + +import { GodaddyAccess } from "./access.js"; + +export type GodaddyRecord = { + domain: string, + type: string, + name: string, + data: string, +}; + +// 这里通过IsDnsProvider注册一个dnsProvider +@IsDnsProvider({ + name: 'godaddy', + title: 'godaddy', + desc: 'GoDaddy', + icon: 'arcticons:dns-changer-3', + // 这里是对应的 cloudflare的access类型名称 + accessType: 'godaddy', + order:10, +}) +export class GodaddyDnsProvider extends AbstractDnsProvider { + access!: GodaddyAccess; + async onInstance() { + //一些初始化的操作 + // 也可以通过ctx成员变量传递context + this.access = this.ctx.access as GodaddyAccess; + } + + /** + * 创建dns解析记录,用于验证域名所有权 + */ + async createRecord(options: CreateRecordOptions): Promise { + /** + * fullRecord: '_acme-challenge.test.example.com', + * value: 一串uuid + * type: 'TXT', + * domain: 'example.com' + * hostRecord: _acme-challenge.test + */ + const { fullRecord,hostRecord, value, type, domain } = options; + this.logger.info('添加域名解析:', fullRecord, value, type, domain); + + + const res = await this.access.doRequest({ + method: 'PATCH', + url: '/v1/domains/'+domain+'/records', + data: [ + { + type: 'TXT', + name: hostRecord, + data: value, + ttl: 600, + } + ] + }) + this.logger.info('添加域名解析成功:', res); + return { + domain: domain, + type: 'TXT', + name: hostRecord, + data: value, + }; + } + + + /** + * 删除dns解析记录,清理申请痕迹 + * @param options + */ + async removeRecord(options: RemoveRecordOptions): Promise { + const { fullRecord, value } = options.recordReq; + const record = options.recordRes; + this.logger.info('删除域名解析:', fullRecord, value); + if (!record) { + this.logger.info('record为空,不执行删除'); + return; + } + //这里调用删除txt dns解析记录接口 + const {name,type,domain} = record + const res = await this.access.doRequest({ + method: 'DELETE', + url: '/v1/domains/'+domain+`/records/${type}/${name}`, + }) + this.logger.info(`删除域名解析成功:fullRecord=${fullRecord},id=${res}`); + } +} + +//实例化这个provider,将其自动注册到系统中 +new GodaddyDnsProvider(); diff --git a/packages/ui/certd-server/src/plugins/plugin-godaddy/index.ts b/packages/ui/certd-server/src/plugins/plugin-godaddy/index.ts new file mode 100644 index 00000000..db899c71 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-godaddy/index.ts @@ -0,0 +1,2 @@ +export * from './dns-provider.js'; +export * from './access.js';