diff --git a/browser/components/extensions/test/xpcshell/test_ext_browsingData_passwords.js b/browser/components/extensions/test/xpcshell/test_ext_browsingData_passwords.js index d39b5df05f79..4e8e498b8f82 100644 --- a/browser/components/extensions/test/xpcshell/test_ext_browsingData_passwords.js +++ b/browser/components/extensions/test/xpcshell/test_ext_browsingData_passwords.js @@ -9,8 +9,8 @@ const OLD_HOST = "http://mozilla.org"; const NEW_HOST = "http://mozilla.com"; const FXA_HOST = "chrome://FirefoxAccounts"; -function checkLoginExists(host, shouldExist) { - const logins = Services.logins.findLogins(host, "", null); +async function checkLoginExists(origin, shouldExist) { + const logins = await Services.logins.searchLoginsAsync({ origin }); equal( logins.length, shouldExist ? 1 : 0, @@ -19,7 +19,7 @@ function checkLoginExists(host, shouldExist) { } async function addLogin(host, timestamp) { - checkLoginExists(host, false); + await checkLoginExists(host, false); let login = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance( Ci.nsILoginInfo ); @@ -27,7 +27,7 @@ async function addLogin(host, timestamp) { login.QueryInterface(Ci.nsILoginMetaInfo); login.timePasswordChanged = timestamp; await Services.logins.addLoginAsync(login); - checkLoginExists(host, true); + await checkLoginExists(host, true); } async function setupPasswords() { @@ -62,27 +62,27 @@ add_task(async function testPasswords() { extension.sendMessage(method, {}); await extension.awaitMessage("passwordsRemoved"); - checkLoginExists(OLD_HOST, false); - checkLoginExists(NEW_HOST, false); - checkLoginExists(FXA_HOST, true); + await checkLoginExists(OLD_HOST, false); + await checkLoginExists(NEW_HOST, false); + await checkLoginExists(FXA_HOST, true); // Clear passwords with recent since value. await setupPasswords(); extension.sendMessage(method, { since: REFERENCE_DATE - 1000 }); await extension.awaitMessage("passwordsRemoved"); - checkLoginExists(OLD_HOST, true); - checkLoginExists(NEW_HOST, false); - checkLoginExists(FXA_HOST, true); + await checkLoginExists(OLD_HOST, true); + await checkLoginExists(NEW_HOST, false); + await checkLoginExists(FXA_HOST, true); // Clear passwords with old since value. await setupPasswords(); extension.sendMessage(method, { since: REFERENCE_DATE - 20000 }); await extension.awaitMessage("passwordsRemoved"); - checkLoginExists(OLD_HOST, false); - checkLoginExists(NEW_HOST, false); - checkLoginExists(FXA_HOST, true); + await checkLoginExists(OLD_HOST, false); + await checkLoginExists(NEW_HOST, false); + await checkLoginExists(FXA_HOST, true); } await extension.startup(); diff --git a/browser/components/migration/tests/marionette/test_refresh_firefox.py b/browser/components/migration/tests/marionette/test_refresh_firefox.py index b3170d270de7..ea5d6bce99e8 100644 --- a/browser/components/migration/tests/marionette/test_refresh_firefox.py +++ b/browser/components/migration/tests/marionette/test_refresh_firefox.py @@ -244,13 +244,13 @@ class TestFirefoxRefresh(MarionetteTestCase): ) def checkPassword(self): - loginInfo = self.marionette.execute_script( + loginInfo = self.runAsyncCode( """ - let ary = Services.logins.findLogins( - "test.marionette.mozilla.com", - "http://test.marionette.mozilla.com/some/form/", - null, {}); - return ary.length ? ary : {username: "null", password: "null"}; + let [resolve] = arguments; + Services.logins.searchLoginsAsync({ + origin: "test.marionette.mozilla.com", + formActionOrigin: "http://test.marionette.mozilla.com/some/form/", + }).then(ary => resolve(ary.length ? ary : {username: "null", password: "null"})); """ ) self.assertEqual(len(loginInfo), 1) diff --git a/services/fxaccounts/FxAccountsStorage.sys.mjs b/services/fxaccounts/FxAccountsStorage.sys.mjs index b3b66c56ac2d..24c85dbc2de9 100644 --- a/services/fxaccounts/FxAccountsStorage.sys.mjs +++ b/services/fxaccounts/FxAccountsStorage.sys.mjs @@ -498,11 +498,10 @@ LoginManagerStorage.prototype = { if (!this._isLoggedIn) { return false; } - let logins = Services.logins.findLogins( - FXA_PWDMGR_HOST, - null, - FXA_PWDMGR_REALM - ); + let logins = await Services.logins.searchLoginsAsync({ + origin: FXA_PWDMGR_HOST, + httpRealm: FXA_PWDMGR_REALM, + }); for (let login of logins) { Services.logins.removeLogin(login); } @@ -554,11 +553,10 @@ LoginManagerStorage.prototype = { "" ); // aPasswordField - let existingLogins = Services.logins.findLogins( - FXA_PWDMGR_HOST, - null, - FXA_PWDMGR_REALM - ); + let existingLogins = await Services.logins.searchLoginsAsync({ + origin: FXA_PWDMGR_HOST, + httpRealm: FXA_PWDMGR_REALM, + }); if (existingLogins.length) { Services.logins.modifyLogin(existingLogins[0], login); } else { @@ -590,11 +588,10 @@ LoginManagerStorage.prototype = { throw new this.STORAGE_LOCKED(); } - let logins = Services.logins.findLogins( - FXA_PWDMGR_HOST, - null, - FXA_PWDMGR_REALM - ); + let logins = await Services.logins.searchLoginsAsync({ + origin: FXA_PWDMGR_HOST, + httpRealm: FXA_PWDMGR_REALM, + }); if (!logins.length) { // This could happen if the MP was locked when we wrote the data. log.info("Can't find any credentials in the login manager"); diff --git a/services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js b/services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js index 50a236918e95..3b1149845a15 100644 --- a/services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js +++ b/services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js @@ -29,12 +29,11 @@ function setLoginMgrLoggedInState(loggedIn) { initTestLogging("Trace"); -function getLoginMgrData() { - let logins = Services.logins.findLogins( - FXA_PWDMGR_HOST, - null, - FXA_PWDMGR_REALM - ); +async function getLoginMgrData() { + let logins = await Services.logins.searchLoginsAsync({ + origin: FXA_PWDMGR_HOST, + httpRealm: FXA_PWDMGR_REALM, + }); if (!logins.length) { return null; } @@ -114,7 +113,7 @@ add_task(async function test_simple() { "scopedKeys not stored in clear text" ); - let login = getLoginMgrData(); + let login = await getLoginMgrData(); Assert.strictEqual(login.username, creds.uid, "uid used for username"); let loginData = JSON.parse(login.password); Assert.strictEqual( @@ -139,7 +138,7 @@ add_task(async function test_simple() { await fxa.signOut(/* localOnly = */ true); Assert.strictEqual( - getLoginMgrData(), + await getLoginMgrData(), null, "login mgr data deleted on logout" ); @@ -158,7 +157,11 @@ add_task(async function test_MPLocked() { verified: true, }; - Assert.strictEqual(getLoginMgrData(), null, "no login mgr at the start"); + Assert.strictEqual( + await getLoginMgrData(), + null, + "no login mgr at the start" + ); // tell the storage that the MP is locked. setLoginMgrLoggedInState(false); await fxa._internal.setSignedInUser(creds); @@ -189,7 +192,11 @@ add_task(async function test_MPLocked() { "scopedKeys not stored in clear text" ); - Assert.strictEqual(getLoginMgrData(), null, "login mgr data doesn't exist"); + Assert.strictEqual( + await getLoginMgrData(), + null, + "login mgr data doesn't exist" + ); await fxa.signOut(/* localOnly = */ true); }); @@ -235,7 +242,7 @@ add_task(async function test_consistentWithMPEdgeCases() { await fxa._internal.setSignedInUser(creds2); // We should still have creds1 data in the login manager. - let login = getLoginMgrData(); + let login = await getLoginMgrData(); Assert.strictEqual(login.username, creds1.uid); // and that we do have the first scopedKeys in the login manager. Assert.deepEqual( @@ -264,7 +271,11 @@ add_task(async function test_consistentWithMPEdgeCases() { // the login manager. add_task(async function test_uidMigration() { setLoginMgrLoggedInState(true); - Assert.strictEqual(getLoginMgrData(), null, "expect no logins at the start"); + Assert.strictEqual( + await getLoginMgrData(), + null, + "expect no logins at the start" + ); // create the login entry using email as a key. let contents = { diff --git a/services/sync/modules/engines/passwords.sys.mjs b/services/sync/modules/engines/passwords.sys.mjs index b2e4cb4ad2f1..8dea5664be6f 100644 --- a/services/sync/modules/engines/passwords.sys.mjs +++ b/services/sync/modules/engines/passwords.sys.mjs @@ -14,8 +14,6 @@ import { } from "resource://services-sync/engines.sys.mjs"; import { Svc, Utils } from "resource://services-sync/util.sys.mjs"; -import { Async } from "resource://services-common/async.sys.mjs"; - // These are valid fields the server could have for a logins record // we mainly use this to detect if there are any unknownFields and // store (but don't process) those fields to roundtrip them back @@ -164,13 +162,11 @@ PasswordEngine.prototype = { return null; } - let logins = this._store.storage.findLogins( - login.origin, - login.formActionOrigin, - login.httpRealm - ); - - await Async.promiseYield(); // Yield back to main thread after synchronous operation. + let logins = await this._store.storage.searchLoginsAsync({ + origin: login.origin, + formActionOrigin: login.formActionOrigin, + httpRealm: login.httpRealm, + }); // Look for existing logins that match the origin, but ignore the password. for (let local of logins) { diff --git a/services/sync/tests/unit/test_password_engine.js b/services/sync/tests/unit/test_password_engine.js index e3c2576bc023..5c026ac5aff1 100644 --- a/services/sync/tests/unit/test_password_engine.js +++ b/services/sync/tests/unit/test_password_engine.js @@ -168,7 +168,9 @@ add_task(async function test_password_engine() { ); await Services.logins.addLoginAsync(login); - let logins = Services.logins.findLogins("https://example.com", "", ""); + let logins = await Services.logins.searchLoginsAsync({ + origin: "https://example.com", + }); equal(logins.length, 1, "Should find new login in login manager"); newLogin = logins[0].QueryInterface(Ci.nsILoginMetaInfo); @@ -208,7 +210,9 @@ add_task(async function test_password_engine() { props.setProperty("timePasswordChanged", localPasswordChangeTime); Services.logins.modifyLogin(login, props); - let logins = Services.logins.findLogins("https://mozilla.com", "", ""); + let logins = await Services.logins.searchLoginsAsync({ + origin: "https://mozilla.com", + }); equal(logins.length, 1, "Should find old login in login manager"); oldLogin = logins[0].QueryInterface(Ci.nsILoginMetaInfo); equal(oldLogin.timePasswordChanged, localPasswordChangeTime); @@ -240,7 +244,9 @@ add_task(async function test_password_engine() { "Should update remote password for newer login" ); - let logins = Services.logins.findLogins("https://mozilla.com", "", ""); + let logins = await Services.logins.searchLoginsAsync({ + origin: "https://mozilla.com", + }); equal( logins[0].password, "n3wpa55", @@ -372,7 +378,6 @@ add_task(async function test_sync_outgoing() { _("Remove the login"); equal(collection.count(), 1); equal(Services.logins.countLogins("", "", ""), 2); - equal(Services.logins.findLogins("", "", "").length, 2); equal((await Services.logins.getAllLogins()).length, 2); ok(await engine._store.itemExists(guid)); @@ -401,7 +406,6 @@ add_task(async function test_sync_outgoing() { // All of these should not include the deleted login. Only the FxA password should exist. equal(Services.logins.countLogins("", "", ""), 1); - equal(Services.logins.findLogins("", "", "").length, 1); equal((await Services.logins.getAllLogins()).length, 1); ok(!(await engine._store.itemExists(guid))); @@ -457,7 +461,9 @@ add_task(async function test_sync_incoming() { _("Perform sync when remote login has been added"); await sync_engine_and_validate_telem(engine, false); - let logins = Services.logins.findLogins("https://www.example.com", "", ""); + let logins = await Services.logins.searchLoginsAsync({ + origin: "https://www.example.com", + }); equal(logins.length, 1); equal(logins[0].QueryInterface(Ci.nsILoginMetaInfo).guid, guid1); @@ -482,7 +488,9 @@ add_task(async function test_sync_incoming() { await engine.setLastSync(newTime / 1000 - 30); await sync_engine_and_validate_telem(engine, false); - logins = Services.logins.findLogins("https://www.example.com", "", ""); + logins = await Services.logins.searchLoginsAsync({ + origin: "https://www.example.com", + }); equal(logins.length, 1); details.password = "alpaca"; @@ -508,7 +516,9 @@ add_task(async function test_sync_incoming() { await engine.setLastSync(newTime / 1000 - 30); await sync_engine_and_validate_telem(engine, false); - logins = Services.logins.findLogins("https://www.example.com", "", ""); + logins = await Services.logins.searchLoginsAsync({ + origin: "https://www.example.com", + }); equal(logins.length, 1); details.username = "guanaco"; @@ -534,7 +544,9 @@ add_task(async function test_sync_incoming() { await engine.setLastSync(newTime / 1000 - 30); await sync_engine_and_validate_telem(engine, false); - logins = Services.logins.findLogins("https://www.example.com", "", ""); + logins = await Services.logins.searchLoginsAsync({ + origin: "https://www.example.com", + }); equal(logins.length, 0); } finally { await cleanup(engine, server); @@ -574,7 +586,9 @@ add_task(async function test_sync_incoming_deleted() { _("Perform sync when remote login has been deleted"); await sync_engine_and_validate_telem(engine, false); - let logins = Services.logins.findLogins("https://www.example.org", "", ""); + let logins = await Services.logins.searchLoginsAsync({ + origin: "https://www.example.com", + }); equal(logins.length, 0); ok(!(await engine._store.getAllIDs())[guid1]); ok(!(await engine._store.itemExists(guid1))); @@ -631,7 +645,9 @@ add_task(async function test_sync_incoming_deleted_localchanged_remotenewer() { ); await sync_engine_and_validate_telem(engine, false); - let logins = Services.logins.findLogins("http://mozilla.com", "", ""); + let logins = await Services.logins.searchLoginsAsync({ + origin: "https://mozilla.com", + }); equal(logins.length, 0); ok(await engine._store.getAllIDs()); } finally { @@ -687,7 +703,9 @@ add_task(async function test_sync_incoming_deleted_localchanged_localnewer() { ); await sync_engine_and_validate_telem(engine, false); - let logins = Services.logins.findLogins("http://www.mozilla.com", "", ""); + let logins = await Services.logins.searchLoginsAsync({ + origin: "http://www.mozilla.com", + }); equal(logins.length, 1); equal(logins[0].password, "cheetah"); equal(logins[0].syncCounter, 0); @@ -734,7 +752,9 @@ add_task(async function test_password_dupe() { _("Perform sync"); await sync_engine_and_validate_telem(engine, true); - let logins = Services.logins.findLogins("https://www.example.com", "", ""); + let logins = await Services.logins.searchLoginsAsync({ + origin: "https://www.example.com", + }); equal(logins.length, 1); equal(logins[0].QueryInterface(Ci.nsILoginMetaInfo).guid, guid2); @@ -788,11 +808,9 @@ add_task(async function test_updated_null_password_sync() { _("Perform sync"); await sync_engine_and_validate_telem(engine, false); - let logins = Services.logins.findLogins( - "https://www.nullupdateexample.com", - "", - "" - ); + let logins = await Services.logins.searchLoginsAsync({ + origin: "https://www.nullupdateexample.com", + }); equal(logins.length, 1); equal(logins[0].QueryInterface(Ci.nsILoginMetaInfo).guid, guid1); @@ -845,11 +863,9 @@ add_task(async function test_updated_undefined_password_sync() { _("Perform sync"); await sync_engine_and_validate_telem(engine, false); - let logins = Services.logins.findLogins( - "https://www.undefinedupdateexample.com", - "", - "" - ); + let logins = await Services.logins.searchLoginsAsync({ + origin: "https://www.undefinedupdateexample.com", + }); equal(logins.length, 1); equal(logins[0].QueryInterface(Ci.nsILoginMetaInfo).guid, guid1); @@ -887,7 +903,9 @@ add_task(async function test_new_null_password_sync() { _("Perform sync"); await sync_engine_and_validate_telem(engine, false); - let logins = Services.logins.findLogins("https://www.example.com", "", ""); + let logins = await Services.logins.searchLoginsAsync({ + origin: "https://www.example.com", + }); equal(logins.length, 1); notEqual(logins[0].QueryInterface(Ci.nsILoginMetaInfo).username, null); @@ -927,7 +945,9 @@ add_task(async function test_new_undefined_password_sync() { _("Perform sync"); await sync_engine_and_validate_telem(engine, false); - let logins = Services.logins.findLogins("https://www.example.com", "", ""); + let logins = await Services.logins.searchLoginsAsync({ + origin: "https://www.example.com", + }); equal(logins.length, 1); notEqual(logins[0].QueryInterface(Ci.nsILoginMetaInfo).username, null); @@ -1002,7 +1022,9 @@ add_task(async function test_roundtrip_unknown_fields() { props.setProperty("timePasswordChanged", localPasswordChangeTime); Services.logins.modifyLogin(login, props); - let logins = Services.logins.findLogins("https://mozilla.com", "", ""); + let logins = await Services.logins.searchLoginsAsync({ + origin: "https://mozilla.com", + }); equal(logins.length, 1, "Should find old login in login manager"); oldLogin = logins[0].QueryInterface(Ci.nsILoginMetaInfo); equal(oldLogin.timePasswordChanged, localPasswordChangeTime); @@ -1032,7 +1054,9 @@ add_task(async function test_roundtrip_unknown_fields() { try { await sync_engine_and_validate_telem(engine, false); - let logins = Services.logins.findLogins("https://mozilla.com", "", ""); + let logins = await Services.logins.searchLoginsAsync({ + origin: "https://mozilla.com", + }); equal( logins[0].password, "n3wpa55", diff --git a/services/sync/tests/unit/test_password_store.js b/services/sync/tests/unit/test_password_store.js index e0a4e1343f86..ed393d624189 100644 --- a/services/sync/tests/unit/test_password_store.js +++ b/services/sync/tests/unit/test_password_store.js @@ -24,11 +24,10 @@ async function checkRecord( let engine = Service.engineManager.get("passwords"); let store = engine._store; - let logins = Services.logins.findLogins( - record.hostname, - record.formSubmitURL, - null - ); + let logins = await Services.logins.searchLoginsAsync({ + origin: record.hostname, + formActionOrigin: record.formSubmitURL, + }); _("Record" + name + ":" + JSON.stringify(logins)); _("Count" + name + ":" + logins.length); @@ -350,16 +349,15 @@ add_task(async function run_test() { ); // Only the good record makes it to Services.logins. - let badLogins = Services.logins.findLogins( - recordA.hostname, - recordA.formSubmitURL, - recordA.httpRealm - ); - let goodLogins = Services.logins.findLogins( - recordB.hostname, - recordB.formSubmitURL, - null - ); + let badLogins = await Services.logins.searchLoginsAsync({ + origin: recordA.hostname, + formActionOrigin: recordA.formSubmitURL, + httpRealm: recordA.httpRealm, + }); + let goodLogins = await Services.logins.searchLoginsAsync({ + origin: recordB.hostname, + formActionOrigin: recordB.formSubmitURL, + }); _("Bad: " + JSON.stringify(badLogins)); _("Good: " + JSON.stringify(goodLogins)); diff --git a/services/sync/tps/extensions/tps/resource/modules/passwords.sys.mjs b/services/sync/tps/extensions/tps/resource/modules/passwords.sys.mjs index 9d1484773cff..976755e9892a 100644 --- a/services/sync/tps/extensions/tps/resource/modules/passwords.sys.mjs +++ b/services/sync/tps/extensions/tps/resource/modules/passwords.sys.mjs @@ -112,12 +112,12 @@ Password.prototype = { * * @return the guid of the password if found, otherwise -1 */ - Find() { - let logins = Services.logins.findLogins( - this.props.hostname, - this.props.submitURL, - this.props.realm - ); + async Find() { + let logins = await Services.logins.searchLoginsAsync({ + origin: this.props.hostname, + formActionOrigin: this.props.submitURL, + httpRealm: this.props.realm, + }); for (var i = 0; i < logins.length; i++) { if ( logins[i].username == this.props.username && diff --git a/services/sync/tps/extensions/tps/resource/tps.sys.mjs b/services/sync/tps/extensions/tps/resource/tps.sys.mjs index 7ca1ee055c89..d975b766cd51 100644 --- a/services/sync/tps/extensions/tps/resource/tps.sys.mjs +++ b/services/sync/tps/extensions/tps/resource/tps.sys.mjs @@ -464,19 +464,19 @@ export var TPS = { break; case ACTION_VERIFY: lazy.Logger.AssertTrue( - passwordOb.Find() != -1, + (await passwordOb.Find()) != -1, "password not found" ); break; case ACTION_VERIFY_NOT: lazy.Logger.AssertTrue( - passwordOb.Find() == -1, + (await passwordOb.Find()) == -1, "password found, but it shouldn't exist" ); break; case ACTION_DELETE: lazy.Logger.AssertTrue( - passwordOb.Find() != -1, + (await passwordOb.Find()) != -1, "password not found" ); passwordOb.Remove(); @@ -484,7 +484,7 @@ export var TPS = { case ACTION_MODIFY: if (passwordOb.updateProps != null) { lazy.Logger.AssertTrue( - passwordOb.Find() != -1, + (await passwordOb.Find()) != -1, "password not found" ); passwordOb.Update(); diff --git a/toolkit/components/forgetaboutsite/test/unit/test_removeDataFromDomain.js b/toolkit/components/forgetaboutsite/test/unit/test_removeDataFromDomain.js index f686627f956d..84894d1ec551 100644 --- a/toolkit/components/forgetaboutsite/test/unit/test_removeDataFromDomain.js +++ b/toolkit/components/forgetaboutsite/test/unit/test_removeDataFromDomain.js @@ -108,7 +108,7 @@ function check_disabled_host(aHost, aIsDisabled) { * The host to add the login for. */ async function add_login(aHost) { - check_login_exists(aHost, false); + await check_login_exists(aHost, false); let login = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance( Ci.nsILoginInfo ); @@ -122,7 +122,7 @@ async function add_login(aHost) { LOGIN_PASSWORD_FIELD ); await Services.logins.addLoginAsync(login); - check_login_exists(aHost, true); + await check_login_exists(aHost, true); } /** @@ -133,8 +133,8 @@ async function add_login(aHost) { * @param aExists * True if the login should exist, false otherwise. */ -function check_login_exists(aHost, aExists) { - let logins = Services.logins.findLogins(aHost, "", null); +async function check_login_exists(aHost, aExists) { + let logins = await Services.logins.searchLoginsAsync({ origin: aHost }); Assert.equal(logins.length, aExists ? 1 : 0); } @@ -314,24 +314,24 @@ async function test_login_manager_logins_cleared_with_direct_match() { const TEST_HOST = "http://mozilla.org"; await add_login(TEST_HOST); await ForgetAboutSite.removeDataFromDomain("mozilla.org"); - check_login_exists(TEST_HOST, true); + await check_login_exists(TEST_HOST, true); } async function test_login_manager_logins_cleared_with_subdomain() { const TEST_HOST = "http://www.mozilla.org"; await add_login(TEST_HOST); await ForgetAboutSite.removeDataFromDomain("mozilla.org"); - check_login_exists(TEST_HOST, true); + await check_login_exists(TEST_HOST, true); } async function test_login_manager_logins_not_cleared_with_uri_contains_domain() { const TEST_HOST = "http://ilovemozilla.org"; await add_login(TEST_HOST); await ForgetAboutSite.removeDataFromDomain("mozilla.org"); - check_login_exists(TEST_HOST, true); + await check_login_exists(TEST_HOST, true); Services.logins.removeAllUserFacingLogins(); - check_login_exists(TEST_HOST, false); + await check_login_exists(TEST_HOST, false); } async function test_login_manager_disabled_hosts_cleared_base_domain() { diff --git a/toolkit/components/passwordmgr/LoginHelper.sys.mjs b/toolkit/components/passwordmgr/LoginHelper.sys.mjs index f4556b09a96d..6108a2aada02 100644 --- a/toolkit/components/passwordmgr/LoginHelper.sys.mjs +++ b/toolkit/components/passwordmgr/LoginHelper.sys.mjs @@ -171,14 +171,14 @@ class ImportRowProcessor { * A login object. * @returns {boolean} True if the entry is similar or identical to another previously processed entry, false otherwise. */ - checkConflictingWithExistingLogins(login) { + async checkConflictingWithExistingLogins(login) { // While here we're passing formActionOrigin and httpRealm, they could be empty/null and get // ignored in that case, leading to multiple logins for the same username. - let existingLogins = Services.logins.findLogins( - login.origin, - login.formActionOrigin, - login.httpRealm - ); + let existingLogins = await Services.logins.searchLoginsAsync({ + origin: login.origin, + httpRealm: login.httpRealm, + }); + // Check for an existing login that matches *including* the password. // If such a login exists, we do not need to add a new login. if ( @@ -1498,7 +1498,7 @@ export const LoginHelper = { if (processor.checkConflictingOriginWithPreviousRows(login)) { continue; } - if (processor.checkConflictingWithExistingLogins(login)) { + if (await processor.checkConflictingWithExistingLogins(login)) { continue; } processor.addLoginToSummary(login, "added"); diff --git a/toolkit/components/passwordmgr/LoginManagerAuthPrompter.sys.mjs b/toolkit/components/passwordmgr/LoginManagerAuthPrompter.sys.mjs index 3aa05d4a2714..8c39cf09b9b6 100644 --- a/toolkit/components/passwordmgr/LoginManagerAuthPrompter.sys.mjs +++ b/toolkit/components/passwordmgr/LoginManagerAuthPrompter.sys.mjs @@ -417,7 +417,13 @@ LoginManagerAuthPrompter.prototype = { } // Look for existing logins. - foundLogins = Services.logins.findLogins(origin, null, realm); + // We don't use searchLoginsAsync here and in asyncPromptPassword + // because of bug 1848682 + let matchData = lazy.LoginHelper.newPropertyBag({ + origin, + httpRealm: realm, + }); + foundLogins = Services.logins.searchLogins(matchData); // XXX Like the original code, we can't deal with multiple // account selection. (bug 227632) @@ -531,7 +537,11 @@ LoginManagerAuthPrompter.prototype = { Services.logins.getLoginSavingEnabled(origin); if (!aPassword.value) { // Look for existing logins. - var foundLogins = Services.logins.findLogins(origin, null, realm); + let matchData = lazy.LoginHelper.newPropertyBag({ + origin, + httpRealm: realm, + }); + let foundLogins = Services.logins.searchLogins(matchData); // XXX Like the original code, we can't deal with multiple // account selection (bug 227632). We can deal with finding the diff --git a/toolkit/components/passwordmgr/nsILoginManager.idl b/toolkit/components/passwordmgr/nsILoginManager.idl index 3001355aa545..d9c1571485f4 100644 --- a/toolkit/components/passwordmgr/nsILoginManager.idl +++ b/toolkit/components/passwordmgr/nsILoginManager.idl @@ -195,7 +195,8 @@ interface nsILoginManager : nsISupports { * Search for logins matching the specified criteria. Called when looking * for logins that might be applicable to a form or authentication request. * - * @deprecated Use `searchLoginsAsync` instead. + * @deprecated Use `searchLoginsAsync` instead. This function is retained + * for Thunderbird compatibility. * * @param aOrigin * The origin to restrict searches to. For example: "http://www.site.com". diff --git a/toolkit/components/passwordmgr/storage-json.sys.mjs b/toolkit/components/passwordmgr/storage-json.sys.mjs index 6c249b1423be..f5c1399c1f42 100644 --- a/toolkit/components/passwordmgr/storage-json.sys.mjs +++ b/toolkit/components/passwordmgr/storage-json.sys.mjs @@ -286,12 +286,12 @@ export class LoginManagerStorage_json { const resultLogins = []; for (const [login, encryptedLogin] of encryptedLogins) { // check for duplicates - const { origin, formActionOrigin, httpRealm } = login; - const existingLogins = this.findLogins( - origin, - formActionOrigin, - httpRealm - ); + let loginData = { + origin: login.origin, + httpRealm: login.httpRealm, + }; + const existingLogins = await Services.logins.searchLoginsAsync(loginData); + const matchingLogin = existingLogins.find(l => login.matches(l, true)); if (matchingLogin) { if (continueOnDuplicates) { @@ -372,10 +372,13 @@ export class LoginManagerStorage_json { // Look for an existing entry in case key properties changed. if (!newLogin.matches(oldLogin, true)) { - let logins = this.findLogins( - newLogin.origin, - newLogin.formActionOrigin, - newLogin.httpRealm + let loginData = { + origin: newLogin.origin, + httpRealm: newLogin.httpRealm, + }; + + let logins = this.searchLogins( + lazy.LoginHelper.newPropertyBag(loginData) ); let matchingLogin = logins.find(login => newLogin.matches(login, true)); diff --git a/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html b/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html index a7cec2d0b93c..6f78d62f1b10 100644 --- a/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html +++ b/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html @@ -63,8 +63,8 @@ let chromeScript = runInParent(() => { }; }); - addMessageListener("getTimeLastUsed", () => { - let logins = Services.logins.findLogins(mozproxyURL, null, "Proxy Realm"); + addMessageListener("getTimeLastUsed", async () => { + let logins = await Services.logins.searchLoginsAsync({ origin: mozproxyURL, httpRealm: "Proxy Realm"}); return logins[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed; }); diff --git a/toolkit/components/passwordmgr/test/unit/test_legacy_empty_formActionOrigin.js b/toolkit/components/passwordmgr/test/unit/test_legacy_empty_formActionOrigin.js index ec6846ab9fbd..d630ed0e078c 100644 --- a/toolkit/components/passwordmgr/test/unit/test_legacy_empty_formActionOrigin.js +++ b/toolkit/components/passwordmgr/test/unit/test_legacy_empty_formActionOrigin.js @@ -65,7 +65,7 @@ add_task(async function test_addLogin_wildcard() { }); /** - * Verifies that findLogins, searchLogins, and countLogins include all logins + * Verifies that searchLogins and countLogins include all logins * that have an empty formActionOrigin in the store, even when a formActionOrigin is * specified. */ @@ -76,11 +76,6 @@ add_task(function test_search_all_wildcard() { }); Assert.equal(Services.logins.searchLogins(matchData).length, 2); - Assert.equal( - Services.logins.findLogins("", "http://www.example.com", null).length, - 2 - ); - Assert.equal( Services.logins.countLogins("", "http://www.example.com", null), 2 @@ -90,15 +85,6 @@ add_task(function test_search_all_wildcard() { matchData.setProperty("origin", "http://any.example.com"); Assert.equal(Services.logins.searchLogins(matchData).length, 1); - Assert.equal( - Services.logins.findLogins( - "http://any.example.com", - "http://www.example.com", - null - ).length, - 1 - ); - Assert.equal( Services.logins.countLogins( "http://any.example.com", diff --git a/toolkit/components/passwordmgr/test/unit/test_logins_decrypt_failure.js b/toolkit/components/passwordmgr/test/unit/test_logins_decrypt_failure.js index eeca48cee591..533bd9dd8de5 100644 --- a/toolkit/components/passwordmgr/test/unit/test_logins_decrypt_failure.js +++ b/toolkit/components/passwordmgr/test/unit/test_logins_decrypt_failure.js @@ -35,9 +35,8 @@ add_task(async function test_logins_decrypt_failure() { // These functions don't see the non-decryptable entries anymore. let savedLogins = await Services.logins.getAllLogins(); - Assert.equal(savedLogins.length, 0); Assert.equal(savedLogins.length, 0, "getAllLogins length"); - Assert.equal(Services.logins.findLogins("", "", "").length, 0); + await Assert.rejects(Services.logins.searchLoginsAsync({}), /is required/); Assert.equal(Services.logins.searchLogins(newPropertyBag()).length, 0); Assert.throws( () => Services.logins.modifyLogin(logins[0], newPropertyBag()), @@ -63,7 +62,11 @@ add_task(async function test_logins_decrypt_failure() { // Finding logins doesn't return the non-decryptable duplicates. Assert.equal( - Services.logins.findLogins("http://www.example.com", "", "").length, + ( + await Services.logins.searchLoginsAsync({ + origin: "http://www.example.com", + }) + ).length, 1 ); let matchData = newPropertyBag({ origin: "http://www.example.com" }); diff --git a/toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js b/toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js index 6a73b2019926..e85156498162 100644 --- a/toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js +++ b/toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js @@ -17,8 +17,8 @@ const gLooksLikeUUIDRegex = /^\{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}\}$/; * the given nsILoginInfo. In case there is more than one login for the * origin, the test fails. */ -function retrieveLoginMatching(aLoginInfo) { - let logins = Services.logins.findLogins(aLoginInfo.origin, "", ""); +async function retrieveOriginMatching(origin) { + let logins = await Services.logins.searchLoginsAsync({ origin }); Assert.equal(logins.length, 1); return logins[0].QueryInterface(Ci.nsILoginMetaInfo); } @@ -94,7 +94,7 @@ add_task(async function test_addLogin_metainfo() { Assert.equal(gLoginInfo1.timesUsed, 0); // A login with valid metadata should have been stored. - gLoginMetaInfo1 = retrieveLoginMatching(gLoginInfo1); + gLoginMetaInfo1 = await retrieveOriginMatching(gLoginInfo1.origin); Assert.ok(gLooksLikeUUIDRegex.test(gLoginMetaInfo1.guid)); let creationTime = gLoginMetaInfo1.timeCreated; LoginTestUtils.assertTimeIsAboutNow(creationTime); @@ -110,12 +110,12 @@ add_task(async function test_addLogin_metainfo() { assertMetaInfoEqual(gLoginInfo2, originalLogin); // A login with the provided metadata should have been stored. - gLoginMetaInfo2 = retrieveLoginMatching(gLoginInfo2); + gLoginMetaInfo2 = await retrieveOriginMatching(gLoginInfo2.origin); assertMetaInfoEqual(gLoginMetaInfo2, gLoginInfo2); // Add an authentication login to the database before continuing. await Services.logins.addLoginAsync(gLoginInfo3); - gLoginMetaInfo3 = retrieveLoginMatching(gLoginInfo3); + gLoginMetaInfo3 = await retrieveOriginMatching(gLoginInfo3.origin); await LoginTestUtils.checkLogins([gLoginInfo1, gLoginInfo2, gLoginInfo3]); }); @@ -140,7 +140,7 @@ add_task(async function test_addLogin_metainfo_duplicate() { * Tests that the existing metadata is not changed when modifyLogin is called * with an nsILoginInfo argument. */ -add_task(function test_modifyLogin_nsILoginInfo_metainfo_ignored() { +add_task(async function test_modifyLogin_nsILoginInfo_metainfo_ignored() { let newLoginInfo = gLoginInfo1.clone().QueryInterface(Ci.nsILoginMetaInfo); newLoginInfo.guid = Services.uuid.generateUUID().toString(); newLoginInfo.timeCreated = Date.now(); @@ -149,14 +149,14 @@ add_task(function test_modifyLogin_nsILoginInfo_metainfo_ignored() { newLoginInfo.timesUsed = 12; Services.logins.modifyLogin(gLoginInfo1, newLoginInfo); - newLoginInfo = retrieveLoginMatching(gLoginInfo1); + newLoginInfo = await retrieveOriginMatching(gLoginInfo1.origin); assertMetaInfoEqual(newLoginInfo, gLoginMetaInfo1); }); /** * Tests the modifyLogin function with an nsIProperyBag argument. */ -add_task(function test_modifyLogin_nsIProperyBag_metainfo() { +add_task(async function test_modifyLogin_nsIProperyBag_metainfo() { // Use a new reference time that is two minutes from now. let newTimeMs = Date.now() + 120000; let newUUIDValue = Services.uuid.generateUUID().toString(); @@ -173,7 +173,7 @@ add_task(function test_modifyLogin_nsIProperyBag_metainfo() { }) ); - gLoginMetaInfo1 = retrieveLoginMatching(gLoginInfo1); + gLoginMetaInfo1 = await retrieveOriginMatching(gLoginInfo1.origin); Assert.equal(gLoginMetaInfo1.guid, newUUIDValue); Assert.equal(gLoginMetaInfo1.timeCreated, newTimeMs); Assert.equal(gLoginMetaInfo1.timeLastUsed, newTimeMs + 2); @@ -190,7 +190,7 @@ add_task(function test_modifyLogin_nsIProperyBag_metainfo() { ); gLoginInfo2.password = "new password"; - gLoginMetaInfo2 = retrieveLoginMatching(gLoginInfo2); + gLoginMetaInfo2 = await retrieveOriginMatching(gLoginInfo2.origin); Assert.equal(gLoginMetaInfo2.password, gLoginInfo2.password); Assert.equal(gLoginMetaInfo2.timeCreated, originalLogin.timeCreated); Assert.equal(gLoginMetaInfo2.timeLastUsed, originalLogin.timeLastUsed); @@ -207,7 +207,7 @@ add_task(function test_modifyLogin_nsIProperyBag_metainfo() { ); gLoginInfo2.password = "other password"; - gLoginMetaInfo2 = retrieveLoginMatching(gLoginInfo2); + gLoginMetaInfo2 = await retrieveOriginMatching(gLoginInfo2.origin); Assert.equal(gLoginMetaInfo2.password, gLoginInfo2.password); Assert.equal(gLoginMetaInfo2.timeCreated, originalLogin.timeCreated); Assert.equal(gLoginMetaInfo2.timeLastUsed, originalLogin.timeLastUsed); @@ -221,7 +221,7 @@ add_task(function test_modifyLogin_nsIProperyBag_metainfo() { }) ); - gLoginMetaInfo2 = retrieveLoginMatching(gLoginInfo2); + gLoginMetaInfo2 = await retrieveOriginMatching(gLoginInfo2.origin); Assert.equal(gLoginMetaInfo2.timeCreated, originalLogin.timeCreated); Assert.equal(gLoginMetaInfo2.timeLastUsed, originalLogin.timeLastUsed); Assert.equal(gLoginMetaInfo2.timePasswordChanged, newTimeMs); @@ -289,7 +289,16 @@ add_task(async function test_storage_metainfo() { await LoginTestUtils.reloadData(); await LoginTestUtils.checkLogins([gLoginInfo1, gLoginInfo2, gLoginInfo3]); - assertMetaInfoEqual(retrieveLoginMatching(gLoginInfo1), gLoginMetaInfo1); - assertMetaInfoEqual(retrieveLoginMatching(gLoginInfo2), gLoginMetaInfo2); - assertMetaInfoEqual(retrieveLoginMatching(gLoginInfo3), gLoginMetaInfo3); + assertMetaInfoEqual( + await retrieveOriginMatching(gLoginInfo1.origin), + gLoginMetaInfo1 + ); + assertMetaInfoEqual( + await retrieveOriginMatching(gLoginInfo2.origin), + gLoginMetaInfo2 + ); + assertMetaInfoEqual( + await retrieveOriginMatching(gLoginInfo3.origin), + gLoginMetaInfo3 + ); }); diff --git a/toolkit/components/passwordmgr/test/unit/test_logins_search.js b/toolkit/components/passwordmgr/test/unit/test_logins_search.js index 89337f872ec6..b69ec16ff833 100644 --- a/toolkit/components/passwordmgr/test/unit/test_logins_search.js +++ b/toolkit/components/passwordmgr/test/unit/test_logins_search.js @@ -1,6 +1,5 @@ /** - * Tests methods that find specific logins in the store (findLogins, - * searchLogins, and countLogins). + * Tests methods that find specific logins in the store (searchLogins and countLogins). * * The getAllLogins method is not tested explicitly here, because it is used by * all tests to verify additions, removals and modifications to the login store. @@ -47,11 +46,11 @@ function checkSearchLogins(aQuery, aExpectedCount) { } /** - * Tests findLogins, searchLogins, and countLogins with the same query. + * Tests searchLogins, and countLogins with the same query. * * @param aQuery * The "origin", "formActionOrigin", and "httpRealm" properties of this - * object are passed as parameters to findLogins and countLogins. The + * object are passed as parameters to countLogins. The * same object is then passed to the checkSearchLogins function. * @param aExpectedCount * Number of logins from the test data that should be found. The actual @@ -65,7 +64,7 @@ function checkAllSearches(aQuery, aExpectedCount) { let expectedLogins = buildExpectedLogins(aQuery); Assert.equal(expectedLogins.length, aExpectedCount); - // The findLogins and countLogins functions support wildcard matches by + // The countLogins function support wildcard matches by // specifying empty strings as parameters, while searchLogins requires // omitting the property entirely. let origin = "origin" in aQuery ? aQuery.origin : ""; @@ -73,10 +72,6 @@ function checkAllSearches(aQuery, aExpectedCount) { "formActionOrigin" in aQuery ? aQuery.formActionOrigin : ""; let httpRealm = "httpRealm" in aQuery ? aQuery.httpRealm : ""; - // Test findLogins. - let logins = Services.logins.findLogins(origin, formActionOrigin, httpRealm); - LoginTestUtils.assertLoginListsEqual(logins, expectedLogins); - // Test countLogins. let count = Services.logins.countLogins(origin, formActionOrigin, httpRealm); Assert.equal(count, expectedLogins.length); @@ -95,7 +90,7 @@ add_setup(async () => { }); /** - * Tests findLogins, searchLogins, and countLogins with basic queries. + * Tests searchLogins, and countLogins with basic queries. */ add_task(function test_search_all_basic() { // Find all logins, using no filters in the search functions. @@ -217,7 +212,7 @@ add_task(function test_search_all_full_case_sensitive() { }); /** - * Tests findLogins, searchLogins, and countLogins with queries that should + * Tests searchLogins, and countLogins with queries that should * return no values. */ add_task(function test_search_all_empty() {