Files
certd/packages/plugins/plugin-cert/src/dns-provider/domain-parser.ts

67 lines
2.3 KiB
TypeScript
Raw Normal View History

import { IDomainParser, ISubDomainsGetter } from "./api";
//@ts-ignore
import psl from "psl";
2025-05-06 00:14:17 +08:00
import { ILogger, utils, logger as globalLogger } from "@certd/basic";
import { resolveDomainBySoaRecord } from "@certd/acme-client";
export class DomainParser implements IDomainParser {
subDomainsGetter: ISubDomainsGetter;
2025-05-06 00:14:17 +08:00
logger: ILogger;
constructor(subDomainsGetter: ISubDomainsGetter, logger?: ILogger) {
this.subDomainsGetter = subDomainsGetter;
2025-05-06 00:14:17 +08:00
this.logger = logger || globalLogger;
}
parseDomainByPsl(fullDomain: string) {
const parsed = psl.parse(fullDomain) as psl.ParsedDomain;
if (parsed.error) {
throw new Error(`解析${fullDomain}域名失败:` + JSON.stringify(parsed.error));
}
return parsed.domain as string;
}
async parse(fullDomain: string) {
2025-05-06 00:14:17 +08:00
this.logger.info(`查找主域名:${fullDomain}`);
const cacheKey = `domain_parse:${fullDomain}`;
const value = utils.cache.get(cacheKey);
if (value) {
2025-05-06 00:14:17 +08:00
this.logger.info(`从缓存获取到主域名:${fullDomain}->${value}`);
return value;
}
const subDomains = await this.subDomainsGetter.getSubDomains();
if (subDomains && subDomains.length > 0) {
2025-05-06 00:14:17 +08:00
const fullDomainDot = "." + fullDomain;
for (const subDomain of subDomains) {
2025-05-06 00:14:17 +08:00
if (fullDomainDot.endsWith("." + subDomain)) {
//找到子域名托管
utils.cache.set(cacheKey, subDomain, {
2025-05-06 00:14:17 +08:00
ttl: 60 * 1000,
});
2025-05-06 00:14:17 +08:00
this.logger.info(`获取到子域名托管域名:${fullDomain}->${subDomain}`);
return subDomain;
}
}
}
const res = this.parseDomainByPsl(fullDomain);
2025-05-06 00:14:17 +08:00
this.logger.info(`从psl获取主域名:${fullDomain}->${res}`);
let soaManDomain = null;
try {
const mainDomain = await resolveDomainBySoaRecord(fullDomain);
if (mainDomain) {
this.logger.info(`从SOA获取到主域名:${fullDomain}->${mainDomain}`);
soaManDomain = mainDomain;
}
} catch (e) {
this.logger.error("从SOA获取主域名失败", e.message);
}
if (soaManDomain && soaManDomain !== res) {
this.logger.warn(`SOA获取的主域名${soaManDomain}和psl获取的主域名(${res})不一致,请确认是否有设置子域名托管`);
}
return res;
}
}