97 lines
3.1 KiB
JavaScript
97 lines
3.1 KiB
JavaScript
import { entropyToMnemonic } from '/public/utils/bip39.ts';
|
|
|
|
const urlParams = new URLSearchParams(globalThis.location.search);
|
|
const codeParam = urlParams.get('code');
|
|
if (codeParam) {
|
|
const input = document.getElementById('inviteCode');
|
|
if (input) {
|
|
input.value = codeParam;
|
|
document.getElementById('username')?.focus();
|
|
}
|
|
}
|
|
|
|
let generatedMnemonic = "";
|
|
|
|
const registerBtn = document.getElementById('registerBtn');
|
|
if (registerBtn) {
|
|
registerBtn.addEventListener('click', async () => {
|
|
const username = document.getElementById('username').value.trim();
|
|
const inviteCode = document.getElementById('inviteCode').value.trim();
|
|
|
|
if (!username || !inviteCode) {
|
|
setStatus("Username and Invite Code are required.", true);
|
|
return;
|
|
}
|
|
|
|
const loader = document.getElementById('loadingIndicator');
|
|
const btn = document.getElementById('registerBtn');
|
|
loader.style.display = 'block';
|
|
btn.disabled = true;
|
|
setStatus('');
|
|
|
|
try {
|
|
const res = await startWebAuthnRegistration(username, inviteCode);
|
|
if (res && res.success) {
|
|
// Generate 16 bytes of entropy for 12 BIP-39 words
|
|
const entropy = new Uint8Array(16);
|
|
crypto.getRandomValues(entropy);
|
|
generatedMnemonic = await entropyToMnemonic(entropy);
|
|
|
|
const words = generatedMnemonic.split(' ');
|
|
const grid = document.getElementById('wordGrid');
|
|
grid.innerHTML = words.map((w, idx) => `
|
|
<div class="word-cell">
|
|
<span class="word-num">${idx + 1}.</span>
|
|
<span class="word-text">${w}</span>
|
|
</div>
|
|
`).join('');
|
|
|
|
// Switch to Step 2
|
|
document.getElementById('step1Container').style.display = 'none';
|
|
document.getElementById('step2Container').style.display = 'block';
|
|
document.getElementById('registerTitle').textContent = "Recovery Voucher";
|
|
document.getElementById('registerSubtitle').textContent = "Save your 12-word backup key in a safe place.";
|
|
}
|
|
} catch (err) {
|
|
console.error(err);
|
|
} finally {
|
|
loader.style.display = 'none';
|
|
btn.disabled = false;
|
|
}
|
|
});
|
|
}
|
|
|
|
const copyWordsBtn = document.getElementById('copyWordsBtn');
|
|
if (copyWordsBtn) {
|
|
copyWordsBtn.addEventListener('click', async () => {
|
|
if (!generatedMnemonic) return;
|
|
try {
|
|
await navigator.clipboard.writeText(generatedMnemonic);
|
|
const btn = document.getElementById('copyWordsBtn');
|
|
const origHtml = btn.innerHTML;
|
|
btn.innerHTML = '<span>✓ Copied to Clipboard!</span>';
|
|
btn.style.borderColor = 'var(--success)';
|
|
btn.style.color = 'var(--success-text)';
|
|
setTimeout(() => {
|
|
btn.innerHTML = origHtml;
|
|
btn.style.borderColor = '';
|
|
btn.style.color = '';
|
|
}, 2500);
|
|
} catch (_e) {
|
|
alert("Select and copy the words manually: " + generatedMnemonic);
|
|
}
|
|
});
|
|
}
|
|
|
|
function setStatus(msg, isError) {
|
|
const statusDiv = document.getElementById('statusMessage');
|
|
if (!statusDiv) return;
|
|
if (msg) {
|
|
statusDiv.textContent = msg;
|
|
statusDiv.className = isError ? 'error' : 'success';
|
|
statusDiv.style.display = 'block';
|
|
} else {
|
|
statusDiv.style.display = 'none';
|
|
}
|
|
}
|