perf: 支持http校验方式申请证书

This commit is contained in:
xiaojunnuo
2025-01-02 00:28:13 +08:00
parent 67af67b92d
commit 405591c5d0
42 changed files with 820 additions and 74 deletions
@@ -0,0 +1,35 @@
import { IAccessService } from "@certd/pipeline";
import { ILogger, utils } from "@certd/basic";
export type HttpChallengeUploader = {
upload: (fileName: string, fileContent: string) => Promise<void>;
remove: (fileName: string) => Promise<void>;
};
export type HttpChallengeUploadContext = {
accessService: IAccessService;
logger: ILogger;
utils: typeof utils;
};
export abstract class BaseHttpChallengeUploader<A> implements HttpChallengeUploader {
rootDir: string;
access: A = null;
logger: ILogger;
utils: typeof utils;
ctx: HttpChallengeUploadContext;
protected constructor(opts: { rootDir: string; access: A }) {
this.rootDir = opts.rootDir;
this.access = opts.access;
}
async setCtx(ctx: any) {
// set context
this.ctx = ctx;
this.logger = ctx.logger;
this.utils = ctx.utils;
}
abstract remove(fileName: string): Promise<void>;
abstract upload(fileName: string, fileContent: string): Promise<void>;
}
@@ -0,0 +1,26 @@
export class HttpChallengeUploaderFactory {
async getClassByType(type: string) {
if (type === "alioss") {
return (await import("./impls/alioss.js")).AliossHttpChallengeUploader;
} else if (type === "ssh") {
return (await import("./impls/ssh.js")).SshHttpChallengeUploader;
} else if (type === "ftp") {
return (await import("./impls/ftp.js")).FtpHttpChallengeUploader;
} else if (type === "tencentcos") {
return (await import("./impls/tencentcos.js")).TencentCosHttpChallengeUploader;
} else if (type === "qiniuoss") {
return (await import("./impls/qiniuoss.js")).QiniuOssHttpChallengeUploader;
} else {
throw new Error(`暂不支持此文件上传方式: ${type}`);
}
}
createUploaderByType(type: string, opts: { rootDir: string; access: any }) {
const cls = this.getClassByType(type);
if (cls) {
// @ts-ignore
return new cls(opts);
}
}
}
export const httpChallengeUploaderFactory = new HttpChallengeUploaderFactory();
@@ -0,0 +1,36 @@
import { BaseHttpChallengeUploader } from "../api";
import { AliossAccess, AliyunAccess } from "@certd/plugin-lib";
import { AliossClient } from "@certd/plugin-lib/dist/aliyun/lib/oss-client";
export class AliossHttpChallengeUploader extends BaseHttpChallengeUploader<AliossAccess> {
async upload(filePath: string, fileContent: string) {
const aliyunAccess = await this.ctx.accessService.getById<AliyunAccess>(this.access.accessId);
const client = new AliossClient({
access: aliyunAccess,
bucket: this.access.bucket,
region: this.access.region,
});
await client.uploadFile(filePath, Buffer.from(fileContent));
this.logger.info(`校验文件上传成功: ${filePath}`);
}
async remove(filePath: string) {
// remove file from alioss
const client = await this.getAliossClient();
await client.removeFile(filePath);
this.logger.info(`文件删除成功: ${filePath}`);
}
private async getAliossClient() {
const aliyunAccess = await this.ctx.accessService.getById<AliyunAccess>(this.access.accessId);
const client = new AliossClient({
access: aliyunAccess,
bucket: this.access.bucket,
region: this.access.region,
});
await client.init();
return client;
}
}
@@ -0,0 +1,25 @@
import { BaseHttpChallengeUploader } from "../api";
import { FtpAccess } from "@certd/plugin-lib";
import { FtpClient } from "@certd/plugin-lib/dist/ftp/client";
export class FtpHttpChallengeUploader extends BaseHttpChallengeUploader<FtpAccess> {
async upload(fileName: string, fileContent: string) {
const client = new FtpClient({
access: this.access,
logger: this.logger,
});
await client.connect(async (client) => {
await client.upload(fileName, fileContent);
});
}
async remove(fileName: string) {
const client = new FtpClient({
access: this.access,
logger: this.logger,
});
await client.connect(async (client) => {
await client.client.remove(fileName);
});
}
}
@@ -0,0 +1,10 @@
import { BaseHttpChallengeUploader } from "../api";
import { FtpAccess } from "@certd/plugin-lib";
export class QiniuOssHttpChallengeUploader extends BaseHttpChallengeUploader<FtpAccess> {
async upload(fileName: string, fileContent: string) {
return null;
}
async remove(fileName: string) {}
}
@@ -0,0 +1,38 @@
import { BaseHttpChallengeUploader } from "../api";
import { SshAccess, SshClient } from "@certd/plugin-lib";
import path from "path";
import os from "os";
import fs from "fs";
export class SshHttpChallengeUploader extends BaseHttpChallengeUploader<SshAccess> {
async upload(fileName: string, fileContent: string) {
const tmpFilePath = path.join(os.tmpdir(), "cert", "http", fileName);
// Write file to temp path
fs.writeFileSync(tmpFilePath, fileContent);
try {
const client = new SshClient(this.logger);
await client.uploadFiles({
connectConf: this.access,
mkdirs: true,
transports: [
{
localPath: fileName,
remotePath: fileName,
},
],
});
} finally {
// Remove temp file
fs.unlinkSync(tmpFilePath);
}
}
async remove(filePath: string) {
const client = new SshClient(this.logger);
await client.removeFiles({
connectConf: this.access,
files: [filePath],
});
}
}
@@ -0,0 +1,10 @@
import { BaseHttpChallengeUploader } from "../api";
import { FtpAccess } from "@certd/plugin-lib";
export class TencentCosHttpChallengeUploader extends BaseHttpChallengeUploader<FtpAccess> {
async upload(fileName: string, fileContent: string) {
return null;
}
async remove(fileName: string) {}
}