Compare commits
1 Commits
fix/issue-
...
b690e0c8e5
| Author | SHA1 | Date | |
|---|---|---|---|
| b690e0c8e5 |
8
TODO.md
8
TODO.md
@@ -44,6 +44,14 @@ undefined identifiers, which is how
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- 2026-08-12: One wording for a rejected password on every screen that asks for
|
||||||
|
one — the send confirmation and the delete-wallet confirmation no longer say
|
||||||
|
"Wrong password." (a fragment, which `RULES.md` Language & Labeling forbids)
|
||||||
|
and the two reveal screens no longer say "not correct", so all five
|
||||||
|
`decryptWithPassword` call sites now show the sentence the dApp approval paths
|
||||||
|
introduced. Strings only, no behaviour change, and each error container
|
||||||
|
measured at a 360px viewport in the pinned Playwright container
|
||||||
|
([#172](https://git.eeqj.de/sneak/AutistMask/issues/172)).
|
||||||
- 2026-08-12: The dust threshold field now explains a rejection instead of
|
- 2026-08-12: The dust threshold field now explains a rejection instead of
|
||||||
snapping back in silence, with the parse in a pure, unit-tested module that
|
snapping back in silence, with the parse in a pure, unit-tested module that
|
||||||
accepts plain decimal digits only — hex and exponent notation are refused
|
accepts plain decimal digits only — hex and exponent notation are refused
|
||||||
|
|||||||
@@ -422,7 +422,10 @@ function init(ctx) {
|
|||||||
password,
|
password,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showError("confirm-tx-password-error", "Wrong password.");
|
showError(
|
||||||
|
"confirm-tx-password-error",
|
||||||
|
"That password is incorrect. Please try again.",
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,8 @@ function init(_ctx) {
|
|||||||
try {
|
try {
|
||||||
await decryptWithPassword(wallet.encryptedSecret, pw);
|
await decryptWithPassword(wallet.encryptedSecret, pw);
|
||||||
} catch (_e) {
|
} catch (_e) {
|
||||||
$("delete-wallet-flash").textContent = "Wrong password.";
|
$("delete-wallet-flash").textContent =
|
||||||
|
"That password is incorrect. Please try again.";
|
||||||
$("delete-wallet-flash").style.visibility = "visible";
|
$("delete-wallet-flash").style.visibility = "visible";
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.classList.remove("text-muted");
|
btn.classList.remove("text-muted");
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ async function reveal() {
|
|||||||
$("export-privkey-flash").style.visibility = "hidden";
|
$("export-privkey-flash").style.visibility = "hidden";
|
||||||
} catch {
|
} catch {
|
||||||
if (!isCurrentReveal(generation)) return;
|
if (!isCurrentReveal(generation)) return;
|
||||||
fail("That password is not correct. Please try again.");
|
fail("That password is incorrect. Please try again.");
|
||||||
} finally {
|
} finally {
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.classList.remove("text-muted");
|
btn.classList.remove("text-muted");
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ async function reveal() {
|
|||||||
if (!isCurrentReveal(generation)) return;
|
if (!isCurrentReveal(generation)) return;
|
||||||
// Deliberately not the caught error: the message is fixed so that
|
// Deliberately not the caught error: the message is fixed so that
|
||||||
// nothing derived from the ciphertext or the attempt can surface.
|
// nothing derived from the ciphertext or the attempt can surface.
|
||||||
fail("That password is not correct. Please try again.");
|
fail("That password is incorrect. Please try again.");
|
||||||
} finally {
|
} finally {
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.classList.remove("text-muted");
|
btn.classList.remove("text-muted");
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ describe("a reveal that is not interrupted", () => {
|
|||||||
|
|
||||||
expect(node("export-privkey-value").textContent).toBe("");
|
expect(node("export-privkey-value").textContent).toBe("");
|
||||||
expect(node("export-privkey-flash").textContent).toBe(
|
expect(node("export-privkey-flash").textContent).toBe(
|
||||||
"That password is not correct. Please try again.",
|
"That password is incorrect. Please try again.",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
79
tests/passwordMessages.test.js
Normal file
79
tests/passwordMessages.test.js
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
// One wording for one condition (issue #172).
|
||||||
|
//
|
||||||
|
// Every screen that asks for the password decrypts the vault itself, and
|
||||||
|
// each one used to write its own sentence for the same failure: the send
|
||||||
|
// confirmation and the delete-wallet confirmation said "Wrong password."
|
||||||
|
// (a fragment, which RULES.md Language & Labeling forbids), the reveal
|
||||||
|
// screens said "That password is not correct.", and the two dApp approval
|
||||||
|
// paths said "That password is incorrect." A user hitting two of those
|
||||||
|
// minutes apart had no way to tell whether the wallet meant the same
|
||||||
|
// thing.
|
||||||
|
//
|
||||||
|
// This scans the source rather than driving six views, because the
|
||||||
|
// invariant is about the set of call sites and not about any one of them:
|
||||||
|
// a seventh screen that decrypts the vault has to join the set, and a
|
||||||
|
// DOM test per view cannot notice one that was never written.
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const SRC = path.join(__dirname, "..", "src");
|
||||||
|
|
||||||
|
const CANONICAL = "That password is incorrect. Please try again.";
|
||||||
|
|
||||||
|
// Wordings this repo has actually shipped for the same condition. A
|
||||||
|
// literal match, so a new variant is caught by the "only the canonical
|
||||||
|
// sentence appears" assertion below rather than by guessing at phrasing.
|
||||||
|
const SUPERSEDED = [
|
||||||
|
"Wrong password.",
|
||||||
|
"That password is not correct. Please try again.",
|
||||||
|
];
|
||||||
|
|
||||||
|
function jsFilesUnder(dir) {
|
||||||
|
return fs.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) return jsFilesUnder(full);
|
||||||
|
return entry.name.endsWith(".js") ? [full] : [];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// The call sites are found, not listed: the file layout moves (the private
|
||||||
|
// key export was in addressDetail.js when #172 was filed and is its own
|
||||||
|
// view now), and a hardcoded list would quietly stop covering a screen it
|
||||||
|
// no longer names.
|
||||||
|
function callSites() {
|
||||||
|
return jsFilesUnder(SRC).filter((file) => {
|
||||||
|
if (file === path.join(SRC, "shared", "vault.js")) return false;
|
||||||
|
return fs.readFileSync(file, "utf8").includes("decryptWithPassword(");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("password failure messages", () => {
|
||||||
|
const files = callSites();
|
||||||
|
|
||||||
|
test("the call sites are found where they are expected", () => {
|
||||||
|
const found = files
|
||||||
|
.map((f) => path.relative(SRC, f).split(path.sep).join("/"))
|
||||||
|
.sort();
|
||||||
|
expect(found).toEqual([
|
||||||
|
"popup/views/approval.js",
|
||||||
|
"popup/views/confirmTx.js",
|
||||||
|
"popup/views/deleteWallet.js",
|
||||||
|
"popup/views/exportPrivkey.js",
|
||||||
|
"popup/views/showPhrase.js",
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("the canonical message is a full sentence", () => {
|
||||||
|
expect(CANONICAL).toMatch(/^[A-Z][^]*\.$/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test.each(files)("%s tells the user the canonical sentence", (f) => {
|
||||||
|
expect(fs.readFileSync(f, "utf8")).toContain(CANONICAL);
|
||||||
|
});
|
||||||
|
|
||||||
|
test.each(files)("%s carries no superseded wording", (f) => {
|
||||||
|
const source = fs.readFileSync(f, "utf8");
|
||||||
|
for (const old of SUPERSEDED) expect(source).not.toContain(old);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user