fix: closing a transaction or signature approval window leaves the request pending (closes #673)
The browser can close the approval window when the user clicks away from it, for example to copy the password from a password manager. Closing it used to reject the request with 4001. Now the request stays pending and the site gets no answer. Until it is answered, the toolbar popup opens the oldest such approval. A worker that starts holds no approvals, so it points the toolbar popup back at the wallet. Reject now closes its window only after the background has the rejection. Sent as the window closed, the rejection could be lost, which the old window-close rejection hid. Site-connection and network-switch windows still reject the request when closed. Model: opus-5-5
This commit is contained in:
@@ -1035,11 +1035,14 @@ step(
|
||||
},
|
||||
);
|
||||
|
||||
// A closed approval window leaves its request pending, and the toolbar button
|
||||
// opens it (https://git.eeqj.de/sneak/AutistMask/issues/673). WebDriver cannot
|
||||
// see the toolbar popup, so its page is opened in a tab, at the URL the
|
||||
// extension put on the button.
|
||||
step(
|
||||
"closing an approval window rejects the request with 4001",
|
||||
"a closed approval window leaves the request pending until it is rejected",
|
||||
async (env) => {
|
||||
const d = env.driver;
|
||||
const before = env.server.broadcast.length;
|
||||
|
||||
await d.switchToWindow(env.dappWindow);
|
||||
await startRequest(d, "sign-closed", "personal_sign", [
|
||||
@@ -1053,15 +1056,45 @@ step(
|
||||
|
||||
// Closed, not rejected: this is the windows.onRemoved path, which can
|
||||
// only fire if windows.create() handed back a window id for the
|
||||
// approval to be matched against — call site 4 in the issue, and the
|
||||
// reason suppressing that write-back turns this step red.
|
||||
// approval to be matched against. Without that id the toolbar button
|
||||
// never opens the approval, and this step fails.
|
||||
await d.closeWindow(env.dappWindow);
|
||||
|
||||
await assertUserRejection(d, "sign-closed", "a closed approval window");
|
||||
const outcome = await settleRequest(d, "sign-closed", 2000);
|
||||
assert(
|
||||
env.server.broadcast.length === before,
|
||||
"a closed approval window still put a transaction on the node",
|
||||
outcome.settled === "pending",
|
||||
"closing the approval window answered the page: " +
|
||||
JSON.stringify(outcome),
|
||||
);
|
||||
|
||||
await d.switchToWindow(env.popupWindow);
|
||||
const url = await d.executeAsync(
|
||||
`const done = arguments[arguments.length - 1];
|
||||
browser.browserAction.getPopup({}).then(done, (e) => done(String(e)));`,
|
||||
);
|
||||
assert(
|
||||
url.includes("?approval="),
|
||||
"the toolbar button does not open the pending approval: " + url,
|
||||
);
|
||||
const reopened = await d.newWindow("tab");
|
||||
await d.switchToWindow(reopened);
|
||||
await d.navigate(url);
|
||||
await d.waitVisible("#view-approve-sign");
|
||||
await d.click("#btn-reject-sign");
|
||||
|
||||
await d.switchToWindow(env.dappWindow);
|
||||
await assertUserRejection(
|
||||
d,
|
||||
"sign-closed",
|
||||
"the signature request rejected from the toolbar button",
|
||||
);
|
||||
|
||||
// A page may close only a window a script opened, so the tab can
|
||||
// still be open.
|
||||
const left = await d.findWindow((u) => u.includes("?approval="));
|
||||
if (left) {
|
||||
await d.switchToWindow(left);
|
||||
await d.closeWindow(env.dappWindow);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user