From 88e04dabe7ff5103895ebb9ed8b5a2c1f48f704f Mon Sep 17 00:00:00 2001
From: Florian Zia
Date: Tue, 12 Mar 2024 13:59:27 +0100
Subject: [PATCH] chore: Remove deprecated directory
---
.eslintrc.json | 2 -
.stylelintignore | 1 -
src/app/(migration_remnants)/layout.tsx | 1 -
.../HighRiskBreachLayout.tsx | 6 +-
.../leaked-passwords/leakedPasswordsData.tsx | 6 +-
.../SecurityRecommendationsLayout.tsx | 6 +-
src/app/api/v1/scan/route.ts | 2 +-
.../v1/user/breaches/bulk-resolve/route.ts | 2 +-
src/app/api/v1/user/breaches/route.ts | 2 +-
.../exposure_card/ExposureCardDataClass.tsx | 2 +-
.../admin/emails/[template]/page.tsx | 172 ------------
.../(authenticated)/admin/emails/page.tsx | 24 --
.../(authenticated)/admin/layout.tsx | 28 --
.../deprecated/(authenticated)/admin/page.tsx | 20 --
.../admin/send-test-email/route.ts | 121 --------
.../user/breaches/breaches.d.ts | 139 ----------
.../(authenticated)/user/breaches/page.tsx | 187 -------------
.../(authenticated)/user/dashboard/page.tsx | 9 -
.../(authenticated)/user/layout.tsx | 152 ----------
.../(authenticated)/user/settings/page.tsx | 262 ------------------
.../(dialogs)/user/dialog/addEmail/route.ts | 20 --
src/app/deprecated/(guest)/layout.tsx | 121 --------
src/app/deprecated/(guest)/page.tsx | 168 -----------
src/app/deprecated/(guest)/scan/page.tsx | 214 --------------
.../(guest)/user/unsubscribe-monthly/page.tsx | 34 ---
.../client/FalseDoorBanner.module.scss | 116 --------
.../client/FalseDoorBanner.stories.ts | 28 --
.../client/FalseDoorBanner.test.tsx | 33 ---
.../components/client/FalseDoorBanner.tsx | 138 ---------
.../components/client/SignInButton.tsx | 44 ---
.../components/client/SiteNavigation.tsx | 110 --------
.../deprecated/components/client/UserMenu.tsx | 104 -------
.../components/client/assets/shield-icon.svg | 5 -
.../client/assets/shield-outline-icon.svg | 4 -
.../components/server/AddEmailDialog.tsx | 63 -----
.../components/server/BreachesTable.tsx | 228 ---------------
.../functions/server/getComponentAsString.ts | 16 --
.../deprecated/functions/server/getNonce.ts | 11 -
src/app/deprecated/layout.tsx | 61 ----
src/app/functions/server/getBreaches.ts | 2 +-
src/app/functions/universal/breach.ts | 36 ++-
src/app/layout.tsx | 4 +-
42 files changed, 53 insertions(+), 2651 deletions(-)
delete mode 100644 src/app/deprecated/(authenticated)/admin/emails/[template]/page.tsx
delete mode 100644 src/app/deprecated/(authenticated)/admin/emails/page.tsx
delete mode 100644 src/app/deprecated/(authenticated)/admin/layout.tsx
delete mode 100644 src/app/deprecated/(authenticated)/admin/page.tsx
delete mode 100644 src/app/deprecated/(authenticated)/admin/send-test-email/route.ts
delete mode 100644 src/app/deprecated/(authenticated)/user/breaches/breaches.d.ts
delete mode 100644 src/app/deprecated/(authenticated)/user/breaches/page.tsx
delete mode 100644 src/app/deprecated/(authenticated)/user/dashboard/page.tsx
delete mode 100644 src/app/deprecated/(authenticated)/user/layout.tsx
delete mode 100644 src/app/deprecated/(authenticated)/user/settings/page.tsx
delete mode 100644 src/app/deprecated/(dialogs)/user/dialog/addEmail/route.ts
delete mode 100644 src/app/deprecated/(guest)/layout.tsx
delete mode 100644 src/app/deprecated/(guest)/page.tsx
delete mode 100644 src/app/deprecated/(guest)/scan/page.tsx
delete mode 100644 src/app/deprecated/(guest)/user/unsubscribe-monthly/page.tsx
delete mode 100644 src/app/deprecated/components/client/FalseDoorBanner.module.scss
delete mode 100644 src/app/deprecated/components/client/FalseDoorBanner.stories.ts
delete mode 100644 src/app/deprecated/components/client/FalseDoorBanner.test.tsx
delete mode 100644 src/app/deprecated/components/client/FalseDoorBanner.tsx
delete mode 100644 src/app/deprecated/components/client/SignInButton.tsx
delete mode 100644 src/app/deprecated/components/client/SiteNavigation.tsx
delete mode 100644 src/app/deprecated/components/client/UserMenu.tsx
delete mode 100644 src/app/deprecated/components/client/assets/shield-icon.svg
delete mode 100644 src/app/deprecated/components/client/assets/shield-outline-icon.svg
delete mode 100644 src/app/deprecated/components/server/AddEmailDialog.tsx
delete mode 100644 src/app/deprecated/components/server/BreachesTable.tsx
delete mode 100644 src/app/deprecated/functions/server/getComponentAsString.ts
delete mode 100644 src/app/deprecated/functions/server/getNonce.ts
delete mode 100644 src/app/deprecated/layout.tsx
diff --git a/.eslintrc.json b/.eslintrc.json
index cebc0bf3b..9102782ed 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -129,7 +129,6 @@
"src/views/**/*.js",
"src/middleware/**/*.js",
"src/controllers/**/*.js",
- "src/app/deprecated/**/*",
"src/app/(migration_remnants)/**/*",
"src/app/functions/server/breachResolution.ts"
],
@@ -149,7 +148,6 @@
// to avoid a barrage of warnings for older code:
"files": ["**/*.{ts,tsx}"],
"excludedFiles": [
- "./src/app/deprecated/**/*",
"./src/app/(migration_remnants)/**/*"
],
"extends": [
diff --git a/.stylelintignore b/.stylelintignore
index 5aaf7d3f9..dafb5e1bb 100644
--- a/.stylelintignore
+++ b/.stylelintignore
@@ -1,3 +1,2 @@
src/client/
src/app/(nextjs_migration)/
-src/app/deprecated/
diff --git a/src/app/(migration_remnants)/layout.tsx b/src/app/(migration_remnants)/layout.tsx
index 20a36bcf4..6085ddf0f 100644
--- a/src/app/(migration_remnants)/layout.tsx
+++ b/src/app/(migration_remnants)/layout.tsx
@@ -10,7 +10,6 @@ import { HandleFalseDoorTest } from "../deprecated/components/client/FalseDoorBa
import { getCountryCode } from "../functions/server/getCountryCode";
import { headers } from "next/headers";
import AppConstants from "../../appConstants";
-import { getNonce } from "../deprecated/functions/server/getNonce";
import { getEnabledFeatureFlags } from "../../db/tables/featureFlags";
export default async function MigrationLayout({
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 ea8902fc7..4d3c57753 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
@@ -22,8 +22,10 @@ import {
} from "../../../../../../../../functions/server/getRelevantGuidedSteps";
import { getGuidedExperienceBreaches } from "../../../../../../../../functions/universal/guidedExperienceBreaches";
import { hasPremium } from "../../../../../../../../functions/universal/user";
-import { HighRiskDataTypes } from "../../../../../../../../functions/universal/breach";
-import { BreachBulkResolutionRequest } from "../../../../../../../../deprecated/(authenticated)/user/breaches/breaches";
+import {
+ BreachBulkResolutionRequest,
+ HighRiskDataTypes,
+} from "../../../../../../../../functions/universal/breach";
import { TelemetryButton } from "../../../../../../../../components/client/TelemetryButton";
import { TelemetryLink } from "../../../../../../../../components/client/TelemetryLink";
diff --git a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/leakedPasswordsData.tsx b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/leakedPasswordsData.tsx
index 760294a28..4ac7e93ab 100644
--- a/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/leakedPasswordsData.tsx
+++ b/src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/fix/leaked-passwords/leakedPasswordsData.tsx
@@ -10,12 +10,12 @@ import { GuidedExperienceBreaches } from "../../../../../../../../functions/serv
import { ExtendedReactLocalization } from "../../../../../../../../hooks/l10n";
import { Button } from "../../../../../../../../components/client/Button";
import { StepLink } from "../../../../../../../../functions/server/getRelevantGuidedSteps";
+import { getLocale } from "../../../../../../../../functions/universal/getLocale";
+import { TelemetryButton } from "../../../../../../../../components/client/TelemetryButton";
import {
BreachResolutionRequest,
HibpBreachDataTypes,
-} from "../../../../../../../../deprecated/(authenticated)/user/breaches/breaches";
-import { getLocale } from "../../../../../../../../functions/universal/getLocale";
-import { TelemetryButton } from "../../../../../../../../components/client/TelemetryButton";
+} from "../../../../../../../../functions/universal/breach";
export const leakedPasswordTypes = [
"passwords",
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 fefb5d3ef..f70a32caf 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
@@ -23,8 +23,10 @@ import {
} from "../../../../../../../../functions/server/getRelevantGuidedSteps";
import { getGuidedExperienceBreaches } from "../../../../../../../../functions/universal/guidedExperienceBreaches";
import { hasPremium } from "../../../../../../../../functions/universal/user";
-import { SecurityRecommendationDataTypes } from "../../../../../../../../functions/universal/breach";
-import { BreachBulkResolutionRequest } from "../../../../../../../../deprecated/(authenticated)/user/breaches/breaches";
+import {
+ BreachBulkResolutionRequest,
+ SecurityRecommendationDataTypes,
+} from "../../../../../../../../functions/universal/breach";
export interface SecurityRecommendationsLayoutProps {
type: SecurityRecommendationTypes;
diff --git a/src/app/api/v1/scan/route.ts b/src/app/api/v1/scan/route.ts
index 1291a47fd..7f5458a5a 100644
--- a/src/app/api/v1/scan/route.ts
+++ b/src/app/api/v1/scan/route.ts
@@ -9,7 +9,7 @@ import { getBreachesForEmail } from "../../../../utils/hibp";
import { getSha1 } from "../../../../utils/fxa";
import { getL10n } from "../../../functions/server/l10n";
import { getBreachLogo } from "../../../../utils/breachLogo";
-import { Breach } from "../../../deprecated/(authenticated)/user/breaches/breaches";
+import { Breach } from "../../../functions/universal/breach";
export interface RequestBreachScanErrorResponse {
success: false;
diff --git a/src/app/api/v1/user/breaches/bulk-resolve/route.ts b/src/app/api/v1/user/breaches/bulk-resolve/route.ts
index 5bf9d5972..a8cea2cf7 100644
--- a/src/app/api/v1/user/breaches/bulk-resolve/route.ts
+++ b/src/app/api/v1/user/breaches/bulk-resolve/route.ts
@@ -5,13 +5,13 @@
import { NextRequest, NextResponse } from "next/server";
import { getServerSession } from "../../../../../functions/server/getServerSession";
import { logger } from "../../../../../functions/server/logging";
-import { BreachBulkResolutionRequest } from "../../../../../deprecated/(authenticated)/user/breaches/breaches.js";
import { getBreaches } from "../../../../../functions/server/getBreaches";
import { getAllEmailsAndBreaches } from "../../../../../../utils/breaches";
import {
getSubscriberByFxaUid,
setBreachResolution,
} from "../../../../../../db/tables/subscribers";
+import { BreachBulkResolutionRequest } from "../../../../../functions/universal/breach";
export async function PUT(req: NextRequest): Promise {
const session = await getServerSession();
diff --git a/src/app/api/v1/user/breaches/route.ts b/src/app/api/v1/user/breaches/route.ts
index 88daf3493..9d02cd19d 100644
--- a/src/app/api/v1/user/breaches/route.ts
+++ b/src/app/api/v1/user/breaches/route.ts
@@ -6,7 +6,6 @@ import { NextRequest, NextResponse } from "next/server";
import { getToken } from "next-auth/jwt";
import { logger } from "../../../../functions/server/logging";
-import { BreachResolutionRequest } from "../../../../deprecated/(authenticated)/user/breaches/breaches.js";
import { getBreaches } from "../../../../functions/server/getBreaches";
import { getAllEmailsAndBreaches } from "../../../../../utils/breaches";
import {
@@ -14,6 +13,7 @@ import {
setBreachResolution,
} from "../../../../../db/tables/subscribers";
import appConstants from "../../../../../appConstants";
+import { BreachResolutionRequest } from "../../../../functions/universal/breach";
// Get breaches data
export async function GET(req: NextRequest) {
diff --git a/src/app/components/client/exposure_card/ExposureCardDataClass.tsx b/src/app/components/client/exposure_card/ExposureCardDataClass.tsx
index 4006aa6de..bb970ae7e 100644
--- a/src/app/components/client/exposure_card/ExposureCardDataClass.tsx
+++ b/src/app/components/client/exposure_card/ExposureCardDataClass.tsx
@@ -9,7 +9,7 @@ import { OnerepScanResultRow } from "knex/types/tables";
import styles from "./ExposureCard.module.scss";
import { useL10n } from "../../../hooks/l10n";
import { Exposure, isScanResult } from "./ExposureCard";
-import { HibpBreachDataTypes } from "../../../deprecated/(authenticated)/user/breaches/breaches";
+import { HibpBreachDataTypes } from "../../../functions/universal/breach";
type OnerepScanResultSerializedColumns = Extract<
keyof OnerepScanResultRow,
diff --git a/src/app/deprecated/(authenticated)/admin/emails/[template]/page.tsx b/src/app/deprecated/(authenticated)/admin/emails/[template]/page.tsx
deleted file mode 100644
index ccdd5f406..000000000
--- a/src/app/deprecated/(authenticated)/admin/emails/[template]/page.tsx
+++ /dev/null
@@ -1,172 +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/. */
-
-import { redirect } from "next/navigation";
-import Script from "next/script";
-import appConstants from "../../../../../../appConstants";
-import {
- EmailTemplateType,
- getMonthlyDummyData,
- getNotificationDummyData,
- getSignupReportDummyData,
- getVerificationDummyData,
-} from "../../../../../../utils/email";
-import { getPreviewTemplate } from "../../../../../../views/emails/email2022";
-import { verifyPartial } from "../../../../../../views/emails/emailVerify";
-import { breachAlertEmailPartial } from "../../../../../../views/emails/emailBreachAlert";
-import { monthlyUnresolvedEmailPartial } from "../../../../../../views/emails/emailMonthlyUnresolved";
-import { signupReportEmailPartial } from "../../../../../../views/emails/emailSignupReport";
-import { getL10n } from "../../../../../functions/server/l10n";
-import { ReactLocalization } from "@fluent/react";
-import { getNonce } from "../../../../functions/server/getNonce";
-import { getServerSession } from "../../../../../functions/server/getServerSession";
-
-declare global {
- // eslint-disable-next-line @typescript-eslint/no-namespace
- namespace JSX {
- interface IntrinsicElements {
- "custom-select": {
- name: string;
- dangerouslySetInnerHTML: { __html: string };
- };
- }
- }
-}
-
-export default async function EmailTemplatePage(props: {
- params: { template: string };
-}) {
- const session = await getServerSession();
-
- if (!session?.user.email) {
- return redirect("/");
- }
-
- const admins = process.env.ADMINS?.split(",") ?? [];
- // Note: ../layout.tsx currently hides this page for non-admins.
- // Not sure if we actually want to have this available to non-admins as well.
- const isAdminPreview = admins.includes(session.user.email);
- const chosenTemplate =
- Object.values(EmailTemplateType).find((t) => t === props.params.template) ??
- EmailTemplateType.Verification;
- const l10n = getL10n();
- const templates = getTemplatesData(l10n);
- const selectedPreviewTemplate = templates[chosenTemplate].template;
- const recipients = [session.user.email];
- if (appConstants.EMAIL_TEST_RECIPIENT) {
- recipients.push(appConstants.EMAIL_TEST_RECIPIENT);
- }
-
- return (
-
-
-
-
- Email preview
-
-
- {isAdminPreview ? (
-
- ) : null}
-
-
-
-
-
- );
-}
-
-function getTemplatesData(l10n: ReactLocalization) {
- return {
- [EmailTemplateType.Verification]: {
- label: "Email verification",
- template: getPreviewTemplate(
- getVerificationDummyData(appConstants.EMAIL_TEST_RECIPIENT, l10n),
- verifyPartial,
- l10n,
- ),
- },
- [EmailTemplateType.Notification]: {
- label: "Breach notification",
- template: getPreviewTemplate(
- getNotificationDummyData(appConstants.EMAIL_TEST_RECIPIENT, l10n),
- breachAlertEmailPartial,
- l10n,
- ),
- },
- [EmailTemplateType.Monthly]: {
- label: "Monthly unresolved breaches",
- template: getPreviewTemplate(
- getMonthlyDummyData(appConstants.EMAIL_TEST_RECIPIENT, l10n),
- monthlyUnresolvedEmailPartial,
- l10n,
- ),
- },
- [EmailTemplateType.SignupReport]: {
- label: "Signup report",
- template: getPreviewTemplate(
- getSignupReportDummyData(appConstants.EMAIL_TEST_RECIPIENT, l10n),
- signupReportEmailPartial,
- l10n,
- ),
- },
- };
-}
-
-// Transitioning from untyped JS:
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-function getPreviewOptions(currentTemplateKey: string, data: any) {
- const optionsElements = Object.keys(data)
- .map(
- (templateKey) => `
-
- ${data[templateKey].label as string}
-
- `,
- )
- .join("");
-
- return optionsElements;
-}
-
-// Transitioning from untyped JS:
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-function getRecipientInputs(recipients: any[]) {
- const recipientInputElements = recipients.map((recipient, index) => {
- return (
-
-
- {recipient}
-
- );
- });
-
- return {recipientInputElements} ;
-}
diff --git a/src/app/deprecated/(authenticated)/admin/emails/page.tsx b/src/app/deprecated/(authenticated)/admin/emails/page.tsx
deleted file mode 100644
index 2f7e2a839..000000000
--- a/src/app/deprecated/(authenticated)/admin/emails/page.tsx
+++ /dev/null
@@ -1,24 +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/. */
-
-import { notFound, redirect } from "next/navigation";
-import { getServerSession } from "../../../../functions/server/getServerSession";
-import { EmailTemplateType } from "../../../../../utils/email";
-
-export default async function EmailRootPage() {
- const session = await getServerSession();
-
- if (!session?.user.email) {
- return notFound();
- }
-
- const admins = process.env.ADMINS?.split(",") ?? [];
- const isAdmin = admins.includes(session.user.email);
-
- if (!isAdmin) {
- return notFound();
- }
-
- return redirect("./emails/" + EmailTemplateType.Verification);
-}
diff --git a/src/app/deprecated/(authenticated)/admin/layout.tsx b/src/app/deprecated/(authenticated)/admin/layout.tsx
deleted file mode 100644
index bc8b84165..000000000
--- a/src/app/deprecated/(authenticated)/admin/layout.tsx
+++ /dev/null
@@ -1,28 +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/. */
-
-import { ReactNode } from "react";
-import { notFound } from "next/navigation";
-import { getServerSession } from "../../../functions/server/getServerSession";
-
-import "../../../../client/css/index.css";
-export type Props = {
- children: ReactNode;
-};
-
-const AdminLayout = async (props: Props) => {
- const session = await getServerSession();
- const admins = process.env.ADMINS?.split(",") ?? [];
- if (
- !session ||
- typeof session.user.email !== "string" ||
- !admins.includes(session.user.email)
- ) {
- return notFound();
- }
-
- return <>{props.children}>;
-};
-
-export default AdminLayout;
diff --git a/src/app/deprecated/(authenticated)/admin/page.tsx b/src/app/deprecated/(authenticated)/admin/page.tsx
deleted file mode 100644
index 4ec06bc7b..000000000
--- a/src/app/deprecated/(authenticated)/admin/page.tsx
+++ /dev/null
@@ -1,20 +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/. */
-
-export default function AdminPage() {
- return (
-
- );
-}
diff --git a/src/app/deprecated/(authenticated)/admin/send-test-email/route.ts b/src/app/deprecated/(authenticated)/admin/send-test-email/route.ts
deleted file mode 100644
index 0be9a79ed..000000000
--- a/src/app/deprecated/(authenticated)/admin/send-test-email/route.ts
+++ /dev/null
@@ -1,121 +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/. */
-
-import { NextRequest, NextResponse } from "next/server";
-import AppConstants from "../../../../../appConstants.js";
-import { logger } from "../../../../functions/server/logging";
-import {
- EmailTemplateType,
- getMonthlyDummyData,
- getSignupReportDummyData,
- getVerificationDummyData,
- initEmail,
- sendEmail,
-} from "../../../../../utils/email.js";
-import { getTemplate } from "../../../../../views/emails/email2022.js";
-import { getL10n } from "../../../../functions/server/l10n";
-import { verifyPartial } from "../../../../../views/emails/emailVerify.js";
-import { monthlyUnresolvedEmailPartial } from "../../../../../views/emails/emailMonthlyUnresolved.js";
-import { signupReportEmailPartial } from "../../../../../views/emails/emailSignupReport.js";
-
-export async function POST(req: NextRequest) {
- const { emailId, recipient } = (await req.json()) as {
- emailId: string;
- recipient: string;
- };
- const l10n = getL10n();
-
- switch (emailId) {
- case EmailTemplateType.Verification: {
- // Send test verification email
- const emailTemplate = getTemplate(
- getVerificationDummyData(recipient, l10n),
- verifyPartial,
- l10n,
- );
- await initEmail(process.env.SMTP_URL);
- await sendEmail(
- recipient,
- l10n.getString("email-subject-verify"),
- emailTemplate,
- );
- break;
- }
- case EmailTemplateType.Notification: {
- // Send test breach notification email
- await sendTestNotification(req, new NextResponse());
- break;
- }
- case EmailTemplateType.Monthly: {
- // Send test monthly unresolved breaches email
- const emailTemplate = getTemplate(
- getMonthlyDummyData(AppConstants.EMAIL_TEST_RECIPIENT, l10n),
- monthlyUnresolvedEmailPartial,
- l10n,
- );
- await initEmail(process.env.SMTP_URL);
- await sendEmail(
- recipient,
- l10n.getString("email-unresolved-heading"),
- emailTemplate,
- );
- break;
- }
- case EmailTemplateType.SignupReport: {
- // Send test sign-up report email
- const emailTemplate = getTemplate(
- getSignupReportDummyData(AppConstants.EMAIL_TEST_RECIPIENT, l10n),
- signupReportEmailPartial,
- l10n,
- );
- await initEmail(process.env.SMTP_URL);
- await sendEmail(
- recipient,
- l10n.getString("email-subject-found-breaches"),
- emailTemplate,
- );
- break;
- }
- default: {
- throw new Error(`No test email found for ${emailId}`);
- }
- }
-
- logger.info(`Sent test email: ${emailId}`);
-
- // The notify function has its own response
- if (emailId !== EmailTemplateType.Notification) {
- return NextResponse.json(
- { success: true, message: `Sent test ${emailId} email` },
- { status: 200 },
- );
- }
-}
-
-// Leaving the `async` for now because of the commented-out `await`:
-// eslint-disable-next-line @typescript-eslint/require-await
-async function sendTestNotification(_req: NextRequest, _res: NextResponse) {
- // The test breach notification can be viewed in the public Mailinator inbox
- // as documented in the README:
- // https://github.com/mozilla/blurts-server#trigger-breach-alert-email
- const _breachNotificationData = {
- breachName: "Adobe",
- // Hash for dummy email `localmonitor20200827@mailinator.com`
- hashPrefix: "365050",
- hashSuffixes: ["53cbb89874fc738c0512daf12bc4d91765"],
- };
-
- // TODO Disabled for now; not sure yet how to trigger this with the functionality
- // moved to a Cloud Function.
- // const notifyReq = {
- // app: req.app,
- // body: {
- // ...req.body,
- // ...breachNotificationData,
- // },
- // token: AppConstants.HIBP_NOTIFY_TOKEN,
- // };
-
- // await notify(notifyReq, res);
-}
diff --git a/src/app/deprecated/(authenticated)/user/breaches/breaches.d.ts b/src/app/deprecated/(authenticated)/user/breaches/breaches.d.ts
deleted file mode 100644
index 638c7c1d5..000000000
--- a/src/app/deprecated/(authenticated)/user/breaches/breaches.d.ts
+++ /dev/null
@@ -1,139 +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/. */
-
-import { BreachDataTypes } from "../../../../functions/universal/breach.js";
-
-export type BreachResolutionTypes = Record<
- keyof BreachDataTypes,
- BreachResolution
->;
-export interface CircleChartProps
- extends React.DetailedHTMLProps<
- React.HTMLAttributes,
- HTMLElement
- > {
- class?: string;
- title?: string;
- "data-txt-other"?: string;
- "data-txt-none"?: string;
- data?: string;
-}
-
-export type HibpBreachDataTypes = typeof BreachDataTypes;
-
-export interface BreachResolution {
- priority: number;
- header: string;
- body?: string;
- applicableCountryCodes?: Array;
-}
-
-export interface SubscriberEmail {
- email: string;
- id: number;
-}
-
-export interface BreachStats {
- monitoredEmails: {
- count: number;
- };
- numBreaches: {
- count: number;
- numResolved: number;
- numUnresolved: number;
- };
- passwords: {
- count: number;
- numResolved: number;
- };
-}
-
-export interface SubscriberBreachResolution {
- useBreachId?: boolean;
- [email: string]: {
- [id: number]: {
- resolutionsChecked: Array;
- };
- };
-}
-
-export interface Breach {
- AddedDate: string;
- BreachDate: string;
- DataClasses: Array;
- Description: string;
- Domain: string;
- Id: number;
- IsFabricated: boolean;
- IsMalware: boolean;
- IsResolved?: boolean;
- IsRetired: boolean;
- IsSensitive: boolean;
- IsSpamList: boolean;
- IsVerified: boolean;
- LogoPath: string;
- ModifiedDate: string;
- Name: string;
- PwnCount: number;
- recencyIndex: number;
- ResolutionsChecked: Array;
- Title: string;
-}
-
-/**
- * @deprecated Use {@see SubscriberRow} instead
- */
-export interface Subscriber {
- id: number;
- primary_sha1: string;
- primary_email: string;
- primary_verification_token: string;
- primary_verified: boolean;
- created_at: Date;
- updated_at: Date;
- fx_newsletter: boolean;
- signup_language: string;
- fxa_refresh_token: string;
- fxa_profile_json: {
- uid: string;
- email: string;
- avatar: string;
- locale: string;
- amrValues: Array;
- avatarDefault: boolean;
- metricsEnabled: boolean;
- twoFactorAuthentication: boolean;
- };
- fxa_uid: string;
- breaches_last_shown: Date;
- all_emails_to_primary: boolean;
- fxa_access_token: string;
- breaches_resolved: {
- [email: string]: Array;
- };
- waitlists_joined: boolean | null;
- breach_stats: BreachStats;
- monthly_email_at: Date | null;
- monthly_email_optout: boolean | null;
- breach_resolution: SubscriberBreachResolution;
- email_addresses: Array;
-}
-
-export interface VerifiedEmail {
- breaches: Array;
- email: string;
- id: number;
- primary: boolean;
- verified: boolean;
-}
-
-export interface BreachResolutionRequest {
- affectedEmail: string;
- breachId: number;
- resolutionsChecked: Array;
-}
-
-export interface BreachBulkResolutionRequest {
- dataType: BreachDataTypes;
-}
diff --git a/src/app/deprecated/(authenticated)/user/breaches/page.tsx b/src/app/deprecated/(authenticated)/user/breaches/page.tsx
deleted file mode 100644
index 8336e5fd2..000000000
--- a/src/app/deprecated/(authenticated)/user/breaches/page.tsx
+++ /dev/null
@@ -1,187 +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/. */
-
-import Image from "next/image";
-import Script from "next/script";
-import { headers } from "next/headers";
-import { getServerSession } from "../../../../functions/server/getServerSession";
-import { CircleChartProps } from "./breaches.d";
-
-import { getL10n } from "../../../../functions/server/l10n";
-import {
- getUserBreaches,
- type UserBreaches as UserBreachesType,
-} from "../../../../functions/server/getUserBreaches";
-
-import "../../../../../client/css/partials/breaches.css";
-import ImageIconEmail from "../../../../../client/images/icon-email.svg";
-
-import { BreachesTable } from "../../../components/server/BreachesTable";
-import { getComponentAsString } from "../../../functions/server/getComponentAsString";
-import { getCountryCode } from "../../../../functions/server/getCountryCode";
-import { getNonce } from "../../../functions/server/getNonce";
-import { SignInButton } from "../../../components/client/SignInButton";
-import { CONST_MAX_NUM_ADDRESSES } from "../../../../../constants";
-
-export function generateMetadata() {
- const l10n = getL10n();
- return {
- title: l10n.getString("breach-meta-title"),
- twitter: {
- card: "summary_large_image",
- title: l10n.getString("brand-mozilla-monitor"),
- description: l10n.getString("meta-desc-2"),
- images: ["/images/og-image.webp"],
- },
- openGraph: {
- title: l10n.getString("brand-mozilla-monitor"),
- description: l10n.getString("meta-desc-2"),
- siteName: l10n.getString("brand-mozilla-monitor"),
- type: "website",
- url: process.env.SERVER_URL,
- images: ["/images/og-image.webp"],
- },
- };
-}
-
-function createEmailOptions({
- breachesData,
- emailSelectIndex,
-}: UserBreachesType) {
- const emails = breachesData.verifiedEmails.map((obj) => obj.email);
- const optionElements = emails.map(
- (email, index) =>
- `${email} `,
- );
-
- return optionElements.join("");
-}
-
-declare global {
- // eslint-disable-next-line @typescript-eslint/no-namespace
- namespace JSX {
- interface IntrinsicElements {
- "circle-chart": CircleChartProps;
- }
- }
-}
-
-export default async function UserBreaches() {
- const session = await getServerSession();
- if (!session?.user?.subscriber) {
- return ;
- }
-
- const l10n = getL10n();
- const headerList = headers();
-
- const userBreachesData: UserBreachesType = await getUserBreaches({
- user: session.user,
- options: {
- countryCode: getCountryCode(headerList),
- },
- });
-
- return (
- <>
- {/* These scripts predate the use of React and thus shouldn’t wait for
- hydration to adjust the layout. */}
- {/* eslint-disable @next/next/no-sync-scripts */}
-
-
-
- {/* eslint-enable @next/next/no-sync-scripts */}
-
-
-
-
-
- ${createEmailOptions(
- userBreachesData,
- )}`,
- }),
- }}
- />
-
-
-
-
-
-
-
- {l10n.getString("emails-monitored", {
- count: userBreachesData.emailVerifiedCount,
- total: CONST_MAX_NUM_ADDRESSES,
- })}
-
-
- {l10n.getString("manage-emails-link")}
-
-
-
-
-
-
-
,
- }),
- }}
- />
-
- >
- );
-}
diff --git a/src/app/deprecated/(authenticated)/user/dashboard/page.tsx b/src/app/deprecated/(authenticated)/user/dashboard/page.tsx
deleted file mode 100644
index 4f3d3271b..000000000
--- a/src/app/deprecated/(authenticated)/user/dashboard/page.tsx
+++ /dev/null
@@ -1,9 +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/. */
-
-import { redirect } from "next/navigation";
-
-export default function UserDashboard() {
- redirect("/user/breaches");
-}
diff --git a/src/app/deprecated/(authenticated)/user/layout.tsx b/src/app/deprecated/(authenticated)/user/layout.tsx
deleted file mode 100644
index 66dd56a1f..000000000
--- a/src/app/deprecated/(authenticated)/user/layout.tsx
+++ /dev/null
@@ -1,152 +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/. */
-
-import { ReactNode } from "react";
-import Image from "next/image";
-import Script from "next/script";
-
-import { logger } from "../../../functions/server/logging";
-import "../../../../client/css/index.css";
-import { UserMenu } from "../../components/client/UserMenu";
-import { SignInButton } from "../../components/client/SignInButton";
-import { SiteNavigation } from "../../components/client/SiteNavigation";
-import AppConstants from "../../../../appConstants.js";
-import MonitorLogo from "../../../../client/images/monitor-logo-transparent@2x.webp";
-import MozillaLogo from "../../../../client/images/moz-logo-1color-white-rgb-01.svg";
-import { getL10n } from "../../../functions/server/l10n";
-import { getNonce } from "../../functions/server/getNonce";
-import { PageLoadEvent } from "../../../components/client/PageLoadEvent";
-import { getExperiments } from "../../../functions/server/getExperiments";
-import { getEnabledFeatureFlags } from "../../../../db/tables/featureFlags";
-import { getServerSession } from "../../../functions/server/getServerSession";
-
-export type Props = {
- children: ReactNode;
-};
-
-const MainLayout = async (props: Props) => {
- const session = await getServerSession();
- if (!session?.user?.subscriber) {
- return ;
- }
-
- const userId = session.user.subscriber.fxa_uid ?? "";
-
- if (!userId) {
- logger.error("No user ID for telemetry");
- }
-
- try {
- // TODO For initial A/A testing `features` is unused. https://mozilla-hub.atlassian.net/browse/MNTOR-2182
- const features = await getExperiments(userId);
- // TODO remove debug for A/A testing https://mozilla-hub.atlassian.net/browse/MNTOR-2182
- logger.debug("Nimbus features in authenticated session:", features);
- } catch (ex) {
- logger.error("Could not fetch Nimbus features:", ex);
- }
-
- const l10n = getL10n();
- const enabledFeatureFlags = await getEnabledFeatureFlags({
- email: session.user.email,
- });
-
- return (
- <>
-
-
-
-
-
-
- {props.children}
-
-
- >
- );
-};
-
-export default MainLayout;
diff --git a/src/app/deprecated/(authenticated)/user/settings/page.tsx b/src/app/deprecated/(authenticated)/user/settings/page.tsx
deleted file mode 100644
index 7786eff6d..000000000
--- a/src/app/deprecated/(authenticated)/user/settings/page.tsx
+++ /dev/null
@@ -1,262 +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/. */
-
-import { redirect } from "next/navigation";
-import Image from "next/image";
-import Script from "next/script";
-import { EmailAddressRow } from "knex/types/tables";
-import AppConstants from "../../../../../appConstants";
-import { getL10n } from "../../../../functions/server/l10n";
-import ImageIconDelete from "../../../../../client/images/icon-delete.svg";
-import "../../../../../client/css/partials/settings.css";
-import React from "react";
-import { getUserEmails } from "../../../../../db/tables/emailAddresses";
-import { getBreaches } from "../../../../functions/server/getBreaches";
-import { getBreachesForEmail } from "../../../../../utils/hibp";
-import { getSha1 } from "../../../../../utils/fxa";
-import { getSubscriberById } from "../../../../../db/tables/subscribers";
-import { getNonce } from "../../../functions/server/getNonce";
-import { CONST_MAX_NUM_ADDRESSES } from "../../../../../constants";
-import { getServerSession } from "../../../../functions/server/getServerSession";
-
-const emailNeedsVerificationSub = (email: EmailAddressRow) => {
- const l10n = getL10n();
-
- return (
- <>
-
- {l10n.getString("settings-email-verification-callout")}
-
-
-
- {l10n.getString("settings-resend-email-verification-link")}
-
- >
- );
-};
-
-const deleteButton = (email: EmailAddressRow) => {
- const l10n = getL10n();
-
- return (
-
-
-
- );
-};
-
-const createEmailItem = (
- email: EmailAddressRow & { primary?: boolean },
- breachCounts: Map,
-) => {
- const l10n = getL10n();
-
- return (
-
-
- {email.primary
- ? l10n.getString("settings-email-label-primary", {
- email: email.email,
- })
- : email.email}
-
- {email.verified
- ? l10n.getString("settings-email-number-of-breaches-info", {
- breachCount: breachCounts.get(email.email)!,
- })
- : emailNeedsVerificationSub(email)}
- {email.primary ? null : deleteButton(email)}
-
- );
-};
-
-// Moves the primary email to the front and sorts the rest alphabeticaly.
-const getSortedEmails = (
- emails: Array,
-) =>
- [...emails].sort((a, b) => {
- if (a.primary) {
- return -1;
- }
-
- if (b.primary) {
- return 1;
- }
-
- return a.email.localeCompare(b.email);
- });
-
-const createEmailList = (
- emails: EmailAddressRow[],
- breachCounts: Map,
-) => {
- return (
-
- {getSortedEmails(emails).map((email) =>
- createEmailItem(email, breachCounts),
- )}
-
- );
-};
-
-const alertOptions = ({
- allEmailsToPrimary,
-}: {
- allEmailsToPrimary: boolean;
-}) => {
- const l10n = getL10n();
-
- return (
-
-
-
-
- {l10n.getString("settings-alert-preferences-option-one")}
-
-
-
-
-
-
- {l10n.getString("settings-alert-preferences-option-two")}
-
-
-
- );
-};
-
-export default async function Settings() {
- const l10n = getL10n();
- const session = await getServerSession();
- if (!session || !session.user?.subscriber) {
- return redirect("/");
- }
-
- // Re-fetch the subscriber every time, rather than reading it from `session`
- // - if the user changes their preferences on this page, the JSON web token
- // containing the subscriber data won't be updated until the next sign-in.
- // (Possibly we shouldn't store subscriber data in that token in the first
- // place, other than their ID?)
- const subscriber = await getSubscriberById(session.user.subscriber.id);
- const emails = await getUserEmails(session.user.subscriber.id);
- // Add primary subscriber email to the list
- emails.push({
- email: session.user.subscriber.primary_email,
- sha1: session.user.subscriber.primary_sha1,
- primary: true,
- verified: true,
- // This is old code that mixed objects with different structure in the same
- // array, hence the need to assert `any`:
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- } as any);
-
- const breachCounts = new Map();
- const allBreaches = await getBreaches();
- for (const email of emails) {
- const breaches = await getBreachesForEmail(
- getSha1(email.email),
- allBreaches,
- true,
- );
- breachCounts.set(email.email, breaches?.length || 0);
- }
-
- return (
- <>
-
-
-
-
-
- {l10n.getString("settings-page-title")}
-
-
-
- {/* Monitored email addresses */}
-
-
- {l10n.getString("settings-email-list-title")}
-
-
- {l10n.getString("settings-email-limit-info", {
- limit: CONST_MAX_NUM_ADDRESSES,
- })}
-
-
- {createEmailList(emails, breachCounts)}
- = CONST_MAX_NUM_ADDRESSES}
- >
- {l10n.getString("settings-add-email-button")}
-
-
-
-
-
- {/* Breach alert preferences */}
-
-
- {l10n.getString("settings-alert-preferences-title")}
-
- {alertOptions({
- allEmailsToPrimary: subscriber.all_emails_to_primary,
- })}
-
-
-
-
- {/* Deactivate account */}
-
-
-
-
- >
- );
-}
diff --git a/src/app/deprecated/(dialogs)/user/dialog/addEmail/route.ts b/src/app/deprecated/(dialogs)/user/dialog/addEmail/route.ts
deleted file mode 100644
index 8acc45f72..000000000
--- a/src/app/deprecated/(dialogs)/user/dialog/addEmail/route.ts
+++ /dev/null
@@ -1,20 +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/. */
-
-import { NextResponse } from "next/server";
-
-import { getComponentAsString } from "../../../../functions/server/getComponentAsString";
-import AddEmailDialog from "../../../../components/server/AddEmailDialog";
-
-export async function GET() {
- try {
- const dialogContentString = await getComponentAsString({
- component: AddEmailDialog(),
- });
-
- return new NextResponse(dialogContentString, { status: 200 });
- } catch (e) {
- return NextResponse.json({ success: false }, { status: 500 });
- }
-}
diff --git a/src/app/deprecated/(guest)/layout.tsx b/src/app/deprecated/(guest)/layout.tsx
deleted file mode 100644
index 80d51e170..000000000
--- a/src/app/deprecated/(guest)/layout.tsx
+++ /dev/null
@@ -1,121 +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/. */
-
-import { v5 as uuidv5 } from "uuid";
-import { ReactNode } from "react";
-
-import { logger } from "../../functions/server/logging";
-import "../../../client/css/index.css";
-import Image from "next/image";
-import MonitorLogo from "../../../client/images/monitor-logo-transparent@2x.webp";
-import MozillaLogo from "../../../client/images/moz-logo-1color-white-rgb-01.svg";
-import { SignInButton } from "../components/client/SignInButton";
-import { getL10n } from "../../functions/server/l10n";
-import { getServerSession } from "../../functions/server/getServerSession";
-import { PageLoadEvent } from "../../components/client/PageLoadEvent";
-import { getExperiments } from "../../functions/server/getExperiments";
-import { getEnabledFeatureFlags } from "../../../db/tables/featureFlags";
-import { getUserId } from "../../functions/server/getUserId";
-
-export type Props = {
- children: ReactNode;
-};
-
-const GuestLayout = async (props: Props) => {
- const l10n = getL10n();
-
- // If the user is logged in, use UUID derived from FxA UID as Nimbus user ID.
- const session = await getServerSession();
- const userId = getUserId(session);
-
- if (!userId) {
- logger.error("No user ID for Nimbus telemetry");
- }
-
- try {
- // TODO For initial A/A testing `features` is unused. https://mozilla-hub.atlassian.net/browse/MNTOR-2182
- const features = await getExperiments(userId);
- // TODO remove debug for A/A testing https://mozilla-hub.atlassian.net/browse/MNTOR-2182
- logger.debug("Nimbus features in guest session:", features);
- } catch (ex) {
- logger.error("Could not fetch Nimbus features:", ex);
- }
-
- const enabledFlags = await getEnabledFeatureFlags({
- email: session?.user.email ?? "",
- });
-
- return (
- <>
-
-
- {props.children}
-
- >
- );
-};
-
-export default GuestLayout;
diff --git a/src/app/deprecated/(guest)/page.tsx b/src/app/deprecated/(guest)/page.tsx
deleted file mode 100644
index 6d6ca0e6a..000000000
--- a/src/app/deprecated/(guest)/page.tsx
+++ /dev/null
@@ -1,168 +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/. */
-
-import Image from "next/image";
-import Script from "next/script";
-import "../../../client/css/partials/landing.css";
-import { getL10n } from "../../functions/server/l10n";
-
-import HeroImage from "../../../client/images/landing-hero@2x.webp";
-import LaptopImage from "../../../client/images/landing-laptop@2x.webp";
-import LockImage from "../../../client/images/landing-lock@2x.webp";
-import MailImage from "../../../client/images/landing-mail@2x.webp";
-import NaturePhoneImage from "../../../client/images/landing-nature-phone@2x.webp";
-import { getNonce } from "../functions/server/getNonce";
-
-export default function Home() {
- const l10n = getL10n();
-
- return (
-
- {/* These scripts predate the use of React and thus shouldn’t wait for
- hydration to adjust the layout. */}
- {/* eslint-disable @next/next/no-sync-scripts */}
-
-
-
-
-
{l10n.getString("exposure-landing-hero-heading")}
-
{l10n.getString("exposure-landing-hero-lead")}
-
-
-
-
-
-
-
-
- {l10n.getString("why-use-monitor")}
- {l10n.getString("identifying-breaches")}
-
-
- {l10n.getString("protect-account")}
- {l10n.getString("protect-account-prevent-hackers")}
-
-
- {l10n.getString("prevent-fraud")}
- {l10n.getString("prevent-fraud-keep-info")}
-
-
- {l10n.getString("get-alerts")}
- {l10n.getString("get-alerts-find-out")}
-
-
-
-
-
- {l10n.getString("how-it-works")}
-
-
-
- {l10n.getString("check-for-breaches")}
- {l10n.getString("check-for-breaches-we-search")}
-
-
-
- {l10n.getString("protect-accounts")}
- {l10n.getString("protect-accounts-clear-steps")}
-
-
-
- {l10n.getString("alerts-for-breaches")}
- {l10n.getString("alerts-for-breaches-monitor-new")}
-
-
-
-
-
-
-
-
-
-
- {l10n.getString("what-is-breach")}
- {l10n.getString("when-info-exposed")}
-
-
- {l10n.getString("what-do-i-do")}
- {l10n.getString("visit-monitor-to-learn")}
-
-
- {l10n.getString("what-gets-exposed")}
- {l10n.getString("depends-on-hackers")}
-
-
-
-
-
-
- );
-}
diff --git a/src/app/deprecated/(guest)/scan/page.tsx b/src/app/deprecated/(guest)/scan/page.tsx
deleted file mode 100644
index 2d85fc017..000000000
--- a/src/app/deprecated/(guest)/scan/page.tsx
+++ /dev/null
@@ -1,214 +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/. */
-
-import Script from "next/script";
-import "../../../../client/css/partials/exposureScan.css";
-import Image from "next/image";
-import HeroImage from "../../../../client/images/exposure-scan-hero.svg";
-import NoBreachesImage from "../../../../client/images/breaches-none.svg";
-import { getL10n } from "../../../functions/server/l10n";
-import { getNonce } from "../../functions/server/getNonce";
-
-export function generateMetadata() {
- const l10n = getL10n();
- return {
- title: l10n.getString("breach-scan-meta-title"),
- };
-}
-
-export default function PublicScan() {
- const l10n = getL10n();
-
- return (
-
-
-
-
- {l10n.getString("exposure-landing-result-loading")}
-
-
- {l10n.getString("exposure-landing-result-error")}
-
-
-
- ${
- /* The company logo and name will be added client-side, after running the scan */ ""
- }
-
-
-
-
-
-
-
${l10n.getString(
- "exposure-landing-result-card-added",
- )}
- ${
- /* The added date will be added client-side, after running the scan */ ""
- }
-
-
-
-
${l10n.getString(
- "exposure-landing-result-card-data",
- )}
- ${
- /* The breached data will be added client-side, after running the scan */ ""
- }
-
-
-
-
-
- `,
- }}
- />
-
-
-
-
-
-
-
- {l10n.getString("exposure-landing-result-card-nothing")}
-
-
-
-
-
- );
-}
diff --git a/src/app/deprecated/(guest)/user/unsubscribe-monthly/page.tsx b/src/app/deprecated/(guest)/user/unsubscribe-monthly/page.tsx
deleted file mode 100644
index 257f01f49..000000000
--- a/src/app/deprecated/(guest)/user/unsubscribe-monthly/page.tsx
+++ /dev/null
@@ -1,34 +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/. */
-
-import { redirect } from "next/navigation";
-import { updateMonthlyEmailOptout } from "../../../../../db/tables/subscribers";
-import { getL10n } from "../../../../functions/server/l10n";
-
-export default async function UnsubscribeMonthly(props: {
- searchParams: { [key: string]: string | string[] | undefined };
-}) {
- const token = props.searchParams.token;
- if (typeof token !== "string") {
- return redirect("/");
- }
- try {
- await updateMonthlyEmailOptout(token);
- } catch (error) {
- console.log(error);
- return redirect("/");
- }
- const l10n = getL10n();
-
- return (
-
-
-
- {l10n.getString("changes-saved")}
-
-
- );
-}
diff --git a/src/app/deprecated/components/client/FalseDoorBanner.module.scss b/src/app/deprecated/components/client/FalseDoorBanner.module.scss
deleted file mode 100644
index 070a8e143..000000000
--- a/src/app/deprecated/components/client/FalseDoorBanner.module.scss
+++ /dev/null
@@ -1,116 +0,0 @@
-@import "../../../tokens";
-
-.falseDoorTestWrapper {
- font: $text-body-md;
- position: fixed;
- bottom: 0;
- left: 0;
- // Overlap all regular content on the site with a z-index,
- // except for ModalOverlay which, at the time of writing, has a z-index of 2
- z-index: 1;
- width: 100%;
- background-color: #ffdff0;
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- gap: $spacing-xl;
- padding-inline: $spacing-sm;
- padding-block: $spacing-md;
-
- @media screen and (min-width: $screen-lg) {
- padding-inline: $spacing-2xl;
- padding-block: $spacing-md;
- }
-
- .dismiss {
- right: $spacing-sm;
- position: absolute;
- color: $color-grey-40;
-
- @media screen and (min-width: $screen-lg) {
- align-self: flex-start;
- margin-left: auto;
- position: static;
- right: 0;
- }
-
- &:focus {
- border: 1px solid $color-informational-active;
- outline: $border-focus-width solid $color-informational-focus;
- }
- }
-
- .content {
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- gap: $spacing-md;
- width: 100%;
- justify-content: center;
- padding-block: $spacing-sm;
- padding-inline: $spacing-sm;
- text-align: center;
-
- @media screen and (min-width: $screen-sm) {
- padding-inline: $spacing-xl;
- }
-
- @media screen and (min-width: $screen-md) {
- display: grid;
- text-align: start;
- grid-template-columns: 1fr 3fr 1fr;
- padding-inline: $spacing-lg;
-
- @media screen and (min-width: $screen-xl) {
- gap: $spacing-lg;
- padding: $spacing-sm $layout-2xl;
- }
- }
-
- .logoWrapper {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 100%;
-
- @media screen and (min-width: $screen-md) {
- width: auto;
- }
-
- @media screen and (min-width: $screen-lg) {
- padding-inline: $spacing-xl;
- }
-
- .logo {
- max-width: 200px; // Width of the Mozilla Monitor logo
- }
- }
-
- p {
- margin: 0;
- }
-
- .cta {
- text-decoration: none;
- padding-inline: $spacing-xl;
- padding-block: $spacing-sm;
- background: $color-blue-50;
- font-weight: 600;
- justify-content: center;
- color: $color-white;
- border-radius: $border-radius-xs;
- cursor: pointer;
- text-align: center;
- width: 150px; // Width of the CTA
-
- &:focus {
- outline: $border-focus-width solid $color-blue-30;
- }
-
- @media screen and (min-width: $screen-lg) {
- margin-left: auto;
- width: 200px; // Width of the CTA
- }
- }
- }
-}
diff --git a/src/app/deprecated/components/client/FalseDoorBanner.stories.ts b/src/app/deprecated/components/client/FalseDoorBanner.stories.ts
deleted file mode 100644
index 6d0eaa4a7..000000000
--- a/src/app/deprecated/components/client/FalseDoorBanner.stories.ts
+++ /dev/null
@@ -1,28 +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/. */
-
-import type { Meta, StoryObj } from "@storybook/react";
-import { FalseDoorBanner } from "./FalseDoorBanner";
-
-// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
-const meta: Meta = {
- title: "False Door Banner",
- component: FalseDoorBanner,
-};
-export default meta;
-type Story = StoryObj;
-
-export const FalseDoorBannerDashboard: Story = {
- args: {
- checkIsOnDashboard: true,
- link: "example.com",
- },
-};
-
-export const FalseDoorBannerDefault: Story = {
- args: {
- checkIsOnDashboard: false,
- link: "example.com",
- },
-};
diff --git a/src/app/deprecated/components/client/FalseDoorBanner.test.tsx b/src/app/deprecated/components/client/FalseDoorBanner.test.tsx
deleted file mode 100644
index 6eec72ca1..000000000
--- a/src/app/deprecated/components/client/FalseDoorBanner.test.tsx
+++ /dev/null
@@ -1,33 +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/. */
-
-import { render, screen } from "@testing-library/react";
-import { it, expect } from "@jest/globals";
-import { composeStory } from "@storybook/react";
-import Meta, {
- FalseDoorBannerDashboard,
- FalseDoorBannerDefault,
-} from "./FalseDoorBanner.stories";
-
-it("shows false door test variant on dashboard", () => {
- const ComposedFalseDoorBanner = composeStory(FalseDoorBannerDashboard, Meta);
- render( );
- // substring match https://testing-library.com/docs/queries/about/#textmatch
- const bannerElem = screen.getByText(
- "Automatically remove data from broker sites with",
- { exact: false },
- );
- expect(bannerElem).toBeInTheDocument();
-});
-
-it("shows false door test", () => {
- const ComposedFalseDoorBanner = composeStory(FalseDoorBannerDefault, Meta);
- render( );
- // substring match https://testing-library.com/docs/queries/about/#textmatch
- const bannerElem = screen.getByText(
- "Automatically remove data from sketchy sites with",
- { exact: false },
- );
- expect(bannerElem).toBeInTheDocument();
-});
diff --git a/src/app/deprecated/components/client/FalseDoorBanner.tsx b/src/app/deprecated/components/client/FalseDoorBanner.tsx
deleted file mode 100644
index c8f707b82..000000000
--- a/src/app/deprecated/components/client/FalseDoorBanner.tsx
+++ /dev/null
@@ -1,138 +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/. */
-
-"use client";
-
-import Image from "next/image";
-import MozillaMonitorLogo from "../../../(proper_react)/images/monitor-logo.webp";
-import styles from "./FalseDoorBanner.module.scss";
-import { CloseBtn } from "../../../components/server/Icons";
-import { useEffect, useState } from "react";
-import { useCookies } from "react-cookie";
-import { useL10n } from "../../../hooks/l10n";
-import Link from "next/link";
-import { usePathname } from "next/navigation";
-import { appendUtmParams } from "../../../../utils/utmParams";
-
-type HandleFalseDoorBanner = {
- link: string;
-};
-
-// Ignoring full coverage here because we'll be creating a custom cookies hook
-// TODO: MNTOR-2043
-/* c8 ignore start */
-export const HandleFalseDoorTest = (props: HandleFalseDoorBanner) => {
- const [cookies, setCookie] = useCookies(["falseDoorDismissedPhase3"]);
- const [shouldShowFalseDoor, setShouldShowFalseDoor] = useState(false);
- const pathname = usePathname();
- const isOnDashboard = pathname === "/user/breaches";
-
- const waitlistLink = appendUtmParams({
- linkUrl: props.link,
- utmParams: {
- utm_source: "monitor",
- utm_medium: "monitor-product",
- utm_content: `banner-phase-3-us_${pathname}`,
- },
- });
-
- const handleDismiss = (event?: Event) => {
- setCookie("falseDoorDismissedPhase3", "true", { path: "/" });
- if (event && event.target && "id" in event.target) {
- let action;
- if (event?.target.id === "close-button") {
- action = "dismissed";
- } else {
- action = "opened";
- }
- window.gtag("event", "clicked_false_door", {
- action,
- result: "success",
- page_location: location.href,
- });
- }
- };
-
- useEffect(() => {
- setShouldShowFalseDoor(!cookies.falseDoorDismissedPhase3);
- }, [cookies.falseDoorDismissedPhase3]);
-
- return (
- <>
- {shouldShowFalseDoor && (
-
- )}
- >
- );
-};
-
-type FalseDoorBanner = {
- onDismiss?: () => void;
- checkIsOnDashboard: boolean;
- link: string;
-};
-export const FalseDoorBanner = (props: FalseDoorBanner) => {
- const l10n = useL10n();
- const [isLargeScreen, setIsLargeScreen] = useState(false);
-
- const handleResize = () => {
- // 1024px is equivalent to $screen-lg
- if (window.innerWidth > 1024) {
- setIsLargeScreen(true);
- } else {
- setIsLargeScreen(false);
- }
- };
-
- useEffect(() => {
- window.addEventListener("resize", handleResize);
- });
-
- const content = (
-
- {l10n.getString("false-door-test-phase-3-content-part-one")}
- {isLargeScreen ? : " "}
- {props.checkIsOnDashboard
- ? l10n.getString("false-door-test-phase-3-content-part-two-dashboard")
- : l10n.getString("false-door-test-phase-3-content-part-two")}
-
- );
- /* c8 ignore stop */
-
- return (
-
-
-
-
-
- {content}
-
- {l10n.getString("false-door-test-cta")}
-
-
-
-
-
-
- );
-};
diff --git a/src/app/deprecated/components/client/SignInButton.tsx b/src/app/deprecated/components/client/SignInButton.tsx
deleted file mode 100644
index 9162580d3..000000000
--- a/src/app/deprecated/components/client/SignInButton.tsx
+++ /dev/null
@@ -1,44 +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/. */
-
-"use client";
-
-import { signIn } from "next-auth/react";
-import { usePathname } from "next/navigation";
-import { useL10n } from "../../../hooks/l10n";
-import { useEffect } from "react";
-
-export type Props = {
- autoSignIn?: boolean;
-};
-
-function initSignIn(callbackUrl: string) {
- void signIn("fxa", { callbackUrl });
-}
-
-export const SignInButton = ({ autoSignIn }: Props) => {
- const l10n = useL10n();
- const pathname = usePathname();
- const callbackUrl = pathname === "/" ? "/user/breaches" : pathname;
-
- useEffect(() => {
- if (autoSignIn) {
- initSignIn(callbackUrl);
- }
- }, [autoSignIn, callbackUrl]);
-
- if (autoSignIn) {
- return null;
- }
-
- return (
- initSignIn(callbackUrl)}
- data-cta-id="sign-in-1"
- className="button secondary"
- >
- {l10n.getString("sign-in")}
-
- );
-};
diff --git a/src/app/deprecated/components/client/SiteNavigation.tsx b/src/app/deprecated/components/client/SiteNavigation.tsx
deleted file mode 100644
index 60b3d8750..000000000
--- a/src/app/deprecated/components/client/SiteNavigation.tsx
+++ /dev/null
@@ -1,110 +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/. */
-
-"use client";
-
-import Image from "next/image";
-import { usePathname } from "next/navigation";
-import { useL10n } from "../../../hooks/l10n";
-
-import RelayLogo from "../../../../client/images/logo-relay.svg";
-import VPNLogo from "../../../../client/images/logo-vpn.svg";
-
-export const SiteNavigation = () => {
- const l10n = useL10n();
- const pathname = usePathname();
-
- const isBreachesPage = pathname === "/user/breaches";
- const isSettingsPage = pathname === "/user/settings";
-
- return (
-
-
-
-
-
-
-
{l10n.getString("site-nav-ad-callout")}
-
-
-
-
-
-
-
-
- );
-};
diff --git a/src/app/deprecated/components/client/UserMenu.tsx b/src/app/deprecated/components/client/UserMenu.tsx
deleted file mode 100644
index 237380965..000000000
--- a/src/app/deprecated/components/client/UserMenu.tsx
+++ /dev/null
@@ -1,104 +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/. */
-
-"use client";
-
-import { Session } from "next-auth";
-import Image from "next/image";
-import { signOut } from "next-auth/react";
-import Script from "next/script";
-
-import { useL10n } from "../../../hooks/l10n";
-import OpenInIcon from "../../../../client/images/icon-open-in.svg";
-import SettingsIcon from "../../../../client/images/icon-settings.svg";
-import HelpIcon from "../../../../client/images/icon-help.svg";
-import SignOutIcon from "../../../../client/images/icon-signout.svg";
-import { FeatureFlagName } from "../../../../db/tables/featureFlags";
-
-export type Props = {
- session: Session;
- fxaSettingsUrl: string;
- nonce: string | undefined;
- enabledFeatureFlags: FeatureFlagName[];
-};
-
-export const UserMenu = ({
- session,
- fxaSettingsUrl,
- nonce,
- enabledFeatureFlags,
-}: Props) => {
- const l10n = useL10n();
- if (!session) {
- return null;
- }
-
- return (
-
- );
-};
diff --git a/src/app/deprecated/components/client/assets/shield-icon.svg b/src/app/deprecated/components/client/assets/shield-icon.svg
deleted file mode 100644
index 0b67bd26a..000000000
--- a/src/app/deprecated/components/client/assets/shield-icon.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/src/app/deprecated/components/client/assets/shield-outline-icon.svg b/src/app/deprecated/components/client/assets/shield-outline-icon.svg
deleted file mode 100644
index dddeedff9..000000000
--- a/src/app/deprecated/components/client/assets/shield-outline-icon.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
diff --git a/src/app/deprecated/components/server/AddEmailDialog.tsx b/src/app/deprecated/components/server/AddEmailDialog.tsx
deleted file mode 100644
index 837d7678c..000000000
--- a/src/app/deprecated/components/server/AddEmailDialog.tsx
+++ /dev/null
@@ -1,63 +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/. */
-
-import React from "react";
-import cloudImage from "../../../../client/images/dialog-email-clouds.svg";
-import AppConstants from "../../../../appConstants";
-import { getL10n } from "../../../functions/server/l10n";
-import { CONST_MAX_NUM_ADDRESSES } from "../../../../constants";
-
-export default function AddEmailDialog() {
- const l10n = getL10n();
- const emailLimit = CONST_MAX_NUM_ADDRESSES;
-
- return (
- <>
- {/* Styles need to be included manually when fetching the component via API */}
- {/* eslint-disable-next-line @next/next/no-css-tags */}
-
-
-
- {/* We can’t use next/image when we fetch the component via API */}
- {/* eslint-disable-next-line @next/next/no-img-element */}
-
- {l10n.getString("add-email-add-another-heading")}
-
-
-
- ${l10n
- .getString("add-email-verify-the-link", {
- email: ' ',
- "settings-href": 'href="/user/settings"',
- })
- // The following are special characters inserted by Fluent,
- // which break the link when inserted into the tag.
- // (For future strings, we can just `getElement` to properly insert
- // tags into localised strings.)
- .replaceAll("", "")
- .replaceAll("", "")}
-
- `,
- }}
- />
- >
- );
-}
diff --git a/src/app/deprecated/components/server/BreachesTable.tsx b/src/app/deprecated/components/server/BreachesTable.tsx
deleted file mode 100644
index bf9843548..000000000
--- a/src/app/deprecated/components/server/BreachesTable.tsx
+++ /dev/null
@@ -1,228 +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/. */
-
-import type { UserBreaches } from "../../../functions/server/getUserBreaches";
-import { getL10n } from "../../../functions/server/l10n";
-import { BreachLogo } from "../../../components/server/BreachLogo";
-import { getLocale } from "../../../../utils/fluent.js";
-
-import ImageBreachesNone from "../../../../client/images/breaches-none.svg";
-import ImageBreachesAllResolved from "../../../../client/images/breaches-all-resolved.svg";
-import { HibpLikeDbBreach } from "../../../../utils/hibp";
-import { Breach } from "../../(authenticated)/user/breaches/breaches";
-
-function createResolveSteps(breach: any) {
- const checkedArr = breach.ResolutionsChecked || [];
- const resolveStepsHTML = Object.entries(breach.breachChecklist).map(
- ([key, value]: [string, any]) => `
-
-
- ${value.header as string}${value.body as string}
-
- `,
- );
-
- return resolveStepsHTML.join("");
-}
-
-export type Props = {
- userBreaches: UserBreaches;
-};
-
-export const BreachesTable = ({ userBreaches }: Props) => {
- const l10n = getL10n();
-
- function createBreachRows({ breachesData }: UserBreaches) {
- const locale = getLocale();
- const shortDate = new Intl.DateTimeFormat(locale, {
- year: "numeric",
- month: "2-digit",
- day: "2-digit",
- timeZone: "UTC",
- });
- const shortList = new Intl.ListFormat(locale, { style: "narrow" });
- const longDate = new Intl.DateTimeFormat(locale, {
- dateStyle: "long",
- timeZone: "UTC",
- });
- const longList = new Intl.ListFormat(locale, { style: "long" });
- const breachRowsHTML = breachesData.verifiedEmails.flatMap((account) => {
- return account.breaches.map((breach: HibpLikeDbBreach | Breach) => {
- const isHidden = !account.primary || (breach as Breach).IsResolved; // initial breach hidden state
- const status = (breach as Breach).IsResolved
- ? "resolved"
- : "unresolved";
- const breachDate = Date.parse(breach.BreachDate);
- const addedDate = Date.parse((breach as Breach).AddedDate);
- const dataClassesTranslated = breach.DataClasses.map((item) =>
- l10n.getString(item),
- );
- const description = l10n.getString("breach-description", {
- companyName: breach.Title,
- breachDate: longDate.format(breachDate),
- addedDate: longDate.format(addedDate),
- dataClasses: longList.format(dataClassesTranslated),
- });
-
- return (
-
-
-
- {" "}
- {breach.Title}
-
- {shortList.format(dataClassesTranslated)}
-
-
- {l10n.getString("column-status-badge-resolved")}
-
-
- {l10n.getString("column-status-badge-active")}
-
-
- {shortDate.format(addedDate)}
-
-
- {description}
-
- {l10n.getString("breaches-resolve-heading")}
-
-
-
-
- );
- });
- });
-
- return breachRowsHTML;
- }
-
- return (
- <>
-
-
-
- {/* The DOM for this element is modified by regular JavaScript files
- that predate our migration to Next.js. We don’t use any React-specific
- features here, so hydration errors should not be a problem. */}
-
- {l10n.getString("filter-label-unresolved")}
-
-
-
- {/* The DOM for this element is modified by regular JavaScript files
- that predate our migration to Next.js. We don’t use any React-specific
- features here, so hydration errors should not be a problem. */}
-
- {l10n.getString("filter-label-resolved")}
-
-
- {/* The DOM for this element is modified by regular JavaScript files
- that predate our migration to Next.js. We don’t use any React-specific
- features here, so hydration errors should not be a problem. */}
-
-
- {l10n.getString("column-company")}
- {l10n.getString("column-breached-data")}
- {/* The active/resolved badge does not have a column header, but by
- including an empty , we can re-use the `nth-child`-based
- selectors for the content columns. */}
-
- {l10n.getString("column-detected")}
-
- {createBreachRows(userBreaches)}
-
-
- ${l10n.getString("breaches-none-headline")}
-
- ${l10n.getString("breaches-none-copy", {
- email: ' ',
- })}
-
-
- ${l10n.getString("breaches-none-cta-blurb")}
-
- ${l10n.getString("breaches-none-cta-button")}
-
-
-
- `,
- }}
- />
-
-
- ${l10n.getString("breaches-all-resolved-headline")}
-
- ${l10n.getString("breaches-all-resolved-copy", {
- email: ' ',
- })}
-
-
- ${l10n.getString(
- "breaches-all-resolved-cta-blurb",
- )}
-
- ${l10n.getString("breaches-all-resolved-cta-button")}
-
-
-
- `,
- }}
- />
-
- >
- );
-};
diff --git a/src/app/deprecated/functions/server/getComponentAsString.ts b/src/app/deprecated/functions/server/getComponentAsString.ts
deleted file mode 100644
index 39f25b7f4..000000000
--- a/src/app/deprecated/functions/server/getComponentAsString.ts
+++ /dev/null
@@ -1,16 +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/. */
-
-import { ReactElement } from "react";
-
-export type Props = {
- component: ReactElement;
-};
-
-// If a component imports `react-dom/server` directly Next.js throws a
-// compilation error `ReactServerComponentsError` for perf and security reasons.
-export const getComponentAsString = async ({ component }: Props) => {
- const ReactDOMServer = (await import("react-dom/server")).default;
- return ReactDOMServer.renderToString(component);
-};
diff --git a/src/app/deprecated/functions/server/getNonce.ts b/src/app/deprecated/functions/server/getNonce.ts
deleted file mode 100644
index 96ffb0898..000000000
--- a/src/app/deprecated/functions/server/getNonce.ts
+++ /dev/null
@@ -1,11 +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/. */
-
-import { headers } from "next/headers";
-
-export function getNonce() {
- // This header gets set in /src/middleware.ts:
- const nonce = headers().get("x-nonce") ?? undefined;
- return nonce;
-}
diff --git a/src/app/deprecated/layout.tsx b/src/app/deprecated/layout.tsx
deleted file mode 100644
index ed6cf19f2..000000000
--- a/src/app/deprecated/layout.tsx
+++ /dev/null
@@ -1,61 +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/. */
-
-import { ReactNode } from "react";
-import Script from "next/script";
-import { L10nProvider } from "../../contextProviders/localization";
-import { getL10nBundles } from "../functions/server/l10n";
-import { HandleFalseDoorTest } from "./components/client/FalseDoorBanner";
-import { getCountryCode } from "../functions/server/getCountryCode";
-import { headers } from "next/headers";
-import AppConstants from "../../appConstants";
-import { getNonce } from "./functions/server/getNonce";
-import { getEnabledFeatureFlags } from "../../db/tables/featureFlags";
-
-export default async function MigrationLayout({
- children,
-}: {
- children: ReactNode;
-}) {
- const headersList = headers();
- const l10nBundles = getL10nBundles();
- const countryCode = getCountryCode(headersList);
- const enabledFlags = await getEnabledFeatureFlags({ ignoreAllowlist: true });
- const waitlistLink = AppConstants.FALSE_DOOR_TEST_LINK_PHASE_ONE;
- const acceptLanguage = headersList.get("Accept-Language");
-
- let locale = "";
- if (acceptLanguage) {
- const acceptedLocales = acceptLanguage.split(",");
- const primaryLocale = acceptedLocales[0];
- locale = primaryLocale.split(";")[0];
- }
-
- return (
-
- {/* This script predates the use of React and thus shouldn’t wait for
- hydration to adjust the layout. */}
- {/* eslint-disable-next-line @next/next/no-sync-scripts */}
-
-
- {children}
- {enabledFlags.includes("FalseDoorTest") &&
- waitlistLink &&
- countryCode.toLowerCase() === "us" &&
- ["en", "en-GB", "en-US", "en-CA"].includes(locale) && (
-
- )}
-
- );
-}
diff --git a/src/app/functions/server/getBreaches.ts b/src/app/functions/server/getBreaches.ts
index f53536535..9a91eb7c0 100644
--- a/src/app/functions/server/getBreaches.ts
+++ b/src/app/functions/server/getBreaches.ts
@@ -10,7 +10,7 @@ import {
req,
} from "../../../utils/hibp.js";
import { upsertBreaches } from "../../../db/tables/breaches.js";
-import { Breach } from "../../deprecated/(authenticated)/user/breaches/breaches.js";
+import { Breach } from "../universal/breach.js";
let breaches: Array;
diff --git a/src/app/functions/universal/breach.ts b/src/app/functions/universal/breach.ts
index 05546bac8..46c32daf6 100644
--- a/src/app/functions/universal/breach.ts
+++ b/src/app/functions/universal/breach.ts
@@ -3,10 +3,32 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { DataClassEffected } from "../../../utils/subscriberBreaches";
-import { HibpBreachDataTypes } from "../../deprecated/(authenticated)/user/breaches/breaches";
// TODO: Move pure functions that operate on breaches to this file
+export interface Breach {
+ AddedDate: string;
+ BreachDate: string;
+ DataClasses: Array;
+ Description: string;
+ Domain: string;
+ Id: number;
+ IsFabricated: boolean;
+ IsMalware: boolean;
+ IsResolved?: boolean;
+ IsRetired: boolean;
+ IsSensitive: boolean;
+ IsSpamList: boolean;
+ IsVerified: boolean;
+ LogoPath: string;
+ ModifiedDate: string;
+ Name: string;
+ PwnCount: number;
+ recencyIndex: number;
+ ResolutionsChecked: Array;
+ Title: string;
+}
+
export const BreachDataTypes = {
Passwords: "passwords",
Email: "email-addresses",
@@ -53,6 +75,18 @@ export const SecurityRecommendationDataTypes = {
IP: BreachDataTypes.IP,
} as const;
+export type HibpBreachDataTypes = typeof BreachDataTypes;
+
+export interface BreachBulkResolutionRequest {
+ dataType: HibpBreachDataTypes;
+}
+
+export interface BreachResolutionRequest {
+ affectedEmail: string;
+ breachId: number;
+ resolutionsChecked: Array;
+}
+
export function isBreachResolved(
dataClassesAffected: DataClassEffected[],
resolvedDataClasses: Array,
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 5a66cb319..057db7060 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -15,7 +15,6 @@ import { metropolis } from "./fonts/Metropolis/metropolis";
import { CONST_GA4_MEASUREMENT_ID } from "../constants";
import { headers } from "next/headers";
import { GoogleAnalyticsWorkaround } from "./components/client/GoogleAnalyticsWorkaround";
-import { getNonce } from "./deprecated/functions/server/getNonce";
import StripeScript from "./components/client/StripeScript";
// DO NOT ADD SECRETS: Env variables added here become public.
@@ -56,6 +55,7 @@ export default async function RootLayout({
}: {
children: ReactNode;
}) {
+ const nonce = headers().get("x-nonce") ?? "";
const currentLocale = getLocale(getL10nBundles());
const session = await getServerSession();
@@ -76,7 +76,7 @@ export default async function RootLayout({
{headers().get("DNT") !== "1" && (