Skip to content

Commit 593c4ab

Browse files
vishu-bhjonpspri
andauthored
fix(ui): remove duplicate onclick handler causing double-click for CA cert upload (#4090)
* fix(ui): remove duplicate onclick handler causing double-click for CA cert upload Fixes #3558 The CA certificate upload drop zone had both an inline onclick attribute and a JavaScript event listener (initializeCACertUpload), causing the file selection dialog to open twice. Removed the inline onclick handler since initializeCACertUpload() already provides complete functionality including click-to-upload, drag-and-drop, and visual feedback. Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com> * fix(ui): prevent multiple event listener registrations for CA cert upload The initializeCACertUpload() function is called multiple times: - On DOMContentLoaded - After 500ms delay - When switching to gateways tab Each call was adding new event listeners without removing old ones, causing multiple click handlers to accumulate and trigger the file dialog multiple times. Added initialization guard using data-initialized attribute to prevent duplicate event listener registrations. Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com> * feat: secrets updated Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com> * test(ui): cover CA cert upload double-init guard Add a regression test that calls initializeCACertUpload() twice on the same drop zone and asserts the click listener is only attached once, so the file picker opens a single time. Also refresh the detect-secrets baseline so generated_at and line numbers match the rebased tree. Signed-off-by: Jonathan Springer <jps@s390x.com> --------- Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com> Signed-off-by: Jonathan Springer <jps@s390x.com> Co-authored-by: Jonathan Springer <jps@s390x.com>
1 parent db17f4a commit 593c4ab

4 files changed

Lines changed: 23 additions & 3 deletions

File tree

.secrets.baseline

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"files": "^.secrets.baseline|package-lock.json|Cargo.lock|scripts/sign_image.sh|scripts/zap|sonar-project.properties|uv.lock|^.secrets.baseline$",
44
"lines": null
55
},
6-
"generated_at": "2026-04-11T12:17:13Z",
6+
"generated_at": "2026-04-11T13:00:03Z",
77
"plugins_used": [
88
{
99
"name": "AWSKeyDetector"
@@ -6288,7 +6288,7 @@
62886288
"hashed_secret": "b4e44716dbbf57be3dae2f819d96795a85d06652",
62896289
"is_secret": false,
62906290
"is_verified": false,
6291-
"line_number": 12461,
6291+
"line_number": 12460,
62926292
"type": "Secret Keyword",
62936293
"verified_result": null
62946294
}

mcpgateway/admin_ui/caCertificate.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,12 @@ export const initializeCACertUpload = function () {
314314
const fileInput = safeGetElement("upload-ca-certificate");
315315

316316
if (dropZone && fileInput) {
317+
// Prevent multiple initializations
318+
if (dropZone.dataset.initialized === "true") {
319+
return;
320+
}
321+
dropZone.dataset.initialized = "true";
322+
317323
// Click to upload
318324
dropZone.addEventListener("click", function (e) {
319325
fileInput.click();

mcpgateway/templates/admin.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6033,7 +6033,6 @@ <h3 class="text-lg font-bold mb-4 dark:text-gray-200">
60336033
<div
60346034
id="ca-certificate-upload-drop-zone"
60356035
class="border-2 border-dashed border-gray-300 dark:border-gray-600 rounded-lg p-6 text-center hover:border-gray-400 dark:hover:border-gray-500 cursor-pointer"
6036-
onclick="Admin.safeGetElement('upload-ca-certificate').click()"
60376036
>
60386037
<div class="space-y-2">
60396038
<svg

tests/unit/js/caCertificate.test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,21 @@ describe("initializeCACertUpload", () => {
279279
expect(() => initializeCACertUpload()).not.toThrow();
280280
});
281281

282+
test("does not re-attach listeners when called twice on the same drop zone", () => {
283+
const { dropZone, fileInput } = setupDropZone();
284+
const addSpy = vi.spyOn(dropZone, "addEventListener");
285+
286+
initializeCACertUpload();
287+
initializeCACertUpload();
288+
289+
const clickCalls = addSpy.mock.calls.filter((c) => c[0] === "click");
290+
expect(clickCalls).toHaveLength(1);
291+
292+
const clickSpy = vi.spyOn(fileInput, "click");
293+
dropZone.click();
294+
expect(clickSpy).toHaveBeenCalledTimes(1);
295+
});
296+
282297
test("click on drop zone triggers file input click", () => {
283298
const { dropZone, fileInput } = setupDropZone();
284299
initializeCACertUpload();

0 commit comments

Comments
 (0)