imagekit
Version:
Offical NodeJS SDK for ImageKit.io integration
95 lines (94 loc) • 4 kB
JavaScript
;
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.verify = void 0;
var crypto_1 = require("crypto");
var lodash_1 = require("lodash");
var errorMessages_1 = __importDefault(require("../libs/constants/errorMessages"));
/**
* @description Enum for Webhook signature item names
*/
var SignatureItems;
(function (SignatureItems) {
SignatureItems["Timestamp"] = "t";
SignatureItems["V1"] = "v1";
})(SignatureItems || (SignatureItems = {}));
var HASH_ALGORITHM = "sha256";
/**
* @param timstamp - Webhook request timestamp
* @param payload - Webhook payload as UTF8 encoded string
* @param secret - Webhook secret as UTF8 encoded string
* @returns Hmac with webhook secret as key and `${timestamp}.${payload}` as hash payload.
*/
var computeHmac = function (timstamp, payload, secret) {
var hashPayload = "".concat(timstamp.getTime(), ".").concat(payload);
return (0, crypto_1.createHmac)(HASH_ALGORITHM, secret).update(hashPayload).digest("hex");
};
/**
* @description Extract items from webhook signature string
*/
var deserializeSignature = function (signature) {
var _a, _b;
var items = signature.split(",");
var itemMap = items.map(function (item) { return item.split("="); }); // eg. [["t", 1656921250765], ["v1", 'afafafafafaf']]
var timestampString = (_a = itemMap.find(function (_a) {
var _b = __read(_a, 1), key = _b[0];
return key === SignatureItems.Timestamp;
})) === null || _a === void 0 ? void 0 : _a[1]; // eg. 1656921250765
// parse timestamp
if (timestampString === undefined) {
throw new Error(errorMessages_1.default.VERIFY_WEBHOOK_EVENT_TIMESTAMP_MISSING.message);
}
var timestamp = parseInt(timestampString, 10);
if ((0, lodash_1.isNaN)(timestamp) || timestamp < 0) {
throw new Error(errorMessages_1.default.VERIFY_WEBHOOK_EVENT_TIMESTAMP_INVALID.message);
}
// parse v1 signature
var v1 = (_b = itemMap.find(function (_a) {
var _b = __read(_a, 1), key = _b[0];
return key === SignatureItems.V1;
})) === null || _b === void 0 ? void 0 : _b[1]; // eg. 'afafafafafaf'
if (v1 === undefined) {
throw new Error(errorMessages_1.default.VERIFY_WEBHOOK_EVENT_SIGNATURE_MISSING.message);
}
return { timestamp: timestamp, v1: v1 };
};
/**
* @param payload - Raw webhook request body (Encoded as UTF8 string or Buffer)
* @param signature - Webhook signature as UTF8 encoded strings (Stored in `x-ik-signature` header of the request)
* @param secret - Webhook secret as UTF8 encoded string [Copy from ImageKit dashboard](https://imagekit.io/dashboard/developer/webhooks)
* @returns \{ `timstamp`: Verified UNIX epoch timestamp if signature, `event`: Parsed webhook event payload \}
*/
var verify = function (payload, signature, secret) {
var _a = deserializeSignature(signature), timestamp = _a.timestamp, v1 = _a.v1;
var payloadAsString = typeof payload === "string"
? payload
: Buffer.from(payload).toString("utf8");
var computedHmac = computeHmac(new Date(timestamp), payloadAsString, secret);
if (v1 !== computedHmac) {
throw new Error(errorMessages_1.default.VERIFY_WEBHOOK_EVENT_SIGNATURE_INCORRECT.message);
}
return {
timestamp: timestamp,
event: JSON.parse(payloadAsString),
};
};
exports.verify = verify;