mirror of https://github.com/certd/certd
				
				
				
			fix: 修复中文域名使用cname方式校验无法通过的问题
							parent
							
								
									6ff509d263
								
							
						
					
					
						commit
						f7d5baa6d0
					
				| 
						 | 
				
			
			@ -27,7 +27,7 @@
 | 
			
		|||
        "https-proxy-agent": "^7.0.5",
 | 
			
		||||
        "lodash-es": "^4.17.21",
 | 
			
		||||
        "node-forge": "^1.3.1",
 | 
			
		||||
        "punycode": "^2.3.1"
 | 
			
		||||
        "punycode.js": "^2.3.1"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@types/node": "^20.14.10",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,7 @@
 | 
			
		|||
    "jszip": "^3.10.1",
 | 
			
		||||
    "lodash-es": "^4.17.21",
 | 
			
		||||
    "psl": "^1.9.0",
 | 
			
		||||
    "punycode": "^2.3.1",
 | 
			
		||||
    "punycode.js": "^2.3.1",
 | 
			
		||||
    "rimraf": "^5.0.5"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,9 +29,25 @@ export type DnsProviderContext = {
 | 
			
		|||
 | 
			
		||||
export interface IDnsProvider<T = any> {
 | 
			
		||||
  onInstance(): Promise<void>;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 中文转英文
 | 
			
		||||
   * @param domain
 | 
			
		||||
   */
 | 
			
		||||
  punyCodeEncode(domain: string): string;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 转中文域名
 | 
			
		||||
   * @param domain
 | 
			
		||||
   */
 | 
			
		||||
  punyCodeDecode(domain: string): string;
 | 
			
		||||
 | 
			
		||||
  createRecord(options: CreateRecordOptions): Promise<T>;
 | 
			
		||||
 | 
			
		||||
  removeRecord(options: RemoveRecordOptions<T>): Promise<void>;
 | 
			
		||||
 | 
			
		||||
  setCtx(ctx: DnsProviderContext): void;
 | 
			
		||||
 | 
			
		||||
  //中文域名是否需要punycode转码,如果返回True,则使用punycode来添加解析记录,否则使用中文域名添加解析记录
 | 
			
		||||
  usePunyCode(): boolean;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
import { CreateRecordOptions, DnsProviderContext, DnsProviderDefine, IDnsProvider, RemoveRecordOptions } from "./api.js";
 | 
			
		||||
import { dnsProviderRegistry } from "./registry.js";
 | 
			
		||||
import { HttpClient, ILogger } from "@certd/basic";
 | 
			
		||||
 | 
			
		||||
import punycode from "punycode.js";
 | 
			
		||||
export abstract class AbstractDnsProvider<T = any> implements IDnsProvider<T> {
 | 
			
		||||
  ctx!: DnsProviderContext;
 | 
			
		||||
  http!: HttpClient;
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +13,22 @@ export abstract class AbstractDnsProvider<T = any> implements IDnsProvider<T> {
 | 
			
		|||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 中文转英文
 | 
			
		||||
   * @param domain
 | 
			
		||||
   */
 | 
			
		||||
  punyCodeEncode(domain: string) {
 | 
			
		||||
    return punycode.toASCII(domain);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 转中文域名
 | 
			
		||||
   * @param domain
 | 
			
		||||
   */
 | 
			
		||||
  punyCodeDecode(domain: string) {
 | 
			
		||||
    return punycode.toUnicode(domain);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  setCtx(ctx: DnsProviderContext) {
 | 
			
		||||
    this.ctx = ctx;
 | 
			
		||||
    this.logger = ctx.logger;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ import { Challenge } from "@certd/acme-client/types/rfc8555";
 | 
			
		|||
import { IContext } from "@certd/pipeline";
 | 
			
		||||
import { ILogger, utils } from "@certd/basic";
 | 
			
		||||
import { IDnsProvider, IDomainParser } from "../../dns-provider/index.js";
 | 
			
		||||
import punycode from "node:punycode";
 | 
			
		||||
import punycode from "punycode.js";
 | 
			
		||||
import { IOssClient } from "@certd/plugin-lib";
 | 
			
		||||
export type CnameVerifyPlan = {
 | 
			
		||||
  type?: string;
 | 
			
		||||
| 
						 | 
				
			
			@ -233,16 +233,18 @@ export class AcmeService {
 | 
			
		|||
    let dnsProvider = providers.dnsProvider;
 | 
			
		||||
    let fullRecord = `_acme-challenge.${fullDomain}`;
 | 
			
		||||
 | 
			
		||||
    const origDomain = punycode.toUnicode(domain);
 | 
			
		||||
    const origFullDomain = punycode.toUnicode(fullDomain);
 | 
			
		||||
    if (providers.domainsVerifyPlan) {
 | 
			
		||||
      //按照计划执行
 | 
			
		||||
      const domainVerifyPlan = providers.domainsVerifyPlan[domain];
 | 
			
		||||
      const domainVerifyPlan = providers.domainsVerifyPlan[origDomain];
 | 
			
		||||
      if (domainVerifyPlan) {
 | 
			
		||||
        if (domainVerifyPlan.type === "dns") {
 | 
			
		||||
          dnsProvider = domainVerifyPlan.dnsProvider;
 | 
			
		||||
        } else if (domainVerifyPlan.type === "cname") {
 | 
			
		||||
          const cnameVerifyPlan = domainVerifyPlan.cnameVerifyPlan;
 | 
			
		||||
          if (cnameVerifyPlan) {
 | 
			
		||||
            const cname = cnameVerifyPlan[fullDomain];
 | 
			
		||||
            const cname = cnameVerifyPlan[origFullDomain];
 | 
			
		||||
            if (cname) {
 | 
			
		||||
              dnsProvider = cname.dnsProvider;
 | 
			
		||||
              domain = await this.options.domainParser.parse(cname.domain);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,8 +26,8 @@
 | 
			
		|||
      <fs-button v-if="settingsStore.sysPublic.aiChatEnabled !== false" key="aiChat" :tooltip="{ title: 'AI分析异常' }" type="primary" icon="ion:color-wand-outline" @click="taskModal.onAiChat">AI分析</fs-button>
 | 
			
		||||
      <fs-button key="rerun" type="primary" :tooltip="{ title: '强制重新执行此步骤' }" text="重新运行" icon="icon-park-outline:replay-music" @click="triggerRun(activeKey)"></fs-button>
 | 
			
		||||
      <fs-button key="downloadLogs" type="primary" :tooltip="{ title: '当前任务日志下载' }" icon="ion:arrow-down-circle-outline" @click="taskModal.onDownloadLogs">下载日志</fs-button>
 | 
			
		||||
      <!--      <fs-button key="cancel" icon="ion:close-circle-outline" @click="taskModal.onOk">关闭</fs-button>-->
 | 
			
		||||
      <fs-button key="submit" :tooltip="{ title: '关闭窗口' }" icon="ion:checkmark-circle-outline" type="primary" @click="taskModal.onOk">确定</fs-button>
 | 
			
		||||
      <fs-button key="cancel" :tooltip="{ title: '关闭窗口' }" icon="ion:close-circle-outline" @click="taskModal.onOk">关闭</fs-button>
 | 
			
		||||
      <!--      <fs-button key="submit" :tooltip="{ title: '关闭窗口' }" icon="ion:checkmark-circle-outline" type="primary" @click="taskModal.onOk">确定</fs-button>-->
 | 
			
		||||
    </template>
 | 
			
		||||
  </a-modal>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,6 +44,7 @@
 | 
			
		|||
    "@certd/acme-client": "^1.34.10",
 | 
			
		||||
    "@certd/basic": "^1.34.10",
 | 
			
		||||
    "@certd/commercial-core": "^1.34.10",
 | 
			
		||||
    "@certd/cv4pve-api-javascript": "^8.4.1",
 | 
			
		||||
    "@certd/jdcloud": "^1.34.10",
 | 
			
		||||
    "@certd/lib-huawei": "^1.34.10",
 | 
			
		||||
    "@certd/lib-k8s": "^1.34.10",
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +55,6 @@
 | 
			
		|||
    "@certd/plugin-lib": "^1.34.10",
 | 
			
		||||
    "@certd/plugin-plus": "^1.34.10",
 | 
			
		||||
    "@certd/plus-core": "^1.34.10",
 | 
			
		||||
    "@certd/cv4pve-api-javascript": "^8.4.1",
 | 
			
		||||
    "@huaweicloud/huaweicloud-sdk-cdn": "^3.1.120",
 | 
			
		||||
    "@huaweicloud/huaweicloud-sdk-core": "^3.1.120",
 | 
			
		||||
    "@koa/cors": "^5.0.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -104,6 +104,7 @@
 | 
			
		|||
    "otplib": "^12.0.1",
 | 
			
		||||
    "pg": "^8.12.0",
 | 
			
		||||
    "psl": "^1.9.0",
 | 
			
		||||
    "punycode.js": "^2.3.1",
 | 
			
		||||
    "qiniu": "^7.12.0",
 | 
			
		||||
    "qrcode": "^1.5.4",
 | 
			
		||||
    "qs": "^6.13.1",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,7 @@ import {CnameProviderEntity} from '../entity/cname-provider.js';
 | 
			
		|||
import {CommonDnsProvider} from './common-provider.js';
 | 
			
		||||
import {SubDomainService, SubDomainsGetter} from "../../pipeline/service/sub-domain-service.js";
 | 
			
		||||
import {DomainParser} from "@certd/plugin-cert/dist/dns-provider/domain-parser.js";
 | 
			
		||||
 | 
			
		||||
import punycode from 'punycode.js'
 | 
			
		||||
type CnameCheckCacheValue = {
 | 
			
		||||
  validating: boolean;
 | 
			
		||||
  pass: boolean;
 | 
			
		||||
| 
						 | 
				
			
			@ -317,7 +317,15 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
 | 
			
		|||
      type: 'TXT',
 | 
			
		||||
      value: testRecordValue,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const dnsProvider = await buildDnsProvider();
 | 
			
		||||
    if(dnsProvider.usePunyCode()){
 | 
			
		||||
      //是否需要中文转英文
 | 
			
		||||
      req.domain = dnsProvider.punyCodeEncode(req.domain)
 | 
			
		||||
      req.fullRecord = dnsProvider.punyCodeEncode(req.fullRecord)
 | 
			
		||||
      req.hostRecord = dnsProvider.punyCodeEncode(req.hostRecord)
 | 
			
		||||
      req.value = dnsProvider.punyCodeEncode(req.value)
 | 
			
		||||
    }
 | 
			
		||||
    const recordRes = await dnsProvider.createRecord(req);
 | 
			
		||||
    value.dnsProvider = dnsProvider;
 | 
			
		||||
    value.validating = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -364,6 +372,7 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
 | 
			
		|||
      return
 | 
			
		||||
    }
 | 
			
		||||
    targetCnameDomain = targetCnameDomain.toLowerCase()
 | 
			
		||||
    targetCnameDomain = punycode.toASCII(targetCnameDomain)
 | 
			
		||||
    if (cnameRecords.length > 0) {
 | 
			
		||||
      for (const cnameRecord of cnameRecords) {
 | 
			
		||||
        if(cnameRecord.toLowerCase() !== targetCnameDomain){
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
import {CreateRecordOptions, DnsProviderContext, IDnsProvider, RemoveRecordOptions} from '@certd/plugin-cert';
 | 
			
		||||
import {PlusService} from '@certd/lib-server';
 | 
			
		||||
 | 
			
		||||
import punycode from 'punycode.js'
 | 
			
		||||
export type CommonCnameProvider = {
 | 
			
		||||
  id: number;
 | 
			
		||||
  domain: string;
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +24,23 @@ export class CommonDnsProvider implements IDnsProvider {
 | 
			
		|||
    this.plusService = opts.plusService;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 中文转英文
 | 
			
		||||
   * @param domain
 | 
			
		||||
   */
 | 
			
		||||
  punyCodeEncode(domain: string) {
 | 
			
		||||
    return punycode.encode(domain);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 转中文域名
 | 
			
		||||
   * @param domain
 | 
			
		||||
   */
 | 
			
		||||
  punyCodeDecode(domain: string) {
 | 
			
		||||
    return punycode.decode(domain);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  usePunyCode(): boolean {
 | 
			
		||||
    return false
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,11 @@ export type CloudflareRecord = {
 | 
			
		|||
})
 | 
			
		||||
export class CloudflareDnsProvider extends AbstractDnsProvider<CloudflareRecord> {
 | 
			
		||||
  access!: CloudflareAccess;
 | 
			
		||||
  usePunyCode(): boolean {
 | 
			
		||||
    //是否使用punycode来添加解析记录
 | 
			
		||||
    //默认都使用原始中文域名来添加
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  async onInstance() {
 | 
			
		||||
    //一些初始化的操作
 | 
			
		||||
    // 也可以通过ctx成员变量传递context
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,7 +72,7 @@ importers:
 | 
			
		|||
      node-forge:
 | 
			
		||||
        specifier: ^1.3.1
 | 
			
		||||
        version: 1.3.1
 | 
			
		||||
      punycode:
 | 
			
		||||
      punycode.js:
 | 
			
		||||
        specifier: ^2.3.1
 | 
			
		||||
        version: 2.3.1
 | 
			
		||||
    devDependencies:
 | 
			
		||||
| 
						 | 
				
			
			@ -633,7 +633,7 @@ importers:
 | 
			
		|||
      psl:
 | 
			
		||||
        specifier: ^1.9.0
 | 
			
		||||
        version: 1.15.0
 | 
			
		||||
      punycode:
 | 
			
		||||
      punycode.js:
 | 
			
		||||
        specifier: ^2.3.1
 | 
			
		||||
        version: 2.3.1
 | 
			
		||||
      rimraf:
 | 
			
		||||
| 
						 | 
				
			
			@ -1662,6 +1662,9 @@ importers:
 | 
			
		|||
      psl:
 | 
			
		||||
        specifier: ^1.9.0
 | 
			
		||||
        version: 1.15.0
 | 
			
		||||
      punycode.js:
 | 
			
		||||
        specifier: ^2.3.1
 | 
			
		||||
        version: 2.3.1
 | 
			
		||||
      qiniu:
 | 
			
		||||
        specifier: ^7.12.0
 | 
			
		||||
        version: 7.14.0
 | 
			
		||||
| 
						 | 
				
			
			@ -20737,13 +20740,13 @@ snapshots:
 | 
			
		|||
      resolve: 1.22.10
 | 
			
		||||
      semver: 6.3.1
 | 
			
		||||
 | 
			
		||||
  eslint-plugin-prettier@3.4.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@7.32.0)(prettier@2.8.8):
 | 
			
		||||
  eslint-plugin-prettier@3.4.1(eslint-config-prettier@8.10.0(eslint@7.32.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@8.57.0)
 | 
			
		||||
      eslint-config-prettier: 8.10.0(eslint@7.32.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:
 | 
			
		||||
| 
						 | 
				
			
			@ -23451,7 +23454,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@8.57.0))(eslint@7.32.0)(prettier@2.8.8)
 | 
			
		||||
      eslint-plugin-prettier: 3.4.1(eslint-config-prettier@8.10.0(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8)
 | 
			
		||||
      execa: 5.1.1
 | 
			
		||||
      inquirer: 7.3.3
 | 
			
		||||
      json5: 2.2.3
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue