// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0 if (localStorage.getItem("PRIVATE-secretKey") !== null || localStorage.getItem("PRIVATE-cryptoKey") !== null) { window.location.replace("/app/") document.body.innerHTML = "Redirecting..." throw new Error(); } let remote = localStorage.getItem("SETTING-homeServer") if (remote == null) { localStorage.setItem("SETTING-homeServer", "https://notes.ailur.dev") remote = "https://notes.ailur.dev" } let usernameBox = document.getElementById("usernameBox") let passwordBox = document.getElementById("passwordBox") let statusBox = document.getElementById("statusBox") let signupButton = document.getElementById("signupButton") let opButton = document.getElementById("opButton") // Leave these variables alone, they are used in the WASM code. async function hashpass(pass) { return await hashwasm.argon2id({ password: pass, salt: new TextEncoder().encode("I munch Burgers!!"), parallelism: 1, iterations: 32, memorySize: 19264, hashLength: 32, outputType: "hex" }) } function showElements(yesorno) { if (!yesorno) { usernameBox.classList.add("hidden") passwordBox.classList.add("hidden") signupButton.classList.add("hidden") opButton.classList.add("hidden") inputContainer.classList.add("hidden") } else { usernameBox.classList.remove("hidden") passwordBox.classList.remove("hidden") signupButton.classList.remove("hidden") opButton.classList.remove("hidden") inputContainer.classList.remove("hidden") } } document.addEventListener("DOMContentLoaded", function() { document.getElementById("homeserver").innerText = "Your homeserver is: " + remote + ". " }); opButton.addEventListener("click", () => { window.location.href = "/login" }); complete = new Event("completed"); window.returnCode = undefined; window.returnVar = undefined; // This is for the WASM code to call when it's done. Do not remove it, even if it looks like it's never called. function WASMComplete() { window.dispatchEvent(complete); } signupButton.addEventListener("click", () => { let username = usernameBox.value let password = passwordBox.value if (username === "") { statusBox.innerText = "Username required!" return } if ((username).length > 20) { statusBox.innerText = "Username cannot be more than 20 characters!" return } if (password === "") { statusBox.innerText = "Password required!" return } if ((password).length < 8) { statusBox.innerText = "Password must be at least 8 characters!" return } showElements(false) statusBox.innerText = "Computing PoW Challenge... (this may take up to 5 minutes at worst, 3 seconds at best)" /* * Compiled version of: * hashcat-wasm (https://concord.ailur.dev/hectabit/hashcat-wasm) * (c) Arzumify * @license AGPL-3.0 * Since this is my software, if you use it with proprietary servers, I will make sure you will walk across hot coals (just kidding, probably). * I'm not kidding about the license though. * I should stop including comments into JS and possibly minify this code. Oh, well. */ window.resourceExtra = "I love Burgernotes!" const go = new Go(); WebAssembly.instantiateStreaming(fetch("/static/wasm/hashcat.wasm"), go.importObject).then((result) => { go.run(result.instance); }) window.addEventListener("completed", async () => { if (window.returnCode === 1) { statusBox.innerText = "Please do not expose your computer to cosmic rays (an impossible logical event has occurred)." showElements(true) return } else if (window.returnCode === 2) { statusBox.innerText = "The PoW Challenge has failed. Please try again." showElements(true) return } statusBox.innerText = "Hashing password..." let hashedPassword = await hashpass(password) statusBox.innerText = "Contacting server..." fetch(remote + "/api/signup", { method: "POST", body: JSON.stringify({ username: username, password: hashedPassword, stamp: window.returnVar, }), headers: { "Content-Type": "application/json; charset=UTF-8", } }) .then((response) => response) .then(async (response) => { let responseData = await response.json() if (response.status === 200) { statusBox.innerText = "Setting up encryption keys..." localStorage.setItem("PRIVATE-secretKey", responseData["key"]) localStorage.setItem("PRIVATE-cryptoKey", await hashwasm.argon2id({ password: password, salt: new TextEncoder().encode("I love Burgernotes!"), parallelism: 1, iterations: 32, memorySize: 19264, hashLength: 32, outputType: "hex" })) statusBox.innerText = "Welcome!" await new Promise(r => setTimeout(r, 200)) window.location.href = "/app/" } else if (response.status === 409) { if (responseData["error"] === "Stamp already spent") { statusBox.innerText = "Pure bad luck... your PoW challenge was accepted, but someone else used the same PoW challenge as you. Please try again. (error: Stamp already spent)" } else { statusBox.innerText = "Username already taken!" } showElements(true) } else if (response.status === 429) { statusBox.innerText = "Please don't sign up to new accounts that quickly. If you are using a VPN, please turn it off!" showElements(true) } else if (response.status === 500) { statusBox.innerText = responseData["error"] showElements(true) } else { statusBox.innerText = "Something went wrong! (error: " + responseData["error"] + ")" showElements(true) } }) }) }); // @license-end