mirror of
https://github.com/certd/certd.git
synced 2026-04-16 05:50:50 +08:00
perf: http校验方式,支持七牛云oss、阿里云oss、腾讯云cos
This commit is contained in:
@@ -1 +1,3 @@
|
||||
export * from "./access.js";
|
||||
export * from "./access-oss.js";
|
||||
export * from "./lib/sdk.js";
|
||||
|
||||
142
packages/plugins/plugin-lib/src/qiniu/lib/sdk.ts
Normal file
142
packages/plugins/plugin-lib/src/qiniu/lib/sdk.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
import { HttpClient, ILogger } from "@certd/basic";
|
||||
import { QiniuAccess } from "../access.js";
|
||||
|
||||
export type QiniuCertInfo = {
|
||||
key: string;
|
||||
crt: string;
|
||||
};
|
||||
export class QiniuClient {
|
||||
http: HttpClient;
|
||||
access: QiniuAccess;
|
||||
logger: ILogger;
|
||||
constructor(opts: { http: HttpClient; access: QiniuAccess; logger: ILogger }) {
|
||||
this.http = opts.http;
|
||||
this.access = opts.access;
|
||||
this.logger = opts.logger;
|
||||
}
|
||||
|
||||
async uploadCert(cert: QiniuCertInfo, certName?: string) {
|
||||
const url = "https://api.qiniu.com/sslcert";
|
||||
|
||||
const body = {
|
||||
name: certName,
|
||||
common_name: "certd",
|
||||
pri: cert.key,
|
||||
ca: cert.crt,
|
||||
};
|
||||
|
||||
const res = await this.doRequest(url, "post", body);
|
||||
|
||||
return res.certID;
|
||||
}
|
||||
|
||||
async bindCert(body: { certid: string; domain: string }) {
|
||||
const url = "https://api.qiniu.com/cert/bind";
|
||||
return await this.doRequest(url, "post", body);
|
||||
}
|
||||
|
||||
async getCertBindings() {
|
||||
const url = "https://api.qiniu.com/cert/bindings";
|
||||
const res = await this.doRequest(url, "get");
|
||||
return res;
|
||||
}
|
||||
|
||||
async doRequest(url: string, method: string, body?: any) {
|
||||
const { generateAccessToken } = await import("qiniu/qiniu/util.js");
|
||||
const token = generateAccessToken(this.access, url);
|
||||
const res = await this.http.request({
|
||||
url,
|
||||
method: method,
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
data: body,
|
||||
logRes: false,
|
||||
});
|
||||
if (res && res.error) {
|
||||
if (res.error.includes("domaintype")) {
|
||||
throw new Error("请求失败:" + res.error + ",该域名属于CDN域名,请使用部署到七牛云CDN插件");
|
||||
}
|
||||
throw new Error("请求失败:" + res.error);
|
||||
}
|
||||
console.log("res", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
async doRequestV2(opts: { url: string; method: string; body?: any; contentType: string }) {
|
||||
const { HttpClient } = await import("qiniu/qiniu/httpc/client.js");
|
||||
const { QiniuAuthMiddleware } = await import("qiniu/qiniu/httpc/middleware/qiniuAuth.js");
|
||||
// X-Qiniu-Date: 20060102T150405Z
|
||||
const auth = new QiniuAuthMiddleware({
|
||||
mac: {
|
||||
...this.access,
|
||||
options: {},
|
||||
},
|
||||
});
|
||||
const http = new HttpClient({ timeout: 10000, middlewares: [auth] });
|
||||
console.log("http", http);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
http.get({
|
||||
url: opts.url,
|
||||
headers: {
|
||||
"Content-Type": opts.contentType,
|
||||
},
|
||||
callback: (nullable, res) => {
|
||||
console.log("nullable", nullable, "res", res);
|
||||
if (res?.error) {
|
||||
reject(res);
|
||||
} else {
|
||||
resolve(res);
|
||||
}
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async uploadFile(bucket: string, key: string, content: Buffer) {
|
||||
const sdk = await import("qiniu");
|
||||
const qiniu = sdk.default;
|
||||
const mac = new qiniu.auth.digest.Mac(this.access.accessKey, this.access.secretKey);
|
||||
const options = {
|
||||
scope: bucket,
|
||||
};
|
||||
const putPolicy = new qiniu.rs.PutPolicy(options);
|
||||
const uploadToken = putPolicy.uploadToken(mac);
|
||||
|
||||
const config = new qiniu.conf.Config();
|
||||
const formUploader = new qiniu.form_up.FormUploader(config);
|
||||
const putExtra = new qiniu.form_up.PutExtra();
|
||||
// 文件上传
|
||||
const { data, resp } = await formUploader.put(uploadToken, key, content, putExtra);
|
||||
if (resp.statusCode === 200) {
|
||||
this.logger.info("文件上传成功:" + key);
|
||||
return data;
|
||||
} else {
|
||||
console.log(resp.statusCode);
|
||||
throw new Error("上传失败:" + JSON.stringify(resp));
|
||||
}
|
||||
}
|
||||
|
||||
async removeFile(bucket: string, key: string) {
|
||||
const sdk = await import("qiniu");
|
||||
const qiniu = sdk.default;
|
||||
const mac = new qiniu.auth.digest.Mac(this.access.accessKey, this.access.secretKey);
|
||||
const config = new qiniu.conf.Config();
|
||||
config.useHttpsDomain = true;
|
||||
const bucketManager = new qiniu.rs.BucketManager(mac, config);
|
||||
|
||||
const { resp } = await bucketManager.delete(bucket, key);
|
||||
|
||||
if (resp.statusCode === 200) {
|
||||
this.logger.info("文件删除成功:" + key);
|
||||
return;
|
||||
} else {
|
||||
throw new Error("删除失败:" + JSON.stringify(resp));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,3 +61,5 @@ export class TencentCosAccess extends BaseAccess {
|
||||
})
|
||||
bucket = "";
|
||||
}
|
||||
|
||||
new TencentCosAccess();
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
export * from "./access.js";
|
||||
export * from "./access-cos.js";
|
||||
export * from "./lib/index.js";
|
||||
|
||||
69
packages/plugins/plugin-lib/src/tencent/lib/cos-client.ts
Normal file
69
packages/plugins/plugin-lib/src/tencent/lib/cos-client.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { TencentAccess } from "../access.js";
|
||||
import { ILogger } from "@certd/basic";
|
||||
|
||||
export class TencentCosClient {
|
||||
access: TencentAccess;
|
||||
logger: ILogger;
|
||||
region: string;
|
||||
bucket: string;
|
||||
|
||||
constructor(opts: { access: TencentAccess; logger: ILogger; region: string; bucket: string }) {
|
||||
this.access = opts.access;
|
||||
this.logger = opts.logger;
|
||||
this.bucket = opts.bucket;
|
||||
this.region = opts.region;
|
||||
}
|
||||
|
||||
async getCosClient() {
|
||||
const sdk = await import("cos-nodejs-sdk-v5");
|
||||
const clientConfig = {
|
||||
SecretId: this.access.secretId,
|
||||
SecretKey: this.access.secretKey,
|
||||
};
|
||||
return new sdk.default(clientConfig);
|
||||
}
|
||||
|
||||
async uploadFile(key: string, file: Buffer) {
|
||||
const cos = await this.getCosClient();
|
||||
return new Promise((resolve, reject) => {
|
||||
cos.putObject(
|
||||
{
|
||||
Bucket: this.bucket /* 必须 */,
|
||||
Region: this.region /* 必须 */,
|
||||
Key: key /* 必须 */,
|
||||
Body: file, // 上传文件对象
|
||||
onProgress: function (progressData) {
|
||||
console.log(JSON.stringify(progressData));
|
||||
},
|
||||
},
|
||||
function (err, data) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
resolve(data);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async removeFile(key: string) {
|
||||
const cos = await this.getCosClient();
|
||||
return new Promise((resolve, reject) => {
|
||||
cos.deleteObject(
|
||||
{
|
||||
Bucket: this.bucket,
|
||||
Region: this.region,
|
||||
Key: key,
|
||||
},
|
||||
function (err, data) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
resolve(data);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
2
packages/plugins/plugin-lib/src/tencent/lib/index.ts
Normal file
2
packages/plugins/plugin-lib/src/tencent/lib/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./ssl-client.js";
|
||||
export * from "./cos-client.js";
|
||||
79
packages/plugins/plugin-lib/src/tencent/lib/ssl-client.ts
Normal file
79
packages/plugins/plugin-lib/src/tencent/lib/ssl-client.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { ILogger } from "@certd/basic";
|
||||
import { TencentAccess } from "../access.js";
|
||||
|
||||
export type TencentCertInfo = {
|
||||
key: string;
|
||||
crt: string;
|
||||
};
|
||||
export class TencentSslClient {
|
||||
access: TencentAccess;
|
||||
logger: ILogger;
|
||||
region?: string;
|
||||
constructor(opts: { access: TencentAccess; logger: ILogger; region?: string }) {
|
||||
this.access = opts.access;
|
||||
this.logger = opts.logger;
|
||||
this.region = opts.region;
|
||||
}
|
||||
async getSslClient(): Promise<any> {
|
||||
const sdk = await import("tencentcloud-sdk-nodejs/tencentcloud/services/ssl/v20191205/index.js");
|
||||
const SslClient = sdk.v20191205.Client;
|
||||
|
||||
const clientConfig = {
|
||||
credential: {
|
||||
secretId: this.access.secretId,
|
||||
secretKey: this.access.secretKey,
|
||||
},
|
||||
region: this.region,
|
||||
profile: {
|
||||
httpProfile: {
|
||||
endpoint: "ssl.tencentcloudapi.com",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return new SslClient(clientConfig);
|
||||
}
|
||||
|
||||
checkRet(ret: any) {
|
||||
if (!ret || ret.Error) {
|
||||
throw new Error("请求失败:" + ret.Error.Code + "," + ret.Error.Message);
|
||||
}
|
||||
}
|
||||
|
||||
async uploadToTencent(opts: { certName: string; cert: TencentCertInfo }): Promise<string> {
|
||||
const client = await this.getSslClient();
|
||||
const params = {
|
||||
CertificatePublicKey: opts.cert.crt,
|
||||
CertificatePrivateKey: opts.cert.key,
|
||||
Alias: opts.certName,
|
||||
};
|
||||
const ret = await client.UploadCertificate(params);
|
||||
this.checkRet(ret);
|
||||
this.logger.info("证书上传成功:tencentCertId=", ret.CertificateId);
|
||||
return ret.CertificateId;
|
||||
}
|
||||
|
||||
async deployCertificateInstance(params: any) {
|
||||
const client = await this.getSslClient();
|
||||
const res = await client.DeployCertificateInstance(params);
|
||||
this.checkRet(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
async DescribeCertificates(params: any) {
|
||||
const client = await this.getSslClient();
|
||||
const res = await client.DescribeCertificates(params);
|
||||
this.checkRet(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
async doRequest(action: string, params: any) {
|
||||
const client = await this.getSslClient();
|
||||
if (!client[action]) {
|
||||
throw new Error(`action ${action} not found`);
|
||||
}
|
||||
const res = await client[action](params);
|
||||
this.checkRet(res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user