Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MNTOR-3378 - Data broker manual removal #5287

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
dec0aa7
fix ui
codemist Nov 4, 2024
1bd3c2d
apply ui changes tto scanresultcard
codemist Nov 4, 2024
1ab2f5d
apply styling to button
codemist Nov 4, 2024
a22d17f
add removal under maintenance status
codemist Nov 4, 2024
e7d8016
change cta label and write test
codemist Nov 4, 2024
98a5cd4
add new removal under maintenance page
codemist Nov 4, 2024
2552e73
test exposure card in new view data broker page
codemist Nov 6, 2024
27635ae
change terminology ot data broker
codemist Nov 7, 2024
b0e33d2
make new scan result component for resolution flow
codemist Nov 7, 2024
fc50d36
ui fixes
codemist Nov 7, 2024
517feb7
add header
codemist Nov 8, 2024
dc27aa7
add header string
codemist Nov 8, 2024
24cb2c7
add box shadow
codemist Nov 8, 2024
9f47831
add estimated time of removal
codemist Nov 8, 2024
23439bd
add removal instructions view
codemist Nov 12, 2024
b9a31d3
ui tweaks
codemist Nov 12, 2024
7e39450
rremove ispremium force
codemist Nov 12, 2024
b8c87c0
remove commented out code
codemist Nov 12, 2024
dc69fb9
fix tests
codemist Nov 12, 2024
d052179
add strings
codemist Nov 12, 2024
38b080d
revert back to info for sale
codemist Nov 12, 2024
a2f42ed
fix deprecated strings
codemist Nov 12, 2024
6c06f12
move cta button to the bottom on mobile
codemist Nov 12, 2024
a55ea7d
fix ftl
codemist Nov 13, 2024
6af38e2
fix string changes
codemist Nov 13, 2024
4d4b27a
ftl lint
codemist Nov 13, 2024
fd0e94f
add condition to remove navclose from fixview
codemist Nov 13, 2024
58e3fbf
add back arrow
codemist Nov 13, 2024
06da548
Update locales-pending/dashboard-premium.ftl
codemist Nov 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 46 additions & 2 deletions locales-pending/dashboard-premium.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ modal-heres-what-we-fixed-description-part-two = <b>Auto-removed</b> includes an
modal-heres-what-we-fixed-description-part-three = <b>In Progress</b> includes anything that we are currently working on fixing.

dashboard-exposures-filter-exposure-type = Exposure type
dashboard-exposures-filter-exposure-type-info-for-sale = Your info for sale
dashboard-exposures-filter-exposure-type-info-for-sale = Info for sale
dashboard-exposures-filter-exposure-type-data-breach = Data breach
dashboard-exposures-filter-exposure-removal-time-title = Removal time
dashboard-exposures-filter-exposure-removal-time-label-7 = Up to 7 days
Expand All @@ -60,7 +60,7 @@ modal-exposure-type-description = {
}
modal-exposure-type-data-breach = <b>Data breach</b> means your information has been compromised in a breach and could be in the wrong hands.
Resolving these typically requires accessing your accounts, so you’ll need to take manual steps to resolve each breach even if you’ve subscribed to { -brand-monitor-plus }.
modal-exposure-type-data-broker-part-one = <b>Info for sale</b> means a data broker site is publicly publishing and selling your personal info.
modal-exposure-type-data-broker-part-one = <b>Your info for sale</b> means a data broker site is publicly publishing and selling your personal info.
You’ll need to manually request removal from each site.
modal-exposure-type-data-broker-part-two = But if you’re a { -brand-monitor-plus } subscriber, we auto-remove the profiles for you.

Expand Down Expand Up @@ -205,6 +205,50 @@ exposure-card-description-info-for-sale-action-needed-dashboard = This site is p
exposure-card-description-info-for-sale-in-progress-dashboard = As a { -brand-monitor-plus } member, we’ve removed <data_broker_profile>this profile</data_broker_profile> and are confirming the data broker’s removal compliance.
exposure-card-description-info-for-sale-fixed = As a { -brand-monitor-plus } member, we’ve <data_broker_profile>removed this profile</data_broker_profile> for you and will continually monitor to make sure they don’t add you back.
exposure-card-description-info-for-sale-fixed-manually-fixed = You marked this profile as fixed. Be sure you’ve followed all instructions on <data_broker_profile>the site</data_broker_profile> to ensure they remove your personal info.
exposure-card-description-info-for-sale-manual-removal-needed = We’ve asked this data broker to remove your profile but they haven’t done it. To start the process sooner, we can guide you step-by-step to manually remove your profile and resolve any exposures. Select <b>Resolve exposures</b> to get started.

