Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* Any copyright is dedicated to the Public Domain.
EXPECTED_BREACH = {
AddedDate: "2018-12-20T23:56:26Z",
BreachDate: "2018-12-16",
Domain: "breached.example.com",
Name: "Breached",
PwnCount: 1643100,
DataClasses: ["Email addresses", "Usernames", "Passwords", "IP addresses"],
_status: "synced",
id: "047940fe-d2fd-4314-b636-b4a952ee0043",
last_modified: "1541615610052",
schema: "1541615609018",
};
let VULNERABLE_TEST_LOGIN2 = new nsLoginInfo(
null,
"user2",
"pass3",
"username",
"password"
);
add_setup(async function () {
TEST_LOGIN1 = await addLogin(TEST_LOGIN1);
VULNERABLE_TEST_LOGIN2 = await addLogin(VULNERABLE_TEST_LOGIN2);
TEST_LOGIN3 = await addLogin(TEST_LOGIN3);
await BrowserTestUtils.openNewForegroundTab({
gBrowser,
url: "about:logins",
});
registerCleanupFunction(() => {
BrowserTestUtils.removeTab(gBrowser.selectedTab);
Services.logins.removeAllUserFacingLogins();
});
});
add_task(async function test_added_login_shows_breach_warning() {
let browser = gBrowser.selectedBrowser;
await SpecialPowers.spawn(
browser,
[[TEST_LOGIN1.guid, VULNERABLE_TEST_LOGIN2.guid, TEST_LOGIN3.guid]],
async ([regularLoginGuid, vulnerableLoginGuid, breachedLoginGuid]) => {
let loginList = Cu.waiveXrays(
content.document.querySelector("login-list")
);
await ContentTaskUtils.waitForCondition(
() => loginList.shadowRoot.querySelectorAll("login-list-item").length,
"Waiting for login-list to get populated"
);
let { listItem: regularListItem } = loginList._logins[regularLoginGuid];
let { listItem: vulnerableListItem } =
loginList._logins[vulnerableLoginGuid];
let { listItem: breachedListItem } = loginList._logins[breachedLoginGuid];
await ContentTaskUtils.waitForCondition(() => {
return (
!regularListItem.matches(".breached.vulnerable") &&
vulnerableListItem.matches(".vulnerable") &&
breachedListItem.matches(".breached")
);
}, `waiting for the list items to get their classes updated: ${regularListItem.className} / ${vulnerableListItem.className} / ${breachedListItem.className}`);
Assert.ok(
!regularListItem.classList.contains("breached") &&
!regularListItem.classList.contains("vulnerable"),
"regular login should not be marked breached or vulnerable: " +
regularLoginGuid.className
);
Assert.ok(
!vulnerableListItem.classList.contains("breached") &&
vulnerableListItem.classList.contains("vulnerable"),
"vulnerable login should be marked vulnerable: " +
vulnerableListItem.className
);
Assert.ok(
breachedListItem.classList.contains("breached") &&
!breachedListItem.classList.contains("vulnerable"),
"breached login should be marked breached: " +
breachedListItem.className
);
breachedListItem.click();
let loginItem = Cu.waiveXrays(
content.document.querySelector("login-item")
);
await ContentTaskUtils.waitForCondition(() => {
return loginItem._login && loginItem._login.guid == breachedLoginGuid;
}, "waiting for breached login to get selected");
Assert.ok(
!ContentTaskUtils.isHidden(
loginItem.shadowRoot.querySelector("login-breach-alert")
),
"the breach alert should be visible"
);
}
);
if (!OSKeyStoreTestUtils.canTestOSKeyStoreLogin()) {
info(
"leaving test early since the remaining part of the test requires 'edit' mode which requires 'oskeystore' login"
);
return;
}
let reauthObserved = forceAuthTimeoutAndWaitForOSKeyStoreLogin({
loginResult: true,
});
// Change the password on the breached login and check that the
// login is no longer marked as breached. The vulnerable login
// should still be marked as vulnerable afterwards.
await SpecialPowers.spawn(browser, [], () => {
let loginItem = Cu.waiveXrays(content.document.querySelector("login-item"));
loginItem.shadowRoot.querySelector("edit-button").click();
});
await reauthObserved;
await SpecialPowers.spawn(
browser,
[[VULNERABLE_TEST_LOGIN2.guid, TEST_LOGIN3.guid]],
async ([vulnerableLoginGuid, breachedLoginGuid]) => {
let loginList = Cu.waiveXrays(
content.document.querySelector("login-list")
);
let loginItem = Cu.waiveXrays(
content.document.querySelector("login-item")
);
await ContentTaskUtils.waitForCondition(
() => loginItem.dataset.editing == "true",
"waiting for login-item to enter edit mode"
);
// The password display field is in the DOM when password input is unfocused.
// To get the password input field, ensure it receives focus.
let passwordInput = loginItem.shadowRoot.querySelector(
"input[type='password']"
);
passwordInput.focus();
passwordInput = loginItem.shadowRoot.querySelector(
"input[name='password']"
);
const CHANGED_PASSWORD_VALUE = "changedPassword";
passwordInput.value = CHANGED_PASSWORD_VALUE;
let saveChangesButton = loginItem.shadowRoot.querySelector(
".save-changes-button"
);
saveChangesButton.click();
await ContentTaskUtils.waitForCondition(() => {
return (
loginList._logins[breachedLoginGuid].login.password ==
CHANGED_PASSWORD_VALUE
);
}, "waiting for stored login to get updated");
Assert.ok(
ContentTaskUtils.isHidden(
loginItem.shadowRoot.querySelector("login-breach-alert")
),
"the breach alert should be hidden now"
);
let { listItem: breachedListItem } = loginList._logins[breachedLoginGuid];
let { listItem: vulnerableListItem } =
loginList._logins[vulnerableLoginGuid];
Assert.ok(
!breachedListItem.classList.contains("breached") &&
!breachedListItem.classList.contains("vulnerable"),
"the originally breached login should no longer be marked as breached"
);
Assert.ok(
!vulnerableListItem.classList.contains("breached") &&
vulnerableListItem.classList.contains("vulnerable"),
"vulnerable login should still be marked vulnerable: " +
vulnerableListItem.className
);
// Change the password on the vulnerable login and check that the
// login is no longer marked as vulnerable.
vulnerableListItem.click();
await ContentTaskUtils.waitForCondition(() => {
return loginItem._login && loginItem._login.guid == vulnerableLoginGuid;
}, "waiting for vulnerable login to get selected");
Assert.ok(
!ContentTaskUtils.isHidden(
loginItem.shadowRoot.querySelector("login-vulnerable-password-alert")
),
"the vulnerable alert should be visible"
);
loginItem.shadowRoot.querySelector("edit-button").click();
await ContentTaskUtils.waitForCondition(
() => loginItem.dataset.editing == "true",
"waiting for login-item to enter edit mode"
);
passwordInput.value = CHANGED_PASSWORD_VALUE;
saveChangesButton.click();
await ContentTaskUtils.waitForCondition(() => {
return (
loginList._logins[vulnerableLoginGuid].login.password ==
CHANGED_PASSWORD_VALUE
);
}, "waiting for stored login to get updated");
Assert.ok(
ContentTaskUtils.isHidden(
loginItem.shadowRoot.querySelector("login-vulnerable-password-alert")
),
"the vulnerable alert should be hidden now"
);
Assert.equal(
vulnerableListItem.notificationIcon,
"",
".alert-icon for the vulnerable list item should have its source removed"
);
vulnerableListItem = loginList._logins[vulnerableLoginGuid].listItem;
Assert.ok(
!vulnerableListItem.classList.contains("breached") &&
!vulnerableListItem.classList.contains("vulnerable"),
"vulnerable login should no longer be marked vulnerable: " +
vulnerableListItem.className
);
}
);
});