File: /var/www/api.javaapp.co.uk/node_modules/@aws-sdk/cloudfront-signer/dist-es/sign.js
import { createSign } from "crypto";
export function getSignedUrl({ dateLessThan, dateGreaterThan, url, keyPairId, privateKey, ipAddress, policy, passphrase, }) {
const cloudfrontSignBuilder = new CloudfrontSignBuilder({
keyPairId,
privateKey,
passphrase,
});
if (!url && !policy) {
throw new Error("@aws-sdk/cloudfront-signer: Please provide 'url' or 'policy'.");
}
if (policy) {
cloudfrontSignBuilder.setCustomPolicy(policy);
}
else {
cloudfrontSignBuilder.setPolicyParameters({
url,
dateLessThan,
dateGreaterThan,
ipAddress,
});
}
let baseUrl;
if (url) {
baseUrl = url;
}
else if (policy) {
const resources = getPolicyResources(policy);
if (!resources[0]) {
throw new Error("@aws-sdk/cloudfront-signer: No URL provided and unable to determine URL from first policy statement resource.");
}
baseUrl = resources[0].replace("*://", "https://");
}
const newURL = new URL(baseUrl);
newURL.search = Array.from(newURL.searchParams.entries())
.concat(Object.entries(cloudfrontSignBuilder.createCloudfrontAttribute()))
.filter(([, value]) => value !== undefined)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join("&");
return getResource(newURL);
}
export function getSignedCookies({ ipAddress, url, privateKey, keyPairId, dateLessThan, dateGreaterThan, policy, passphrase, }) {
const cloudfrontSignBuilder = new CloudfrontSignBuilder({
keyPairId,
privateKey,
passphrase,
});
if (policy) {
cloudfrontSignBuilder.setCustomPolicy(policy);
}
else {
cloudfrontSignBuilder.setPolicyParameters({
url,
dateLessThan,
dateGreaterThan,
ipAddress,
});
}
const cloudfrontCookieAttributes = cloudfrontSignBuilder.createCloudfrontAttribute();
const cookies = {
"CloudFront-Key-Pair-Id": cloudfrontCookieAttributes["Key-Pair-Id"],
"CloudFront-Signature": cloudfrontCookieAttributes["Signature"],
};
if (cloudfrontCookieAttributes["Expires"]) {
cookies["CloudFront-Expires"] = cloudfrontCookieAttributes["Expires"];
}
if (cloudfrontCookieAttributes["Policy"]) {
cookies["CloudFront-Policy"] = cloudfrontCookieAttributes["Policy"];
}
return cookies;
}
function getPolicyResources(policy) {
const parsedPolicy = typeof policy === "string" ? JSON.parse(policy) : policy;
return (parsedPolicy?.Statement ?? []).map((s) => s.Resource);
}
function getResource(url) {
switch (url.protocol) {
case "http:":
case "https:":
return url.toString();
case "rtmp:":
return url.pathname.replace(/^\//, "") + url.search + url.hash;
default:
throw new Error("Invalid URI scheme. Scheme must be one of http, https, or rtmp");
}
}
class CloudfrontSignBuilder {
constructor({ privateKey, keyPairId, passphrase }) {
this.customPolicy = false;
this.keyPairId = keyPairId;
this.privateKey = privateKey;
this.policy = "";
this.passphrase = passphrase;
}
buildPolicy(args) {
const policy = {
Statement: [
{
Resource: args.resource,
Condition: {
DateLessThan: {
"AWS:EpochTime": args.dateLessThan,
},
},
},
],
};
if (args.dateGreaterThan) {
policy.Statement[0].Condition["DateGreaterThan"] = {
"AWS:EpochTime": args.dateGreaterThan,
};
}
if (args.ipAddress) {
const cidr = this.parseCIDR(args.ipAddress);
policy.Statement[0].Condition["IpAddress"] = {
"AWS:SourceIp": cidr,
};
}
return policy;
}
normalizeBase64(str) {
const replacements = {
"+": "-",
"=": "_",
"/": "~",
};
return str.replace(/[+=/]/g, function (match) {
return replacements[match];
});
}
encodeToBase64(str) {
return this.normalizeBase64(Buffer.from(str).toString("base64"));
}
validateIP(ipStr) {
const octets = ipStr.split(".");
if (octets.length !== 4) {
throw new Error(`IP does not contain four octets.`);
}
const isValid = octets.every((octet) => {
const num = Number(octet);
return Number.isInteger(num) && num >= 0 && num <= 255;
});
if (!isValid) {
throw new Error("invalid IP octets");
}
}
validateMask(maskStr) {
const mask = Number(maskStr);
const isValid = Number.isInteger(mask) && mask >= 0 && mask <= 32;
if (!isValid) {
throw new Error("invalid mask");
}
}
parseCIDR(cidrStr) {
try {
const cidrParts = cidrStr.split("/");
if (cidrParts.some((part) => part.length === 0)) {
throw new Error("missing ip or mask part of CIDR");
}
this.validateIP(cidrParts[0]);
let mask = "32";
if (cidrParts.length === 2) {
this.validateMask(cidrParts[1]);
mask = cidrParts[1];
}
return `${cidrParts[0]}/${mask}`;
}
catch (error) {
const errMessage = `IP address "${cidrStr}" is invalid`;
if (error instanceof Error) {
throw new Error(`${errMessage} due to ${error.message}.`);
}
else {
throw new Error(`${errMessage}.`);
}
}
}
epochTime(date) {
return Math.round(date.getTime() / 1000);
}
parseDate(date) {
if (!date) {
return undefined;
}
const parsedDate = Date.parse(date);
return isNaN(parsedDate) ? undefined : this.epochTime(new Date(parsedDate));
}
parseDateWindow(expiration, start) {
const dateLessThan = this.parseDate(expiration);
if (!dateLessThan) {
throw new Error("dateLessThan is invalid. Ensure the date string is compatible with the Date constructor.");
}
return {
dateLessThan,
dateGreaterThan: this.parseDate(start),
};
}
signData(data, privateKey, passphrase) {
const sign = createSign("RSA-SHA1");
sign.update(data);
return sign.sign({ key: privateKey, passphrase }, "base64");
}
signPolicy(policy, privateKey, passphrase) {
return this.normalizeBase64(this.signData(policy, privateKey, passphrase));
}
setCustomPolicy(policy) {
this.customPolicy = true;
this.policy = policy;
}
setPolicyParameters({ url, dateLessThan, dateGreaterThan, ipAddress, }) {
if (!url || !dateLessThan) {
return false;
}
const resource = getResource(new URL(url));
const parsedDates = this.parseDateWindow(dateLessThan, dateGreaterThan);
this.dateLessThan = parsedDates.dateLessThan;
this.customPolicy = Boolean(parsedDates.dateGreaterThan) || Boolean(ipAddress);
this.policy = JSON.stringify(this.buildPolicy({
resource,
ipAddress,
dateLessThan: parsedDates.dateLessThan,
dateGreaterThan: parsedDates.dateGreaterThan,
}));
}
createCloudfrontAttribute() {
if (!Boolean(this.policy)) {
throw new Error("Invalid policy");
}
const signature = this.signPolicy(this.policy, this.privateKey, this.passphrase);
return {
Expires: this.customPolicy ? undefined : this.dateLessThan,
Policy: this.customPolicy ? this.encodeToBase64(this.policy) : undefined,
"Key-Pair-Id": this.keyPairId,
Signature: signature,
};
}
}