Files
codeql-action/node_modules/@octokit/webhooks-methods/dist-src/web.js
2025-02-19 11:13:12 -08:00

84 lines
2.2 KiB
JavaScript

const enc = new TextEncoder();
function hexToUInt8Array(string) {
const pairs = string.match(/[\dA-F]{2}/gi);
const integers = pairs.map(function(s) {
return parseInt(s, 16);
});
return new Uint8Array(integers);
}
function UInt8ArrayToHex(signature) {
return Array.prototype.map.call(new Uint8Array(signature), (x) => x.toString(16).padStart(2, "0")).join("");
}
async function importKey(secret) {
return crypto.subtle.importKey(
"raw",
// raw format of the key - should be Uint8Array
enc.encode(secret),
{
// algorithm details
name: "HMAC",
hash: { name: "SHA-256" }
},
false,
// export = false
["sign", "verify"]
// what this key can do
);
}
async function sign(secret, payload) {
if (!secret || !payload) {
throw new TypeError(
"[@octokit/webhooks-methods] secret & payload required for sign()"
);
}
if (typeof payload !== "string") {
throw new TypeError("[@octokit/webhooks-methods] payload must be a string");
}
const algorithm = "sha256";
const signature = await crypto.subtle.sign(
"HMAC",
await importKey(secret),
enc.encode(payload)
);
return `${algorithm}=${UInt8ArrayToHex(signature)}`;
}
async function verify(secret, eventPayload, signature) {
if (!secret || !eventPayload || !signature) {
throw new TypeError(
"[@octokit/webhooks-methods] secret, eventPayload & signature required"
);
}
if (typeof eventPayload !== "string") {
throw new TypeError(
"[@octokit/webhooks-methods] eventPayload must be a string"
);
}
const algorithm = "sha256";
return await crypto.subtle.verify(
"HMAC",
await importKey(secret),
hexToUInt8Array(signature.replace(`${algorithm}=`, "")),
enc.encode(eventPayload)
);
}
async function verifyWithFallback(secret, payload, signature, additionalSecrets) {
const firstPass = await verify(secret, payload, signature);
if (firstPass) {
return true;
}
if (additionalSecrets !== void 0) {
for (const s of additionalSecrets) {
const v = await verify(s, payload, signature);
if (v) {
return v;
}
}
}
return false;
}
export {
sign,
verify,
verifyWithFallback
};