// -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /* 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/. */ /*** =================== SAVED SIGNONS CODE =================== ***/ var kSignonBundle; var showingPasswords = false; function SignonsStartup() { kSignonBundle = document.getElementById("signonBundle"); document.getElementById("togglePasswords").label = kSignonBundle.getString("showPasswords"); document.getElementById("togglePasswords").accessKey = kSignonBundle.getString("showPasswordsAccessKey"); document.getElementById("signonsIntro").textContent = kSignonBundle.getString("loginsSpielAll"); LoadSignons(); // filter the table if requested by caller if (window.arguments && window.arguments[0] && window.arguments[0].filterString) setFilter(window.arguments[0].filterString); FocusFilterBox(); } function setFilter(aFilterString) { document.getElementById("filter").value = aFilterString; _filterPasswords(); } var signonsTreeView = { _filterSet : [], _lastSelectedRanges : [], selection: null, rowCount : 0, setTree : function(tree) {}, getImageSrc : function(row,column) {}, getProgressMode : function(row,column) {}, getCellValue : function(row,column) {}, getCellText : function(row,column) { var signon = this._filterSet.length ? this._filterSet[row] : signons[row]; switch (column.id) { case "siteCol": return signon.httpRealm ? (signon.hostname + " (" + signon.httpRealm + ")"): signon.hostname; case "userCol": return signon.username || ""; case "passwordCol": return signon.password || ""; default: return ""; } }, isSeparator : function(index) { return false; }, isSorted : function() { return false; }, isContainer : function(index) { return false; }, cycleHeader : function(column) {}, getRowProperties : function(row,prop) {}, getColumnProperties : function(column,prop) {}, getCellProperties : function(row,column,prop) { if (column.element.getAttribute("id") == "siteCol") prop.AppendElement(kLTRAtom); } }; function LoadSignons() { // loads signons into table try { signons = passwordmanager.getAllLogins(); } catch (e) { signons = []; } signonsTreeView.rowCount = signons.length; // sort and display the table signonsTree.treeBoxObject.view = signonsTreeView; // The sort column didn't change. SortTree (called by // SignonColumnSort) assumes we want to toggle the sort // direction but here we don't so we have to trick it lastSignonSortAscending = !lastSignonSortAscending; SignonColumnSort(lastSignonSortColumn); // disable "remove all signons" button if there are no signons var element = document.getElementById("removeAllSignons"); var toggle = document.getElementById("togglePasswords"); if (signons.length == 0 || gSelectUserInUse) { element.setAttribute("disabled","true"); toggle.setAttribute("disabled","true"); } else { element.removeAttribute("disabled"); toggle.removeAttribute("disabled"); } return true; } function SignonSelected() { var selections = GetTreeSelections(signonsTree); if (selections.length && !gSelectUserInUse) { document.getElementById("removeSignon").removeAttribute("disabled"); } } function DeleteSignon() { var syncNeeded = (signonsTreeView._filterSet.length != 0); DeleteSelectedItemFromTree(signonsTree, signonsTreeView, signonsTreeView._filterSet.length ? signonsTreeView._filterSet : signons, deletedSignons, "removeSignon", "removeAllSignons"); FinalizeSignonDeletions(syncNeeded); } function DeleteAllSignons() { var prompter = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] .getService(Components.interfaces.nsIPromptService); // Confirm the user wants to remove all passwords var dummy = { value: false }; if (prompter.confirmEx(window, kSignonBundle.getString("removeAllPasswordsTitle"), kSignonBundle.getString("removeAllPasswordsPrompt"), prompter.STD_YES_NO_BUTTONS + prompter.BUTTON_POS_1_DEFAULT, null, null, null, null, dummy) == 1) // 1 == "No" button return; var syncNeeded = (signonsTreeView._filterSet.length != 0); DeleteAllFromTree(signonsTree, signonsTreeView, signonsTreeView._filterSet.length ? signonsTreeView._filterSet : signons, deletedSignons, "removeSignon", "removeAllSignons"); FinalizeSignonDeletions(syncNeeded); } function TogglePasswordVisible() { if (showingPasswords || masterPasswordLogin(AskUserShowPasswords)) { showingPasswords = !showingPasswords; document.getElementById("togglePasswords").label = kSignonBundle.getString(showingPasswords ? "hidePasswords" : "showPasswords"); document.getElementById("togglePasswords").accessKey = kSignonBundle.getString(showingPasswords ? "hidePasswordsAccessKey" : "showPasswordsAccessKey"); document.getElementById("passwordCol").hidden = !showingPasswords; _filterPasswords(); } // Notify observers that the password visibility toggling is // completed. (Mostly useful for tests) Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService) .notifyObservers(null, "passwordmgr-password-toggle-complete", null); } function AskUserShowPasswords() { var prompter = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService); var dummy = { value: false }; // Confirm the user wants to display passwords return prompter.confirmEx(window, null, kSignonBundle.getString("noMasterPasswordPrompt"), prompter.STD_YES_NO_BUTTONS, null, null, null, null, dummy) == 0; // 0=="Yes" button } function FinalizeSignonDeletions(syncNeeded) { for (var s=0; s 0) signonsTreeView.selection.select(0); document.getElementById("signonsIntro").textContent = kSignonBundle.getString("loginsSpielFiltered"); } function CopyPassword() { // Don't copy passwords if we aren't already showing the passwords & a master // password hasn't been entered. if (!showingPasswords && !masterPasswordLogin()) return; // Copy selected signon's password to clipboard var clipboard = Components.classes["@mozilla.org/widget/clipboardhelper;1"]. getService(Components.interfaces.nsIClipboardHelper); var row = document.getElementById("signonsTree").currentIndex; var password = signonsTreeView.getCellText(row, {id : "passwordCol" }); clipboard.copyString(password, document); } function CopyUsername() { // Copy selected signon's username to clipboard var clipboard = Components.classes["@mozilla.org/widget/clipboardhelper;1"]. getService(Components.interfaces.nsIClipboardHelper); var row = document.getElementById("signonsTree").currentIndex; var username = signonsTreeView.getCellText(row, {id : "userCol" }); clipboard.copyString(username); } function UpdateCopyPassword() { var singleSelection = (signonsTreeView.selection.count == 1); var passwordMenuitem = document.getElementById("context-copypassword"); var usernameMenuitem = document.getElementById("context-copyusername"); if (singleSelection) { usernameMenuitem.removeAttribute("disabled"); passwordMenuitem.removeAttribute("disabled"); } else { usernameMenuitem.setAttribute("disabled", "true"); passwordMenuitem.setAttribute("disabled", "true"); } } function masterPasswordLogin(noPasswordCallback) { // This doesn't harm if passwords are not encrypted var tokendb = Components.classes["@mozilla.org/security/pk11tokendb;1"] .createInstance(Components.interfaces.nsIPK11TokenDB); var token = tokendb.getInternalKeyToken(); // If there is no master password, still give the user a chance to opt-out of displaying passwords if (token.checkPassword("")) return noPasswordCallback ? noPasswordCallback() : true; // So there's a master password. But since checkPassword didn't succeed, we're logged out (per nsIPK11Token.idl). try { // Relogin and ask for the master password. token.login(true); // 'true' means always prompt for token password. User will be prompted until // clicking 'Cancel' or entering the correct password. } catch (e) { // An exception will be thrown if the user cancels the login prompt dialog. // User is also logged out of Software Security Device. } return token.isLoggedIn(); }