django-vue3-admin-web/node_modules/@aws-sdk/signature-v4-crt/dist-es/CrtSignerV4.js
2025-10-20 21:21:14 +08:00

134 lines
6.8 KiB
JavaScript

import { auth as crtAuth, http as crtHttp, io as crtIO } from "@aws-sdk/crt-loader";
import { parseQueryString } from "@smithy/querystring-parser";
import { getCanonicalQuery, getPayloadHash, moveHeadersToQuery, prepareRequest, } from "@smithy/signature-v4";
import { normalizeProvider } from "@smithy/util-middleware";
import { MAX_PRESIGNED_TTL, SHA256_HEADER } from "./constants";
import { deleteHeader } from "./headerUtil";
function sdkHttpRequest2crtHttpRequest(sdkRequest) {
deleteHeader(SHA256_HEADER, sdkRequest.headers);
const headersArray = Object.entries(sdkRequest.headers);
const crtHttpHeaders = new crtHttp.HttpHeaders(headersArray);
const queryString = getCanonicalQuery(sdkRequest);
return new crtHttp.HttpRequest(sdkRequest.method, sdkRequest.path + "?" + queryString, crtHttpHeaders);
}
export class CrtSignerV4 {
service;
regionProvider;
credentialProvider;
sha256;
uriEscapePath;
applyChecksum;
signingAlgorithm;
constructor({ credentials, region, service, sha256, applyChecksum = true, uriEscapePath = true, signingAlgorithm = crtAuth.AwsSigningAlgorithm.SigV4, }) {
this.service = service;
this.sha256 = sha256;
this.uriEscapePath = uriEscapePath;
this.signingAlgorithm = signingAlgorithm;
this.applyChecksum = applyChecksum;
this.regionProvider = normalizeProvider(region);
this.credentialProvider = normalizeProvider(credentials);
crtIO.enable_logging(crtIO.LogLevel.ERROR);
}
async options2crtConfigure({ signingDate = new Date(), signableHeaders, unsignableHeaders, signingRegion, signingService, } = {}, viaHeader, payloadHash, expiresIn, _credentials) {
const credentials = _credentials ?? (await this.credentialProvider());
const region = signingRegion ?? (await this.regionProvider());
const service = signingService ?? this.service;
if (signableHeaders?.has("x-amzn-trace-id") || signableHeaders?.has("user-agent")) {
throw new Error("internal check (x-amzn-trace-id, user-agent) is not supported to be included to sign with CRT.");
}
const headersUnsignable = getHeadersUnsignable(unsignableHeaders, signableHeaders);
return {
algorithm: this.signingAlgorithm,
signature_type: viaHeader
? crtAuth.AwsSignatureType.HttpRequestViaHeaders
: crtAuth.AwsSignatureType.HttpRequestViaQueryParams,
provider: sdk2crtCredentialsProvider(credentials),
region: region,
service: service,
date: new Date(signingDate),
header_blacklist: headersUnsignable,
use_double_uri_encode: this.uriEscapePath,
signed_body_value: payloadHash,
signed_body_header: this.applyChecksum && viaHeader
? crtAuth.AwsSignedBodyHeaderType.XAmzContentSha256
: crtAuth.AwsSignedBodyHeaderType.None,
expiration_in_seconds: expiresIn,
};
}
async presign(originalRequest, options = {}) {
if (options.expiresIn && options.expiresIn > MAX_PRESIGNED_TTL) {
return Promise.reject("Signature version 4 presigned URLs" + " must have an expiration date less than one week in" + " the future");
}
const request = moveHeadersToQuery(prepareRequest(originalRequest));
const crtSignedRequest = await this.signRequest(request, await this.options2crtConfigure(options, false, await getPayloadHash(originalRequest, this.sha256), options.expiresIn ? options.expiresIn : 3600));
request.query = this.getQueryParam(crtSignedRequest.path);
return request;
}
async sign(toSign, options) {
const request = prepareRequest(toSign);
const crtSignedRequest = await this.signRequest(request, await this.options2crtConfigure(options, true, await getPayloadHash(toSign, this.sha256)));
request.headers = crtSignedRequest.headers._flatten().reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {});
return request;
}
async signWithCredentials(toSign, credentials, options) {
const request = prepareRequest(toSign);
const crtSignedRequest = await this.signRequest(request, await this.options2crtConfigure(options, true, await getPayloadHash(toSign, this.sha256), undefined, credentials));
request.headers = crtSignedRequest.headers._flatten().reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {});
return request;
}
getQueryParam(crtPath) {
const start = crtPath.search(/\?/);
const startHash = crtPath.search(/\#/);
const end = startHash == -1 ? undefined : startHash;
const queryParam = {};
if (start == -1) {
return queryParam;
}
const queryString = crtPath.slice(start + 1, end);
return parseQueryString(queryString);
}
async signRequest(requestToSign, crtConfig) {
const request = sdkHttpRequest2crtHttpRequest(requestToSign);
try {
return await crtAuth.aws_sign_request(request, crtConfig);
}
catch (error) {
throw new Error(error);
}
}
async verifySigv4aSigning(request, signature, expectedCanonicalRequest, eccPubKeyX, eccPubKeyY, options = {}) {
const sdkRequest = prepareRequest(request);
const crtRequest = sdkHttpRequest2crtHttpRequest(sdkRequest);
const payloadHash = await getPayloadHash(request, this.sha256);
const crtConfig = await this.options2crtConfigure(options, true, payloadHash);
return crtAuth.aws_verify_sigv4a_signing(crtRequest, crtConfig, expectedCanonicalRequest, signature, eccPubKeyX, eccPubKeyY);
}
async verifySigv4aPreSigning(request, signature, expectedCanonicalRequest, eccPubKeyX, eccPubKeyY, options = {}) {
if (typeof signature != "string") {
return false;
}
const sdkRequest = prepareRequest(request);
const crtRequest = sdkHttpRequest2crtHttpRequest(sdkRequest);
const crtConfig = await this.options2crtConfigure(options, false, await getPayloadHash(request, this.sha256), options.expiresIn ? options.expiresIn : 3600);
return crtAuth.aws_verify_sigv4a_signing(crtRequest, crtConfig, expectedCanonicalRequest, signature, eccPubKeyX, eccPubKeyY);
}
}
function sdk2crtCredentialsProvider(credentials) {
return crtAuth.AwsCredentialsProvider.newStatic(credentials.accessKeyId, credentials.secretAccessKey, credentials.sessionToken);
}
function getHeadersUnsignable(unsignableHeaders, signableHeaders) {
if (!unsignableHeaders) {
return [];
}
if (!signableHeaders) {
return [...unsignableHeaders];
}
const result = new Set([...unsignableHeaders]);
for (let it = signableHeaders.values(), val = null; (val = it.next().value);) {
if (result.has(val)) {
result.delete(val);
}
}
return [...result];
}