The Login Manager manages and stores user passwords. Extensions can replace the built-in password storage with their own implementation. This can be useful if you want to integrate a gecko application's password management with an existing password management system, or use your own password storage format or database.
If you just want to use the Login Manager in your extensions, refer to the article Using nsILoginManager.
Overriding the built-in Login Manager storage consists of two tasks:
- Implement the
nsILoginManagerStorage
interface. - Register that interface in a specific category.
Sample JavaScript implementation
The following code snippet is a JavaScript component that implements a dummy nsILoginManagerStorage
interface. See How_to_Build_an_XPCOM_Component_in_Javascript for more details about JavaScript components.
const Cc = Components.classes; const Ci = Components.interfaces; Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); function SampleLoginManagerStorage() {} SampleLoginManagerStorage.prototype = { classDescription: "Sample nsILoginManagerStorage implementation", contractID: "@example.com/login-manager/storage/sample;1", classID: Components.ID("{364a118c-747a-4f6d-ac63-2d2998e5a5c1}"), QueryInterface: XPCOMUtils.generateQI([Ci.nsILoginManagerStorage]), // This registers the category for overriding the built-in nsILoginManagerStorage _xpcom_categories: [ { category: "login-manager-storage", entry: "nsILoginManagerStorage" } ], // Console logging service, used for debugging. __logService : null, get _logService() { if (!this.__logService) this.__logService = Cc["@mozilla.org/consoleservice;1"]. getService(Ci.nsIConsoleService); return this.__logService; }, log: function (message) { dump("SampleLoginManager: " + message + "\n"); this._logService.logStringMessage("SampleLoginManager: " + message); }, // Logs function name and arguments for debugging stub: function(arguments) { var args = []; for (let i = 0; i < arguments.length; i++) args.push(arguments[i]) this.log("Called " + arguments.callee.name + "(" + args.join(",") + ")"); }, init: function SLMS_init() { this.stub(arguments); }, initWithFile: function SLMS_initWithFile(aInputFile, aOutputFile) { this.stub(arguments); }, addLogin: function SLMS_addLogin(login) { this.stub(arguments); }, removeLogin: function SLMS_removeLogin(login) { this.stub(arguments); }, modifyLogin: function SLMS_modifyLogin(oldLogin, newLogin) { this.stub(arguments); }, getAllLogins: function SLMS_getAllLogins(count) { this.stub(arguments); }, removeAllLogins: function SLMS_removeAllLogins() { this.stub(arguments); }, getAllDisabledHosts: function SLMS_getAllDisabledHosts(count) { this.stub(arguments); }, getLoginSavingEnabled: function SLMS_getLoginSavingEnabled(hostname) { this.stub(arguments); }, setLoginSavingEnabled: function SLMS_setLoginSavingEnabled(hostname, enabled) { this.stub(arguments); }, findLogins: function SLMS_findLogins(count, hostname, formSubmitURL, httpRealm) { this.stub(arguments); }, countLogins: function SLMS_countLogins(aHostname, aFormSubmitURL, aHttpRealm) { this.stub(arguments); } }; function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([SampleLoginManagerStorage]);
Sample C++ Implementation
bug 309807 contains a complete example. The category registration looks like this:
nsCOMPtr<nsICategoryManager> cat = do_GetService(NS_CATEGORYMANAGER_CONTRACTID); NS_ENSURE_STATE(cat); cat->AddCategoryEntry("login-manager-storage", "nsILoginManagerStorage", kYourContractID, PR_TRUE, PR_TRUE, nsnull);
Don't forget to unregister the category on unload.