зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1559427 - Display data from Lockwise on the Monitor card. r=MattN
Depends on D38228 Differential Revision: https://phabricator.services.mozilla.com/D38385 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
2e658e3d4b
Коммит
3ec2df99e1
|
@ -20,6 +20,11 @@ ChromeUtils.defineModuleGetter(
|
|||
"fxAccounts",
|
||||
"resource://gre/modules/FxAccounts.jsm"
|
||||
);
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"LoginHelper",
|
||||
"resource://gre/modules/LoginHelper.jsm"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
this,
|
||||
|
@ -170,11 +175,13 @@ var AboutProtectionsHandler = {
|
|||
* @return {{ monitoredEmails: Number,
|
||||
* numBreaches: Number,
|
||||
* passwords: Number,
|
||||
* potentiallyBreachedLogins: Number,
|
||||
* error: Boolean }}
|
||||
* Monitor data.
|
||||
*/
|
||||
async getMonitorData() {
|
||||
let monitorData = {};
|
||||
let potentiallyBreachedLogins = 0;
|
||||
const hasFxa = await fxAccounts.accountStatus();
|
||||
|
||||
if (hasFxa) {
|
||||
|
@ -201,6 +208,12 @@ var AboutProtectionsHandler = {
|
|||
monitorData.errorMessage = e.message;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the stats for number of potentially breached Lockwise passwords
|
||||
const logins = await LoginHelper.getAllUserFacingLogins();
|
||||
potentiallyBreachedLogins = await LoginHelper.getBreachesForLogins(
|
||||
logins
|
||||
);
|
||||
} else {
|
||||
// If no account exists, then the user is not logged in with an fxAccount.
|
||||
monitorData = {
|
||||
|
@ -210,6 +223,7 @@ var AboutProtectionsHandler = {
|
|||
|
||||
return {
|
||||
...monitorData,
|
||||
potentiallyBreachedLogins: potentiallyBreachedLogins.size,
|
||||
error: !!monitorData.errorMessage,
|
||||
};
|
||||
},
|
||||
|
|
|
@ -24,11 +24,6 @@ ChromeUtils.defineModuleGetter(
|
|||
"MigrationUtils",
|
||||
"resource:///modules/MigrationUtils.jsm"
|
||||
);
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"RemoteSettings",
|
||||
"resource://services-settings/remote-settings.js"
|
||||
);
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"Services",
|
||||
|
@ -67,14 +62,10 @@ const EXPECTED_ABOUTLOGINS_REMOTE_TYPE = PRIVILEGEDABOUT_PROCESS_ENABLED
|
|||
? E10SUtils.PRIVILEGEDABOUT_REMOTE_TYPE
|
||||
: E10SUtils.DEFAULT_REMOTE_TYPE;
|
||||
|
||||
const isValidLogin = login => {
|
||||
return !(login.origin || "").startsWith("chrome://");
|
||||
};
|
||||
|
||||
const convertSubjectToLogin = subject => {
|
||||
subject.QueryInterface(Ci.nsILoginMetaInfo).QueryInterface(Ci.nsILoginInfo);
|
||||
const login = LoginHelper.loginToVanillaObject(subject);
|
||||
if (!isValidLogin(login)) {
|
||||
if (!LoginHelper.isUserFacingLogin(login)) {
|
||||
return null;
|
||||
}
|
||||
return augmentVanillaLoginObject(login);
|
||||
|
@ -188,22 +179,22 @@ var AboutLoginsParent = {
|
|||
this._subscribers.add(message.target);
|
||||
|
||||
let messageManager = message.target.messageManager;
|
||||
this.getAllLogins().then(async logins => {
|
||||
messageManager.sendAsyncMessage("AboutLogins:AllLogins", logins);
|
||||
if (!BREACH_ALERTS_ENABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
const breaches = await RemoteSettings("fxmonitor-breaches").get();
|
||||
const breachesByLoginGUID = await this.getBreachesForLogins(
|
||||
logins,
|
||||
breaches
|
||||
);
|
||||
messageManager.sendAsyncMessage(
|
||||
"AboutLogins:UpdateBreaches",
|
||||
breachesByLoginGUID
|
||||
);
|
||||
});
|
||||
const logins = await this.getAllLogins();
|
||||
messageManager.sendAsyncMessage("AboutLogins:AllLogins", logins);
|
||||
|
||||
if (!BREACH_ALERTS_ENABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
const breachesByLoginGUID = await LoginHelper.getBreachesForLogins(
|
||||
logins
|
||||
);
|
||||
messageManager.sendAsyncMessage(
|
||||
"AboutLogins:UpdateBreaches",
|
||||
breachesByLoginGUID
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
case "AboutLogins:UpdateLogin": {
|
||||
|
@ -375,9 +366,8 @@ var AboutLoginsParent = {
|
|||
|
||||
async getAllLogins() {
|
||||
try {
|
||||
let logins = await Services.logins.getAllLoginsAsync();
|
||||
let logins = await LoginHelper.getAllUserFacingLogins();
|
||||
return logins
|
||||
.filter(isValidLogin)
|
||||
.map(LoginHelper.loginToVanillaObject)
|
||||
.map(augmentVanillaLoginObject);
|
||||
} catch (e) {
|
||||
|
@ -388,23 +378,4 @@ var AboutLoginsParent = {
|
|||
throw e;
|
||||
}
|
||||
},
|
||||
|
||||
async getBreachesForLogins(logins, breaches) {
|
||||
const breachesByLoginGUID = new Map();
|
||||
for (const login of logins) {
|
||||
const loginURI = Services.io.newURI(login.origin);
|
||||
for (const breach of breaches) {
|
||||
if (!breach.Domain) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
Services.eTLD.hasRootDomain(loginURI.host, breach.Domain) &&
|
||||
login.timePasswordChanged < new Date(breach.BreachDate).getTime()
|
||||
) {
|
||||
breachesByLoginGUID.set(login.guid, breach);
|
||||
}
|
||||
}
|
||||
}
|
||||
return breachesByLoginGUID;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Test AboutLoginsParent.getBreachesForLogins
|
||||
* Test LoginHelper.getBreachesForLogins
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
@ -9,6 +9,12 @@ const { AboutLoginsParent } = ChromeUtils.import(
|
|||
"resource:///modules/AboutLoginsParent.jsm"
|
||||
);
|
||||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"LoginHelper",
|
||||
"resource://gre/modules/LoginHelper.jsm"
|
||||
);
|
||||
|
||||
const TEST_BREACHES = [
|
||||
{
|
||||
AddedDate: "2018-12-20T23:56:26Z",
|
||||
|
@ -65,7 +71,7 @@ const BREACHED_SUBDOMAIN_LOGIN = LoginTestUtils.testData.formLogin({
|
|||
add_task(async function test_getBreachesForLogins_notBreachedLogin() {
|
||||
Services.logins.addLogin(NOT_BREACHED_LOGIN);
|
||||
|
||||
const breachesByLoginGUID = await AboutLoginsParent.getBreachesForLogins(
|
||||
const breachesByLoginGUID = await LoginHelper.getBreachesForLogins(
|
||||
[NOT_BREACHED_LOGIN],
|
||||
TEST_BREACHES
|
||||
);
|
||||
|
@ -79,7 +85,7 @@ add_task(async function test_getBreachesForLogins_notBreachedLogin() {
|
|||
add_task(async function test_getBreachesForLogins_breachedLogin() {
|
||||
Services.logins.addLogin(BREACHED_LOGIN);
|
||||
|
||||
const breachesByLoginGUID = await AboutLoginsParent.getBreachesForLogins(
|
||||
const breachesByLoginGUID = await LoginHelper.getBreachesForLogins(
|
||||
[NOT_BREACHED_LOGIN, BREACHED_LOGIN],
|
||||
TEST_BREACHES
|
||||
);
|
||||
|
@ -93,7 +99,7 @@ add_task(async function test_getBreachesForLogins_breachedLogin() {
|
|||
add_task(async function test_getBreachesForLogins_notBreachedSubdomain() {
|
||||
Services.logins.addLogin(NOT_BREACHED_SUBDOMAIN_LOGIN);
|
||||
|
||||
const breachesByLoginGUID = await AboutLoginsParent.getBreachesForLogins(
|
||||
const breachesByLoginGUID = await LoginHelper.getBreachesForLogins(
|
||||
[NOT_BREACHED_LOGIN, NOT_BREACHED_SUBDOMAIN_LOGIN],
|
||||
TEST_BREACHES
|
||||
);
|
||||
|
@ -107,7 +113,7 @@ add_task(async function test_getBreachesForLogins_notBreachedSubdomain() {
|
|||
add_task(async function test_getBreachesForLogins_breachedSubdomain() {
|
||||
Services.logins.addLogin(BREACHED_SUBDOMAIN_LOGIN);
|
||||
|
||||
const breachesByLoginGUID = await AboutLoginsParent.getBreachesForLogins(
|
||||
const breachesByLoginGUID = await LoginHelper.getBreachesForLogins(
|
||||
[NOT_BREACHED_SUBDOMAIN_LOGIN, BREACHED_SUBDOMAIN_LOGIN],
|
||||
TEST_BREACHES
|
||||
);
|
||||
|
|
|
@ -78,14 +78,13 @@ export default class MonitorClass {
|
|||
"span[data-type='exposed-passwords']"
|
||||
);
|
||||
const exposedLockwisePasswords = this.doc.querySelector(
|
||||
".number-of-breaches.block"
|
||||
"span[data-type='breached-lockwise-passwords']"
|
||||
);
|
||||
|
||||
storedEmail.textContent = monitorData.monitoredEmails;
|
||||
knownBreaches.textContent = monitorData.numBreaches;
|
||||
exposedPasswords.textContent = monitorData.passwords;
|
||||
|
||||
// TODO: Bug 1559427: Display data from Lockwise here
|
||||
exposedLockwisePasswords.textContent = 2;
|
||||
exposedLockwisePasswords.textContent =
|
||||
monitorData.potentiallyBreachedLogins;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,12 +138,12 @@
|
|||
<a href="">Firefox Monitor</a>
|
||||
</div>
|
||||
<div class="monitor-breached-passwords">
|
||||
<span class="number-of-breaches block">
|
||||
<span data-type="breached-lockwise-passwords" class="number-of-breaches block">
|
||||
<!-- Display number of exposed stored passwords here. -->
|
||||
</span>
|
||||
<span class="">
|
||||
Saved passwords have appeared in known data breaches. Change these passwords to protect your accounts.
|
||||
<a href="">Open Lockwise</a>
|
||||
<span>
|
||||
Passwords saved in Firefox may have been exposed in a data breach. Change these passwords to protect your accounts.
|
||||
<a href="">View Saved Logins</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -28,7 +28,7 @@ let fakeDataWithNoError = {
|
|||
monitoredEmails: 1,
|
||||
numBreaches: 11,
|
||||
passwords: 8,
|
||||
lockwisePasswords: 2,
|
||||
potentiallyBreachedLogins: 2,
|
||||
error: false,
|
||||
};
|
||||
|
||||
|
@ -36,7 +36,7 @@ let fakeDataWithError = {
|
|||
monitoredEmails: null,
|
||||
numBreaches: null,
|
||||
passwords: null,
|
||||
lockwisePasswords: null,
|
||||
potentiallyBreachedLogins: null,
|
||||
error: true,
|
||||
};
|
||||
|
||||
|
@ -108,10 +108,18 @@ add_task(async function() {
|
|||
const breaches = content.document.querySelector(
|
||||
".monitor-stat span[data-type='known-breaches']"
|
||||
);
|
||||
const breachedLockwisePasswords = content.document.querySelector(
|
||||
".monitor-breached-passwords span[data-type='breached-lockwise-passwords']"
|
||||
);
|
||||
|
||||
is(emails.textContent, 1, "1 monitored email is displayed");
|
||||
is(passwords.textContent, 8, "8 exposed stored passwords is displayed");
|
||||
is(breaches.textContent, 11, "11 known data breaches is displayed.");
|
||||
is(passwords.textContent, 8, "8 exposed passwords are displayed");
|
||||
is(breaches.textContent, 11, "11 known data breaches are displayed.");
|
||||
is(
|
||||
breachedLockwisePasswords.textContent,
|
||||
2,
|
||||
"2 saved passwords are displayed."
|
||||
);
|
||||
});
|
||||
|
||||
info(
|
||||
|
|
|
@ -21,6 +21,12 @@ const { XPCOMUtils } = ChromeUtils.import(
|
|||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"RemoteSettings",
|
||||
"resource://services-settings/remote-settings.js"
|
||||
);
|
||||
|
||||
/**
|
||||
* Contains functions shared by different Login Manager components.
|
||||
*/
|
||||
|
@ -1082,6 +1088,49 @@ this.LoginHelper = {
|
|||
changeType
|
||||
);
|
||||
},
|
||||
|
||||
isUserFacingLogin(login) {
|
||||
return !login.origin.startsWith("chrome://");
|
||||
},
|
||||
|
||||
async getAllUserFacingLogins() {
|
||||
try {
|
||||
let logins = await Services.logins.getAllLoginsAsync();
|
||||
return logins.filter(this.isUserFacingLogin);
|
||||
} catch (e) {
|
||||
if (e.result == Cr.NS_ERROR_ABORT) {
|
||||
// If the user cancels the MP prompt then return no logins.
|
||||
return [];
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
|
||||
async getBreachesForLogins(logins, breaches = null) {
|
||||
if (!breaches) {
|
||||
breaches = await RemoteSettings("fxmonitor-breaches").get();
|
||||
}
|
||||
|
||||
// Determine potentially breached logins by checking their origin and the last time
|
||||
// they were changed. It's important to note here that we are NOT considering the
|
||||
// username and password of that login.
|
||||
const breachesByLoginGUID = new Map();
|
||||
for (const login of logins) {
|
||||
const loginURI = Services.io.newURI(login.origin);
|
||||
for (const breach of breaches) {
|
||||
if (!breach.Domain) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
Services.eTLD.hasRootDomain(loginURI.host, breach.Domain) &&
|
||||
login.timePasswordChanged < new Date(breach.BreachDate).getTime()
|
||||
) {
|
||||
breachesByLoginGUID.set(login.guid, breach);
|
||||
}
|
||||
}
|
||||
}
|
||||
return breachesByLoginGUID;
|
||||
},
|
||||
};
|
||||
|
||||
LoginHelper.init();
|
||||
|
|
Загрузка…
Ссылка в новой задаче