UNPKG

@scayle/storefront-core

Version:

Collection of essential utilities to work with the Storefront API

66 lines (65 loc) 2.77 kB
import { subtle } from "uncrypto"; function stringToBoolean(value, defaultValue = false) { return value ? value.toLowerCase() === "true" : defaultValue; } export const md5 = async (value) => { if (!stringToBoolean(process.env.SFC_OMIT_MD5)) { const md5EncryptImport = await import("crypto-js/md5.js"); const hexImport = await import("crypto-js/enc-hex.js"); const md5Encrypt = md5EncryptImport.default && (typeof md5EncryptImport.default === "function" || typeof md5EncryptImport.default === "object") ? md5EncryptImport.default : md5EncryptImport; const hex = hexImport.default && (typeof hexImport.default === "function" || typeof hexImport.default === "object") ? hexImport.default : hexImport; return hex.stringify(md5Encrypt(value)); } else { throw Error("SFC was built without support for MD5"); } }; export const sha256 = async (value) => Array.from( new Uint8Array( await subtle.digest("SHA-256", new TextEncoder().encode(value)) ) ).map((b) => b.toString(16).padStart(2, "0")).join(""); export const hmac = async (value, secret, algorithm = "SHA-256") => { const encoder = new TextEncoder(); const messageUint8Array = encoder.encode(value); const keyUint8Array = encoder.encode(secret); const cryptoKey = await subtle.importKey( "raw", keyUint8Array, { name: "HMAC", hash: algorithm }, false, ["sign"] ); const signature = await subtle.sign("HMAC", cryptoKey, messageUint8Array); const hashArray = Array.from(new Uint8Array(signature)); return hashArray.map((b) => b.toString(16).padStart(2, "0")).join(""); }; function base64ToBytes(base64) { const binString = atob(base64); return Uint8Array.from(binString, (m) => m.codePointAt(0)); } function bytesToBase64(bytes) { const binString = Array.from(bytes, (x) => String.fromCodePoint(x)).join(""); return btoa(binString); } export const encodeBase64 = (string) => { if (typeof Buffer === "function") { return Buffer.from(string).toString("base64"); } return bytesToBase64(new TextEncoder().encode(string)); }; export const decodeBase64 = (string) => { if (typeof Buffer === "function") { return Buffer.from(string, "base64").toString("utf-8"); } return new TextDecoder().decode(base64ToBytes(string)); }; export const verifyOrderSuccessToken = async (token, secret) => { const [encodedPayload, signature] = token.split(".", 2); const expectedSignature = encodeBase64(await hmac(encodedPayload, secret)); if (expectedSignature !== signature) { return; } return JSON.parse(decodeBase64(encodedPayload)); }; export const buildHashPayload = (payload) => encodeBase64(JSON.stringify(payload)); export const buildSignature = async (payloadHash, secret) => encodeBase64(await hmac(payloadHash, secret));