Settings gains a Passwords section with an "Allow weak passwords" checkbox. It is off in a new profile, and only a stored true turns it on. While it is off, AddWallet refuses a password shorter than 12 characters, as before. While it is on, AddWallet accepts any password that is not empty. Key derivation is unchanged. The README describes the setting under Settings and AddWallet. Its Key Decisions section now states the Argon2id parameters and why they are light. The user guide lists the setting under Settings. Model: opus-5-5
88 lines
3.0 KiB
JavaScript
88 lines
3.0 KiB
JavaScript
// "Allow weak passwords" in Settings is off until the user ticks it. While it
|
|
// is off, AddWallet refuses a password shorter than 12 characters. While it is
|
|
// on, AddWallet accepts any password that is not empty
|
|
// (https://git.eeqj.de/sneak/AutistMask/issues/674). These boot the real popup,
|
|
// set the checkbox in Settings as the user does, and then add a wallet.
|
|
|
|
jest.mock("../src/shared/vault", () => ({
|
|
decryptWithPassword: jest.fn(),
|
|
encryptWithPassword: jest.fn(async () => ({
|
|
salt: "salt",
|
|
nonce: "nonce",
|
|
ciphertext: "ciphertext",
|
|
})),
|
|
}));
|
|
|
|
const {
|
|
bootPopup,
|
|
cleanupPopup,
|
|
unversionedValidProfile,
|
|
} = require("./support/popupBoot");
|
|
|
|
const CHECKBOX = "settings-allow-weak-passwords";
|
|
const ERROR = "add-wallet-password-error";
|
|
|
|
afterEach(() => {
|
|
cleanupPopup();
|
|
});
|
|
|
|
// Boots a popup that holds one wallet and opens Settings, where the checkbox
|
|
// starts unticked. Ticks it when `allow` is true. Then opens AddWallet and
|
|
// presses the die for a recovery phrase.
|
|
async function openAddWallet(allow) {
|
|
const page = await bootPopup(unversionedValidProfile());
|
|
await page.click("btn-settings");
|
|
const checkbox = page.node(CHECKBOX);
|
|
expect(checkbox.checked).toBe(false);
|
|
if (allow) {
|
|
checkbox.checked = true;
|
|
for (const fn of checkbox.listeners.change) await fn();
|
|
expect(page.storage.read("autistmask").allowWeakPasswords).toBe(true);
|
|
}
|
|
await page.click("btn-main-add-wallet");
|
|
await page.click("btn-generate-phrase");
|
|
return page;
|
|
}
|
|
|
|
// Types `password` into both password fields and presses Import.
|
|
async function importWith(page, password) {
|
|
page.node("add-wallet-password").value = password;
|
|
page.node("add-wallet-password-confirm").value = password;
|
|
await page.click("btn-add-wallet-confirm");
|
|
}
|
|
|
|
function storedWalletCount(page) {
|
|
return page.storage.read("autistmask").wallets.length;
|
|
}
|
|
|
|
describe("Allow weak passwords", () => {
|
|
test("unticked: a password shorter than 12 characters is refused", async () => {
|
|
const page = await openAddWallet(false);
|
|
await importWith(page, "short");
|
|
expect(page.text(ERROR)).toBe(
|
|
"Password must be at least 12 characters.",
|
|
);
|
|
expect(storedWalletCount(page)).toBe(1);
|
|
expect(page.visibleViews()).toEqual(["add-wallet"]);
|
|
});
|
|
|
|
test("ticked: a password shorter than 12 characters is accepted", async () => {
|
|
const page = await openAddWallet(true);
|
|
await importWith(page, "short");
|
|
expect(page.text(ERROR)).toBe("");
|
|
expect(storedWalletCount(page)).toBe(2);
|
|
expect(page.visibleViews()).toEqual(["main"]);
|
|
});
|
|
|
|
test.each([false, true])(
|
|
"an empty password is refused (ticked: %s)",
|
|
async (allow) => {
|
|
const page = await openAddWallet(allow);
|
|
await importWith(page, "");
|
|
expect(page.text(ERROR)).toBe("Please choose a password.");
|
|
expect(storedWalletCount(page)).toBe(1);
|
|
expect(page.visibleViews()).toEqual(["add-wallet"]);
|
|
},
|
|
);
|
|
});
|