From e930adbd05f8db31ca96669c21251731a19773c7 Mon Sep 17 00:00:00 2001 From: Florian Zia Date: Wed, 5 Apr 2023 16:40:13 +0200 Subject: [PATCH] chore: Only show breached company links if they are not on our block list --- locales/en/breaches.ftl | 4 +-- src/app-constants.js | 28 ++++++++++++++++++- ...json => hibp-breach-link-status-list.json} | 0 src/utils/breach-links/index.js | 18 ------------ src/utils/breach-resolution.js | 18 ++++++------ 5 files changed, 39 insertions(+), 29 deletions(-) rename src/{utils/breach-links/link-status-list.json => hibp-breach-link-status-list.json} (100%) delete mode 100644 src/utils/breach-links/index.js diff --git a/locales/en/breaches.ftl b/locales/en/breaches.ftl index 1daaa3790..2e2242aee 100644 --- a/locales/en/breaches.ftl +++ b/locales/en/breaches.ftl @@ -71,7 +71,7 @@ breach-checklist-link-mozilla-vpn = { -brand-mozilla-vpn } breach-checklist-pw-header-3 = { $breachedCompanyLink -> - [zero] Go to the company’s website to change your password and enable two-factor authentication (2FA). + [empty] Go to the company’s website to change your password and enable two-factor authentication (2FA). *[other] Go to { $breachedCompanyLink } to change your password and enable two-factor authentication (2FA). } @@ -145,7 +145,7 @@ breach-checklist-phone-header-2 = Protect your phone number with a masking servi breach-checklist-sq-header-3 = { $breachedCompanyLink -> - [zero] Update your security questions on the company’s website. + [empty] Update your security questions on the company’s website. *[other] Update your security questions on { $breachedCompanyLink }. } diff --git a/src/app-constants.js b/src/app-constants.js index 67310b3eb..5366d9247 100644 --- a/src/app-constants.js +++ b/src/app-constants.js @@ -4,6 +4,12 @@ // TODO: these vars were copy/pasted from the old app-constants.js and should be cleaned up import * as dotenv from 'dotenv' +import { readFileSync } from 'fs' +import path from 'path' +import { fileURLToPath } from 'url' + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) dotenv.config({ path: '../.env' }) @@ -53,7 +59,7 @@ const optionalEnvVars = [ 'SENTRY_DSN_LEGACY' ] -const AppConstants = { } +const AppConstants = {} if (!process.env.SERVER_URL && process.env.NODE_ENV === 'heroku') { process.env.SERVER_URL = `https://${process.env.HEROKU_APP_NAME}.herokuapp.com` @@ -70,4 +76,24 @@ optionalEnvVars.forEach(key => { if (key in process.env) AppConstants[key] = process.env[key] }) +// Create HIBP breach link blocklist +const linkStatusList = JSON.parse(readFileSync(path.join( + __dirname, + './hibp-breach-link-status-list.json' +))) + +const linkBlockList = linkStatusList.links + .reduce((blockList, breachLink) => { + const { status, statusCode } = breachLink + + if (status !== 'alive' || statusCode !== 200) { + blockList.push(breachLink.link) + } + + return blockList + }, []) + .join(',') + +AppConstants.HIBP_BREACH_LINK_BLOCKLIST = linkBlockList + export default Object.freeze(AppConstants) diff --git a/src/utils/breach-links/link-status-list.json b/src/hibp-breach-link-status-list.json similarity index 100% rename from src/utils/breach-links/link-status-list.json rename to src/hibp-breach-link-status-list.json diff --git a/src/utils/breach-links/index.js b/src/utils/breach-links/index.js deleted file mode 100644 index 8e6dcc5f3..000000000 --- a/src/utils/breach-links/index.js +++ /dev/null @@ -1,18 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Check if the provided link is a valid link - * - * @param {string} linkUrl - * @returns {boolean} True if link is valid - */ - -function isValidLink (linkUrl) { - return true -} - -export { - isValidLink -} diff --git a/src/utils/breach-resolution.js b/src/utils/breach-resolution.js index 28b738bb9..91f0a23e8 100644 --- a/src/utils/breach-resolution.js +++ b/src/utils/breach-resolution.js @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +import AppConstants from '../app-constants.js' import { getMessage } from './fluent.js' /** @@ -107,18 +108,21 @@ const breachResolutionDataTypes = { * @param {Partial<{ countryCode: string }>} options * @returns {*} void */ -function appendBreachResolutionChecklist (userBreachData, options = {}) { +async function appendBreachResolutionChecklist (userBreachData, options = {}) { const { verifiedEmails } = userBreachData for (const { breaches } of verifiedEmails) { breaches.forEach(b => { const dataClasses = b.DataClasses - // TODO: Add condition for hiding breach links - const hideBreachLink = false + const showLink = b.Domain && + !AppConstants.HIBP_BREACH_LINK_BLOCKLIST.includes(b.Domain) + + console.log(b.Domain, showLink) + const args = { companyName: b.Name, - breachedCompanyLink: b.Domain + breachedCompanyLink: !showLink ? `${b.Domain}` - : '', + : 'empty', firefoxRelayLink: `${getMessage('breach-checklist-link-firefox-relay')}`, passwordManagerLink: `${getMessage('breach-checklist-link-password-manager')}`, mozillaVpnLink: `${getMessage('breach-checklist-link-mozilla-vpn')}`, @@ -126,7 +130,7 @@ function appendBreachResolutionChecklist (userBreachData, options = {}) { experianLink: 'Experian', transUnionLink: 'TransUnion' } - b.breachChecklist = getResolutionRecsPerBreach(dataClasses, args, { ...options, hideBreachLink }) + b.breachChecklist = getResolutionRecsPerBreach(dataClasses, args, options) }) } } @@ -149,8 +153,6 @@ function getResolutionRecsPerBreach (dataTypes, args, options = {}) { for (const [key, value] of Object.entries(breachResolutionDataTypes)) { if ( dataTypes.includes(key) && - // Hide the security question or password resolution if we decided to not link to the breached site: - !options.hideBreachLink && // Hide resolutions that apply to other countries than the user's: (!options.countryCode || !Array.isArray(value.applicableCountryCodes) || value.applicableCountryCodes.includes(options.countryCode.toLowerCase())) ) {