feat: 添加多项功能和修复
功能新增: - OSS 存储使用情况显示(文件页面) - OSS 当日流量统计(阿里云云监控API) - 分享页面路由修复(/s/xxx 格式支持) Bug修复: - 修复分享页面资源路径(相对路径改绝对路径) - 修复分享码获取逻辑(支持路径格式) - 修复OSS配额undefined显示问题 - 修复登录流程OSS配置检查 - 修复文件数为null时的显示问题 依赖更新: - 添加 @alicloud/cms20190101 云监控SDK - 添加 @alicloud/openapi-client Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
35
backend/node_modules/@alicloud/gateway-pop/dist/client.d.ts
generated
vendored
Normal file
35
backend/node_modules/@alicloud/gateway-pop/dist/client.d.ts
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/// <reference types="node" />
|
||||
import SPI, * as $SPI from '@alicloud/gateway-spi';
|
||||
export default class Client extends SPI {
|
||||
_sha256: string;
|
||||
_sm3: string;
|
||||
constructor();
|
||||
modifyConfiguration(context: $SPI.InterceptorContext, attributeMap: $SPI.AttributeMap): Promise<void>;
|
||||
modifyRequest(context: $SPI.InterceptorContext, attributeMap: $SPI.AttributeMap): Promise<void>;
|
||||
modifyResponse(context: $SPI.InterceptorContext, attributeMap: $SPI.AttributeMap): Promise<void>;
|
||||
getEndpoint(productId: string, regionId: string, endpointRule: string, network: string, suffix: string, endpointMap: {
|
||||
[key: string]: string;
|
||||
}, endpoint: string): string;
|
||||
defaultAny(inputValue: any, defaultValue: any): any;
|
||||
getAuthorization(pathname: string, method: string, query: {
|
||||
[key: string]: string;
|
||||
}, headers: {
|
||||
[key: string]: string;
|
||||
}, signatureAlgorithm: string, payload: string, ak: string, signingkey: Buffer, product: string, region: string, date: string): Promise<string>;
|
||||
getSignature(pathname: string, method: string, query: {
|
||||
[key: string]: string;
|
||||
}, headers: {
|
||||
[key: string]: string;
|
||||
}, signatureAlgorithm: string, payload: string, signingkey: Buffer): Promise<string>;
|
||||
getSigningkey(signatureAlgorithm: string, secret: string, product: string, region: string, date: string): Promise<Buffer>;
|
||||
getRegion(product: string, endpoint: string): string;
|
||||
buildCanonicalizedResource(query: {
|
||||
[key: string]: string;
|
||||
}): Promise<string>;
|
||||
buildCanonicalizedHeaders(headers: {
|
||||
[key: string]: string;
|
||||
}): Promise<string>;
|
||||
getSignedHeaders(headers: {
|
||||
[key: string]: string;
|
||||
}): Promise<string[]>;
|
||||
}
|
||||
288
backend/node_modules/@alicloud/gateway-pop/dist/client.js
generated
vendored
Normal file
288
backend/node_modules/@alicloud/gateway-pop/dist/client.js
generated
vendored
Normal file
@@ -0,0 +1,288 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
// This file is auto-generated, don't edit it
|
||||
const gateway_spi_1 = __importDefault(require("@alicloud/gateway-spi"));
|
||||
const tea_util_1 = __importDefault(require("@alicloud/tea-util"));
|
||||
const openapi_util_1 = __importDefault(require("@alicloud/openapi-util"));
|
||||
const endpoint_util_1 = __importDefault(require("@alicloud/endpoint-util"));
|
||||
const darabonba_encode_util_1 = __importDefault(require("@alicloud/darabonba-encode-util"));
|
||||
const darabonba_signature_util_1 = __importDefault(require("@alicloud/darabonba-signature-util"));
|
||||
const darabonba_string_1 = __importDefault(require("@alicloud/darabonba-string"));
|
||||
const darabonba_map_1 = __importDefault(require("@alicloud/darabonba-map"));
|
||||
const darabonba_array_1 = __importDefault(require("@alicloud/darabonba-array"));
|
||||
const $tea = __importStar(require("@alicloud/tea-typescript"));
|
||||
class Client extends gateway_spi_1.default {
|
||||
constructor() {
|
||||
super();
|
||||
this._sha256 = "ACS4-HMAC-SHA256";
|
||||
this._sm3 = "ACS4-HMAC-SM3";
|
||||
}
|
||||
async modifyConfiguration(context, attributeMap) {
|
||||
let request = context.request;
|
||||
let config = context.configuration;
|
||||
config.endpoint = this.getEndpoint(request.productId, config.regionId, config.endpointRule, config.network, config.suffix, config.endpointMap, config.endpoint);
|
||||
}
|
||||
async modifyRequest(context, attributeMap) {
|
||||
let request = context.request;
|
||||
let config = context.configuration;
|
||||
let date = openapi_util_1.default.getTimestamp();
|
||||
request.headers = Object.assign({ host: config.endpoint, 'x-acs-version': request.version, 'x-acs-action': request.action, 'user-agent': request.userAgent, 'x-acs-date': date, 'x-acs-signature-nonce': tea_util_1.default.getNonce(), accept: "application/json" }, request.headers);
|
||||
let signatureAlgorithm = tea_util_1.default.defaultString(request.signatureAlgorithm, this._sha256);
|
||||
let hashedRequestPayload = darabonba_encode_util_1.default.hexEncode(darabonba_encode_util_1.default.hash(tea_util_1.default.toBytes(""), signatureAlgorithm));
|
||||
if (!tea_util_1.default.isUnset(request.stream)) {
|
||||
let tmp = await tea_util_1.default.readAsBytes(request.stream);
|
||||
hashedRequestPayload = darabonba_encode_util_1.default.hexEncode(darabonba_encode_util_1.default.hash(tmp, signatureAlgorithm));
|
||||
request.stream = new $tea.BytesReadable(tmp);
|
||||
request.headers["content-type"] = "application/octet-stream";
|
||||
}
|
||||
else {
|
||||
if (!tea_util_1.default.isUnset(request.body)) {
|
||||
if (tea_util_1.default.equalString(request.reqBodyType, "json")) {
|
||||
let jsonObj = tea_util_1.default.toJSONString(request.body);
|
||||
hashedRequestPayload = darabonba_encode_util_1.default.hexEncode(darabonba_encode_util_1.default.hash(tea_util_1.default.toBytes(jsonObj), signatureAlgorithm));
|
||||
request.stream = new $tea.BytesReadable(jsonObj);
|
||||
request.headers["content-type"] = "application/json; charset=utf-8";
|
||||
}
|
||||
else {
|
||||
let m = tea_util_1.default.assertAsMap(request.body);
|
||||
let formObj = openapi_util_1.default.toForm(m);
|
||||
hashedRequestPayload = darabonba_encode_util_1.default.hexEncode(darabonba_encode_util_1.default.hash(tea_util_1.default.toBytes(formObj), signatureAlgorithm));
|
||||
request.stream = new $tea.BytesReadable(formObj);
|
||||
request.headers["content-type"] = "application/x-www-form-urlencoded";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tea_util_1.default.equalString(signatureAlgorithm, this._sm3)) {
|
||||
request.headers["x-acs-content-sm3"] = hashedRequestPayload;
|
||||
}
|
||||
else {
|
||||
request.headers["x-acs-content-sha256"] = hashedRequestPayload;
|
||||
}
|
||||
if (!tea_util_1.default.equalString(request.authType, "Anonymous")) {
|
||||
let credential = request.credential;
|
||||
if (tea_util_1.default.isUnset(credential)) {
|
||||
throw $tea.newError({
|
||||
code: "ParameterMissing",
|
||||
message: "'config.credential' can not be unset",
|
||||
});
|
||||
}
|
||||
let authType = credential.getType();
|
||||
if (tea_util_1.default.equalString(authType, "bearer")) {
|
||||
let bearerToken = credential.getBearerToken();
|
||||
request.headers["x-acs-bearer-token"] = bearerToken;
|
||||
request.headers["Authorization"] = `Bearer ${bearerToken}`;
|
||||
}
|
||||
else {
|
||||
let accessKeyId = await credential.getAccessKeyId();
|
||||
let accessKeySecret = await credential.getAccessKeySecret();
|
||||
let securityToken = await credential.getSecurityToken();
|
||||
if (!tea_util_1.default.empty(securityToken)) {
|
||||
request.headers["x-acs-accesskey-id"] = accessKeyId;
|
||||
request.headers["x-acs-security-token"] = securityToken;
|
||||
}
|
||||
let dateNew = darabonba_string_1.default.subString(date, 0, 10);
|
||||
dateNew = darabonba_string_1.default.replace(dateNew, "-", "", null);
|
||||
let region = this.getRegion(request.productId, config.endpoint);
|
||||
let signingkey = await this.getSigningkey(signatureAlgorithm, accessKeySecret, request.productId, region, dateNew);
|
||||
request.headers["Authorization"] = await this.getAuthorization(request.pathname, request.method, request.query, request.headers, signatureAlgorithm, hashedRequestPayload, accessKeyId, signingkey, request.productId, region, dateNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
async modifyResponse(context, attributeMap) {
|
||||
let request = context.request;
|
||||
let response = context.response;
|
||||
if (tea_util_1.default.is4xx(response.statusCode) || tea_util_1.default.is5xx(response.statusCode)) {
|
||||
let _res = await tea_util_1.default.readAsJSON(response.body);
|
||||
let err = tea_util_1.default.assertAsMap(_res);
|
||||
let requestId = this.defaultAny(err["RequestId"], err["requestId"]);
|
||||
if (!tea_util_1.default.isUnset(response.headers["x-acs-request-id"])) {
|
||||
requestId = response.headers["x-acs-request-id"];
|
||||
}
|
||||
err["statusCode"] = response.statusCode;
|
||||
throw $tea.newError({
|
||||
code: `${this.defaultAny(err["Code"], err["code"])}`,
|
||||
message: `code: ${response.statusCode}, ${this.defaultAny(err["Message"], err["message"])} request id: ${requestId}`,
|
||||
data: err,
|
||||
description: `${this.defaultAny(err["Description"], err["description"])}`,
|
||||
accessDeniedDetail: this.defaultAny(err["AccessDeniedDetail"], err["accessDeniedDetail"]),
|
||||
});
|
||||
}
|
||||
if (tea_util_1.default.equalNumber(response.statusCode, 204)) {
|
||||
await tea_util_1.default.readAsString(response.body);
|
||||
}
|
||||
else if (tea_util_1.default.equalString(request.bodyType, "binary")) {
|
||||
response.deserializedBody = response.body;
|
||||
}
|
||||
else if (tea_util_1.default.equalString(request.bodyType, "byte")) {
|
||||
let byt = await tea_util_1.default.readAsBytes(response.body);
|
||||
response.deserializedBody = byt;
|
||||
}
|
||||
else if (tea_util_1.default.equalString(request.bodyType, "string")) {
|
||||
let str = await tea_util_1.default.readAsString(response.body);
|
||||
response.deserializedBody = str;
|
||||
}
|
||||
else if (tea_util_1.default.equalString(request.bodyType, "json")) {
|
||||
let obj = await tea_util_1.default.readAsJSON(response.body);
|
||||
let res = tea_util_1.default.assertAsMap(obj);
|
||||
response.deserializedBody = res;
|
||||
}
|
||||
else if (tea_util_1.default.equalString(request.bodyType, "array")) {
|
||||
let arr = await tea_util_1.default.readAsJSON(response.body);
|
||||
response.deserializedBody = arr;
|
||||
}
|
||||
else {
|
||||
response.deserializedBody = await tea_util_1.default.readAsString(response.body);
|
||||
}
|
||||
}
|
||||
getEndpoint(productId, regionId, endpointRule, network, suffix, endpointMap, endpoint) {
|
||||
if (!tea_util_1.default.empty(endpoint)) {
|
||||
return endpoint;
|
||||
}
|
||||
if (!tea_util_1.default.isUnset(endpointMap) && !tea_util_1.default.empty(endpointMap[regionId])) {
|
||||
return endpointMap[regionId];
|
||||
}
|
||||
return endpoint_util_1.default.getEndpointRules(productId, regionId, endpointRule, network, suffix);
|
||||
}
|
||||
defaultAny(inputValue, defaultValue) {
|
||||
if (tea_util_1.default.isUnset(inputValue)) {
|
||||
return defaultValue;
|
||||
}
|
||||
return inputValue;
|
||||
}
|
||||
async getAuthorization(pathname, method, query, headers, signatureAlgorithm, payload, ak, signingkey, product, region, date) {
|
||||
let signature = await this.getSignature(pathname, method, query, headers, signatureAlgorithm, payload, signingkey);
|
||||
let signedHeaders = await this.getSignedHeaders(headers);
|
||||
let signedHeadersStr = darabonba_array_1.default.join(signedHeaders, ";");
|
||||
return `${signatureAlgorithm} Credential=${ak}/${date}/${region}/${product}/aliyun_v4_request,SignedHeaders=${signedHeadersStr},Signature=${signature}`;
|
||||
}
|
||||
async getSignature(pathname, method, query, headers, signatureAlgorithm, payload, signingkey) {
|
||||
let canonicalURI = "/";
|
||||
if (!tea_util_1.default.empty(pathname)) {
|
||||
canonicalURI = pathname;
|
||||
}
|
||||
let stringToSign = "";
|
||||
let canonicalizedResource = await this.buildCanonicalizedResource(query);
|
||||
let canonicalizedHeaders = await this.buildCanonicalizedHeaders(headers);
|
||||
let signedHeaders = await this.getSignedHeaders(headers);
|
||||
let signedHeadersStr = darabonba_array_1.default.join(signedHeaders, ";");
|
||||
stringToSign = `${method}\n${canonicalURI}\n${canonicalizedResource}\n${canonicalizedHeaders}\n${signedHeadersStr}\n${payload}`;
|
||||
let hex = darabonba_encode_util_1.default.hexEncode(darabonba_encode_util_1.default.hash(tea_util_1.default.toBytes(stringToSign), signatureAlgorithm));
|
||||
stringToSign = `${signatureAlgorithm}\n${hex}`;
|
||||
let signature = tea_util_1.default.toBytes("");
|
||||
if (tea_util_1.default.equalString(signatureAlgorithm, this._sha256)) {
|
||||
signature = darabonba_signature_util_1.default.HmacSHA256SignByBytes(stringToSign, signingkey);
|
||||
}
|
||||
else if (tea_util_1.default.equalString(signatureAlgorithm, this._sm3)) {
|
||||
signature = darabonba_signature_util_1.default.HmacSM3SignByBytes(stringToSign, signingkey);
|
||||
}
|
||||
return darabonba_encode_util_1.default.hexEncode(signature);
|
||||
}
|
||||
async getSigningkey(signatureAlgorithm, secret, product, region, date) {
|
||||
let sc1 = `aliyun_v4${secret}`;
|
||||
let sc2 = tea_util_1.default.toBytes("");
|
||||
if (tea_util_1.default.equalString(signatureAlgorithm, this._sha256)) {
|
||||
sc2 = darabonba_signature_util_1.default.HmacSHA256Sign(date, sc1);
|
||||
}
|
||||
else if (tea_util_1.default.equalString(signatureAlgorithm, this._sm3)) {
|
||||
sc2 = darabonba_signature_util_1.default.HmacSM3Sign(date, sc1);
|
||||
}
|
||||
let sc3 = tea_util_1.default.toBytes("");
|
||||
if (tea_util_1.default.equalString(signatureAlgorithm, this._sha256)) {
|
||||
sc3 = darabonba_signature_util_1.default.HmacSHA256SignByBytes(region, sc2);
|
||||
}
|
||||
else if (tea_util_1.default.equalString(signatureAlgorithm, this._sm3)) {
|
||||
sc3 = darabonba_signature_util_1.default.HmacSM3SignByBytes(region, sc2);
|
||||
}
|
||||
let sc4 = tea_util_1.default.toBytes("");
|
||||
if (tea_util_1.default.equalString(signatureAlgorithm, this._sha256)) {
|
||||
sc4 = darabonba_signature_util_1.default.HmacSHA256SignByBytes(product, sc3);
|
||||
}
|
||||
else if (tea_util_1.default.equalString(signatureAlgorithm, this._sm3)) {
|
||||
sc4 = darabonba_signature_util_1.default.HmacSM3SignByBytes(product, sc3);
|
||||
}
|
||||
let hmac = tea_util_1.default.toBytes("");
|
||||
if (tea_util_1.default.equalString(signatureAlgorithm, this._sha256)) {
|
||||
hmac = darabonba_signature_util_1.default.HmacSHA256SignByBytes("aliyun_v4_request", sc4);
|
||||
}
|
||||
else if (tea_util_1.default.equalString(signatureAlgorithm, this._sm3)) {
|
||||
hmac = darabonba_signature_util_1.default.HmacSM3SignByBytes("aliyun_v4_request", sc4);
|
||||
}
|
||||
return hmac;
|
||||
}
|
||||
getRegion(product, endpoint) {
|
||||
let region = "center";
|
||||
if (tea_util_1.default.empty(product) || tea_util_1.default.empty(endpoint)) {
|
||||
return region;
|
||||
}
|
||||
let preRegion = darabonba_string_1.default.replace(endpoint, ".aliyuncs.com", "", null);
|
||||
let nodes = darabonba_string_1.default.split(preRegion, ".", null);
|
||||
if (tea_util_1.default.equalNumber(darabonba_array_1.default.size(nodes), 2)) {
|
||||
region = nodes[1];
|
||||
}
|
||||
return region;
|
||||
}
|
||||
async buildCanonicalizedResource(query) {
|
||||
let canonicalizedResource = "";
|
||||
if (!tea_util_1.default.isUnset(query)) {
|
||||
let queryArray = darabonba_map_1.default.keySet(query);
|
||||
let sortedQueryArray = darabonba_array_1.default.ascSort(queryArray);
|
||||
let separator = "";
|
||||
for (let key of sortedQueryArray) {
|
||||
canonicalizedResource = `${canonicalizedResource}${separator}${darabonba_encode_util_1.default.percentEncode(key)}`;
|
||||
if (!tea_util_1.default.empty(query[key])) {
|
||||
canonicalizedResource = `${canonicalizedResource}=${darabonba_encode_util_1.default.percentEncode(query[key])}`;
|
||||
}
|
||||
separator = "&";
|
||||
}
|
||||
}
|
||||
return canonicalizedResource;
|
||||
}
|
||||
async buildCanonicalizedHeaders(headers) {
|
||||
let canonicalizedHeaders = "";
|
||||
let sortedHeaders = await this.getSignedHeaders(headers);
|
||||
for (let header of sortedHeaders) {
|
||||
canonicalizedHeaders = `${canonicalizedHeaders}${header}:${darabonba_string_1.default.trim(headers[header])}\n`;
|
||||
}
|
||||
return canonicalizedHeaders;
|
||||
}
|
||||
async getSignedHeaders(headers) {
|
||||
let headersArray = darabonba_map_1.default.keySet(headers);
|
||||
let sortedHeadersArray = darabonba_array_1.default.ascSort(headersArray);
|
||||
let tmp = "";
|
||||
let separator = "";
|
||||
for (let key of sortedHeadersArray) {
|
||||
let lowerKey = darabonba_string_1.default.toLower(key);
|
||||
if (darabonba_string_1.default.hasPrefix(lowerKey, "x-acs-") || darabonba_string_1.default.equals(lowerKey, "host") || darabonba_string_1.default.equals(lowerKey, "content-type")) {
|
||||
if (!darabonba_string_1.default.contains(tmp, lowerKey)) {
|
||||
tmp = `${tmp}${separator}${lowerKey}`;
|
||||
separator = ";";
|
||||
}
|
||||
}
|
||||
}
|
||||
return darabonba_string_1.default.split(tmp, ";", null);
|
||||
}
|
||||
}
|
||||
exports.default = Client;
|
||||
//# sourceMappingURL=client.js.map
|
||||
1
backend/node_modules/@alicloud/gateway-pop/dist/client.js.map
generated
vendored
Normal file
1
backend/node_modules/@alicloud/gateway-pop/dist/client.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
40
backend/node_modules/@alicloud/gateway-pop/package.json
generated
vendored
Normal file
40
backend/node_modules/@alicloud/gateway-pop/package.json
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "@alicloud/gateway-pop",
|
||||
"version": "0.0.6",
|
||||
"description": "",
|
||||
"main": "dist/client.js",
|
||||
"scripts": {
|
||||
"test": "mocha -r ts-node/register -r source-map-support/register test/**/*.spec.ts",
|
||||
"test-cov": "nyc -e .ts -r=html -r=text -r=lcov npm run test",
|
||||
"build": "tsc",
|
||||
"prepublishOnly": "tsc"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^7.0.1",
|
||||
"@types/node": "^12.12.26",
|
||||
"mocha": "^7.0.1",
|
||||
"nyc": "^15.0.0",
|
||||
"source-map-support": "^0.5.16",
|
||||
"ts-node": "^8.6.2",
|
||||
"typescript": "^3.7.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@alicloud/tea-typescript": "^1.7.1",
|
||||
"@alicloud/gateway-spi": "^0.0.8",
|
||||
"@alicloud/credentials": "^2",
|
||||
"@alicloud/tea-util": "^1.4.8",
|
||||
"@alicloud/openapi-util": "^0.3.2",
|
||||
"@alicloud/endpoint-util": "^0.0.1",
|
||||
"@alicloud/darabonba-encode-util": "^0.0.2",
|
||||
"@alicloud/darabonba-signature-util": "^0.0.4",
|
||||
"@alicloud/darabonba-string": "^1.0.2",
|
||||
"@alicloud/darabonba-map": "^0.0.1",
|
||||
"@alicloud/darabonba-array": "^0.1.0"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"src"
|
||||
]
|
||||
}
|
||||
305
backend/node_modules/@alicloud/gateway-pop/src/client.ts
generated
vendored
Normal file
305
backend/node_modules/@alicloud/gateway-pop/src/client.ts
generated
vendored
Normal file
@@ -0,0 +1,305 @@
|
||||
// This file is auto-generated, don't edit it
|
||||
import SPI, * as $SPI from '@alicloud/gateway-spi';
|
||||
import Credential from '@alicloud/credentials';
|
||||
import Util from '@alicloud/tea-util';
|
||||
import OpenApiUtil from '@alicloud/openapi-util';
|
||||
import EndpointUtil from '@alicloud/endpoint-util';
|
||||
import EncodeUtil from '@alicloud/darabonba-encode-util';
|
||||
import SignatureUtil from '@alicloud/darabonba-signature-util';
|
||||
import String from '@alicloud/darabonba-string';
|
||||
import Map from '@alicloud/darabonba-map';
|
||||
import Array from '@alicloud/darabonba-array';
|
||||
import * as $tea from '@alicloud/tea-typescript';
|
||||
|
||||
|
||||
export default class Client extends SPI {
|
||||
_sha256: string;
|
||||
_sm3: string;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._sha256 = "ACS4-HMAC-SHA256";
|
||||
this._sm3 = "ACS4-HMAC-SM3";
|
||||
}
|
||||
|
||||
|
||||
async modifyConfiguration(context: $SPI.InterceptorContext, attributeMap: $SPI.AttributeMap): Promise<void> {
|
||||
let request = context.request;
|
||||
let config = context.configuration;
|
||||
config.endpoint = this.getEndpoint(request.productId, config.regionId, config.endpointRule, config.network, config.suffix, config.endpointMap, config.endpoint);
|
||||
}
|
||||
|
||||
async modifyRequest(context: $SPI.InterceptorContext, attributeMap: $SPI.AttributeMap): Promise<void> {
|
||||
let request = context.request;
|
||||
let config = context.configuration;
|
||||
let date = OpenApiUtil.getTimestamp();
|
||||
request.headers = {
|
||||
host: config.endpoint,
|
||||
'x-acs-version': request.version,
|
||||
'x-acs-action': request.action,
|
||||
'user-agent': request.userAgent,
|
||||
'x-acs-date': date,
|
||||
'x-acs-signature-nonce': Util.getNonce(),
|
||||
accept: "application/json",
|
||||
...request.headers,
|
||||
};
|
||||
let signatureAlgorithm : string = Util.defaultString(request.signatureAlgorithm, this._sha256);
|
||||
let hashedRequestPayload = EncodeUtil.hexEncode(EncodeUtil.hash(Util.toBytes(""), signatureAlgorithm));
|
||||
if (!Util.isUnset(request.stream)) {
|
||||
let tmp = await Util.readAsBytes(request.stream);
|
||||
hashedRequestPayload = EncodeUtil.hexEncode(EncodeUtil.hash(tmp, signatureAlgorithm));
|
||||
request.stream = new $tea.BytesReadable(tmp);
|
||||
request.headers["content-type"] = "application/octet-stream";
|
||||
} else {
|
||||
if (!Util.isUnset(request.body)) {
|
||||
if (Util.equalString(request.reqBodyType, "json")) {
|
||||
let jsonObj = Util.toJSONString(request.body);
|
||||
hashedRequestPayload = EncodeUtil.hexEncode(EncodeUtil.hash(Util.toBytes(jsonObj), signatureAlgorithm));
|
||||
request.stream = new $tea.BytesReadable(jsonObj);
|
||||
request.headers["content-type"] = "application/json; charset=utf-8";
|
||||
} else {
|
||||
let m = Util.assertAsMap(request.body);
|
||||
let formObj = OpenApiUtil.toForm(m);
|
||||
hashedRequestPayload = EncodeUtil.hexEncode(EncodeUtil.hash(Util.toBytes(formObj), signatureAlgorithm));
|
||||
request.stream = new $tea.BytesReadable(formObj);
|
||||
request.headers["content-type"] = "application/x-www-form-urlencoded";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (Util.equalString(signatureAlgorithm, this._sm3)) {
|
||||
request.headers["x-acs-content-sm3"] = hashedRequestPayload;
|
||||
} else {
|
||||
request.headers["x-acs-content-sha256"] = hashedRequestPayload;
|
||||
}
|
||||
|
||||
if (!Util.equalString(request.authType, "Anonymous")) {
|
||||
let credential : Credential = request.credential;
|
||||
if (Util.isUnset(credential)) {
|
||||
throw $tea.newError({
|
||||
code: "ParameterMissing",
|
||||
message: "'config.credential' can not be unset",
|
||||
});
|
||||
}
|
||||
|
||||
let authType = credential.getType();
|
||||
if (Util.equalString(authType, "bearer")) {
|
||||
let bearerToken = credential.getBearerToken();
|
||||
request.headers["x-acs-bearer-token"] = bearerToken;
|
||||
request.headers["Authorization"] = `Bearer ${bearerToken}`;
|
||||
} else {
|
||||
let accessKeyId = await credential.getAccessKeyId();
|
||||
let accessKeySecret = await credential.getAccessKeySecret();
|
||||
let securityToken = await credential.getSecurityToken();
|
||||
if (!Util.empty(securityToken)) {
|
||||
request.headers["x-acs-accesskey-id"] = accessKeyId;
|
||||
request.headers["x-acs-security-token"] = securityToken;
|
||||
}
|
||||
|
||||
let dateNew = String.subString(date, 0, 10);
|
||||
dateNew = String.replace(dateNew, "-", "", null);
|
||||
let region = this.getRegion(request.productId, config.endpoint);
|
||||
let signingkey = await this.getSigningkey(signatureAlgorithm, accessKeySecret, request.productId, region, dateNew);
|
||||
request.headers["Authorization"] = await this.getAuthorization(request.pathname, request.method, request.query, request.headers, signatureAlgorithm, hashedRequestPayload, accessKeyId, signingkey, request.productId, region, dateNew);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async modifyResponse(context: $SPI.InterceptorContext, attributeMap: $SPI.AttributeMap): Promise<void> {
|
||||
let request = context.request;
|
||||
let response = context.response;
|
||||
if (Util.is4xx(response.statusCode) || Util.is5xx(response.statusCode)) {
|
||||
let _res = await Util.readAsJSON(response.body);
|
||||
let err = Util.assertAsMap(_res);
|
||||
let requestId = this.defaultAny(err["RequestId"], err["requestId"]);
|
||||
if (!Util.isUnset(response.headers["x-acs-request-id"])) {
|
||||
requestId = response.headers["x-acs-request-id"];
|
||||
}
|
||||
|
||||
err["statusCode"] = response.statusCode;
|
||||
throw $tea.newError({
|
||||
code: `${this.defaultAny(err["Code"], err["code"])}`,
|
||||
message: `code: ${response.statusCode}, ${this.defaultAny(err["Message"], err["message"])} request id: ${requestId}`,
|
||||
data: err,
|
||||
description: `${this.defaultAny(err["Description"], err["description"])}`,
|
||||
accessDeniedDetail: this.defaultAny(err["AccessDeniedDetail"], err["accessDeniedDetail"]),
|
||||
});
|
||||
}
|
||||
|
||||
if (Util.equalNumber(response.statusCode, 204)) {
|
||||
await Util.readAsString(response.body);
|
||||
} else if (Util.equalString(request.bodyType, "binary")) {
|
||||
response.deserializedBody = response.body;
|
||||
} else if (Util.equalString(request.bodyType, "byte")) {
|
||||
let byt = await Util.readAsBytes(response.body);
|
||||
response.deserializedBody = byt;
|
||||
} else if (Util.equalString(request.bodyType, "string")) {
|
||||
let str = await Util.readAsString(response.body);
|
||||
response.deserializedBody = str;
|
||||
} else if (Util.equalString(request.bodyType, "json")) {
|
||||
let obj = await Util.readAsJSON(response.body);
|
||||
let res = Util.assertAsMap(obj);
|
||||
response.deserializedBody = res;
|
||||
} else if (Util.equalString(request.bodyType, "array")) {
|
||||
let arr = await Util.readAsJSON(response.body);
|
||||
response.deserializedBody = arr;
|
||||
} else {
|
||||
response.deserializedBody = await Util.readAsString(response.body);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getEndpoint(productId: string, regionId: string, endpointRule: string, network: string, suffix: string, endpointMap: {[key: string ]: string}, endpoint: string): string {
|
||||
if (!Util.empty(endpoint)) {
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
if (!Util.isUnset(endpointMap) && !Util.empty(endpointMap[regionId])) {
|
||||
return endpointMap[regionId];
|
||||
}
|
||||
|
||||
return EndpointUtil.getEndpointRules(productId, regionId, endpointRule, network, suffix);
|
||||
}
|
||||
|
||||
defaultAny(inputValue: any, defaultValue: any): any {
|
||||
if (Util.isUnset(inputValue)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return inputValue;
|
||||
}
|
||||
|
||||
async getAuthorization(pathname: string, method: string, query: {[key: string ]: string}, headers: {[key: string ]: string}, signatureAlgorithm: string, payload: string, ak: string, signingkey: Buffer, product: string, region: string, date: string): Promise<string> {
|
||||
let signature = await this.getSignature(pathname, method, query, headers, signatureAlgorithm, payload, signingkey);
|
||||
let signedHeaders = await this.getSignedHeaders(headers);
|
||||
let signedHeadersStr = Array.join(signedHeaders, ";");
|
||||
return `${signatureAlgorithm} Credential=${ak}/${date}/${region}/${product}/aliyun_v4_request,SignedHeaders=${signedHeadersStr},Signature=${signature}`;
|
||||
}
|
||||
|
||||
async getSignature(pathname: string, method: string, query: {[key: string ]: string}, headers: {[key: string ]: string}, signatureAlgorithm: string, payload: string, signingkey: Buffer): Promise<string> {
|
||||
let canonicalURI : string = "/";
|
||||
if (!Util.empty(pathname)) {
|
||||
canonicalURI = pathname;
|
||||
}
|
||||
|
||||
let stringToSign : string = "";
|
||||
let canonicalizedResource = await this.buildCanonicalizedResource(query);
|
||||
let canonicalizedHeaders = await this.buildCanonicalizedHeaders(headers);
|
||||
let signedHeaders = await this.getSignedHeaders(headers);
|
||||
let signedHeadersStr = Array.join(signedHeaders, ";");
|
||||
stringToSign = `${method}\n${canonicalURI}\n${canonicalizedResource}\n${canonicalizedHeaders}\n${signedHeadersStr}\n${payload}`;
|
||||
let hex = EncodeUtil.hexEncode(EncodeUtil.hash(Util.toBytes(stringToSign), signatureAlgorithm));
|
||||
stringToSign = `${signatureAlgorithm}\n${hex}`;
|
||||
let signature = Util.toBytes("");
|
||||
if (Util.equalString(signatureAlgorithm, this._sha256)) {
|
||||
signature = SignatureUtil.HmacSHA256SignByBytes(stringToSign, signingkey);
|
||||
} else if (Util.equalString(signatureAlgorithm, this._sm3)) {
|
||||
signature = SignatureUtil.HmacSM3SignByBytes(stringToSign, signingkey);
|
||||
}
|
||||
|
||||
return EncodeUtil.hexEncode(signature);
|
||||
}
|
||||
|
||||
async getSigningkey(signatureAlgorithm: string, secret: string, product: string, region: string, date: string): Promise<Buffer> {
|
||||
let sc1 = `aliyun_v4${secret}`;
|
||||
let sc2 = Util.toBytes("");
|
||||
if (Util.equalString(signatureAlgorithm, this._sha256)) {
|
||||
sc2 = SignatureUtil.HmacSHA256Sign(date, sc1);
|
||||
} else if (Util.equalString(signatureAlgorithm, this._sm3)) {
|
||||
sc2 = SignatureUtil.HmacSM3Sign(date, sc1);
|
||||
}
|
||||
|
||||
let sc3 = Util.toBytes("");
|
||||
if (Util.equalString(signatureAlgorithm, this._sha256)) {
|
||||
sc3 = SignatureUtil.HmacSHA256SignByBytes(region, sc2);
|
||||
} else if (Util.equalString(signatureAlgorithm, this._sm3)) {
|
||||
sc3 = SignatureUtil.HmacSM3SignByBytes(region, sc2);
|
||||
}
|
||||
|
||||
let sc4 = Util.toBytes("");
|
||||
if (Util.equalString(signatureAlgorithm, this._sha256)) {
|
||||
sc4 = SignatureUtil.HmacSHA256SignByBytes(product, sc3);
|
||||
} else if (Util.equalString(signatureAlgorithm, this._sm3)) {
|
||||
sc4 = SignatureUtil.HmacSM3SignByBytes(product, sc3);
|
||||
}
|
||||
|
||||
let hmac = Util.toBytes("");
|
||||
if (Util.equalString(signatureAlgorithm, this._sha256)) {
|
||||
hmac = SignatureUtil.HmacSHA256SignByBytes("aliyun_v4_request", sc4);
|
||||
} else if (Util.equalString(signatureAlgorithm, this._sm3)) {
|
||||
hmac = SignatureUtil.HmacSM3SignByBytes("aliyun_v4_request", sc4);
|
||||
}
|
||||
|
||||
return hmac;
|
||||
}
|
||||
|
||||
getRegion(product: string, endpoint: string): string {
|
||||
let region = "center";
|
||||
if (Util.empty(product) || Util.empty(endpoint)) {
|
||||
return region;
|
||||
}
|
||||
|
||||
let preRegion : string = String.replace(endpoint, ".aliyuncs.com", "", null);
|
||||
let nodes = String.split(preRegion, ".", null);
|
||||
if (Util.equalNumber(Array.size(nodes), 2)) {
|
||||
region = nodes[1];
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
async buildCanonicalizedResource(query: {[key: string ]: string}): Promise<string> {
|
||||
let canonicalizedResource : string = "";
|
||||
if (!Util.isUnset(query)) {
|
||||
let queryArray : string[] = Map.keySet(query);
|
||||
let sortedQueryArray = Array.ascSort(queryArray);
|
||||
let separator : string = "";
|
||||
|
||||
for (let key of sortedQueryArray) {
|
||||
canonicalizedResource = `${canonicalizedResource}${separator}${EncodeUtil.percentEncode(key)}`;
|
||||
if (!Util.empty(query[key])) {
|
||||
canonicalizedResource = `${canonicalizedResource}=${EncodeUtil.percentEncode(query[key])}`;
|
||||
}
|
||||
|
||||
separator = "&";
|
||||
}
|
||||
}
|
||||
|
||||
return canonicalizedResource;
|
||||
}
|
||||
|
||||
async buildCanonicalizedHeaders(headers: {[key: string ]: string}): Promise<string> {
|
||||
let canonicalizedHeaders : string = "";
|
||||
let sortedHeaders : string[] = await this.getSignedHeaders(headers);
|
||||
|
||||
for (let header of sortedHeaders) {
|
||||
canonicalizedHeaders = `${canonicalizedHeaders}${header}:${String.trim(headers[header])}\n`;
|
||||
}
|
||||
return canonicalizedHeaders;
|
||||
}
|
||||
|
||||
async getSignedHeaders(headers: {[key: string ]: string}): Promise<string[]> {
|
||||
let headersArray : string[] = Map.keySet(headers);
|
||||
let sortedHeadersArray = Array.ascSort(headersArray);
|
||||
let tmp : string = "";
|
||||
let separator : string = "";
|
||||
|
||||
for (let key of sortedHeadersArray) {
|
||||
let lowerKey = String.toLower(key);
|
||||
if (String.hasPrefix(lowerKey, "x-acs-") || String.equals(lowerKey, "host") || String.equals(lowerKey, "content-type")) {
|
||||
if (!String.contains(tmp, lowerKey)) {
|
||||
tmp = `${tmp}${separator}${lowerKey}`;
|
||||
separator = ";";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return String.split(tmp, ";", null);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user