From c60e6c8ce2ac3139d1932dcd35986f279373e725 Mon Sep 17 00:00:00 2001 From: Oleksandr Kozachuk <201152+ok2@users.noreply.github.com> Date: Tue, 9 Jun 2026 22:53:44 +0200 Subject: [PATCH] helwasm: colour is per name+master, not per root master Mark correct now stores/checks the leaf's own SHA1(name||password) (correct ), read from the leaf warning in the enc output. Changing the name (or mistyping the master) drops back to black until that exact name+master is marked. Mark/unmark wraps add/rm for an ephemeral (not Stored) entry. --- helwasm/index.html | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/helwasm/index.html b/helwasm/index.html index bcd111e..0abc71a 100644 --- a/helwasm/index.html +++ b/helwasm/index.html @@ -68,8 +68,8 @@ Type an account name and your master phrase. The password appears instantly, masked; click it (or the master) to reveal. Press Copy, or Store to remember the name (never the password). - Click Mark correct once and the right master shows in colour, - so a typo stays black. + Mark correct remembers this name and master, so that exact + combination shows in colour; anything unmarked or mistyped stays black.

@@ -227,6 +227,7 @@ const persist = () => hel_command("save " + CATALOG_KEY); const esc = (s) => s.replace(/&/g, "&").replace(//g, ">"); const stripNoise = (out) => out.split("\n").filter((l) => l && !/^(warning|error):/.test(l)); + const escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); let toastT; function toast(msg) { @@ -271,8 +272,8 @@ b.classList.toggle("is-correct", !!enabled && !!isCorrect); b.textContent = enabled && isCorrect ? "Correct ✓" : "Mark correct"; b.title = enabled && isCorrect - ? "This master is remembered as correct on this device. Click to forget it." - : "Remember this master as correct on this device, so the right master shows in colour."; + ? "This name and master are remembered as correct on this device. Click to forget." + : "Remember this name and master as correct on this device, so this combination shows in colour."; } function quickGen(silent) { const spec = $("#qname").value.trim(); @@ -304,27 +305,38 @@ hel_command("rm " + name); } const pw = stripNoise(out).pop() || ""; - // Colour = "is the master correct?" — derived from the engine so it reflects - // `correct /` / `unpass /` typed in the console too. `enc /` re-emits the root - // correctness check; needs secrets["/"], which the gen above just set. - const rootChk = hel_command("enc /"); - const haveRoot = !/^error:/m.test(rootChk); - const masterOK = haveRoot && !/warning: password \/ is not marked as correct/.test(rootChk); + // Colour = "is THIS name + master marked correct?" — read straight from the + // leaf's own correct-check in the enc output (per name+password, not per master), + // so changing the name (or mistyping the master) drops back to black until you + // mark that exact combination. `correct` typed in the console is reflected too. + const warnRe = new RegExp("^warning: password " + escapeRegExp(name) + " is not marked as correct$", "m"); + const correct = !!pw && !warnRe.test(out); lastSecret = pw; sec.textContent = pw; - sec.classList.toggle("correct", !!pw && masterOK); + sec.classList.toggle("correct", correct); lenEl.textContent = pw ? "len " + pw.length : ""; - refreshCorrectBtn(!!pw && haveRoot, masterOK); + refreshCorrectBtn(!!pw, correct); if (!pw && !silent) toast("No output"); } function toggleCorrect() { const b = $("#markCorrect"); if (!b || b.disabled) return; - const wasCorrect = b.classList.contains("is-correct"); - // Store / remove the root-master hash on the device (same as the console). - hel_command(wasCorrect ? "uncorrect /" : "correct /"); + const spec = $("#qname").value.trim(); + const name = hel_parse_name(spec); + if (!name) return; + const verb = b.classList.contains("is-correct") ? "uncorrect " : "correct "; + // Mark / unmark THIS name + master on the device (stores SHA1(name‖password)). + // The entry may be ephemeral (not Stored), so wrap add/rm around it so + // correct/uncorrect can recompute the password to hash — same as the console. + if (/^error: name .* not found/m.test(hel_command("enc " + name))) { + hel_command("add " + spec); + hel_command(verb + name); + hel_command("rm " + name); + } else { + hel_command(verb + name); + } quickGen(true); - toast(wasCorrect ? "Master no longer marked correct" : "Master marked correct"); + toast(verb === "correct " ? "Marked correct" : "No longer marked correct"); } function quickStore() { const spec = $("#qname").value.trim();