From 6d8d154ad0f196d32a69cfce96a6bac4917fcfbe Mon Sep 17 00:00:00 2001 From: jelveh Date: Sat, 25 Jul 2026 21:56:50 -0700 Subject: [PATCH] Key the dialog dedup by the identity its gate accepts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The gate treats an empty app_uid as absent and falls through to the origin; the dedup key used ?? and kept the empty string, so two requests from different origins would collide on one key and share a single decision. No caller can produce a blank uid today — server uids are never empty and the IPC path's empty attribute is stopped by the gate — but the two lines have to agree. --- src/gui/src/UI/UIPermissionDialog.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/src/UI/UIPermissionDialog.js b/src/gui/src/UI/UIPermissionDialog.js index 7d3ea08cc..ef5c18750 100644 --- a/src/gui/src/UI/UIPermissionDialog.js +++ b/src/gui/src/UI/UIPermissionDialog.js @@ -67,7 +67,10 @@ async function UIPermissionDialog (options) { return false; } - const pending_key = `${options.app_uid ?? options.origin ?? ''}\n${options.permission}`; + // `||`, not `??`: the gate above treats an empty uid as absent, so the key + // has to fall through to the origin too — otherwise two different origins + // arriving with a blank uid would share one decision. + const pending_key = `${options.app_uid || options.origin || ''}\n${options.permission}`; if ( pending_dialogs.has(pending_key) ) { return pending_dialogs.get(pending_key); }