Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64a9850d97 |
@@ -45,6 +45,15 @@ but the review is broader than any of them.
|
||||
|
||||
# Completed Steps
|
||||
|
||||
- 2026-10-06: The private key export screen opens again in the same popup
|
||||
session ([#460](https://git.eeqj.de/sneak/AutistMask/issues/460)). `show()`
|
||||
found the address line through the element inside it, which its own rendering
|
||||
replaced, so the second open threw before it navigated. The line now carries
|
||||
the `export-privkey-address` id itself. `tests/exportPrivkey.test.js` opens
|
||||
the screen twice, its DOM stub now takes an element out of the document when
|
||||
its parent's contents are replaced, and the `#253` e2e case no longer reopens
|
||||
the popup before its second open.
|
||||
|
||||
- 2026-10-06: The canonical files are re-vendored from `sneak/prompts` at
|
||||
`dd4027b` ([#472](https://git.eeqj.de/sneak/AutistMask/issues/472)). The
|
||||
`Dockerfile` has separate `lint` and `test` phases, and its last stage depends
|
||||
|
||||
@@ -391,14 +391,7 @@
|
||||
></div>
|
||||
<h2 class="font-bold mb-1">Export Private Key</h2>
|
||||
<p class="text-xs mb-1" id="export-privkey-title"></p>
|
||||
<div class="text-xs mb-3">
|
||||
<span id="export-privkey-dot"></span>
|
||||
<span
|
||||
id="export-privkey-address"
|
||||
class="cursor-pointer"
|
||||
title="Click to copy"
|
||||
></span>
|
||||
</div>
|
||||
<div id="export-privkey-address" class="text-xs mb-3"></div>
|
||||
<p class="text-xs mb-3 text-muted">
|
||||
Warning: anyone with this private key can access and
|
||||
transfer all funds from this address. Never share it.
|
||||
|
||||
@@ -98,7 +98,7 @@ function show(walletIdx, addrIdx) {
|
||||
|
||||
$("export-privkey-title").textContent =
|
||||
wallet.name + " — Address " + (addrIdx + 1);
|
||||
const addrContainer = $("export-privkey-dot").parentElement;
|
||||
const addrContainer = $("export-privkey-address");
|
||||
addrContainer.innerHTML = renderAddressHtml(addr.address);
|
||||
attachCopyHandlers(addrContainer);
|
||||
|
||||
|
||||
+2
-4
@@ -1104,10 +1104,8 @@ test("leaving by the settings gear wipes the private key (#253)", async (env) =>
|
||||
test("leaving while the decrypt is in flight reveals no private key (#253)", async (env) => {
|
||||
try {
|
||||
await leavePrivkeyScreen(env.page);
|
||||
// The export screen cannot yet be opened twice in one popup session
|
||||
// (https://git.eeqj.de/sneak/AutistMask/issues/460), so this second
|
||||
// open gets a fresh one.
|
||||
await reopenPopup(env, "main");
|
||||
// The second open in this popup session
|
||||
// (https://git.eeqj.de/sneak/AutistMask/issues/460).
|
||||
await openPrivkeyScreen(env.page);
|
||||
await env.page.fill("#export-privkey-password", PASSWORD);
|
||||
const inFlight = await env.page.evaluate(() => {
|
||||
|
||||
@@ -58,7 +58,20 @@ function makeElement(id, withParent) {
|
||||
remove: () => {},
|
||||
querySelectorAll: () => [],
|
||||
};
|
||||
el.parentElement = withParent ? makeElement(id + "-parent", false) : null;
|
||||
el.parentElement = null;
|
||||
if (withParent) {
|
||||
// As in a browser, replacing the parent's contents takes this
|
||||
// element out of the document: getElementById no longer finds it.
|
||||
el.parentElement = makeElement(id + "-parent", false);
|
||||
let html = "";
|
||||
Object.defineProperty(el.parentElement, "innerHTML", {
|
||||
get: () => html,
|
||||
set: (value) => {
|
||||
html = value;
|
||||
el.removed = true;
|
||||
},
|
||||
});
|
||||
}
|
||||
return el;
|
||||
}
|
||||
|
||||
@@ -70,7 +83,8 @@ function makeDocument() {
|
||||
// is the state a non-debug, non-testnet popup is in.
|
||||
if (id === "debug-banner") return null;
|
||||
if (!els.has(id)) els.set(id, makeElement(id, true));
|
||||
return els.get(id);
|
||||
const el = els.get(id);
|
||||
return el.removed ? null : el;
|
||||
},
|
||||
createElement: () => makeElement("created", false),
|
||||
addEventListener: () => {},
|
||||
@@ -300,6 +314,28 @@ describe("leaving the screen after the key is on it", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("opening the screen again in the same popup session", () => {
|
||||
// https://git.eeqj.de/sneak/AutistMask/issues/460: show() found the
|
||||
// address line through an element inside it, which its own rendering
|
||||
// deleted, so the second open threw before it navigated.
|
||||
test("shows it for the address chosen the second time", async () => {
|
||||
const { state, exportPrivkey } = load();
|
||||
exportPrivkey.show(0, 0);
|
||||
await click("btn-export-privkey-back");
|
||||
expect(state.currentView).toBe("address");
|
||||
|
||||
exportPrivkey.show(0, 1);
|
||||
|
||||
expect(state.currentView).toBe(VIEW);
|
||||
expect(node("export-privkey-title").textContent).toBe(
|
||||
"Wallet 1 — Address 2",
|
||||
);
|
||||
expect(node("export-privkey-address").innerHTML).toContain(
|
||||
"0x" + "22".repeat(20),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("views the popup may reopen onto", () => {
|
||||
// Restoring onto this screen would put a private key on display with no
|
||||
// password prompt in front of it, on a popup reopened by accident.
|
||||
|
||||
Reference in New Issue
Block a user