From f201a3a7753af4d60e35cc4007877d22218052f0 Mon Sep 17 00:00:00 2001 From: Florian Zia Date: Fri, 1 Dec 2023 01:20:53 +0100 Subject: [PATCH 1/2] fix: Prevent reading of user if there is no session --- .../(authenticated)/user/breaches/page.tsx | 10 ++++++---- .../(nextjs_migration)/(authenticated)/user/layout.tsx | 3 +-- .../(authenticated)/user/settings/page.tsx | 5 +---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/app/(nextjs_migration)/(authenticated)/user/breaches/page.tsx b/src/app/(nextjs_migration)/(authenticated)/user/breaches/page.tsx index beadc61eb0f..7554689e776 100644 --- a/src/app/(nextjs_migration)/(authenticated)/user/breaches/page.tsx +++ b/src/app/(nextjs_migration)/(authenticated)/user/breaches/page.tsx @@ -23,6 +23,7 @@ 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"; export function generateMetadata() { const l10n = getL10n(); @@ -68,14 +69,15 @@ declare global { export default async function UserBreaches() { const session = await getServerSession(authOptions); + if (!session || !session.user?.subscriber) { + return ; + } + const l10n = getL10n(); const headerList = headers(); const userBreachesData: UserBreaches = await getUserBreaches({ - // `(authenticated)/layout.tsx` ensures that `session` is not undefined, - // so the type assertion should be safe: - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - user: session!.user, + user: session.user, options: { countryCode: getCountryCode(headerList), }, diff --git a/src/app/(nextjs_migration)/(authenticated)/user/layout.tsx b/src/app/(nextjs_migration)/(authenticated)/user/layout.tsx index a2657545023..56b45c199ac 100644 --- a/src/app/(nextjs_migration)/(authenticated)/user/layout.tsx +++ b/src/app/(nextjs_migration)/(authenticated)/user/layout.tsx @@ -2,7 +2,6 @@ * 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 { getServerSession } from "next-auth"; import Image from "next/image"; @@ -29,7 +28,7 @@ export type Props = { const MainLayout = async (props: Props) => { const session = await getServerSession(authOptions); - if (!session) { + if (!session || !session.user?.subscriber) { return ; } diff --git a/src/app/(nextjs_migration)/(authenticated)/user/settings/page.tsx b/src/app/(nextjs_migration)/(authenticated)/user/settings/page.tsx index f464d3dacc1..08164133300 100644 --- a/src/app/(nextjs_migration)/(authenticated)/user/settings/page.tsx +++ b/src/app/(nextjs_migration)/(authenticated)/user/settings/page.tsx @@ -21,7 +21,6 @@ import { getBreachesForEmail } from "../../../../../utils/hibp"; import { getSha1 } from "../../../../../utils/fxa"; import { getSubscriberById } from "../../../../../db/tables/subscribers"; import { getNonce } from "../../../functions/server/getNonce"; -import { getEnabledFeatureFlags } from "../../../../../db/tables/featureFlags"; const emailNeedsVerificationSub = (email: EmailRow) => { const l10n = getL10n(); @@ -153,9 +152,7 @@ export default async function Settings() { if (!session || !session.user?.subscriber) { return redirect("/"); } - const enabledFlags = await getEnabledFeatureFlags({ - email: session.user.email, - }); + // 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. From 7c024e2b4c203d3653fd472e33e0cc529106f67c Mon Sep 17 00:00:00 2001 From: Florian Zia Date: Tue, 5 Dec 2023 19:14:13 +0100 Subject: [PATCH 2/2] chore: Convert session access to optional chaining --- .../(nextjs_migration)/(authenticated)/user/breaches/page.tsx | 2 +- src/app/(nextjs_migration)/(authenticated)/user/layout.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/(nextjs_migration)/(authenticated)/user/breaches/page.tsx b/src/app/(nextjs_migration)/(authenticated)/user/breaches/page.tsx index 7554689e776..3dd5b9d031d 100644 --- a/src/app/(nextjs_migration)/(authenticated)/user/breaches/page.tsx +++ b/src/app/(nextjs_migration)/(authenticated)/user/breaches/page.tsx @@ -69,7 +69,7 @@ declare global { export default async function UserBreaches() { const session = await getServerSession(authOptions); - if (!session || !session.user?.subscriber) { + if (!session?.user?.subscriber) { return ; } diff --git a/src/app/(nextjs_migration)/(authenticated)/user/layout.tsx b/src/app/(nextjs_migration)/(authenticated)/user/layout.tsx index 56b45c199ac..e627c046e40 100644 --- a/src/app/(nextjs_migration)/(authenticated)/user/layout.tsx +++ b/src/app/(nextjs_migration)/(authenticated)/user/layout.tsx @@ -28,11 +28,11 @@ export type Props = { const MainLayout = async (props: Props) => { const session = await getServerSession(authOptions); - if (!session || !session.user?.subscriber) { + if (!session?.user?.subscriber) { return ; } - const userId = session?.user?.subscriber?.fxa_uid ?? ""; + const userId = session.user.subscriber.fxa_uid ?? ""; if (!userId) { logger.error("No user ID for telemetry");