@scayle/storefront-core
Version:
Collection of essential utilities to work with the Storefront API
66 lines (65 loc) • 2.77 kB
JavaScript
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));