LoginStorageDelegate.sys.mjs (3423B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import { GeckoViewUtils } from "resource://gre/modules/GeckoViewUtils.sys.mjs"; 6 7 const lazy = {}; 8 9 ChromeUtils.defineESModuleGetters(lazy, { 10 GeckoViewAutocomplete: "resource://gre/modules/GeckoViewAutocomplete.sys.mjs", 11 GeckoViewPrompter: "resource://gre/modules/GeckoViewPrompter.sys.mjs", 12 LoginEntry: "resource://gre/modules/GeckoViewAutocomplete.sys.mjs", 13 }); 14 15 const { debug, warn } = GeckoViewUtils.initLogging("LoginStorageDelegate"); 16 17 // Sync with LoginSaveOption.Hint in Autocomplete.java. 18 const LoginStorageHint = { 19 NONE: 0, 20 GENERATED: 1 << 0, 21 LOW_CONFIDENCE: 1 << 1, 22 }; 23 24 export class LoginStorageDelegate { 25 _createMessage({ dismissed, autoSavedLoginGuid }, aLogins) { 26 let hint = LoginStorageHint.NONE; 27 if (dismissed) { 28 hint |= LoginStorageHint.LOW_CONFIDENCE; 29 } 30 if (autoSavedLoginGuid) { 31 hint |= LoginStorageHint.GENERATED; 32 } 33 return { 34 // Sync with PromptController 35 type: "Autocomplete:Save:Login", 36 hint, 37 logins: aLogins, 38 }; 39 } 40 41 promptToSavePassword(aBrowser, aLogin, dismissed = false) { 42 const prompt = new lazy.GeckoViewPrompter(aBrowser.ownerGlobal); 43 prompt.asyncShowPrompt( 44 this._createMessage({ dismissed }, [ 45 lazy.LoginEntry.fromLoginInfo(aLogin), 46 ]), 47 result => { 48 const selectedLogin = result?.selection?.value; 49 50 if (!selectedLogin) { 51 return; 52 } 53 54 const loginInfo = lazy.LoginEntry.parse(selectedLogin).toLoginInfo(); 55 Services.obs.notifyObservers(loginInfo, "passwordmgr-prompt-save"); 56 57 lazy.GeckoViewAutocomplete.onLoginSave(selectedLogin); 58 } 59 ); 60 61 return { 62 dismiss() { 63 prompt.dismiss(); 64 }, 65 }; 66 } 67 68 promptToChangePassword( 69 aBrowser, 70 aOldLogin, 71 aNewLogin, 72 dismissed = false, 73 notifySaved, 74 autoSavedLoginGuid = "" 75 ) { 76 const newLogin = lazy.LoginEntry.fromLoginInfo(aOldLogin || aNewLogin); 77 const oldGuid = (aOldLogin && newLogin.guid) || null; 78 newLogin.origin = aNewLogin.origin; 79 newLogin.formActionOrigin = aNewLogin.formActionOrigin; 80 newLogin.password = aNewLogin.password; 81 newLogin.username = aNewLogin.username; 82 83 const prompt = new lazy.GeckoViewPrompter(aBrowser.ownerGlobal); 84 prompt.asyncShowPrompt( 85 this._createMessage({ dismissed, autoSavedLoginGuid }, [newLogin]), 86 result => { 87 const selectedLogin = result?.selection?.value; 88 89 if (!selectedLogin) { 90 return; 91 } 92 93 lazy.GeckoViewAutocomplete.onLoginSave(selectedLogin); 94 95 const loginInfo = lazy.LoginEntry.parse(selectedLogin).toLoginInfo(); 96 Services.obs.notifyObservers( 97 loginInfo, 98 "passwordmgr-prompt-change", 99 oldGuid 100 ); 101 } 102 ); 103 104 return { 105 dismiss() { 106 prompt.dismiss(); 107 }, 108 }; 109 } 110 111 promptToChangePasswordWithUsernames(aBrowser, aLogins, aNewLogin) { 112 this.promptToChangePassword(aBrowser, null /* oldLogin */, aNewLogin); 113 } 114 } 115 116 LoginStorageDelegate.prototype.classID = Components.ID( 117 "{3d765750-1c3d-11ea-aaef-0800200c9a66}" 118 ); 119 LoginStorageDelegate.prototype.QueryInterface = ChromeUtils.generateQI([ 120 "nsILoginManagerPrompter", 121 ]);