Files
certd/packages/ui/certd-server/src/modules/cert/service/domain-service.ts
xiaojunnuo 19e1df1e5d chore:
2025-07-13 23:58:07 +08:00

191 lines
4.9 KiB
TypeScript

import {Inject, Provide, Scope, ScopeEnum} from '@midwayjs/core';
import {InjectEntityModel} from '@midwayjs/typeorm';
import {In, Not, Repository} from 'typeorm';
import {AccessService, BaseService} from '@certd/lib-server';
import {DomainEntity} from '../entity/domain.js';
import {SubDomainService} from "../../pipeline/service/sub-domain-service.js";
import {DomainParser} from "@certd/plugin-cert/dist/dns-provider/domain-parser.js";
import {DomainVerifiers} from "@certd/plugin-cert";
import { SubDomainsGetter } from '../../pipeline/service/getter/sub-domain-getter.js';
import { CnameRecordService } from '../../cname/service/cname-record-service.js';
import { CnameRecordEntity } from "../../cname/entity/cname-record.js";
/**
*
*/
@Provide()
@Scope(ScopeEnum.Request, {allowDowngrade: true})
export class DomainService extends BaseService<DomainEntity> {
@InjectEntityModel(DomainEntity)
repository: Repository<DomainEntity>;
@Inject()
accessService: AccessService;
@Inject()
subDomainService: SubDomainService;
@Inject()
cnameRecordService: CnameRecordService;
//@ts-ignore
getRepository() {
return this.repository;
}
async add(param) {
if (param.userId == null ){
throw new Error('userId 不能为空');
}
if (!param.domain) {
throw new Error('domain 不能为空');
}
const old = await this.repository.findOne({
where: {
domain: param.domain,
userId: param.userId
}
});
if (old) {
throw new Error(`域名(${param.domain})不能重复`);
}
return await super.add(param);
}
async update(param) {
if (!param.id) {
throw new Error('id 不能为空');
}
const old = await this.info(param.id)
if (!old) {
throw new Error('domain记录不存在');
}
const same = await this.repository.findOne({
where: {
domain: param.domain,
userId: old.userId,
id: Not(param.id)
}
});
if (same) {
throw new Error(`域名(${param.domain})不能重复`);
}
delete param.userId
return await super.update(param);
}
/**
*
* @param userId
* @param domains //去除* 且去重之后的域名列表
*/
async getDomainVerifiers(userId: number, domains: string[]):Promise<DomainVerifiers> {
const mainDomainMap:Record<string, string> = {}
const subDomainGetter = new SubDomainsGetter(userId, this.subDomainService)
const domainParser = new DomainParser(subDomainGetter)
const mainDomains = []
for (const domain of domains) {
const mainDomain = await domainParser.parse(domain);
mainDomainMap[domain] = mainDomain;
mainDomains.push(mainDomain)
}
//匹配DNS记录
let allDomains = [...domains,...mainDomains]
//去重
allDomains = [...new Set(allDomains)]
//从 domain 表中获取配置
const domainRecords = await this.find({
where: {
domain: In(allDomains),
userId,
disabled:false,
}
})
const dnsMap = domainRecords.filter(item=>item.challengeType === 'dns').reduce((pre, item) => {
pre[item.domain] = item
return pre
}, {})
const httpMap = domainRecords.filter(item=>item.challengeType === 'http').reduce((pre, item) => {
pre[item.domain] = item
return pre
}, {})
//从cname record表中获取配置
const cnameRecords = await this.cnameRecordService.find({
where: {
domain: In(allDomains),
userId,
status: "valid",
}
})
const cnameMap = cnameRecords.reduce((pre, item) => {
pre[item.domain] = item
return pre
}, {})
//构建域名验证计划
const domainVerifiers:DomainVerifiers = {}
for (const domain of domains) {
const mainDomain = mainDomainMap[domain]
const dnsRecord = dnsMap[mainDomain]
if (dnsRecord) {
domainVerifiers[domain] = {
domain,
mainDomain,
type: 'dns',
dns: {
dnsProviderType: dnsRecord.dnsProviderType,
dnsProviderAccessId: dnsRecord.dnsProviderAccess
}
}
continue
}
const cnameRecord:CnameRecordEntity = cnameMap[domain]
if (cnameRecord) {
domainVerifiers[domain] = {
domain,
mainDomain,
type: 'cname',
cname: {
domain: cnameRecord.domain,
hostRecord: cnameRecord.hostRecord,
recordValue: cnameRecord.recordValue
}
}
continue
}
const httpRecord = httpMap[domain]
if (httpRecord) {
domainVerifiers[domain] = {
domain,
mainDomain,
type: 'http',
http: {
httpUploaderType: httpRecord.httpUploaderType,
httpUploaderAccess: httpRecord.httpUploaderAccess,
httpUploadRootDir: httpRecord.httpUploadRootDir
}
}
continue
}
domainVerifiers[domain] = null
}
return domainVerifiers;
}
}