mirror of https://github.com/certd/certd
perf: 支持自动选择校验方式申请证书
parent
785bee2b39
commit
3f9943270c
|
@ -73,18 +73,22 @@ export type CnameVerifier = {
|
|||
export type HttpVerifier = {
|
||||
// http校验
|
||||
httpUploaderType: string;
|
||||
httpUploaderAccess: string;
|
||||
httpUploaderAccess: number;
|
||||
httpUploadRootDir: string;
|
||||
};
|
||||
export type DomainVerifier = {
|
||||
domain: string;
|
||||
mainDomain: string;
|
||||
challengeType: string;
|
||||
type: string;
|
||||
dns?: DnsVerifier;
|
||||
cname?: CnameVerifier;
|
||||
http?: HttpVerifier;
|
||||
};
|
||||
|
||||
export type DomainVerifiers = {
|
||||
[key: string]: DomainVerifier;
|
||||
};
|
||||
|
||||
export interface IDomainVerifierGetter {
|
||||
getVerifiers(domains: string[]): Promise<DomainVerifier[]>;
|
||||
getVerifiers(domains: string[]): Promise<DomainVerifiers>;
|
||||
}
|
||||
|
|
|
@ -23,10 +23,11 @@ export type HttpVerifyPlan = {
|
|||
|
||||
export type DomainVerifyPlan = {
|
||||
domain: string;
|
||||
mainDomain: string;
|
||||
type: "cname" | "dns" | "http";
|
||||
dnsProvider?: IDnsProvider;
|
||||
cnameVerifyPlan?: Record<string, CnameVerifyPlan>;
|
||||
httpVerifyPlan?: Record<string, HttpVerifyPlan>;
|
||||
cnameVerifyPlan?: CnameVerifyPlan;
|
||||
httpVerifyPlan?: HttpVerifyPlan;
|
||||
};
|
||||
export type DomainsVerifyPlan = {
|
||||
[key: string]: DomainVerifyPlan;
|
||||
|
@ -233,23 +234,20 @@ export class AcmeService {
|
|||
let dnsProvider = providers.dnsProvider;
|
||||
let fullRecord = `_acme-challenge.${fullDomain}`;
|
||||
|
||||
const origDomain = punycode.toUnicode(domain);
|
||||
// const origDomain = punycode.toUnicode(domain);
|
||||
const origFullDomain = punycode.toUnicode(fullDomain);
|
||||
if (providers.domainsVerifyPlan) {
|
||||
//按照计划执行
|
||||
const domainVerifyPlan = providers.domainsVerifyPlan[origDomain];
|
||||
const domainVerifyPlan = providers.domainsVerifyPlan[origFullDomain];
|
||||
if (domainVerifyPlan) {
|
||||
if (domainVerifyPlan.type === "dns") {
|
||||
dnsProvider = domainVerifyPlan.dnsProvider;
|
||||
} else if (domainVerifyPlan.type === "cname") {
|
||||
const cnameVerifyPlan = domainVerifyPlan.cnameVerifyPlan;
|
||||
if (cnameVerifyPlan) {
|
||||
const cname = cnameVerifyPlan[origFullDomain];
|
||||
if (cname) {
|
||||
dnsProvider = cname.dnsProvider;
|
||||
domain = await this.options.domainParser.parse(cname.domain);
|
||||
fullRecord = cname.fullRecord;
|
||||
}
|
||||
const cname: CnameVerifyPlan = domainVerifyPlan.cnameVerifyPlan;
|
||||
if (cname) {
|
||||
dnsProvider = cname.dnsProvider;
|
||||
domain = await this.options.domainParser.parse(cname.domain);
|
||||
fullRecord = cname.fullRecord;
|
||||
} else {
|
||||
this.logger.error(`未找到域名${fullDomain}的CNAME校验计划,请修改证书申请配置`);
|
||||
}
|
||||
|
@ -257,13 +255,12 @@ export class AcmeService {
|
|||
throw new Error(`未找到域名${fullDomain}CNAME校验计划的DnsProvider,请修改证书申请配置`);
|
||||
}
|
||||
} else if (domainVerifyPlan.type === "http") {
|
||||
const httpVerifyPlan = domainVerifyPlan.httpVerifyPlan;
|
||||
if (httpVerifyPlan) {
|
||||
const plan: HttpVerifyPlan = domainVerifyPlan.httpVerifyPlan;
|
||||
if (plan) {
|
||||
const httpChallenge = getChallenge("http-01");
|
||||
if (httpChallenge == null) {
|
||||
throw new Error("该域名不支持http-01方式校验");
|
||||
}
|
||||
const plan = httpVerifyPlan[fullDomain];
|
||||
return await doHttpVerify(httpChallenge, plan.httpUploader);
|
||||
} else {
|
||||
throw new Error("未找到域名【" + fullDomain + "】的http校验配置");
|
||||
|
@ -275,6 +272,9 @@ export class AcmeService {
|
|||
this.logger.info("未找到域名校验计划,使用默认的dnsProvider");
|
||||
}
|
||||
}
|
||||
if (!dnsProvider) {
|
||||
this.logger.error("dnsProvider不存在,无法申请证书");
|
||||
}
|
||||
|
||||
const dnsChallenge = getChallenge("dns-01");
|
||||
return await doDnsVerify(dnsChallenge, fullRecord, dnsProvider);
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import { CancelError, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||
import { utils } from "@certd/basic";
|
||||
|
||||
import type { CertInfo, CnameVerifyPlan, DomainsVerifyPlan, HttpVerifyPlan, PrivateKeyType, SSLProvider } from "./acme.js";
|
||||
import { AcmeService } from "./acme.js";
|
||||
import { AcmeService, CertInfo, DomainsVerifyPlan, DomainVerifyPlan, PrivateKeyType, SSLProvider } from "./acme.js";
|
||||
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 { CertApplyBasePlugin } from "./base.js";
|
||||
import { GoogleClient } from "../../libs/google.js";
|
||||
import { EabAccess } from "../../access";
|
||||
import { DomainParser } from "../../dns-provider/domain-parser.js";
|
||||
import { ossClientFactory } from "@certd/plugin-lib";
|
||||
|
||||
export * from "./base.js";
|
||||
export type { CertInfo };
|
||||
export * from "./cert-reader.js";
|
||||
|
@ -335,6 +335,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
acme!: AcmeService;
|
||||
|
||||
eab!: EabAccess;
|
||||
|
||||
async onInit() {
|
||||
let eab: EabAccess = null;
|
||||
|
||||
|
@ -410,11 +411,9 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
let dnsProvider: IDnsProvider = null;
|
||||
let domainsVerifyPlan: DomainsVerifyPlan = null;
|
||||
if (this.challengeType === "cname" || this.challengeType === "http" || this.challengeType === "dnses") {
|
||||
domainsVerifyPlan = await this.createDomainsVerifyPlan(this.domainsVerifyPlan);
|
||||
}
|
||||
if (this.challengeType === "auto") {
|
||||
const planInput = await this.buildVerifyPlanInputByAuto();
|
||||
domainsVerifyPlan = await this.createDomainsVerifyPlan(planInput);
|
||||
domainsVerifyPlan = await this.createDomainsVerifyPlan(domains, this.domainsVerifyPlan);
|
||||
} else if (this.challengeType === "auto") {
|
||||
domainsVerifyPlan = await this.createDomainsVerifyPlanByAuto(domains);
|
||||
} else {
|
||||
const dnsProviderType = this.dnsProviderType;
|
||||
const access = await this.getAccess(this.dnsProviderAccess);
|
||||
|
@ -450,75 +449,39 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
|
||||
async createDnsProvider(dnsProviderType: string, dnsProviderAccess: any): Promise<IDnsProvider> {
|
||||
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({
|
||||
dnsProviderType,
|
||||
context,
|
||||
});
|
||||
}
|
||||
|
||||
async createDomainsVerifyPlan(verifyPlanSetting: DomainsVerifyPlanInput): Promise<DomainsVerifyPlan> {
|
||||
async createDomainsVerifyPlan(domains: string[], verifyPlanSetting: DomainsVerifyPlanInput): Promise<DomainsVerifyPlan> {
|
||||
const plan: DomainsVerifyPlan = {};
|
||||
for (const domain in verifyPlanSetting) {
|
||||
const domainVerifyPlan = verifyPlanSetting[domain];
|
||||
let dnsProvider = null;
|
||||
const cnameVerifyPlan: Record<string, CnameVerifyPlan> = {};
|
||||
const httpVerifyPlan: Record<string, HttpVerifyPlan> = {};
|
||||
if (domainVerifyPlan.type === "dns") {
|
||||
const access = await this.getAccess(domainVerifyPlan.dnsProviderAccessId);
|
||||
dnsProvider = await this.createDnsProvider(domainVerifyPlan.dnsProviderType, access);
|
||||
} else if (domainVerifyPlan.type === "cname") {
|
||||
for (const key in domainVerifyPlan.cnameVerifyPlan) {
|
||||
const cnameRecord = await this.ctx.cnameProxyService.getByDomain(key);
|
||||
let dnsProvider = cnameRecord.commonDnsProvider;
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
const domainParser = this.acme.options.domainParser;
|
||||
for (const fullDomain of domains) {
|
||||
const domain = fullDomain.replaceAll("*.", "");
|
||||
const mainDomain = await domainParser.parse(domain);
|
||||
const planSetting = verifyPlanSetting[mainDomain];
|
||||
if (planSetting.type === "dns") {
|
||||
await this.createDnsDomainVerifyPlan(planSetting[mainDomain], domain, mainDomain);
|
||||
} else if (planSetting.type === "cname") {
|
||||
await this.createCnameDomainVerifyPlan(domain, mainDomain);
|
||||
} else if (planSetting.type === "http") {
|
||||
await this.createHttpDomainVerifyPlan(planSetting.httpVerifyPlan[domain], domain, mainDomain);
|
||||
}
|
||||
plan[domain] = {
|
||||
domain,
|
||||
type: domainVerifyPlan.type,
|
||||
dnsProvider,
|
||||
cnameVerifyPlan,
|
||||
httpVerifyPlan,
|
||||
};
|
||||
}
|
||||
return plan;
|
||||
}
|
||||
|
||||
private async buildVerifyPlanInputByAuto() {
|
||||
private async createDomainsVerifyPlanByAuto(domains: string[]) {
|
||||
//从数据库里面自动选择校验方式
|
||||
// domain list
|
||||
const domainList = new Set<string>();
|
||||
|
@ -527,55 +490,84 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
domain = domain.replaceAll("*.", "");
|
||||
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) {
|
||||
const domain = verifier.domain;
|
||||
const mainDomain = verifier.mainDomain;
|
||||
let plan = verifyPlanInput[mainDomain];
|
||||
if (!plan) {
|
||||
plan = {
|
||||
domain: mainDomain,
|
||||
type: "cname",
|
||||
};
|
||||
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
|
||||
for (const domain in verifiers) {
|
||||
const verifier = verifiers[domain];
|
||||
if (verifier.type === "dns") {
|
||||
plan[domain] = await this.createDnsDomainVerifyPlan(verifier.dns, domain, verifier.mainDomain);
|
||||
} else if (verifier.type === "cname") {
|
||||
plan[domain] = await this.createCnameDomainVerifyPlan(domain, verifier.mainDomain);
|
||||
} else if (verifier.type === "http") {
|
||||
plan[domain] = await this.createHttpDomainVerifyPlan(verifier.http, domain, verifier.mainDomain);
|
||||
}
|
||||
}
|
||||
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,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import {ALL, Body, Controller, Inject, Post, Provide, Query} from '@midwayjs/core';
|
||||
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 { SubDomainsGetter } from '../../../modules/pipeline/service/getter/sub-domain-getter.js';
|
||||
|
||||
/**
|
||||
* 子域名托管
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import {Inject, Provide, Scope, ScopeEnum} from '@midwayjs/core';
|
||||
import {InjectEntityModel} from '@midwayjs/typeorm';
|
||||
import {Not, Repository} from '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';
|
||||
|
||||
|
||||
/**
|
||||
|
@ -16,6 +20,8 @@ export class DomainService extends BaseService<DomainEntity> {
|
|||
|
||||
@Inject()
|
||||
accessService: AccessService;
|
||||
@Inject()
|
||||
subDomainService: SubDomainService;
|
||||
|
||||
//@ts-ignore
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { INotificationService, NotificationSendReq } from '@certd/pipeline';
|
||||
import { NotificationService } from './notification-service.js';
|
||||
import {NotificationService} from "../notification-service.js";
|
||||
|
||||
export class NotificationGetter implements INotificationService {
|
||||
userId: number;
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ import {UrlService} from "./url-service.js";
|
|||
import {NotificationService} from "./notification-service.js";
|
||||
import {UserSuiteEntity, UserSuiteService} from "@certd/commercial-core";
|
||||
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 {set} from "lodash-es";
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import {InjectEntityModel} from '@midwayjs/typeorm';
|
|||
import {Repository} from 'typeorm';
|
||||
import {SubDomainEntity} from '../entity/sub-domain.js';
|
||||
import {EmailService} from '../../basic/service/email-service.js';
|
||||
import {ISubDomainsGetter} from "@certd/plugin-cert";
|
||||
|
||||
@Provide()
|
||||
@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)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue