@owlrelay/webhook
Version:
OwlRelay Webhook utilities
72 lines (67 loc) • 2.31 kB
JavaScript
import { fetch } from 'ofetch';
function arrayBufferToBase64(arrayBuffer) {
return btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
}
function base64ToArrayBuffer(base64) {
return new Uint8Array(atob(base64).split("").map((char) => char.charCodeAt(0))).buffer;
}
async function signBody({
bodyBuffer,
secret
}) {
const encoder = new TextEncoder();
const keyData = encoder.encode(secret);
const key = await crypto.subtle.importKey("raw", keyData, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
const signature = await crypto.subtle.sign("HMAC", key, bodyBuffer);
const signatureBase64 = arrayBufferToBase64(signature);
return { signature: signatureBase64 };
}
async function verifySignature({
bodyBuffer,
signature: base64Signature,
secret
}) {
const encoder = new TextEncoder();
const keyData = encoder.encode(secret);
const key = await crypto.subtle.importKey("raw", keyData, { name: "HMAC", hash: "SHA-256" }, false, ["verify"]);
const signatureBuffer = base64ToArrayBuffer(base64Signature);
return crypto.subtle.verify("HMAC", key, signatureBuffer, bodyBuffer);
}
function serializeEmailForWebhook({ email }) {
const body = new FormData();
const { attachments = [], ...rest } = email;
body.append("email", JSON.stringify(rest));
for (const attachment of attachments ?? []) {
body.append("attachments[]", new File([attachment.content], attachment.filename ?? "file", { type: attachment.mimeType }));
}
return { body };
}
async function triggerWebhook({
email,
webhookUrl,
webhookSecret,
httpClient = fetch
}) {
const { body } = serializeEmailForWebhook({ email });
const bodyResponse = new Response(body);
const headers = Object.fromEntries(bodyResponse.headers.entries());
const bodyBuffer = await bodyResponse.arrayBuffer();
if (webhookSecret) {
const { signature } = await signBody({ bodyBuffer, secret: webhookSecret });
headers["X-Signature"] = signature;
}
const response = await httpClient(
webhookUrl,
{
method: "POST",
body: bodyBuffer,
headers: {
"User-Agent": "owlrelay-webhook-client",
...headers
}
}
);
return response;
}
export { serializeEmailForWebhook, signBody, triggerWebhook, verifySignature };
//# sourceMappingURL=index.mjs.map