function displayHash(hash) { document.getElementById("hash").innerText = hash document.getElementById("hash-container").classList.add("done") } function getHashSetup(formData) { let setup = { password: formData.get("password"), hashType: formData.get("hash-type"), privateOptions: {}, } switch (setup.hashType) { case "bcrypt": setup.privateOptions.cost = formData.get("bcrypt-cost") break case "sha512crypt": setup.privateOptions.rounds = formData.get("sha512crypt-rounds") break default: console.warn("Unknown hash type " + setup.hashType + ", not setting private options") } return setup } // Returns function that accepts two arguments: a password and an object of // private options for the hasher. function getHasher(hashType) { switch (hashType) { case "bcrypt": return (password, { cost }) => wasmBindings.hash_bcrypt(password, cost) case "sha512crypt": return (password, { rounds }) => wasmBindings.hash_sha512crypt(password, rounds) default: throw Error("Invalid hash type specified: " + hashType) } } (async () => { document.getElementById("generate").addEventListener("click", e => { e.target.disabled = true const buttonText = e.target.innerText e.target.innerText = "Calculating hash…" document.getElementById("hash-container").classList.remove("done") const formData = new FormData(document.getElementById("hash-setup")) const hashSetup = getHashSetup(formData) console.debug("Hash type:", hashSetup.hashType, "Private options:", hashSetup.privateOptions) const hasher = getHasher(hashSetup.hashType) // Hack for enforcing that the DOM changes get propagated to the view // before the hash is calculated (which blocks the thread). setTimeout(() => { displayHash(hasher(hashSetup.password, hashSetup.privateOptions)) e.target.innerText = buttonText e.target.disabled = false }, 0) }) })()