Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Handle Fetch Headers and subscriptable JS object separately
  • Loading branch information
mattt committed Aug 29, 2024
commit 1b472e361e9adc78488ad8ea5a62d9eeae959531
58 changes: 39 additions & 19 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,17 @@ async function validateWebhook(requestData, secret) {
const signingSecret = secret || requestData.secret;

if (requestData && requestData.headers && requestData.body) {
id =
requestData.headers["webhook-id"] ||
requestData.headers.get?.("webhook-id");
timestamp =
requestData.headers["webhook-timestamp"] ||
requestData.headers.get?.("webhook-timestamp");
signature =
requestData.headers["webhook-signature"] ||
requestData.headers.get?.("webhook-signature");
if (typeof requestData.headers.get === "function") {
// Headers object (e.g. Fetch API Headers)
id = requestData.headers.get("webhook-id");
timestamp = requestData.headers.get("webhook-timestamp");
signature = requestData.headers.get("webhook-signature");
} else {
// Plain object with header key-value pairs
id = requestData.headers["webhook-id"];
timestamp = requestData.headers["webhook-timestamp"];
signature = requestData.headers["webhook-signature"];
}
body = requestData.body;
}

Expand Down Expand Up @@ -75,11 +77,18 @@ async function validateWebhook(requestData, secret) {

const signedContent = `${id}.${timestamp}.${body}`;

const computedSignature = await createHMACSHA256(signingSecret.split("_").pop(), signedContent);
const computedSignature = await createHMACSHA256(
signingSecret.split("_").pop(),
signedContent
);

const expectedSignatures = signature.split(" ").map((sig) => sig.split(",")[1]);
const expectedSignatures = signature
.split(" ")
.map((sig) => sig.split(",")[1]);

return expectedSignatures.some((expectedSignature) => expectedSignature === computedSignature);
return expectedSignatures.some(
(expectedSignature) => expectedSignature === computedSignature
);
}

/**
Expand All @@ -106,9 +115,13 @@ async function createHMACSHA256(secret, data) {
crypto = require.call(null, "node:crypto").webcrypto;
}

const key = await crypto.subtle.importKey("raw", base64ToBytes(secret), { name: "HMAC", hash: "SHA-256" }, false, [
"sign",
]);
const key = await crypto.subtle.importKey(
"raw",
base64ToBytes(secret),
{ name: "HMAC", hash: "SHA-256" },
false,
["sign"]
);

const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(data));
return bytesToBase64(signature);
Expand Down Expand Up @@ -232,7 +245,11 @@ async function transformFileInputs(client, inputs, strategy) {
try {
return await transformFileInputsToReplicateFileURLs(client, inputs);
} catch (error) {
if (error instanceof ApiError && error.response.status >= 400 && error.response.status < 500) {
if (
error instanceof ApiError &&
error.response.status >= 400 &&
error.response.status < 500
) {
throw error;
}
return await transformFileInputsToBase64EncodedDataURIs(inputs);
Expand Down Expand Up @@ -296,7 +313,7 @@ async function transformFileInputsToBase64EncodedDataURIs(inputs) {
totalBytes += buffer.byteLength;
if (totalBytes > MAX_DATA_URI_SIZE) {
throw new Error(
`Combined filesize of prediction ${totalBytes} bytes exceeds 10mb limit for inline encoding, please provide URLs instead`,
`Combined filesize of prediction ${totalBytes} bytes exceeds 10mb limit for inline encoding, please provide URLs instead`
);
}

Expand Down Expand Up @@ -354,11 +371,14 @@ function isPlainObject(value) {
if (proto === null) {
return true;
}
const Ctor = Object.prototype.hasOwnProperty.call(proto, "constructor") && proto.constructor;
const Ctor =
Object.prototype.hasOwnProperty.call(proto, "constructor") &&
proto.constructor;
return (
typeof Ctor === "function" &&
Ctor instanceof Ctor &&
Function.prototype.toString.call(Ctor) === Function.prototype.toString.call(Object)
Function.prototype.toString.call(Ctor) ===
Function.prototype.toString.call(Object)
);
}

Expand Down