@intuitionrobotics/ts-common
Version:
36 lines • 1.75 kB
JavaScript
// Use the Web Crypto API via globalThis.crypto.subtle instead of Node's
// "crypto" module. Both environments expose subtle.sign() — Node since v19,
// every modern browser since forever. Importing "crypto" at module top-level
// otherwise pulls the crypto-browserify polyfill chain into browser bundles,
// where it produces "ReferenceError: exports is not defined" at runtime.
//
// The Web Crypto API is async-only; this is the breaking change vs the
// previous Node-crypto-backed sync implementation. The single caller in this
// framework (user-account's AccountModule) has been updated to await.
export function randomNumber(range) {
return Math.floor(Math.random() * (range));
}
export function randomObject(items) {
return items[randomNumber(items.length)];
}
/**
* Returns the SHA-512 HMAC of `password` keyed by `salt`, hex-encoded.
*
* Async because backed by Web Crypto API. Replaces the previous
* Node-crypto-backed sync implementation; existing callers must `await`.
*/
export async function hashPasswordWithSalt(salt, password) {
const enc = new TextEncoder();
const saltBuf = typeof salt === 'string' ? enc.encode(salt) : salt;
const passBuf = typeof password === 'string' ? enc.encode(password) : password;
const subtle = globalThis.crypto?.subtle;
if (!subtle)
throw new Error('Web Crypto API (globalThis.crypto.subtle) is not available in this environment');
const key = await subtle.importKey('raw', saltBuf, { name: 'HMAC', hash: 'SHA-512' }, false, ['sign']);
const sig = await subtle.sign('HMAC', key, passBuf);
let hex = '';
for (const b of new Uint8Array(sig))
hex += b.toString(16).padStart(2, '0');
return hex;
}
//# sourceMappingURL=crypto-tools.js.map