feat: 域名验证方法支持CNAME间接方式,此方式支持所有域名注册商,且无需提供Access授权,但是需要手动添加cname解析

This commit is contained in:
xiaojunnuo
2024-10-07 03:21:16 +08:00
parent 0c8e83e125
commit f3d35084ed
123 changed files with 2373 additions and 456 deletions
@@ -8,7 +8,7 @@ import { HistoryLogEntity } from '../entity/history-log.js';
import { PipelineService } from '../service/pipeline-service.js';
import * as fs from 'fs';
import { logger } from '@certd/pipeline';
import { AuthService } from '../../authority/service/auth-service.js';
import { AuthService } from '../../sys/authority/service/auth-service.js';
import { SysSettingsService } from '@certd/lib-server';
import { In } from 'typeorm';
@@ -4,7 +4,7 @@ import { PipelineService } from '../service/pipeline-service.js';
import { PipelineEntity } from '../entity/pipeline.js';
import { Constants } from '@certd/lib-server';
import { HistoryService } from '../service/history-service.js';
import { AuthService } from '../../authority/service/auth-service.js';
import { AuthService } from '../../sys/authority/service/auth-service.js';
import { SysSettingsService } from '@certd/lib-server';
/**
@@ -0,0 +1,14 @@
import { IAccessService } from '@certd/pipeline';
export class AccessGetter implements IAccessService {
userId: number;
getter: <T>(id: any, userId?: number) => Promise<T>;
constructor(userId: number, getter: (id: any, userId: number) => Promise<any>) {
this.userId = userId;
this.getter = getter;
}
async getById<T = any>(id: any) {
return await this.getter<T>(id, this.userId);
}
}
@@ -1,18 +1,17 @@
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { BaseService } from '@certd/lib-server';
import { BaseService, PermissionException, ValidateException } from '@certd/lib-server';
import { AccessEntity } from '../entity/access.js';
import { AccessDefine, accessRegistry, IAccessService, newAccess } from '@certd/pipeline';
import { AccessDefine, accessRegistry, newAccess } from '@certd/pipeline';
import { EncryptService } from './encrypt-service.js';
import { ValidateException } from '@certd/lib-server';
/**
* 授权
*/
@Provide()
@Scope(ScopeEnum.Singleton)
export class AccessService extends BaseService<AccessEntity> implements IAccessService {
export class AccessService extends BaseService<AccessEntity> {
@InjectEntityModel(AccessEntity)
repository: Repository<AccessEntity>;
@@ -102,11 +101,14 @@ export class AccessService extends BaseService<AccessEntity> implements IAccessS
return await super.update(param);
}
async getById(id: any): Promise<any> {
async getById(id: any, userId?: number): Promise<any> {
const entity = await this.info(id);
if (entity == null) {
throw new Error(`该授权配置不存在,请确认是否已被删除:id=${id}`);
}
if (userId !== entity.userId) {
throw new PermissionException('您对该授权无访问权限');
}
// const access = accessRegistry.get(entity.type);
const setting = this.decryptAccessEntity(entity);
const input = {
@@ -0,0 +1,14 @@
import { CnameRecord, ICnameProxyService } from '@certd/pipeline';
export class CnameProxyService implements ICnameProxyService {
userId: number;
getter: <T>(domain: string, userId?: number) => Promise<T>;
constructor(userId: number, getter: (domain: string, userId: number) => Promise<any>) {
this.userId = userId;
this.getter = getter;
}
getByDomain(domain: string): Promise<CnameRecord> {
return this.getter<CnameRecord>(domain, this.userId);
}
}
@@ -16,7 +16,10 @@ import { HistoryLogService } from './history-log-service.js';
import { logger } from '@certd/pipeline';
import { EmailService } from '../../basic/service/email-service.js';
import { NeedVIPException } from '@certd/lib-server';
import { UserService } from '../../authority/service/user-service.js';
import { UserService } from '../../sys/authority/service/user-service.js';
import { AccessGetter } from './access-getter.js';
import { CnameRecordService } from '../../cname/service/cname-record-service.js';
import { CnameProxyService } from './cname-proxy-service.js';
const runningTasks: Map<string | number, Executor> = new Map();
const freeCount = 10;
@@ -34,6 +37,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
@Inject()
accessService: AccessService;
@Inject()
cnameRecordService: CnameRecordService;
@Inject()
storageService: StorageService;
@Inject()
historyService: HistoryService;
@@ -341,11 +346,14 @@ export class PipelineService extends BaseService<PipelineEntity> {
id: userId,
role: userIsAdmin ? 'admin' : 'user',
};
const accessGetter = new AccessGetter(userId, this.accessService.getById.bind(this.accessService));
const cnameProxyService = new CnameProxyService(userId, this.cnameRecordService.getByDomain.bind(this.cnameRecordService));
const executor = new Executor({
user,
pipeline,
onChanged,
accessService: this.accessService,
accessService: accessGetter,
cnameProxyService,
storage: new DbStorage(userId, this.storageService),
emailService: this.emailService,
fileRootDir: this.certdConfig.fileRootDir,