From 49d669df3d3395fe72c03f695abfc48dc639e539 Mon Sep 17 00:00:00 2001 From: Micah Tigley Date: Fri, 26 Jul 2019 00:07:04 +0000 Subject: [PATCH] Bug 1567477 - Add actions to Monitor card buttons. r=ewright,rfkelly Differential Revision: https://phabricator.services.mozilla.com/D39105 --HG-- extra : moz-landing-system : lando --- .../about/AboutProtectionsHandler.jsm | 10 +++++ .../protections/content/monitor-card.js | 39 ++++++++++++++----- .../protections/content/protections.css | 26 ++++++++++++- .../protections/content/protections.html | 6 +-- .../browser/browser_protections_monitor.js | 12 +++--- 5 files changed, 71 insertions(+), 22 deletions(-) diff --git a/browser/components/about/AboutProtectionsHandler.jsm b/browser/components/about/AboutProtectionsHandler.jsm index 96fa45c537ac..7df2c2cf0c92 100644 --- a/browser/components/about/AboutProtectionsHandler.jsm +++ b/browser/components/about/AboutProtectionsHandler.jsm @@ -176,6 +176,7 @@ var AboutProtectionsHandler = { * @return {{ monitoredEmails: Number, * numBreaches: Number, * passwords: Number, + * userEmail: String|null, * potentiallyBreachedLogins: Number, * error: Boolean }} * Monitor data. @@ -183,6 +184,7 @@ var AboutProtectionsHandler = { async getMonitorData() { let monitorData = {}; let potentiallyBreachedLogins = null; + let userEmail = null; const hasFxa = await fxAccounts.accountStatus(); if (hasFxa) { @@ -221,6 +223,13 @@ var AboutProtectionsHandler = { potentiallyBreachedLogins = await LoginHelper.getBreachesForLogins( logins ); + + // If the user isn't subscribed to Monitor, then send back their email so the + // protections report can direct them to the proper OAuth flow on Monitor. + if (monitorData.errorMessage) { + const { email } = await fxAccounts.getSignedInUser(); + userEmail = email; + } } } else { // If no account exists, then the user is not logged in with an fxAccount. @@ -231,6 +240,7 @@ var AboutProtectionsHandler = { return { ...monitorData, + userEmail, potentiallyBreachedLogins: potentiallyBreachedLogins ? potentiallyBreachedLogins.size : 0, diff --git a/browser/components/protections/content/monitor-card.js b/browser/components/protections/content/monitor-card.js index c00907288004..f0d53127e5d2 100644 --- a/browser/components/protections/content/monitor-card.js +++ b/browser/components/protections/content/monitor-card.js @@ -4,19 +4,14 @@ /* eslint-env mozilla/frame-script */ +const MONITOR_SIGN_IN_URL = "https://monitor.firefox.com"; + export default class MonitorClass { constructor(document) { this.doc = document; } init() { - const signUpForMonitorButton = this.doc.getElementById( - "sign-up-for-monitor-button" - ); - signUpForMonitorButton.addEventListener("click", () => { - console.log("TODO: Where is this link supposed to go."); - }); - RPMAddMessageListener("SendUserLoginsData", ({ data }) => { // Wait for monitor data and display the card. this.getMonitorData(data); @@ -56,17 +51,41 @@ export default class MonitorClass { this.renderContentForUserWithLogins(monitorData); } else { monitorCard.classList.add("no-logins"); - const signUpForMonitorButton = this.doc.getElementById( - "sign-up-for-monitor-button" + const signUpForMonitorLink = this.doc.getElementById( + "sign-up-for-monitor-link" ); - signUpForMonitorButton.textContent = hasFxa + signUpForMonitorLink.textContent = hasFxa ? "Turn on Monitor" : "Sign up for Monitor"; + signUpForMonitorLink.href = this.buildMonitorUrl(monitorData.userEmail); headerContent.textContent = "Check Firefox Monitor to see if you've been part of a data breach and get alerts about new breaches."; } } + /** + * Builds the appropriate URL that takes the user to the Monitor website's + * sign-up/sign-in page. + * + * @param {String|null} email + * Optional. The email used to direct the user to the Monitor website's OAuth + * sign-in flow. If null, then direct user to just the Monitor website. + * + * @return URL to Monitor website. + */ + buildMonitorUrl(email = null) { + let url = MONITOR_SIGN_IN_URL; + + if (email) { + url += `/oauth/init?email=${email}&entrypoint=protection_report_monitor&utm_source=about-protections`; + } else { + url += + "/?entrypoint=protection_report_monitor&utm_source=about-protections"; + } + + return url; + } + renderContentForUserWithLogins(monitorData) { const storedEmail = this.doc.querySelector( "span[data-type='stored-emails']" diff --git a/browser/components/protections/content/protections.css b/browser/components/protections/content/protections.css index 277bc32866e1..6c617e2713ab 100644 --- a/browser/components/protections/content/protections.css +++ b/browser/components/protections/content/protections.css @@ -52,13 +52,15 @@ body[focuseddatatype=cryptominer] { margin: 0 auto; } -.card-header > button { +.card-header > button, +#sign-up-for-monitor-link { font-size: 0.95em; cursor: pointer; margin-inline-end: 15px; margin-inline-start: 15px; padding: 10px; align-self: center; + text-align: center; } .card.lockwise-card .card-header, @@ -77,7 +79,7 @@ a.hidden, .monitor-card.no-logins .card-body, .monitor-card.no-logins #monitor-header-content a, .monitor-card.no-logins .inline-text-icon.monitor-scanned-text, -.monitor-card.has-logins #sign-up-for-monitor-button, +.monitor-card.has-logins #sign-up-for-monitor-link, #monitor-body-content .monitor-breached-passwords.hidden { display: none; } @@ -520,3 +522,23 @@ label:hover { background-color: var(--orange); padding: 15px; } + +#sign-up-for-monitor-link { + -moz-appearance: button; + background-color: var(--blue-60); + border-radius: 2px; + text-decoration: none; + color: #fff; +} + +#sign-up-for-monitor-link:active { + background-color: var(--blue-80) !important; +} + +#sign-up-for-monitor-link:hover { + background-color: var(--blue-70); +} + +#sign-up-for-monitor-link:focus-visible { + box-shadow: 0 0 0 1px #0a84ff inset, 0 0 0 1px #0a84ff, 0 0 0 4px rgba(10, 132, 255, 0.3); +} diff --git a/browser/components/protections/content/protections.html b/browser/components/protections/content/protections.html index b9b405917c34..b40320465f4e 100644 --- a/browser/components/protections/content/protections.html +++ b/browser/components/protections/content/protections.html @@ -99,9 +99,9 @@ Automatically scanned today - + + +
diff --git a/browser/components/protections/test/browser/browser_protections_monitor.js b/browser/components/protections/test/browser/browser_protections_monitor.js index 7c9e6d8c83f8..50bada6755ee 100644 --- a/browser/components/protections/test/browser/browser_protections_monitor.js +++ b/browser/components/protections/test/browser/browser_protections_monitor.js @@ -193,11 +193,11 @@ add_task(async function() { await BrowserTestUtils.removeTab(tab); }); -async function checkNoLoginsContentIsDisplayed(tab, expectedButtonContent) { +async function checkNoLoginsContentIsDisplayed(tab, expectedLinkContent) { await ContentTask.spawn( tab.linkedBrowser, - { buttonText: expectedButtonContent }, - async function({ buttonText }) { + { linkText: expectedLinkContent }, + async function({ linkText }) { await ContentTaskUtils.waitForCondition(() => { const noLogins = content.document.querySelector( ".monitor-card.no-logins" @@ -211,9 +211,7 @@ async function checkNoLoginsContentIsDisplayed(tab, expectedButtonContent) { const cardBody = content.document.querySelector( ".monitor-card .card-body" ); - const button = content.document.getElementById( - "sign-up-for-monitor-button" - ); + const link = content.document.getElementById("sign-up-for-monitor-link"); ok( ContentTaskUtils.is_hidden(cardBody), @@ -224,7 +222,7 @@ async function checkNoLoginsContentIsDisplayed(tab, expectedButtonContent) { "Check Firefox Monitor to see if you've been part of a data breach and get alerts about new breaches.", "Header content for user with no logins is correct" ); - is(button.textContent, buttonText, "Text content for button is correct"); + is(link.textContent, linkText, "Text content for link is correct"); } ); }