diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js')
-rw-r--r-- | services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js b/services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js new file mode 100644 index 0000000000..5b80035418 --- /dev/null +++ b/services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js @@ -0,0 +1,307 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Tests for FxAccounts, storage and the master password. + +// See verbose logging from FxAccounts.jsm +Services.prefs.setStringPref("identity.fxaccounts.loglevel", "Trace"); + +const { FxAccounts } = ChromeUtils.importESModule( + "resource://gre/modules/FxAccounts.sys.mjs" +); +const { FXA_PWDMGR_HOST, FXA_PWDMGR_REALM } = ChromeUtils.importESModule( + "resource://gre/modules/FxAccountsCommon.sys.mjs" +); + +// Use a backstage pass to get at our LoginManagerStorage object, so we can +// mock the prototype. +var { LoginManagerStorage } = ChromeUtils.importESModule( + "resource://gre/modules/FxAccountsStorage.sys.mjs" +); +var isLoggedIn = true; +LoginManagerStorage.prototype.__defineGetter__("_isLoggedIn", () => isLoggedIn); + +function setLoginMgrLoggedInState(loggedIn) { + isLoggedIn = loggedIn; +} + +initTestLogging("Trace"); + +async function getLoginMgrData() { + let logins = await Services.logins.searchLoginsAsync({ + origin: FXA_PWDMGR_HOST, + httpRealm: FXA_PWDMGR_REALM, + }); + if (!logins.length) { + return null; + } + Assert.equal(logins.length, 1, "only 1 login available"); + return logins[0]; +} + +function createFxAccounts() { + return new FxAccounts({ + _fxAccountsClient: { + async registerDevice() { + return { id: "deviceAAAAAA" }; + }, + async recoveryEmailStatus() { + return { verified: true }; + }, + async signOut() {}, + }, + updateDeviceRegistration() {}, + _getDeviceName() { + return "mock device name"; + }, + observerPreloads: [], + fxaPushService: { + async registerPushEndpoint() { + return { + endpoint: "http://mochi.test:8888", + getKey() { + return null; + }, + }; + }, + async unsubscribe() { + return true; + }, + }, + }); +} + +add_task(async function test_simple() { + let fxa = createFxAccounts(); + + let creds = { + uid: "abcd", + email: "test@example.com", + sessionToken: "sessionToken", + scopedKeys: { + ...MOCK_ACCOUNT_KEYS.scopedKeys, + }, + verified: true, + }; + await fxa._internal.setSignedInUser(creds); + + // This should have stored stuff in both the .json file in the profile + // dir, and the login dir. + let path = PathUtils.join(PathUtils.profileDir, "signedInUser.json"); + let data = await IOUtils.readJSON(path); + + Assert.strictEqual( + data.accountData.email, + creds.email, + "correct email in the clear text" + ); + Assert.strictEqual( + data.accountData.sessionToken, + creds.sessionToken, + "correct sessionToken in the clear text" + ); + Assert.strictEqual( + data.accountData.verified, + creds.verified, + "correct verified flag" + ); + + Assert.ok( + !("scopedKeys" in data.accountData), + "scopedKeys not stored in clear text" + ); + + let login = await getLoginMgrData(); + Assert.strictEqual(login.username, creds.uid, "uid used for username"); + let loginData = JSON.parse(login.password); + Assert.strictEqual( + loginData.version, + data.version, + "same version flag in both places" + ); + Assert.deepEqual( + loginData.accountData.scopedKeys, + creds.scopedKeys, + "correct scoped keys in the login mgr" + ); + Assert.ok(!("email" in loginData), "email not stored in the login mgr json"); + Assert.ok( + !("sessionToken" in loginData), + "sessionToken not stored in the login mgr json" + ); + Assert.ok( + !("verified" in loginData), + "verified not stored in the login mgr json" + ); + + await fxa.signOut(/* localOnly = */ true); + Assert.strictEqual( + await getLoginMgrData(), + null, + "login mgr data deleted on logout" + ); +}); + +add_task(async function test_MPLocked() { + let fxa = createFxAccounts(); + + let creds = { + uid: "abcd", + email: "test@example.com", + sessionToken: "sessionToken", + scopedKeys: { + ...MOCK_ACCOUNT_KEYS.scopedKeys, + }, + verified: true, + }; + + 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); + + // This should have stored stuff in the .json, and the login manager stuff + // will not exist. + let path = PathUtils.join(PathUtils.profileDir, "signedInUser.json"); + let data = await IOUtils.readJSON(path); + + Assert.strictEqual( + data.accountData.email, + creds.email, + "correct email in the clear text" + ); + Assert.strictEqual( + data.accountData.sessionToken, + creds.sessionToken, + "correct sessionToken in the clear text" + ); + Assert.strictEqual( + data.accountData.verified, + creds.verified, + "correct verified flag" + ); + + Assert.ok( + !("scopedKeys" in data.accountData), + "scopedKeys not stored in clear text" + ); + + Assert.strictEqual( + await getLoginMgrData(), + null, + "login mgr data doesn't exist" + ); + await fxa.signOut(/* localOnly = */ true); +}); + +add_task(async function test_consistentWithMPEdgeCases() { + setLoginMgrLoggedInState(true); + + let fxa = createFxAccounts(); + + let creds1 = { + uid: "uid1", + email: "test@example.com", + sessionToken: "sessionToken", + scopedKeys: { + [SCOPE_OLD_SYNC]: { + kid: "key id 1", + k: "key material 1", + kty: "oct", + }, + }, + verified: true, + }; + + let creds2 = { + uid: "uid2", + email: "test2@example.com", + sessionToken: "sessionToken2", + [SCOPE_OLD_SYNC]: { + kid: "key id 2", + k: "key material 2", + kty: "oct", + }, + verified: false, + }; + + // Log a user in while MP is unlocked. + await fxa._internal.setSignedInUser(creds1); + + // tell the storage that the MP is locked - this will prevent logout from + // being able to clear the data. + setLoginMgrLoggedInState(false); + + // now set the second credentials. + await fxa._internal.setSignedInUser(creds2); + + // We should still have creds1 data in the login manager. + let login = await getLoginMgrData(); + Assert.strictEqual(login.username, creds1.uid); + // and that we do have the first scopedKeys in the login manager. + Assert.deepEqual( + JSON.parse(login.password).accountData.scopedKeys, + creds1.scopedKeys, + "stale data still in login mgr" + ); + + // Make a new FxA instance (otherwise the values in memory will be used) + // and we want the login manager to be unlocked. + setLoginMgrLoggedInState(true); + fxa = createFxAccounts(); + + let accountData = await fxa.getSignedInUser(); + Assert.strictEqual(accountData.email, creds2.email); + // we should have no scopedKeys at all. + Assert.strictEqual( + accountData.scopedKeys, + undefined, + "stale scopedKey wasn't used" + ); + await fxa.signOut(/* localOnly = */ true); +}); + +// A test for the fact we will accept either a UID or email when looking in +// the login manager. +add_task(async function test_uidMigration() { + setLoginMgrLoggedInState(true); + Assert.strictEqual( + await getLoginMgrData(), + null, + "expect no logins at the start" + ); + + // create the login entry using email as a key. + let contents = { + scopedKeys: { + ...MOCK_ACCOUNT_KEYS.scopedKeys, + }, + }; + + let loginInfo = new Components.Constructor( + "@mozilla.org/login-manager/loginInfo;1", + Ci.nsILoginInfo, + "init" + ); + let login = new loginInfo( + FXA_PWDMGR_HOST, + null, // aFormActionOrigin, + FXA_PWDMGR_REALM, // aHttpRealm, + "foo@bar.com", // aUsername + JSON.stringify(contents), // aPassword + "", // aUsernameField + "" + ); // aPasswordField + await Services.logins.addLoginAsync(login); + + // ensure we read it. + let storage = new LoginManagerStorage(); + let got = await storage.get("uid", "foo@bar.com"); + Assert.deepEqual(got, contents); +}); |