## Manual Removal Data Broker

# Variables:
# $data_broker_name is the name of the data broker under removal maintenance
data-broker-removal-maintenance-header = { -brand-monitor } found this profile on <link_to_data_broker>{ $data_broker_name }</link_to_data_broker>
data-broker-removal-maintenance-cta-go-to-data-broker = Go to data broker site to get started
data-broker-removal-maintenance-cta-mark-as-resolved = Mark exposure resolved
# Est. is short for "estimated"
# Variables:
# $range is the range of minutes it would take to complete the removal. E.g. 3-5 minutes.
data-broker-removal-maintenance-estimated-time =
{ $range ->
[one] Est. time to complete: { $range } minute
*[other] Est. time to complete: { $range } minutes
}
data-broker-removal-maintenance-steps-to-remove-header = How to remove your profile from data broker websites
data-broker-removal-maintenance-steps-to-remove-header-step-one = Visit this data broker website then locate their removal instructions. These may be purposely difficult to find, so check in the footer, terms page, privacy page, or “do not sell” page for removal instructions.
data-broker-removal-maintenance-steps-to-remove-header-step-two = When you’ve determined your profile was successfully removed, you can mark the exposure as resolved by toggling on the switch within this exposure data card in your dashboard.
data-broker-removal-maintenance-steps-to-remove-view-more-link = View removal instructions
data-broker-removal-maintenance-rationale-header = Why do I need to manually remove this profile?
data-broker-removal-maintenance-rationale-answer = { -brand-monitor } works hard to auto-remove your profiles from data broker sites. But some are more difficult than others or are non-compliant, which requires manual removal from the profile owner. <learn_about_data_exposure_link>Learn about data exposures</learn_about_data_exposure_link>

## Manual Removal Guide

data-broker-removal-guide-header = Removal guide for data broker websites
data-broker-removal-guide-top-section-para-1 = { -brand-mozilla-monitor } works hard to automatically remove your personal information from data brokers sites. However, some data brokers are more difficult and may ignore removal requests from third parties.
data-broker-removal-guide-top-section-para-2 = We’re sorry we couldn’t remove this profile for you. Data brokers benefit from sharing personal information, so they often change their removal instructions to prevent companies like us from protecting your information. We are constantly evaluating our auto-removal processes to counter this behavior. But in the meantime, here’s what you need to do to manually remove your information.
data-broker-removal-guide-step-1-header = Step 1: Go to the data broker site and find their opt out instructions
data-broker-removal-guide-step-1-body = Visit the data broker website and locate the instructions they provide for requesting removal of your profile. Because data brokers often make money by selling your information, they may intentionally make it hard to find these instructions. Here are a few tips to find removal instructions:
data-broker-removal-guide-step-1-list-item-1 = They may be called data suppression, delete my data, do not show my data, or opt out instructions.
data-broker-removal-guide-step-1-list-item-2 = Start by checking the footer of the website.
data-broker-removal-guide-step-1-list-item-3 = You can also check the Privacy section of their website.
data-broker-removal-guide-step-1-list-item-4 = You can also check the site FAQs.
data-broker-removal-guide-step-2-header = Step 2: Follow the instructions
data-broker-removal-guide-step-2-body-para-1 = Each data broker’s removal process is different, and they usually require you to submit personal details such as your name, email address, or physical address. Sometimes it’s as easy as submitting your email address. But some may require you to mail a physical letter. Be sure to follow the directions fully to ensure removal. Each removal should take only a few minutes.
data-broker-removal-guide-step-2-body-para-2 = If you have many exposures needing manual removal, try to do them in batches, and keep going until they’re all removed.
data-broker-removal-guide-step-3-header = Step 3: Verify removal
data-broker-removal-guide-step-3-body-para-1 = Once you’ve verified your profile has been removed from the data broker site, you can use { -brand-monitor } to track this status. After removal, simply go to the exposure card in your dashboard and you’ll see that it’s been marked as “Removed”. Because data brokers usually add profiles back to their databases, you can toggle the “Removed” status on or off in cases where you’ve been added back.
data-broker-removal-guide-step-3-body-para-2 = Data brokers can take 2 weeks to remove your information, and sometimes even longer.
data-broker-removal-guide-step-4-header = Step 4: Watch for re-exposures
data-broker-removal-guide-step-4-body = Please note that this process does not remove your information from public records, which means your information could be added back to data brokers that you’ve been removed from. As a { -brand-monitor-plus } subscriber, we’ll continually watch for new exposures from this data broker.
data-broker-removal-guide-button-back-to-exposures = Back to exposures

