/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // ClientAuthDialogService implements nsIClientAuthDialogService, and aims to // open a dialog asking the user to select a client authentication certificate. // Ideally the dialog will be tab-modal to the tab corresponding to the load // that resulted in the request for the client authentication certificate. export function ClientAuthDialogService() {} const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { PromptUtils: "resource://gre/modules/PromptUtils.sys.mjs", }); // Given a loadContext (CanonicalBrowsingContext), attempts to return a // TabDialogBox for the browser corresponding to loadContext. function getTabDialogBoxForLoadContext(loadContext) { let tabBrowser = loadContext?.topFrameElement?.getTabBrowser(); if (!tabBrowser) { return null; } for (let browser of tabBrowser.browsers) { if (browser.browserId == loadContext.top?.browserId) { return tabBrowser.getTabDialogBox(browser); } } return null; } ClientAuthDialogService.prototype = { classID: Components.ID("{d7d2490d-2640-411b-9f09-a538803c11ee}"), QueryInterface: ChromeUtils.generateQI(["nsIClientAuthDialogService"]), chooseCertificate: function ClientAuthDialogService_chooseCertificate( hostname, certArray, loadContext, callback ) { const clientAuthAskURI = "chrome://pippki/content/clientauthask.xhtml"; let retVals = { cert: null, rememberDecision: false }; let args = lazy.PromptUtils.objectToPropBag({ hostname, certArray, retVals, }); // First attempt to find a TabDialogBox for the loadContext. This allows // for a tab-modal dialog specific to the tab causing the load, which is a // better user experience. let tabDialogBox = getTabDialogBoxForLoadContext(loadContext); if (tabDialogBox) { tabDialogBox.open(clientAuthAskURI, {}, args).closedPromise.then(() => { callback.certificateChosen(retVals.cert, retVals.rememberDecision); }); return; } // Otherwise, attempt to open a window-modal dialog on the window that at // least has the tab the load is occurring in. let browserWindow = loadContext?.topFrameElement?.ownerGlobal; // Failing that, open a window-modal dialog on the most recent window. if (!browserWindow?.gDialogBox) { browserWindow = Services.wm.getMostRecentBrowserWindow(); } if (browserWindow?.gDialogBox) { browserWindow.gDialogBox.open(clientAuthAskURI, args).then(() => { callback.certificateChosen(retVals.cert, retVals.rememberDecision); }); return; } let mostRecentWindow = Services.wm.getMostRecentWindow(""); Services.ww.openWindow( mostRecentWindow, clientAuthAskURI, "_blank", "centerscreen,chrome,modal,titlebar", args ); callback.certificateChosen(retVals.cert, retVals.rememberDecision); }, };