oak-general-business/lib/utils/cos/aliyun.backend.js

160 lines
7.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const assert_1 = require("oak-domain/lib/utils/assert");
const aliyun_1 = tslib_1.__importDefault(require("./aliyun"));
const oak_external_sdk_1 = require("oak-external-sdk");
const Exception_1 = require("oak-domain/lib/types/Exception");
const sts_1 = require("oak-external-sdk/lib/service/ali/sts");
class ALiYunBackend extends aliyun_1.default {
getConfigAndInstance(application) {
const { config, account } = this.getConfig(application);
const instance = oak_external_sdk_1.ALiYunSDK.getInstance(account.accessKeyId, account.accessKeySecret);
return {
config,
instance,
account,
};
}
async composeFileUrlBackend(options) {
const { application, extraFile, context, style } = options;
const { config: aliyunCosConfig } = this.getConfig(application);
if (aliyunCosConfig) {
let bucket = aliyunCosConfig.buckets.find((ele) => ele.name === extraFile.bucket);
if (bucket) {
const { domain, protocol } = bucket;
let protocol2 = protocol;
if (protocol instanceof Array) {
// protocol存在https: 说明域名有证书
const index = protocol.includes('https:')
? protocol.findIndex((ele) => ele === 'https:')
: 0;
protocol2 = protocol[index];
}
return `${protocol2}//${domain}/${this.formKey(extraFile)}${style ? style : ''}`;
}
}
return '';
}
async formUploadMeta(application, extraFile) {
const { bucket } = extraFile;
// 构造文件上传所需的key
const key = this.formKey(extraFile);
const { instance, config: aliyunCosConfig } = this.getConfigAndInstance(application);
const { buckets } = aliyunCosConfig;
let bucket2 = bucket;
if (!bucket2) {
const { defaultBucket } = aliyunCosConfig;
bucket2 = defaultBucket;
}
(0, assert_1.assert)(bucket2);
const b = buckets.find((ele) => ele.name === bucket2);
(0, assert_1.assert)(b, `${bucket2}不是一个有效的桶配置`);
Object.assign(extraFile, {
bucket: bucket2,
uploadMeta: instance.getUploadInfo(bucket2, b.zone, key),
});
}
async checkWhetherSuccess(application, extraFile) {
const key = this.formKey(extraFile);
const { instance, config: aliyunCosConfig } = this.getConfigAndInstance(application);
const b = aliyunCosConfig.buckets.find((ele) => ele.name === extraFile.bucket);
(0, assert_1.assert)(b, `extraFile中的bucket名称在阿里云配置中找不到「${extraFile.bucket}`);
try {
const result = await instance.isExistObject(extraFile.bucket, b.zone, key);
return result;
}
catch (err) {
throw err;
}
}
async removeFile(application, extraFile) {
const key = this.formKey(extraFile);
const { instance, config: aliyunCosConfig } = this.getConfigAndInstance(application);
const b = aliyunCosConfig.buckets.find((ele) => ele.name === extraFile.bucket);
(0, assert_1.assert)(b, `extraFile中的bucket名称在阿里云配置中找不到「${extraFile.bucket}`);
try {
await instance.removeFile(extraFile.bucket, b.zone, key);
}
catch (err) {
throw err;
}
}
async composeChunkUploadInfo(application, extraFile, context) {
const key = this.formKey(extraFile);
const { instance, config: aliyunCosConfig, account } = this.getConfigAndInstance(application);
let useSts = true;
let stsInfo = {};
if (!account.stsEndpoint || !account.roleArn || !account.roleSessionName) {
useSts = false;
console.warn("阿里云Cos配置中缺少sts相关配置无法使用sts方式上传分片将使用账号授权进行上传可能存在安全风险请检查确保不会暴露accessKey");
}
else {
try {
const res = await (0, sts_1.stsAssumeRole)({
accessKeyId: account.accessKeyId,
accessKeySecret: account.accessKeySecret,
endpoint: account.stsEndpoint,
roleArn: account.roleArn,
roleSessionName: account.roleSessionName,
});
stsInfo = {
stsToken: res.Credentials.SecurityToken,
accessKeyId: res.Credentials.AccessKeyId,
accessKeySecret: res.Credentials.AccessKeySecret,
};
}
catch (err) {
console.error("Failed to assume role for STS:", err);
throw new Exception_1.OakPreConditionUnsetException("获取阿里云STS临时凭证失败请检查配置是否正确", 'extraFile');
}
}
// 大部分校验都在formUploadMeta中完成这里可以不多做判断了
const b = aliyunCosConfig.buckets.find((ele) => ele.name === extraFile.bucket);
const preInit = await instance.prepareMultipartUpload(extraFile.bucket, b.zone, key, extraFile.chunkInfo?.partCount, {
timeout: 30 * 1000, // 30 seconds
...(useSts ? stsInfo
: {}),
expires: 3 * 24 * 60 * 60, // 3 days
});
return {
uploadId: preInit.uploadId,
chunkSize: extraFile.chunkInfo?.chunkSize,
partCount: preInit.parts.length,
parts: preInit.parts.map((part) => ({
partNumber: part.partNumber,
uploadUrl: part.uploadUrl,
formData: {}, // 阿里云不需要额外的formData
})),
};
}
/**
* 完成分片上传后的合并操作
*/
async mergeChunkedUpload(application, extraFile, context) {
const key = this.formKey(extraFile);
const { instance, config: aliyunCosConfig } = this.getConfigAndInstance(application);
const b = aliyunCosConfig.buckets.find((ele) => ele.name === extraFile.bucket);
(0, assert_1.assert)(b, `extraFile中的bucket名称在阿里云配置中找不到「${extraFile.bucket}`);
await instance.completeMultipartUpload(extraFile.bucket, b.zone, key, extraFile.chunkInfo.uploadId, extraFile.chunkInfo.parts.map((part) => ({
number: part.partNumber,
etag: part.etag,
})));
}
async abortMultipartUpload(application, extraFile, context) {
const key = this.formKey(extraFile);
const { instance, config: aliyunCosConfig } = this.getConfigAndInstance(application);
const b = aliyunCosConfig.buckets.find((ele) => ele.name === extraFile.bucket);
(0, assert_1.assert)(b, `extraFile中的bucket名称在阿里云配置中找不到「${extraFile.bucket}`);
await instance.abortMultipartUpload(extraFile.bucket, b.zone, key, extraFile.chunkInfo.uploadId);
}
async listMultipartUploads(application, extraFile, context) {
const key = this.formKey(extraFile);
const { instance, config: aliyunCosConfig } = this.getConfigAndInstance(application);
const b = aliyunCosConfig.buckets.find((ele) => ele.name === extraFile.bucket);
(0, assert_1.assert)(b, `extraFile中的bucket名称在阿里云配置中找不到「${extraFile.bucket}`);
return await instance.listParts(extraFile.bucket, b.zone, key, extraFile.chunkInfo.uploadId);
}
}
exports.default = ALiYunBackend;