UNPKG

@synet/credential

Version:

VC Credentials - Simple, Robust, Unit-based Verifiable Credentials service

84 lines (83 loc) 3.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createId = createId; exports.base64urlEncode = base64urlEncode; exports.base64urlDecode = base64urlDecode; const node_crypto_1 = require("node:crypto"); /** * Generate a CUID2-like identifier using Node.js crypto * * This is a simplified, zero-dependency implementation of CUID2 concepts: * - Uses native Node.js crypto instead of @noble/hashes * - Maintains similar structure: letter + hash of (time + entropy + counter) * - Provides collision-resistant, sortable, URL-safe IDs * * @param length - Length of the generated ID (default: 24) * @returns A CUID2-like identifier string */ function createId(length = 24) { // Start with a random letter (a-z) const firstLetter = String.fromCharCode(97 + Math.floor(Math.random() * 26)); // Create entropy components const time = Date.now().toString(36); const entropy = (0, node_crypto_1.randomBytes)(8).toString("hex"); const counter = Math.floor(Math.random() * 0xffffff).toString(36); // Combine and hash const input = `${time}${entropy}${counter}`; const hash = (0, node_crypto_1.createHash)("sha3-512").update(input).digest("hex"); // Convert to base36 and take required length const hashBigInt = BigInt(`0x${hash}`); const base36Hash = hashBigInt.toString(36); // Combine first letter with hash, ensuring we get the right length return (firstLetter + base36Hash).substring(0, length); } /** * Base64url encoding utilities (simplified) */ function base64urlEncode(data) { try { // Try Node.js Buffer first const nodeBuffer = globalThis?.Buffer; if (nodeBuffer && typeof nodeBuffer === "object" && "from" in nodeBuffer) { return nodeBuffer .from(data) .toString("base64url"); } // Fallback to browser btoa const browserBtoa = globalThis?.btoa; if (browserBtoa && typeof browserBtoa === "function") { return browserBtoa(data) .replace(/\+/g, "-") .replace(/\//g, "_") .replace(/=/g, ""); } throw new Error("No base64 encoding available"); } catch (error) { throw new Error(`Base64 encoding failed: ${error instanceof Error ? error.message : String(error)}`); } } function base64urlDecode(data) { try { // Try Node.js Buffer first const nodeBuffer = globalThis?.Buffer; if (nodeBuffer && typeof nodeBuffer === "object" && "from" in nodeBuffer) { return nodeBuffer .from(data, "base64url") .toString(); } // Fallback to browser atob const browserAtob = globalThis?.atob; if (browserAtob && typeof browserAtob === "function") { let base64 = data.replace(/-/g, "+").replace(/_/g, "/"); while (base64.length % 4) { base64 += "="; } return browserAtob(base64); } throw new Error("No base64 decoding available"); } catch (error) { throw new Error(`Base64 decoding failed: ${error instanceof Error ? error.message : String(error)}`); } }