perf: 支持自动选择校验方式申请证书

v2-dev-auto
xiaojunnuo 2025-07-13 18:25:09 +08:00
parent 785bee2b39
commit 3f9943270c
13 changed files with 341 additions and 212 deletions

View File

@ -73,18 +73,22 @@ export type CnameVerifier = {
export type HttpVerifier = { export type HttpVerifier = {
// http校验 // http校验
httpUploaderType: string; httpUploaderType: string;
httpUploaderAccess: string; httpUploaderAccess: number;
httpUploadRootDir: string; httpUploadRootDir: string;
}; };
export type DomainVerifier = { export type DomainVerifier = {
domain: string; domain: string;
mainDomain: string; mainDomain: string;
challengeType: string; type: string;
dns?: DnsVerifier; dns?: DnsVerifier;
cname?: CnameVerifier; cname?: CnameVerifier;
http?: HttpVerifier; http?: HttpVerifier;
}; };
export type DomainVerifiers = {
[key: string]: DomainVerifier;
};
export interface IDomainVerifierGetter { export interface IDomainVerifierGetter {
getVerifiers(domains: string[]): Promise<DomainVerifier[]>; getVerifiers(domains: string[]): Promise<DomainVerifiers>;
} }

View File

@ -23,10 +23,11 @@ export type HttpVerifyPlan = {
export type DomainVerifyPlan = { export type DomainVerifyPlan = {
domain: string; domain: string;
mainDomain: string;
type: "cname" | "dns" | "http"; type: "cname" | "dns" | "http";
dnsProvider?: IDnsProvider; dnsProvider?: IDnsProvider;
cnameVerifyPlan?: Record<string, CnameVerifyPlan>; cnameVerifyPlan?: CnameVerifyPlan;
httpVerifyPlan?: Record<string, HttpVerifyPlan>; httpVerifyPlan?: HttpVerifyPlan;
}; };
export type DomainsVerifyPlan = { export type DomainsVerifyPlan = {
[key: string]: DomainVerifyPlan; [key: string]: DomainVerifyPlan;
@ -233,23 +234,20 @@ export class AcmeService {
let dnsProvider = providers.dnsProvider; let dnsProvider = providers.dnsProvider;
let fullRecord = `_acme-challenge.${fullDomain}`; let fullRecord = `_acme-challenge.${fullDomain}`;
const origDomain = punycode.toUnicode(domain); // const origDomain = punycode.toUnicode(domain);
const origFullDomain = punycode.toUnicode(fullDomain); const origFullDomain = punycode.toUnicode(fullDomain);
if (providers.domainsVerifyPlan) { if (providers.domainsVerifyPlan) {
//按照计划执行 //按照计划执行
const domainVerifyPlan = providers.domainsVerifyPlan[origDomain]; const domainVerifyPlan = providers.domainsVerifyPlan[origFullDomain];
if (domainVerifyPlan) { if (domainVerifyPlan) {
if (domainVerifyPlan.type === "dns") { if (domainVerifyPlan.type === "dns") {
dnsProvider = domainVerifyPlan.dnsProvider; dnsProvider = domainVerifyPlan.dnsProvider;
} else if (domainVerifyPlan.type === "cname") { } else if (domainVerifyPlan.type === "cname") {
const cnameVerifyPlan = domainVerifyPlan.cnameVerifyPlan; const cname: CnameVerifyPlan = domainVerifyPlan.cnameVerifyPlan;
if (cnameVerifyPlan) { if (cname) {
const cname = cnameVerifyPlan[origFullDomain]; dnsProvider = cname.dnsProvider;
if (cname) { domain = await this.options.domainParser.parse(cname.domain);
dnsProvider = cname.dnsProvider; fullRecord = cname.fullRecord;
domain = await this.options.domainParser.parse(cname.domain);
fullRecord = cname.fullRecord;
}
} else { } else {
this.logger.error(`未找到域名${fullDomain}的CNAME校验计划请修改证书申请配置`); this.logger.error(`未找到域名${fullDomain}的CNAME校验计划请修改证书申请配置`);
} }
@ -257,13 +255,12 @@ export class AcmeService {
throw new Error(`未找到域名${fullDomain}CNAME校验计划的DnsProvider请修改证书申请配置`); throw new Error(`未找到域名${fullDomain}CNAME校验计划的DnsProvider请修改证书申请配置`);
} }
} else if (domainVerifyPlan.type === "http") { } else if (domainVerifyPlan.type === "http") {
const httpVerifyPlan = domainVerifyPlan.httpVerifyPlan; const plan: HttpVerifyPlan = domainVerifyPlan.httpVerifyPlan;
if (httpVerifyPlan) { if (plan) {
const httpChallenge = getChallenge("http-01"); const httpChallenge = getChallenge("http-01");
if (httpChallenge == null) { if (httpChallenge == null) {
throw new Error("该域名不支持http-01方式校验"); throw new Error("该域名不支持http-01方式校验");
} }
const plan = httpVerifyPlan[fullDomain];
return await doHttpVerify(httpChallenge, plan.httpUploader); return await doHttpVerify(httpChallenge, plan.httpUploader);
} else { } else {
throw new Error("未找到域名【" + fullDomain + "】的http校验配置"); throw new Error("未找到域名【" + fullDomain + "】的http校验配置");
@ -275,6 +272,9 @@ export class AcmeService {
this.logger.info("未找到域名校验计划使用默认的dnsProvider"); this.logger.info("未找到域名校验计划使用默认的dnsProvider");
} }
} }
if (!dnsProvider) {
this.logger.error("dnsProvider不存在无法申请证书");
}
const dnsChallenge = getChallenge("dns-01"); const dnsChallenge = getChallenge("dns-01");
return await doDnsVerify(dnsChallenge, fullRecord, dnsProvider); return await doDnsVerify(dnsChallenge, fullRecord, dnsProvider);

View File

@ -1,16 +1,16 @@
import { CancelError, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline"; import { CancelError, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { utils } from "@certd/basic"; import { utils } from "@certd/basic";
import type { CertInfo, CnameVerifyPlan, DomainsVerifyPlan, HttpVerifyPlan, PrivateKeyType, SSLProvider } from "./acme.js"; import { AcmeService, CertInfo, DomainsVerifyPlan, DomainVerifyPlan, PrivateKeyType, SSLProvider } from "./acme.js";
import { AcmeService } from "./acme.js";
import * as _ from "lodash-es"; import * as _ from "lodash-es";
import { createDnsProvider, DnsProviderContext, DomainVerifier, IDnsProvider, IDomainVerifierGetter, ISubDomainsGetter } from "../../dns-provider/index.js"; import { createDnsProvider, DnsProviderContext, DnsVerifier, DomainVerifiers, HttpVerifier, IDnsProvider, IDomainVerifierGetter, ISubDomainsGetter } from "../../dns-provider/index.js";
import { CertReader } from "./cert-reader.js"; import { CertReader } from "./cert-reader.js";
import { CertApplyBasePlugin } from "./base.js"; import { CertApplyBasePlugin } from "./base.js";
import { GoogleClient } from "../../libs/google.js"; import { GoogleClient } from "../../libs/google.js";
import { EabAccess } from "../../access"; import { EabAccess } from "../../access";
import { DomainParser } from "../../dns-provider/domain-parser.js"; import { DomainParser } from "../../dns-provider/domain-parser.js";
import { ossClientFactory } from "@certd/plugin-lib"; import { ossClientFactory } from "@certd/plugin-lib";
export * from "./base.js"; export * from "./base.js";
export type { CertInfo }; export type { CertInfo };
export * from "./cert-reader.js"; export * from "./cert-reader.js";
@ -335,6 +335,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
acme!: AcmeService; acme!: AcmeService;
eab!: EabAccess; eab!: EabAccess;
async onInit() { async onInit() {
let eab: EabAccess = null; let eab: EabAccess = null;
@ -410,11 +411,9 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
let dnsProvider: IDnsProvider = null; let dnsProvider: IDnsProvider = null;
let domainsVerifyPlan: DomainsVerifyPlan = null; let domainsVerifyPlan: DomainsVerifyPlan = null;
if (this.challengeType === "cname" || this.challengeType === "http" || this.challengeType === "dnses") { if (this.challengeType === "cname" || this.challengeType === "http" || this.challengeType === "dnses") {
domainsVerifyPlan = await this.createDomainsVerifyPlan(this.domainsVerifyPlan); domainsVerifyPlan = await this.createDomainsVerifyPlan(domains, this.domainsVerifyPlan);
} } else if (this.challengeType === "auto") {
if (this.challengeType === "auto") { domainsVerifyPlan = await this.createDomainsVerifyPlanByAuto(domains);
const planInput = await this.buildVerifyPlanInputByAuto();
domainsVerifyPlan = await this.createDomainsVerifyPlan(planInput);
} else { } else {
const dnsProviderType = this.dnsProviderType; const dnsProviderType = this.dnsProviderType;
const access = await this.getAccess(this.dnsProviderAccess); const access = await this.getAccess(this.dnsProviderAccess);
@ -450,75 +449,39 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
async createDnsProvider(dnsProviderType: string, dnsProviderAccess: any): Promise<IDnsProvider> { async createDnsProvider(dnsProviderType: string, dnsProviderAccess: any): Promise<IDnsProvider> {
const domainParser = this.acme.options.domainParser; const domainParser = this.acme.options.domainParser;
const context: DnsProviderContext = { access: dnsProviderAccess, logger: this.logger, http: this.ctx.http, utils, domainParser }; const context: DnsProviderContext = {
access: dnsProviderAccess,
logger: this.logger,
http: this.ctx.http,
utils,
domainParser,
};
return await createDnsProvider({ return await createDnsProvider({
dnsProviderType, dnsProviderType,
context, context,
}); });
} }
async createDomainsVerifyPlan(verifyPlanSetting: DomainsVerifyPlanInput): Promise<DomainsVerifyPlan> { async createDomainsVerifyPlan(domains: string[], verifyPlanSetting: DomainsVerifyPlanInput): Promise<DomainsVerifyPlan> {
const plan: DomainsVerifyPlan = {}; const plan: DomainsVerifyPlan = {};
for (const domain in verifyPlanSetting) {
const domainVerifyPlan = verifyPlanSetting[domain]; const domainParser = this.acme.options.domainParser;
let dnsProvider = null; for (const fullDomain of domains) {
const cnameVerifyPlan: Record<string, CnameVerifyPlan> = {}; const domain = fullDomain.replaceAll("*.", "");
const httpVerifyPlan: Record<string, HttpVerifyPlan> = {}; const mainDomain = await domainParser.parse(domain);
if (domainVerifyPlan.type === "dns") { const planSetting = verifyPlanSetting[mainDomain];
const access = await this.getAccess(domainVerifyPlan.dnsProviderAccessId); if (planSetting.type === "dns") {
dnsProvider = await this.createDnsProvider(domainVerifyPlan.dnsProviderType, access); await this.createDnsDomainVerifyPlan(planSetting[mainDomain], domain, mainDomain);
} else if (domainVerifyPlan.type === "cname") { } else if (planSetting.type === "cname") {
for (const key in domainVerifyPlan.cnameVerifyPlan) { await this.createCnameDomainVerifyPlan(domain, mainDomain);
const cnameRecord = await this.ctx.cnameProxyService.getByDomain(key); } else if (planSetting.type === "http") {
let dnsProvider = cnameRecord.commonDnsProvider; await this.createHttpDomainVerifyPlan(planSetting.httpVerifyPlan[domain], domain, mainDomain);
if (cnameRecord.cnameProvider.id > 0) {
dnsProvider = await this.createDnsProvider(cnameRecord.cnameProvider.dnsProviderType, cnameRecord.cnameProvider.access);
}
cnameVerifyPlan[key] = {
type: "cname",
domain: cnameRecord.cnameProvider.domain,
fullRecord: cnameRecord.recordValue,
dnsProvider,
};
}
} else if (domainVerifyPlan.type === "http") {
const httpUploaderContext = {
accessService: this.ctx.accessService,
logger: this.logger,
utils,
};
for (const key in domainVerifyPlan.httpVerifyPlan) {
const httpRecord = domainVerifyPlan.httpVerifyPlan[key];
const access = await this.getAccess(httpRecord.httpUploaderAccess);
let rootDir = httpRecord.httpUploadRootDir;
if (!rootDir.endsWith("/") && !rootDir.endsWith("\\")) {
rootDir = rootDir + "/";
}
this.logger.info("上传方式", httpRecord.httpUploaderType);
const httpUploader = await ossClientFactory.createOssClientByType(httpRecord.httpUploaderType, {
access,
rootDir: rootDir,
ctx: httpUploaderContext,
});
httpVerifyPlan[key] = {
type: "http",
domain: key,
httpUploader,
};
}
} }
plan[domain] = {
domain,
type: domainVerifyPlan.type,
dnsProvider,
cnameVerifyPlan,
httpVerifyPlan,
};
} }
return plan; return plan;
} }
private async buildVerifyPlanInputByAuto() { private async createDomainsVerifyPlanByAuto(domains: string[]) {
//从数据库里面自动选择校验方式 //从数据库里面自动选择校验方式
// domain list // domain list
const domainList = new Set<string>(); const domainList = new Set<string>();
@ -527,55 +490,84 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
domain = domain.replaceAll("*.", ""); domain = domain.replaceAll("*.", "");
domainList.add(domain); domainList.add(domain);
} }
const domainVerifierGetter: IDomainVerifierGetter = await this.ctx.serviceGetter.get("DomainVerifierGetter"); const domainVerifierGetter: IDomainVerifierGetter = await this.ctx.serviceGetter.get("domainVerifierGetter");
const verifiers = await domainVerifierGetter.getVerifiers([...domainList]); const verifiers: DomainVerifiers = await domainVerifierGetter.getVerifiers([...domainList]);
const verifyPlanInput: DomainsVerifyPlanInput = {}; const plan: DomainsVerifyPlan = {};
for (const verifier of verifiers) { for (const domain in verifiers) {
const domain = verifier.domain; const verifier = verifiers[domain];
const mainDomain = verifier.mainDomain; if (verifier.type === "dns") {
let plan = verifyPlanInput[mainDomain]; plan[domain] = await this.createDnsDomainVerifyPlan(verifier.dns, domain, verifier.mainDomain);
if (!plan) { } else if (verifier.type === "cname") {
plan = { plan[domain] = await this.createCnameDomainVerifyPlan(domain, verifier.mainDomain);
domain: mainDomain, } else if (verifier.type === "http") {
type: "cname", plan[domain] = await this.createHttpDomainVerifyPlan(verifier.http, domain, verifier.mainDomain);
};
verifyPlanInput[mainDomain] = plan;
}
if (verifier.challengeType === "cname") {
verifyPlanInput[domain] = {
type: "cname",
domain: domain,
cnameVerifyPlan: {
[domain]: {
id: 0,
status: "validate",
},
},
};
} else if (verifier.challengeType === "http") {
//http
const http = verifier.http;
verifyPlanInput[domain] = {
type: "http",
domain: domain,
httpVerifyPlan: {
[domain]: {
domain: domain,
httpUploaderType: http.httpUploaderType,
httpUploaderAccess: http.httpUploaderAccess,
httpUploadRootDir: http.httpUploadRootDir,
},
},
};
} else {
//dns
} }
} }
return plan;
}
return verifyPlanInput; private async createDnsDomainVerifyPlan(planSetting: DnsVerifier, domain: string, mainDomain: string): Promise<DomainVerifyPlan> {
const access = await this.getAccess(planSetting.dnsProviderAccessId);
return {
type: "dns",
mainDomain,
domain,
dnsProvider: await this.createDnsProvider(planSetting.dnsProviderType, access),
};
}
private async createHttpDomainVerifyPlan(httpSetting: HttpVerifier, domain: string, mainDomain: string): Promise<DomainVerifyPlan> {
const httpUploaderContext = {
accessService: this.ctx.accessService,
logger: this.logger,
utils,
};
const access = await this.getAccess(httpSetting.httpUploaderAccess);
let rootDir = httpSetting.httpUploadRootDir;
if (!rootDir.endsWith("/") && !rootDir.endsWith("\\")) {
rootDir = rootDir + "/";
}
this.logger.info("上传方式", httpSetting.httpUploaderType);
const httpUploader = await ossClientFactory.createOssClientByType(httpSetting.httpUploaderType, {
access,
rootDir: rootDir,
ctx: httpUploaderContext,
});
return {
type: "http",
domain,
mainDomain,
httpVerifyPlan: {
type: "http",
domain,
httpUploader,
},
};
}
private async createCnameDomainVerifyPlan(domain: string, mainDomain: string): Promise<DomainVerifyPlan> {
const cnameRecord = await this.ctx.cnameProxyService.getByDomain(domain);
if (cnameRecord == null) {
throw new Error(`请先配置${domain}的CNAME记录并通过校验`);
}
let dnsProvider = cnameRecord.commonDnsProvider;
if (cnameRecord.cnameProvider.id > 0) {
dnsProvider = await this.createDnsProvider(cnameRecord.cnameProvider.dnsProviderType, cnameRecord.cnameProvider.access);
}
return {
type: "cname",
domain,
mainDomain,
cnameVerifyPlan: {
domain,
fullRecord: cnameRecord.recordValue,
dnsProvider,
},
};
} }
} }

View File

@ -1,7 +1,8 @@
import {ALL, Body, Controller, Inject, Post, Provide, Query} from '@midwayjs/core'; import {ALL, Body, Controller, Inject, Post, Provide, Query} from '@midwayjs/core';
import {Constants, CrudController} from '@certd/lib-server'; import {Constants, CrudController} from '@certd/lib-server';
import {SubDomainService, SubDomainsGetter} from "../../../modules/pipeline/service/sub-domain-service.js"; import {SubDomainService} from "../../../modules/pipeline/service/sub-domain-service.js";
import {DomainParser} from '@certd/plugin-cert/dist/dns-provider/domain-parser.js'; import {DomainParser} from '@certd/plugin-cert/dist/dns-provider/domain-parser.js';
import { SubDomainsGetter } from '../../../modules/pipeline/service/getter/sub-domain-getter.js';
/** /**
* *

View File

@ -1,8 +1,12 @@
import {Inject, Provide, Scope, ScopeEnum} from '@midwayjs/core'; import {Inject, Provide, Scope, ScopeEnum} from '@midwayjs/core';
import {InjectEntityModel} from '@midwayjs/typeorm'; import {InjectEntityModel} from '@midwayjs/typeorm';
import {Not, Repository} from 'typeorm'; import {In, Not, Repository} from 'typeorm';
import {AccessService, BaseService} from '@certd/lib-server'; import {AccessService, BaseService} from '@certd/lib-server';
import {DomainEntity} from '../entity/domain.js'; 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';
/** /**
@ -16,6 +20,8 @@ export class DomainService extends BaseService<DomainEntity> {
@Inject() @Inject()
accessService: AccessService; accessService: AccessService;
@Inject()
subDomainService: SubDomainService;
//@ts-ignore //@ts-ignore
getRepository() { getRepository() {
@ -67,4 +73,97 @@ export class DomainService extends BaseService<DomainEntity> {
} }
/**
*
* @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)]
const domainRecords = await this.find({
where: {
domain: In(allDomains),
userId
}
})
const dnsMap = domainRecords.filter(item=>item.challengeType === 'dns').reduce((pre, item) => {
pre[item.domain] = item
return pre
}, {})
const cnameMap = domainRecords.filter(item=>item.challengeType === 'cname').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
}, {})
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.dnsProviderAccessId
}
}
continue
}
const cnameRecord = cnameMap[mainDomain]
if (cnameRecord) {
domainVerifiers[domain] = {
domain,
mainDomain,
type: 'cname',
cname: {
cnameRecord: cnameRecord.cnameRecord
}
}
continue
}
const httpRecord = httpMap[mainDomain]
if (httpRecord) {
domainVerifiers[domain] = {
domain,
mainDomain,
type: 'http',
http: {
httpUploaderType: httpRecord.httpUploaderType,
httpUploaderAccess: httpRecord.httpUploaderAccess,
httpUploadRootDir: httpRecord.httpUploadRootDir
}
}
continue
}
domainVerifiers[domain] = null
}
return domainVerifiers;
}
} }

View File

@ -0,0 +1,17 @@
import {DomainVerifiers, IDomainVerifierGetter} from "@certd/plugin-cert";
import {DomainService} from "../../../cert/service/domain-service.js";
export class DomainVerifierGetter implements IDomainVerifierGetter {
private userId: number;
private domainService: DomainService;
constructor(userId: number, domainService: DomainService) {
this.userId = userId;
this.domainService = domainService;
}
async getVerifiers(domains: string[]): Promise<DomainVerifiers>{
return await this.domainService.getDomainVerifiers(this.userId,domains);
}
}

View File

@ -1,5 +1,5 @@
import { INotificationService, NotificationSendReq } from '@certd/pipeline'; import { INotificationService, NotificationSendReq } from '@certd/pipeline';
import { NotificationService } from './notification-service.js'; import {NotificationService} from "../notification-service.js";
export class NotificationGetter implements INotificationService { export class NotificationGetter implements INotificationService {
userId: number; userId: number;

View File

@ -0,0 +1,17 @@
import {ISubDomainsGetter} from "@certd/plugin-cert";
import {SubDomainService} from "../service/sub-domain-service.js";
export class SubDomainsGetter implements ISubDomainsGetter {
userId: number;
subDomainService: SubDomainService;
constructor(userId: number, subDomainService: SubDomainService) {
this.userId = userId;
this.subDomainService = subDomainService;
}
async getSubDomains() {
return await this.subDomainService.getListByUserId(this.userId)
}
}

View File

@ -0,0 +1,81 @@
import {IServiceGetter} from "@certd/pipeline";
import {Inject, Provide, Scope, ScopeEnum} from "@midwayjs/core";
import {SubDomainService} from "../sub-domain-service.js";
import {AccessGetter, AccessService} from "@certd/lib-server";
import {CnameProxyService} from "./cname-proxy-service.js";
import {NotificationGetter} from "./notification-getter.js";
import {NotificationService} from "../notification-service.js";
import {CnameRecordService} from "../../../cname/service/cname-record-service.js";
import {SubDomainsGetter} from './sub-domain-getter.js'
import {DomainVerifierGetter} from "./domain-verifier-getter.js";
import {Context} from "@midwayjs/koa";
import {DomainService} from "../../../cert/service/domain-service.js";
export class TaskServiceGetter implements IServiceGetter{
private userId: number;
private ctx : Context;
constructor(userId:number,ctx:Context) {
this.userId = userId;
this.ctx = ctx
}
async get<T>(serviceName: string): Promise<T> {
if(serviceName === 'subDomainsGetter'){
return await this.getSubDomainsGetter() as T
} if (serviceName === 'accessService') {
return await this.getAccessService() as T
} else if (serviceName === 'cnameProxyService') {
return await this.getCnameProxyService() as T
} else if (serviceName === 'notificationService') {
return await this.getNotificationService() as T
} else if (serviceName === 'domainVerifierGetter') {
return await this.getDomainVerifierGetter() as T
}else{
throw new Error(`service ${serviceName} not found`)
}
}
async getSubDomainsGetter(): Promise<SubDomainsGetter> {
const subDomainsService = await this.ctx.requestContext.getAsync("subDomainService")
return new SubDomainsGetter(this.userId, subDomainsService)
}
async getAccessService(): Promise<AccessGetter> {
const accessService:AccessService = await this.ctx.requestContext.getAsync("accessService")
return new AccessGetter(this.userId, accessService.getById.bind(accessService));
}
async getCnameProxyService(): Promise<CnameProxyService> {
const cnameRecordService:CnameRecordService = await this.ctx.requestContext.getAsync("cnameRecordService")
return new CnameProxyService(this.userId, cnameRecordService.getWithAccessByDomain.bind(cnameRecordService));
}
async getNotificationService(): Promise<NotificationGetter> {
const notificationService:NotificationService = await this.ctx.requestContext.getAsync("notificationService")
return new NotificationGetter(this.userId, notificationService);
}
async getDomainVerifierGetter(): Promise<DomainVerifierGetter> {
const domainService:DomainService = await this.ctx.requestContext.getAsync("domainService")
return new DomainVerifierGetter(this.userId, domainService);
}
}
export type TaskServiceCreateReq = {
userId: number;
}
@Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
export class TaskServiceBuilder {
@Inject()
ctx: Context;
create(req:TaskServiceCreateReq){
const userId = req.userId;
return new TaskServiceGetter(userId,this.ctx)
}
}

View File

@ -44,7 +44,7 @@ import {UrlService} from "./url-service.js";
import {NotificationService} from "./notification-service.js"; import {NotificationService} from "./notification-service.js";
import {UserSuiteEntity, UserSuiteService} from "@certd/commercial-core"; import {UserSuiteEntity, UserSuiteService} from "@certd/commercial-core";
import {CertInfoService} from "../../monitor/service/cert-info-service.js"; import {CertInfoService} from "../../monitor/service/cert-info-service.js";
import {TaskServiceBuilder} from "./task-service-getter.js"; import {TaskServiceBuilder} from "./getter/task-service-getter.js";
import {nanoid} from "nanoid"; import {nanoid} from "nanoid";
import {set} from "lodash-es"; import {set} from "lodash-es";

View File

@ -4,7 +4,6 @@ import {InjectEntityModel} from '@midwayjs/typeorm';
import {Repository} from 'typeorm'; import {Repository} from 'typeorm';
import {SubDomainEntity} from '../entity/sub-domain.js'; import {SubDomainEntity} from '../entity/sub-domain.js';
import {EmailService} from '../../basic/service/email-service.js'; import {EmailService} from '../../basic/service/email-service.js';
import {ISubDomainsGetter} from "@certd/plugin-cert";
@Provide() @Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true }) @Scope(ScopeEnum.Request, { allowDowngrade: true })
@ -38,21 +37,3 @@ export class SubDomainService extends BaseService<SubDomainEntity> {
} }
} }
export class SubDomainsGetter implements ISubDomainsGetter {
userId: number;
subDomainService: SubDomainService;
constructor(userId: number, subDomainService: SubDomainService) {
this.userId = userId;
this.subDomainService = subDomainService;
}
async getSubDomains() {
return await this.subDomainService.getListByUserId(this.userId)
}
}

View File

@ -1,63 +0,0 @@
import {IServiceGetter} from "@certd/pipeline";
import {Inject, Provide, Scope, ScopeEnum} from "@midwayjs/core";
import {SubDomainService, SubDomainsGetter} from "./sub-domain-service.js";
import {AccessGetter, AccessService} from "@certd/lib-server";
import {CnameProxyService} from "./cname-proxy-service.js";
import {NotificationGetter} from "./notification-getter.js";
import {NotificationService} from "./notification-service.js";
import {CnameRecordService} from "../../cname/service/cname-record-service.js";
export class TaskServiceGetter implements IServiceGetter{
serviceContainer:Record<string, any>;
constructor(serviceContainer:Record<string, any>) {
this.serviceContainer = serviceContainer;
}
async get<T>(serviceName: string): Promise<T> {
const ret = this.serviceContainer[serviceName] as T;
if(!ret){
throw new Error(`service ${serviceName} not found`)
}
return ret
}
}
export type TaskServiceCreateReq = {
userId: number;
}
export type TaskServiceContainer = {
subDomainsGetter:SubDomainsGetter;
accessService: AccessGetter;
cnameProxyService: CnameProxyService;
notificationService: NotificationGetter;
}
@Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
export class TaskServiceBuilder {
@Inject()
subDomainService: SubDomainService;
@Inject()
accessService: AccessService;
@Inject()
cnameRecordService: CnameRecordService;
@Inject()
notificationService: NotificationService;
create(req:TaskServiceCreateReq){
const userId = req.userId;
const accessGetter = new AccessGetter(userId, this.accessService.getById.bind(this.accessService));
const cnameProxyService = new CnameProxyService(userId, this.cnameRecordService.getWithAccessByDomain.bind(this.cnameRecordService));
const notificationGetter = new NotificationGetter(userId, this.notificationService);
const serviceContainer:TaskServiceContainer = {
subDomainsGetter:new SubDomainsGetter(req.userId, this.subDomainService),
accessService: accessGetter,
cnameProxyService:cnameProxyService,
notificationService:notificationGetter
}
return new TaskServiceGetter(serviceContainer)
}
}