## CSAT survey banner for subscribers

Expand Down
3 changes: 2 additions & 1 deletion locales/en/exposure-card.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ exposure-card-other = Other
exposure-card-description-data-breach-action-needed = Your information was exposed in the <data_breach_link>{ $data_breach_company } data breach on { $data_breach_date }.</data_breach_link> We’ll walk you through the steps to fix it.
exposure-card-description-data-breach-fixed = You’ve taken the steps needed to fix <data_breach_link>this breach</data_breach_link>. We’ll continually monitor for data breaches and alert you of any new exposures.
exposure-card-your-exposed-info = Your exposed info:
exposure-card-found-the-following-data = { -brand-monitor } found the following exposed data:
exposure-card-exposure-type-data-broker = Info for sale
exposure-card-exposure-type-data-breach = Data breach
exposure-card-cta = Fix all exposures
exposure-card-resolve-exposures-cta = Resolve exposures
exposure-card-label-company-logo = Company logo
exposure-card-label-company = Company
# Status of the exposure card, could be In Progress, Fixed or Action Needed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,9 @@ const OnerepConfigPage = (props: Props) => {
<option value="new">New</option>
<option value="optout_in_progress">In Progress</option>
<option value="removed">Removed</option>
<option value="removal_under_maintenance">
Removal under maintenance
</option>
</select>
</label>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2793,7 +2793,7 @@ it("allows Plus users to filter by info for sale", async () => {
await user.click(filterMenuButton);

const filterDialog = screen.getByRole("dialog");
const exposureTypeInput = getByLabelText(filterDialog, "Your info for sale");
const exposureTypeInput = getByLabelText(filterDialog, "Info for sale");
await user.click(exposureTypeInput);

const showResultsButton = getByRole(filterDialog, "button", {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ export const View = (props: Props) => {
}).href
}
>
{l10n.getString("exposure-card-cta")}
{l10n.getString("exposure-card-resolve-exposures-cta")}
codemist marked this conversation as resolved.
Show resolved Hide resolved
</Button>
}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export type FixViewProps = {
| "leaked-passwords"
| "security-recommendations";
hideProgressIndicator?: boolean;
hideNavClose?: boolean;
hideNextNavigationRightArrow?: boolean;
showConfetti?: boolean;
};

Expand Down Expand Up @@ -90,21 +92,23 @@ export const FixView = (props: FixViewProps) => {
)}
/>
)}
{navigationClose()}
{!props.hideNavClose && navigationClose()}
<section className={styles.fixSection}>
<div className={styles.viewWrapper}>{props.children}</div>
<Link
className={`${styles.navArrow} ${styles.navArrowNext}`}
href={props.nextStep.href}
aria-label={l10n.getString("guided-resolution-flow-next-arrow")}
onClick={() => {
recordTelemetry("button", "click", {
button_id: "next_arrow",
});
}}
>
<Image alt="" src={ImageArrowRight} />
</Link>
{!props.hideNextNavigationRightArrow && (
<Link
className={`${styles.navArrow} ${styles.navArrowNext}`}
href={props.nextStep.href}
aria-label={l10n.getString("guided-resolution-flow-next-arrow")}
onClick={() => {
recordTelemetry("button", "click", {
button_id: "next_arrow",
});
}}
>
<Image alt="" src={ImageArrowRight} />
</Link>
)}
</section>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
@import "../../../../../../../../../tokens";

