@shopify/shopify-api
Version:
Shopify API Library for Node - accelerate development with support for authentication, graphql proxy, webhooks
63 lines (60 loc) • 2.1 kB
JavaScript
import { ShopifyError } from '../../lib/error.mjs';
import { HashFormat } from './types.mjs';
async function createSHA256HMAC(secret, payload, returnFormat = HashFormat.Base64) {
const cryptoLib = typeof crypto?.webcrypto === 'undefined'
? crypto
: crypto.webcrypto;
const enc = new TextEncoder();
const key = await cryptoLib.subtle.importKey('raw', enc.encode(secret), {
name: 'HMAC',
hash: { name: 'SHA-256' },
}, false, ['sign']);
const signature = await cryptoLib.subtle.sign('HMAC', key, enc.encode(payload));
return returnFormat === HashFormat.Base64
? asBase64(signature)
: asHex(signature);
}
function asHex(buffer) {
return [...new Uint8Array(buffer)]
.map((byte) => byte.toString(16).padStart(2, '0'))
.join('');
}
const LookupTable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
function asBase64(buffer) {
let output = '';
const input = new Uint8Array(buffer);
for (let i = 0; i < input.length;) {
const byte1 = input[i++];
const byte2 = input[i++];
const byte3 = input[i++];
const enc1 = byte1 >> 2;
const enc2 = ((byte1 & 0b00000011) << 4) | (byte2 >> 4);
let enc3 = ((byte2 & 0b00001111) << 2) | (byte3 >> 6);
let enc4 = byte3 & 0b00111111;
if (isNaN(byte2)) {
enc3 = 64;
}
if (isNaN(byte3)) {
enc4 = 64;
}
output +=
LookupTable[enc1] +
LookupTable[enc2] +
LookupTable[enc3] +
LookupTable[enc4];
}
return output;
}
function hashString(str, returnFormat) {
const buffer = new TextEncoder().encode(str);
switch (returnFormat) {
case HashFormat.Base64:
return asBase64(buffer);
case HashFormat.Hex:
return asHex(buffer);
default:
throw new ShopifyError(`Unrecognized hash format '${returnFormat}'`);
}
}
export { asBase64, asHex, createSHA256HMAC, hashString };
//# sourceMappingURL=utils.mjs.map