Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion src/main/preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ require("core-js/stable");
require("regenerator-runtime/runtime");
// Core
const { contextBridge } = require("electron");
const { app } = require("@electron/remote");
const { app, dialog } = require("@electron/remote");

const DesktopStorageService = require("./preload-apis/DesktopStorageService");
// Sub
Expand All @@ -20,6 +20,40 @@ if (process.env.NODE_ENV === "development") {
appVersion = app.getVersion();
}

// Work around Electron Windows bug where built-in alert/confirm cause
// input fields (including CodeMirror editors) to lose a visible caret and
// stop accepting text until the window is re-focused.
//
// See: https://github.com/electron/electron/issues/20400
// Instead of the browser's native confirm, delegate to Electron's
// dialog.showMessageBoxSync, which does not trigger the problematic
// focus behavior.
try {
if (process.platform === "win32" && typeof window !== "undefined") {
// Preserve any existing implementation in case something depends on it
const originalConfirm = window.confirm;

window.confirm = function (message) {
try {
const buttonIdx = dialog.showMessageBoxSync(null, {
type: "question",
buttons: ["OK", "Cancel"],
defaultId: 0,
cancelId: 1,
detail: String(message ?? ""),
message: "",
});
return buttonIdx === 0;
} catch (e) {
// Fallback to original confirm if dialog fails for any reason
return originalConfirm ? originalConfirm(message) : true;
Comment on lines +47 to +49
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Do not auto-confirm on fallback failure.

Line 49 returns true when both showMessageBoxSync and originalConfirm are unavailable. That turns a dialog error into implicit user consent and can execute destructive flows without confirmation.

🛠️ Proposed fix
-        return originalConfirm ? originalConfirm(message) : true;
+        return originalConfirm ? originalConfirm.call(window, message) : false;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/preload.js` around lines 47 - 49, The fallback in the catch block
inside the confirm shim currently returns true when both showMessageBoxSync and
originalConfirm are unavailable, which auto-confirms on error; change the catch
to return originalConfirm ? originalConfirm(message) : false (or otherwise
explicitly deny) and optionally log the caught error so failures do not grant
implicit consent; update the catch that references showMessageBoxSync and
originalConfirm in preload.js accordingly.

}
};
}
} catch (e) {
// Best-effort override only; ignore any preload-time errors.
}

(function (window) {
// Build the RQ object
const RQ = window.RQ || {};
Expand Down