.exposureCard {
display: flex;
flex-direction: column;
background-color: $color-white;
border: 2px solid rgba($color-purple-70, 0.2);
border-radius: $border-radius-lg;
padding: $layout-sm $layout-sm $layout-xs $layout-sm;

.dataClassesList {
justify-content: space-between;
margin-left: 0;
display: grid;
grid-template-columns: 1fr;
grid-row-gap: $spacing-sm;

@media screen and (min-width: $screen-md) {
grid-template-columns: 1fr 1fr 1fr;
gap: $spacing-sm;
}

@media screen and (min-width: $screen-lg) {
display: flex;
flex-direction: row;
align-items: flex-start;
gap: $layout-xs;
flex-wrap: wrap;
justify-content: flex-start;
}
}

.buttonsWrapper {
margin-top: $spacing-lg;
border-top: 2px solid $color-grey-10;
padding-top: $spacing-lg;
display: flex;
gap: $spacing-sm;
}

.estimatedTime {
@include estimated-time;
padding-top: $spacing-sm;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/* 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/. */

"use client";

import { OnerepScanResultRow } from "knex/types/tables";
import { useL10n } from "../../../../../../../../../hooks/l10n";
import { ExposureCardDataClassLayout } from "../../../../../../../../../components/client/exposure_card/ExposureCardDataClass";
import styles from "./DataBrokerRemovalMaintenance.module.scss";
import React from "react";
import { TelemetryButton } from "../../../../../../../../../components/client/TelemetryButton";
import { ClockIcon } from "../../../../../../../../../components/server/Icons";

export type DataBrokerRemovalMaintenanceProps = {
scanResult: OnerepScanResultRow;
isPremiumUser: boolean;
};

export const DataBrokerRemovalMaintenance = (
props: DataBrokerRemovalMaintenanceProps,
) => {
const { scanResult } = props;
const l10n = useL10n();

const exposureCategoriesArray: React.ReactElement[] = [];

// Scan Result Categories
if (scanResult.relatives.length > 0) {
exposureCategoriesArray.push(
<ExposureCardDataClassLayout
exposure={scanResult}
key="relatives"
dataBrokerDataType="relatives"
label={l10n.getString("exposure-card-family-members")}
count={scanResult.relatives.length}
isPremiumUser={props.isPremiumUser}
/>,
);
}
if (scanResult.phones.length > 0) {
exposureCategoriesArray.push(
<ExposureCardDataClassLayout
exposure={scanResult}
key="phones"
dataBrokerDataType="phones"
label={l10n.getString("exposure-card-phone-number")}
count={scanResult.phones.length}
isPremiumUser={props.isPremiumUser}
/>,
);
}
if (scanResult.emails.length > 0) {
exposureCategoriesArray.push(
<ExposureCardDataClassLayout
exposure={scanResult}
key="emails"
dataBrokerDataType="emails"
label={l10n.getString("exposure-card-email")}
count={scanResult.emails.length}
isPremiumUser={props.isPremiumUser}
/>,
);
}
if (scanResult.addresses.length > 0) {
exposureCategoriesArray.push(
<ExposureCardDataClassLayout
exposure={scanResult}
key="addresses"
dataBrokerDataType="addresses"
label={l10n.getString("exposure-card-address")}
count={scanResult.addresses.length}
isPremiumUser={props.isPremiumUser}
/>,
);
}

const exposureCard = (
<div
className={styles.exposureCard}
aria-label={props.scanResult.data_broker}
>
<div className={styles.dataClassesList}>
{exposureCategoriesArray.map((item) => (
<React.Fragment key={item.key}>{item}</React.Fragment>
))}
</div>
<div className={styles.buttonsWrapper}>
{/* TODO: Add functionality to these buttons */}
<TelemetryButton
variant="primary"
href={props.scanResult.link}
event={{
module: "ctaButton",
name: "click",
data: {
button_id: `go_to_${props.scanResult.data_broker}_link_to_get_started`,
},
}}
>
{l10n.getString(
"data-broker-removal-maintenance-cta-go-to-data-broker",
)}
</TelemetryButton>
<TelemetryButton
variant="secondary"
href={props.scanResult.link}
event={{
module: "ctaButton",
name: "click",
data: {
button_id: `data_broker_removal_mark_as_resolved`,
},
}}
>
{l10n.getString(
"data-broker-removal-maintenance-cta-mark-as-resolved",
)}
</TelemetryButton>
</div>
<div className={styles.estimatedTime}>
<ClockIcon width="15" height="15" alt="" />
{l10n.getString("data-broker-removal-maintenance-estimated-time", {
range: "5 - 10",
})}
</div>
</div>
);

return exposureCard;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
@import "../../../../../../../../../tokens";

.dataBrokerInformationWrapper {
.exposureCardWrapper {
margin-top: $spacing-md;
padding-bottom: $spacing-lg;
}

.header {
font: $text-body-lg;
font-weight: 700;
}
}

.removalGuideInstructionsWrapper {
.backArrow {
all: unset;
cursor: pointer;
}
.headerRemovalGuide {
padding-top: $spacing-lg;
font: $text-body-xl;
font-weight: 700;
}

.buttonWrapper {
display: flex;
justify-content: center;
padding-top: $spacing-lg;
}
}

.removalContentSection {
margin-top: $layout-md;

dt {
font: $text-body-lg;
font-weight: 600;

&.removalGuideInstructions {
font: $text-body-md;
font-weight: 700;
}
}

dd {
padding-top: $spacing-sm;
}

ol {
padding-top: $spacing-sm;

li {
margin-bottom: $spacing-xs;
}
}

button {
margin-top: $spacing-lg;
}
}
Loading
Loading