UNPKG

@code-nl/shopify-hmac

Version:

Shopify HMAC lib to verify Shopify calls

68 lines (53 loc) 1.67 kB
"use strict"; const querystring = require("querystring"); const { hmacTimingSafeEqual, getHmacFromString } = require("./hmac"); /** * Get the request object translated into a string as of Shopify would have signed it. * * @param {Object} request The request object * @return {String} The query string as it would have been signed by Shopify */ exports.getSignableMessage = (request) => { // clone the query object const map = Object.assign({}, request.query); // leave out the hmac itself delete map.hmac; // get the querystring as a string const message = querystring.stringify(map); return message; }; /** * Generate a signature based on request query. * * @param {Object} request The request object * @param {String} secret API Secret * @return {String} Generated HMAC */ exports.generate = (request, secret) => { // get a signable message const message = module.exports.getSignableMessage(request); // generate hmac based on the message const generatedHmac = getHmacFromString(message, secret, "hex"); return generatedHmac; }; /** * Verify request is from Shopify. * HMAC verification based on the query string that is transmitted. * * @param {Object} request The request object * @param {String} secret API Secret * @return {Bool} */ exports.verify = (request, secret) => { // get included hmac const { hmac } = request.query; // guard: hmac is a required property if (typeof hmac !== "string" || !hmac) { return false; } // generate HMAC const generatedHmac = module.exports.generate(request, secret); // verify const valid = hmacTimingSafeEqual(hmac, generatedHmac); return valid; };