Compare commits
1 Commits
61e0cad31f
...
e54465ac9f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e54465ac9f |
@@ -160,15 +160,9 @@
|
|||||||
Two things stop that: the three wordings in
|
Two things stop that: the three wordings in
|
||||||
PASSWORD_HINTS are kept within a couple of
|
PASSWORD_HINTS are kept within a couple of
|
||||||
characters of each other in length, and this floor
|
characters of each other in length, and this floor
|
||||||
matches what each of them needs. All three measure
|
is above what the longest of them needs. -->
|
||||||
48px -- 3 lines at the 16px line height, at the
|
|
||||||
368px width this box has in the 396px popup body.
|
|
||||||
Do not raise it: the reserve is unused height on
|
|
||||||
every tab, and at 6rem it pushed
|
|
||||||
#btn-add-wallet-confirm to bottom=628px in a 600px
|
|
||||||
viewport, below the fold. -->
|
|
||||||
<p
|
<p
|
||||||
class="text-xs text-muted mb-1 min-h-[3rem]"
|
class="text-xs text-muted mb-1 min-h-[6rem]"
|
||||||
id="add-wallet-password-hint"
|
id="add-wallet-password-hint"
|
||||||
>
|
>
|
||||||
This password encrypts your recovery phrase on this
|
This password encrypts your recovery phrase on this
|
||||||
|
|||||||
@@ -26,17 +26,6 @@ function displayName(walletIdx) {
|
|||||||
return (wallet && wallet.name) || "Wallet " + (walletIdx + 1);
|
return (wallet && wallet.name) || "Wallet " + (walletIdx + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// What the typed confirmation and the wallet name are compared as. HTML
|
|
||||||
// collapses runs of whitespace when it renders the name, so a wallet named
|
|
||||||
// "My Wallet" with two spaces DISPLAYS as "My Wallet": the user cannot
|
|
||||||
// see the second space and cannot type a string that matches the stored
|
|
||||||
// name. Comparing collapsed on both sides is what keeps the confirmation
|
|
||||||
// satisfiable, on the one screen whose whole purpose is unwedging a user
|
|
||||||
// who is already stuck. Case and surrounding space go the same way.
|
|
||||||
function confirmKey(name) {
|
|
||||||
return name.trim().replace(/\s+/g, " ").toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drop the password from the DOM and the wallet selection from the
|
// Drop the password from the DOM and the wallet selection from the
|
||||||
// closure. Registered as the view-leave handler as well as run on entry,
|
// closure. Registered as the view-leave handler as well as run on entry,
|
||||||
// so the typed password does not sit in the hidden view after the user
|
// so the typed password does not sit in the hidden view after the user
|
||||||
@@ -167,14 +156,13 @@ function init(_ctx) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case, surrounding spaces and repeated inner spaces are not part
|
// Case and surrounding spaces are not part of the confirmation.
|
||||||
// of the confirmation; see confirmKey(). This asks whether the
|
// This asks whether the user knows which wallet they are on; it is
|
||||||
// user knows which wallet they are on; it is not a secret, and
|
// not a secret, and refusing "wallet 2" for "Wallet 2" would only
|
||||||
// refusing "wallet 2" for "Wallet 2" would only teach the user to
|
// teach the user to distrust the control.
|
||||||
// distrust the control.
|
const typed = $("delete-wallet-lost-name-input").value.trim();
|
||||||
const typed = $("delete-wallet-lost-name-input").value;
|
|
||||||
const expected = displayName(lostPasswordIndex);
|
const expected = displayName(lostPasswordIndex);
|
||||||
if (confirmKey(typed) !== confirmKey(expected)) {
|
if (typed.toLowerCase() !== expected.toLowerCase()) {
|
||||||
$("delete-wallet-lost-flash").textContent =
|
$("delete-wallet-lost-flash").textContent =
|
||||||
"That is not the name of this wallet. Type " +
|
"That is not the name of this wallet. Type " +
|
||||||
expected +
|
expected +
|
||||||
|
|||||||
@@ -326,33 +326,6 @@ describe("the typed confirmation", () => {
|
|||||||
]);
|
]);
|
||||||
expect(await persistedWallets(storage)).toHaveLength(2);
|
expect(await persistedWallets(storage)).toHaveLength(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
// A name with a doubled inner space RENDERS with one — HTML collapses
|
|
||||||
// runs of whitespace — so the string the user can see and type is not
|
|
||||||
// the string the name is stored as. Comparing the two raw would make
|
|
||||||
// this wallet's confirmation impossible to satisfy by any typing at
|
|
||||||
// all, wedging the one screen that exists to unwedge people.
|
|
||||||
test("a doubled space inside the name is typed back as one", async () => {
|
|
||||||
const { deleteWallet, state, storage } = load();
|
|
||||||
state.wallets[1].name = "My Wallet";
|
|
||||||
await openLostPassword(deleteWallet, 1);
|
|
||||||
|
|
||||||
// What the DOM was handed still has both spaces; what the user
|
|
||||||
// reads off the screen, and therefore types, has one.
|
|
||||||
expect(node("delete-wallet-lost-name").textContent).toBe("My Wallet");
|
|
||||||
node("delete-wallet-lost-name-input").value = "My Wallet";
|
|
||||||
await click("btn-delete-wallet-lost-confirm");
|
|
||||||
|
|
||||||
expect(state.wallets.map((w) => w.name)).toEqual([
|
|
||||||
"Wallet 1",
|
|
||||||
"Wallet 3",
|
|
||||||
]);
|
|
||||||
const persisted = await persistedWallets(storage);
|
|
||||||
expect(persisted.map((w) => w.encryptedSecret)).toEqual([
|
|
||||||
"secret-one",
|
|
||||||
"secret-three",
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("deleting without the password", () => {
|
describe("deleting without the password", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user