59 lines
2.5 KiB
JavaScript
59 lines
2.5 KiB
JavaScript
import { SignatureV4MultiRegion } from "@aws-sdk/signature-v4-multi-region";
|
|
import { SHA256_HEADER, UNSIGNED_PAYLOAD } from "./constants";
|
|
export class S3RequestPresigner {
|
|
signer;
|
|
constructor(options) {
|
|
const resolvedOptions = {
|
|
service: options.signingName || options.service || "s3",
|
|
uriEscapePath: options.uriEscapePath || false,
|
|
applyChecksum: options.applyChecksum || false,
|
|
...options,
|
|
};
|
|
this.signer = new SignatureV4MultiRegion(resolvedOptions);
|
|
}
|
|
presign(requestToSign, { unsignableHeaders = new Set(), hoistableHeaders = new Set(), unhoistableHeaders = new Set(), ...options } = {}) {
|
|
this.prepareRequest(requestToSign, {
|
|
unsignableHeaders,
|
|
unhoistableHeaders,
|
|
hoistableHeaders,
|
|
});
|
|
return this.signer.presign(requestToSign, {
|
|
expiresIn: 900,
|
|
unsignableHeaders,
|
|
unhoistableHeaders,
|
|
...options,
|
|
});
|
|
}
|
|
presignWithCredentials(requestToSign, credentials, { unsignableHeaders = new Set(), hoistableHeaders = new Set(), unhoistableHeaders = new Set(), ...options } = {}) {
|
|
this.prepareRequest(requestToSign, {
|
|
unsignableHeaders,
|
|
unhoistableHeaders,
|
|
hoistableHeaders,
|
|
});
|
|
return this.signer.presignWithCredentials(requestToSign, credentials, {
|
|
expiresIn: 900,
|
|
unsignableHeaders,
|
|
unhoistableHeaders,
|
|
...options,
|
|
});
|
|
}
|
|
prepareRequest(requestToSign, { unsignableHeaders = new Set(), unhoistableHeaders = new Set(), hoistableHeaders = new Set(), } = {}) {
|
|
unsignableHeaders.add("content-type");
|
|
Object.keys(requestToSign.headers)
|
|
.map((header) => header.toLowerCase())
|
|
.filter((header) => header.startsWith("x-amz-server-side-encryption"))
|
|
.forEach((header) => {
|
|
if (!hoistableHeaders.has(header)) {
|
|
unhoistableHeaders.add(header);
|
|
}
|
|
});
|
|
requestToSign.headers[SHA256_HEADER] = UNSIGNED_PAYLOAD;
|
|
const currentHostHeader = requestToSign.headers.host;
|
|
const port = requestToSign.port;
|
|
const expectedHostHeader = `${requestToSign.hostname}${requestToSign.port != null ? ":" + port : ""}`;
|
|
if (!currentHostHeader || (currentHostHeader === requestToSign.hostname && requestToSign.port != null)) {
|
|
requestToSign.headers.host = expectedHostHeader;
|
|
}
|
|
}
|
|
}
|