diff --git a/jest.config.cjs b/jest.config.cjs index 54193a9cf84..d8279168e39 100644 --- a/jest.config.cjs +++ b/jest.config.cjs @@ -193,9 +193,7 @@ const customJestConfig = { // ], // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped - // testPathIgnorePatterns: [ - // "/node_modules/" - // ], + testPathIgnorePatterns: ["/node_modules/", "/dist/"], // The regexp pattern or array of patterns that Jest uses to detect test files // testRegex: [], diff --git a/locales-pending/dashboard-premium.ftl b/locales-pending/dashboard-premium.ftl index 1a278670034..f371281d31b 100644 --- a/locales-pending/dashboard-premium.ftl +++ b/locales-pending/dashboard-premium.ftl @@ -33,10 +33,12 @@ modal-heres-what-we-fixed-description-part-one = Manually fixed includes to be fixed manually, even if you’ve subscribed to { -brand-monitor-plus }. modal-heres-what-we-fixed-description-part-two = Auto-removed includes any exposures from data broker profiles that we’ve removed for you. This is available only for { -brand-monitor-plus } subscribers. -modal-heres-what-we-fixed-description-part-three = In Progress includes anything that we are currently +# Deprecated (once feature flag `SetExpectationsForUsers` is enabled): +modal-heres-what-we-fixed-description-part-three-deprecated = In Progress includes anything that we are currently working on fixing. Removals typically take 7–14 days but the most difficult sites could take longer. You may also start to see removals happening within the same day. +modal-heres-what-we-fixed-description-part-three = In Progress 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 @@ -55,8 +57,10 @@ modal-exposure-type-data-breach = Data breach means your information has 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 = Info for sale 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 = For { -brand-monitor-plus } subscribers, we auto-remove these profiles on your behalf and make sure they don’t re-add you. +# Deprecated (once feature flag `SetExpectationsForUsers` is enabled): +modal-exposure-type-data-broker-part-two-deprecated = For { -brand-monitor-plus } subscribers, we auto-remove these profiles on your behalf and make sure they don’t re-add you. In both cases, removals typically take 7–14 days. Some can take longer, while others can happen within the hour. +modal-exposure-type-data-broker-part-two = But if you’re a { -brand-monitor-plus } subscriber, we auto-remove the profiles for you. # About Exposure Statuses Modal diff --git a/locales-pending/fix-premium.ftl b/locales-pending/fix-premium.ftl index 3ca1204f4c2..452b32562a1 100644 --- a/locales-pending/fix-premium.ftl +++ b/locales-pending/fix-premium.ftl @@ -110,19 +110,32 @@ data-broker-profiles-exposure-reduction = Exposure reduction: { $exposure_reduct # Variables: # $nr (number) - % of exposures reduced for the user exposure-reduction-chart-heading = { $nr }% -exposure-reduction-chart-explanation = exposures willbe reduced +# Deprecated (once feature flag `SetExpectationsForUsers` is enabled): +exposure-reduction-chart-explanation-deprecated = exposures willbe reduced +exposure-reduction-chart-explanation = exposures maybe reduced welcome-to-premium-data-broker-profiles-title-part-one = Welcome to { -brand-monitor-plus }. welcome-to-premium-data-broker-profiles-title-part-two = We’ll remove those profiles ASAP. +# Deprecated (once feature flag `SetExpectationsForUsers` is enabled): # Variables: # $profile_total_num is the number of exposures came back from user data broker scans. # $exposure_reduction_percentage is the percent by which exposures are reduced -welcome-to-premium-data-broker-profiles-description-part-one = +welcome-to-premium-data-broker-profiles-description-part-one-deprecated = { $profile_total_num -> [one] We’ve already started our auto-removal process of 1 profile — which will reduce your exposures by { $exposure_reduction_percentage }%. *[other] We’ve already started our auto-removal process of { $profile_total_num } profiles — which will reduce your exposures by { $exposure_reduction_percentage }%. } +# Variables: +# $profile_total_num is the number of exposures came back from user data broker scans. +# $exposure_reduction_percentage is the percent by which exposures are reduced +welcome-to-premium-data-broker-profiles-description-part-one = + { $profile_total_num -> + [one] We’ve already started our auto-removal process of 1 profile — which may reduce your exposures up to { $exposure_reduction_percentage }%. + *[other] We’ve already started our auto-removal process of { $profile_total_num } profiles — which may reduce your exposures up to { $exposure_reduction_percentage }%. + } +# Deprecated welcome-to-premium-data-broker-profiles-description-part-two = Removals typically take 7-14 days, but some may happen within the hour. No matter how long it takes, we’ll keep working on it. +# There used to be a "part two", but we removed that welcome-to-premium-data-broker-profiles-description-part-three = Next we’ll guide you through high risk data breaches that require manual steps. # Variables: # $data_broker_count is the number of data brokers scanned monthly diff --git a/locales-pending/landing-premium.ftl b/locales-pending/landing-premium.ftl index 398d4b7f1c5..dc30076eeb8 100644 --- a/locales-pending/landing-premium.ftl +++ b/locales-pending/landing-premium.ftl @@ -130,11 +130,17 @@ landing-premium-quote = There’s a $240 billion industry of data landing-premium-what-websites-sell-info-qn = What kinds of websites sell my personal information? landing-premium-what-websites-sell-info-ans = Certain websites are in the business of collecting and selling people’s personal information without their consent, which is unfortunately legal in the US. These sites are called data brokers and they make up a $240 billion dollar industry. They use sophisticated methods to collect personal, financial, location, and even health information, often without your consent or even your knowledge. They’ll sell what they’ve collected to third parties, profiting from your information and leaving you open to violations of your privacy and security. landing-premium-continuous-data-removal-qn = How does continuous data removal work? +# Deprecated (once feature flag `SetExpectationsForUsers` is enabled): # Variables: # $data_broker_sites_total_num is the total number of data broker sites available to scan. It will always be plural. -landing-premium-continuous-data-removal-ans = { $data_broker_sites_total_num -> +landing-premium-continuous-data-removal-ans-deprecated = { $data_broker_sites_total_num -> *[other] Every month, we use the information you provided about yourself (name, location and birthdate) to search across { $data_broker_sites_total_num } data broker sites that sell people’s private information. If we find your data on any of these sites, we initiate the request for removal. Data removal can take anywhere from a day to a month. This feature is available for { -brand-monitor-plus } users only. Learn more here. } +# Variables: +# $data_broker_sites_total_num is the total number of data broker sites available to scan. It will always be plural. +landing-premium-continuous-data-removal-ans = { $data_broker_sites_total_num -> + *[other] Every month, we use the information you provided about yourself (name, location and birthdate) to search across { $data_broker_sites_total_num } data broker sites that sell people’s private information. If we find your data on any of these sites, we initiate the request for removal. This feature is available for { -brand-monitor-plus } users only. Learn more here. +} # Scan Limit diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.stories.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.stories.tsx index c4cfcf2a229..948d6dccfb5 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.stories.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.stories.tsx @@ -215,6 +215,7 @@ const DashboardWrapper = (props: DashboardWrapperProps) => { enabledFeatureFlags={[ ...(props.enabledFeatureFlags ?? []), "HowItWorksPage", + "SetExpectationsForUsers", ]} experimentData={ props.experimentData ?? { diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/DashboardTopBanner/DashboardTopBannerContent.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/DashboardTopBanner/DashboardTopBannerContent.tsx index a4e2b24ef2c..5040a02dd38 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/DashboardTopBanner/DashboardTopBannerContent.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/DashboardTopBanner/DashboardTopBannerContent.tsx @@ -57,7 +57,7 @@ export const DashboardTopBannerContent = (props: DashboardTopBannerProps) => { monthlySubscriptionUrl, yearlySubscriptionUrl, subscriptionBillingAmount, - howItWorksFlagEnabled, + enabledFeatureFlags, } = props; const waitlistDialogState = useOverlayTriggerState({}); @@ -77,6 +77,7 @@ export const DashboardTopBannerContent = (props: DashboardTopBannerProps) => { } autoRemoved={bannerData.dataBrokerAutoFixedDataPointsNum} inProgress={bannerData.dataBrokerInProgressDataPointsNum} + enabledFeatureFlags={enabledFeatureFlags} /> ); } @@ -263,7 +264,7 @@ export const DashboardTopBannerContent = (props: DashboardTopBannerProps) => { )} - {howItWorksFlagEnabled && ( + {enabledFeatureFlags.includes("HowItWorksPage") && ( { @@ -50,24 +51,7 @@ export const DashboardTopBanner = (props: DashboardTopBannerProps) => { return ( <>
- +
{ const countryCode = useContext(CountryCodeContext); const pathname = usePathname(); - const howItWorksFlagEnabled = - props.enabledFeatureFlags.includes("HowItWorksPage"); - const [activeTab, setActiveTab] = useState(props.activeTab); const localDismissalPetitionBanner = useLocalDismissal( `data_privacy_petition_banner-${props.user.subscriber?.id}`, @@ -517,7 +514,7 @@ export const View = (props: Props) => { yearlySubscriptionUrl={props.yearlySubscriptionUrl} subscriptionBillingAmount={props.subscriptionBillingAmount} totalNumberOfPerformedScans={props.totalNumberOfPerformedScans} - howItWorksFlagEnabled={howItWorksFlagEnabled} + enabledFeatureFlags={props.enabledFeatureFlags} />
{activeTab === "action-needed" ? ( diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/ResolutionContainer.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/ResolutionContainer.tsx index 48cdd16065f..6c8771a3a66 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/ResolutionContainer.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/ResolutionContainer.tsx @@ -12,6 +12,7 @@ import styles from "./ResolutionContainer.module.scss"; import { ProgressCard } from "../../../../../../../components/client/ProgressCard"; import { StepDeterminationData } from "../../../../../../../functions/server/getRelevantGuidedSteps"; import { getDashboardSummary } from "../../../../../../../functions/server/dashboard"; +import { FeatureFlagName } from "../../../../../../../../db/tables/featureFlags"; type ResolutionContainerProps = { type: "highRisk" | "leakedPasswords" | "securityRecommendations"; @@ -23,6 +24,7 @@ type ResolutionContainerProps = { isEligibleForPremium: boolean; isStepDone: boolean; data: StepDeterminationData; + enabledFeatureFlags: FeatureFlagName[]; label?: string; cta?: ReactNode; }; @@ -64,6 +66,7 @@ export const ResolutionContainer = (props: ResolutionContainerProps) => { } autoRemoved={resolutionSummary.dataBrokerAutoFixedDataPointsNum} inProgress={resolutionSummary.dataBrokerInProgressDataPointsNum} + enabledFeatureFlags={props.enabledFeatureFlags} />
) : ( diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/welcome-to-plus/WelcomeToPlus.stories.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/welcome-to-plus/WelcomeToPlus.stories.tsx index 47a5be30d27..280d2300556 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/welcome-to-plus/WelcomeToPlus.stories.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/welcome-to-plus/WelcomeToPlus.stories.tsx @@ -77,7 +77,7 @@ const WelcomeToPlusViewWrapper = (props: { brokerScanCount: number }) => { }} l10n={l10n} subscriberEmails={[]} - howItWorksFlagEnabled + enabledFeatureFlags={["HowItWorksPage", "SetExpectationsForUsers"]} /> ); diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/welcome-to-plus/WelcomeToPlusView.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/welcome-to-plus/WelcomeToPlusView.tsx index 043574811ea..5026134ea3a 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/welcome-to-plus/WelcomeToPlusView.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/data-broker-profiles/welcome-to-plus/WelcomeToPlusView.tsx @@ -19,12 +19,13 @@ import noBreachesIllustration from "../../images/high-risk-breaches-none.svg"; import { CONST_ONEREP_DATA_BROKER_COUNT } from "../../../../../../../../../../constants"; import { TelemetryButton } from "../../../../../../../../../components/client/TelemetryButton"; import { TelemetryLink } from "../../../../../../../../../components/client/TelemetryLink"; +import { FeatureFlagName } from "../../../../../../../../../../db/tables/featureFlags"; export type Props = { data: StepDeterminationData; subscriberEmails: string[]; l10n: ExtendedReactLocalization; - howItWorksFlagEnabled: boolean; + enabledFeatureFlags: FeatureFlagName[]; }; export function WelcomeToPlusView(props: Props) { @@ -66,11 +67,19 @@ export function WelcomeToPlusView(props: Props) {

{hasRelevantScanResults - ? l10n.getString( - "welcome-to-premium-data-broker-profiles-description-part-one", + ? /* c8 ignore next 14 */ + // As the `SetExpectationsForUsers` feature flag is removed, the + // branch will be covered again: + l10n.getFragment( + props.enabledFeatureFlags.includes("SetExpectationsForUsers") + ? "welcome-to-premium-data-broker-profiles-description-part-one" + : "welcome-to-premium-data-broker-profiles-description-part-one-deprecated", { - profile_total_num: scanResultsInProgressCount, - exposure_reduction_percentage: dataPointReduction, + vars: { + profile_total_num: scanResultsInProgressCount, + exposure_reduction_percentage: dataPointReduction, + }, + elems: { b: }, }, ) : l10n.getString( @@ -81,8 +90,15 @@ export function WelcomeToPlusView(props: Props) { )}

- {hasRelevantScanResults && props.howItWorksFlagEnabled - ? l10n.getFragment( + {hasRelevantScanResults && + props.enabledFeatureFlags.includes("HowItWorksPage") + ? /* c8 ignore next 23 */ + // As the `SetExpectationsForUsers` feature flag is removed, the + // branch will be covered again: + !props.enabledFeatureFlags.includes( + "SetExpectationsForUsers", + ) && + l10n.getFragment( "welcome-to-premium-data-broker-profiles-description-part-two", { elems: { @@ -133,7 +149,10 @@ export function WelcomeToPlusView(props: Props) {

{hasRelevantScanResults ? (
- +
) : (
); } diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/HighRiskBreachLayout.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/HighRiskBreachLayout.tsx index 4d3c5775364..02fdf8bbf3b 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/HighRiskBreachLayout.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/HighRiskBreachLayout.tsx @@ -28,12 +28,14 @@ import { } from "../../../../../../../../functions/universal/breach"; import { TelemetryButton } from "../../../../../../../../components/client/TelemetryButton"; import { TelemetryLink } from "../../../../../../../../components/client/TelemetryLink"; +import { FeatureFlagName } from "../../../../../../../../../db/tables/featureFlags"; export type HighRiskBreachLayoutProps = { type: HighRiskBreachTypes; subscriberEmails: string[]; data: StepDeterminationData; isEligibleForPremium: boolean; + enabledFeatureFlags: FeatureFlagName[]; }; export function HighRiskBreachLayout(props: HighRiskBreachLayoutProps) { @@ -164,6 +166,7 @@ export function HighRiskBreachLayout(props: HighRiskBreachLayoutProps) { illustration={illustration} isPremiumUser={hasPremium(props.data.user)} isEligibleForPremium={props.isEligibleForPremium} + enabledFeatureFlags={props.enabledFeatureFlags} cta={ !isStepDone && ( <> diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/[type]/HighRiskDataBreach.stories.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/[type]/HighRiskDataBreach.stories.tsx index 8a09f5f26d2..2d9fd441966 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/[type]/HighRiskDataBreach.stories.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/[type]/HighRiskDataBreach.stories.tsx @@ -114,6 +114,7 @@ const HighRiskBreachWrapper = (props: { type={props.type} data={data} isEligibleForPremium={true} + enabledFeatureFlags={["SetExpectationsForUsers"]} /> ); diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/[type]/page.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/[type]/page.tsx index e61106236f4..aacb6e0b172 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/[type]/page.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/[type]/page.tsx @@ -16,6 +16,7 @@ import { getCountryCode } from "../../../../../../../../../functions/server/getC import { getLatestOnerepScanResults } from "../../../../../../../../../../db/tables/onerep_scans"; import { getOnerepProfileId } from "../../../../../../../../../../db/tables/subscribers"; import { isEligibleForPremium } from "../../../../../../../../../functions/server/onerep"; +import { getEnabledFeatureFlags } from "../../../../../../../../../../db/tables/featureFlags"; interface SecurityRecommendationsProps { params: { @@ -56,6 +57,10 @@ export default async function SecurityRecommendations({ latestScanData: scanData, }} isEligibleForPremium={isEligibleForPremium(countryCode)} + enabledFeatureFlags={await getEnabledFeatureFlags({ + ignoreAllowlist: false, + email: session.user.email, + })} /> ); } diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/page.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/page.tsx index 79c2e8f5e57..a42de30d533 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/page.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/high-risk-data-breaches/page.tsx @@ -12,6 +12,7 @@ import { getOnerepProfileId } from "../../../../../../../../../db/tables/subscri import { getLatestOnerepScanResults } from "../../../../../../../../../db/tables/onerep_scans"; import { getCountryCode } from "../../../../../../../../functions/server/getCountryCode"; import { isEligibleForPremium } from "../../../../../../../../functions/server/onerep"; +import { getEnabledFeatureFlags } from "../../../../../../../../../db/tables/featureFlags"; export default async function HighRiskDataBreaches() { const session = await getServerSession(); @@ -41,6 +42,10 @@ export default async function HighRiskDataBreaches() { latestScanData: scanData, }} isEligibleForPremium={isEligibleForPremium(countryCode)} + enabledFeatureFlags={await getEnabledFeatureFlags({ + ignoreAllowlist: false, + email: session.user.email, + })} />
); diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/LeakedPasswordsLayout.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/LeakedPasswordsLayout.tsx index fb9ffd9c0a1..df5d569a85e 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/LeakedPasswordsLayout.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/LeakedPasswordsLayout.tsx @@ -29,12 +29,14 @@ import { useEffect, useState } from "react"; import { useRouter } from "next/navigation"; import { LeakedPasswordsDataTypes } from "../../../../../../../../functions/universal/breach"; import { useTelemetry } from "../../../../../../../../hooks/useTelemetry"; +import { FeatureFlagName } from "../../../../../../../../../db/tables/featureFlags"; export interface LeakedPasswordsLayoutProps { type: LeakedPasswordsTypes; subscriberEmails: string[]; data: StepDeterminationData; isEligibleForPremium: boolean; + enabledFeatureFlags: FeatureFlagName[]; } export function LeakedPasswordsLayout(props: LeakedPasswordsLayoutProps) { @@ -191,6 +193,7 @@ export function LeakedPasswordsLayout(props: LeakedPasswordsLayoutProps) { title={title} illustration={illustration} isPremiumUser={hasPremium(props.data.user)} + enabledFeatureFlags={props.enabledFeatureFlags} cta={ !isStepDone && ( <> diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/[type]/LeakedPasswords.stories.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/[type]/LeakedPasswords.stories.tsx index 0431152ee84..82595b483a6 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/[type]/LeakedPasswords.stories.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/[type]/LeakedPasswords.stories.tsx @@ -81,6 +81,7 @@ const LeakedPasswordsWrapper = (props: { user: mockedSession.user, }} isEligibleForPremium={true} + enabledFeatureFlags={["SetExpectationsForUsers"]} /> ); diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/[type]/page.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/[type]/page.tsx index 172869e238b..a08693bc5d7 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/[type]/page.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/[type]/page.tsx @@ -17,6 +17,7 @@ import { getOnerepProfileId } from "../../../../../../../../../../db/tables/subs import { getLatestOnerepScanResults } from "../../../../../../../../../../db/tables/onerep_scans"; import { isEligibleForPremium } from "../../../../../../../../../functions/server/onerep"; import { logger } from "../../../../../../../../../functions/server/logging"; +import { getEnabledFeatureFlags } from "../../../../../../../../../../db/tables/featureFlags"; interface LeakedPasswordsProps { params: { @@ -60,6 +61,10 @@ export default async function LeakedPasswords({ latestScanData: scanData, }} isEligibleForPremium={isEligibleForPremium(countryCode)} + enabledFeatureFlags={await getEnabledFeatureFlags({ + ignoreAllowlist: false, + email: session.user.email, + })} /> ); } diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/security-recommendations/SecurityRecommendationsLayout.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/security-recommendations/SecurityRecommendationsLayout.tsx index f70a32caf7d..da037c7d9f0 100644 --- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/security-recommendations/SecurityRecommendationsLayout.tsx +++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/security-recommendations/SecurityRecommendationsLayout.tsx @@ -27,12 +27,14 @@ import { BreachBulkResolutionRequest, SecurityRecommendationDataTypes, } from "../../../../../../../../functions/universal/breach"; +import { FeatureFlagName } from "../../../../../../../../../db/tables/featureFlags"; export interface SecurityRecommendationsLayoutProps { type: SecurityRecommendationTypes; subscriberEmails: string[]; data: StepDeterminationData; isEligibleForPremium: boolean; + enabledFeatureFlags: FeatureFlagName[]; } export function SecurityRecommendationsLayout( @@ -157,6 +159,7 @@ export function SecurityRecommendationsLayout( title={title} illustration={illustration} isPremiumUser={hasPremium(props.data.user)} + enabledFeatureFlags={props.enabledFeatureFlags} cta={ !isStepDone && (