mirror of
https://github.com/certd/certd.git
synced 2026-04-14 12:30:54 +08:00
181 lines
5.3 KiB
TypeScript
181 lines
5.3 KiB
TypeScript
import { HttpClient, ILogger, utils } from "@certd/basic";
|
||
import { QiniuAccess } from "../access.js";
|
||
import fs from "fs";
|
||
|
||
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 | string) {
|
||
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();
|
||
let res: any = {};
|
||
if (typeof content === "string") {
|
||
const readableStream = fs.createReadStream(content);
|
||
res = await formUploader.putStream(uploadToken, key, readableStream, putExtra);
|
||
} else {
|
||
// 文件上传
|
||
res = await formUploader.put(uploadToken, key, content, putExtra);
|
||
}
|
||
const { data, resp } = res;
|
||
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 bucketManager = await this.getBucketManager();
|
||
|
||
const { resp } = await bucketManager.delete(bucket, key);
|
||
|
||
if (resp.statusCode === 200) {
|
||
this.logger.info("文件删除成功:" + key);
|
||
return;
|
||
} else {
|
||
throw new Error("删除失败:" + JSON.stringify(resp));
|
||
}
|
||
}
|
||
|
||
async downloadFile(bucket: string, path: string, savePath: string) {
|
||
const bucketManager = await this.getBucketManager();
|
||
const privateBucketDomain = `http://${bucket}.qiniudn.com`;
|
||
const deadline = Math.floor(Date.now() / 1000) + 3600; // 1小时过期
|
||
const privateDownloadUrl = bucketManager.privateDownloadUrl(privateBucketDomain, path, deadline);
|
||
|
||
await utils.request.download({
|
||
http: this.http,
|
||
logger: this.logger,
|
||
config: {
|
||
url: privateDownloadUrl,
|
||
method: "get",
|
||
},
|
||
savePath,
|
||
});
|
||
}
|
||
|
||
private async getBucketManager() {
|
||
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;
|
||
return new qiniu.rs.BucketManager(mac, config);
|
||
}
|
||
|
||
async listDir(bucket: string, path: string) {
|
||
const bucketManager = await this.getBucketManager();
|
||
const res = await bucketManager.listPrefix(bucket, {
|
||
prefix: path,
|
||
limit: 1000,
|
||
});
|
||
return res.data;
|
||
}
|
||
}
|