diff --git a/app/[lang]/(live)/(protected)/layout.tsx b/app/[lang]/(live)/(protected)/layout.tsx index 182d77b5a..75d409ee5 100644 --- a/app/[lang]/(live)/(protected)/layout.tsx +++ b/app/[lang]/(live)/(protected)/layout.tsx @@ -1,5 +1,9 @@ +import { headers } from "next/headers" import { redirect } from "next/navigation" +import { overview } from "@/constants/routes/myPages" +import { serverClient } from "@/lib/trpc/server" + import { auth } from "@/auth" import type { LangParams, LayoutArgs } from "@/types/params" @@ -13,8 +17,18 @@ export default async function ProtectedLayout({ * Fallback to make sure every route nested in the * protected route group is actually protected. */ + const h = headers() + const redirectTo = encodeURIComponent( + h.get("x-url") ?? h.get("x-pathname") ?? overview[params.lang] + ) + if (!session) { - redirect(`/${params.lang}/login`) + redirect(`/${params.lang}/login?redirectTo=${redirectTo}`) + } + + const user = await serverClient().user.get() + if (!user || "error" in user) { + redirect(`/${params.lang}/login?redirectTo=${redirectTo}`) } return children diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@profile/edit/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@profile/edit/page.tsx index f9977baf0..fa83ee3b1 100644 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@profile/edit/page.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@profile/edit/page.tsx @@ -4,7 +4,7 @@ import Form from "@/components/Forms/Edit/Profile" export default async function EditProfileSlot() { const user = await serverClient().user.get({ mask: false }) - if (!user) { + if (!user || "error" in user) { return null } return
diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@profile/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@profile/page.tsx index 76cf6f994..455dc3159 100644 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@profile/page.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@profile/page.tsx @@ -24,7 +24,7 @@ import type { LangParams, PageArgs } from "@/types/params" export default async function Profile({ params }: PageArgs) { const { formatMessage } = await getIntl() const user = await serverClient().user.get() - if (!user) { + if (!user || "error" in user) { return null } const language = languageSelect.find((l) => l.value === user.language) diff --git a/app/[lang]/webview/[contentType]/[uid]/page.tsx b/app/[lang]/webview/[contentType]/[uid]/page.tsx index 8a3fdfe9e..21f1766a4 100644 --- a/app/[lang]/webview/[contentType]/[uid]/page.tsx +++ b/app/[lang]/webview/[contentType]/[uid]/page.tsx @@ -1,4 +1,6 @@ -import { notFound } from "next/navigation" +import { notFound, redirect } from "next/navigation" + +import { serverClient } from "@/lib/trpc/server" import AccountPage from "@/components/ContentType/Webviews/AccountPage" import LoyaltyPage from "@/components/ContentType/Webviews/LoyaltyPage" @@ -13,6 +15,21 @@ import { export default async function ContentTypePage({ params, }: PageArgs) { + const user = await serverClient().user.get() + + if (!user) { + return

Error: No user could be loaded

+ } + + if ("error" in user) { + switch (user.cause) { + case "unauthorized": // fall through + case "forbidden": // fall through + case "token_expired": + redirect(`/${params.lang}/webview/refresh`) + } + } + switch (params.contentType) { case "loyalty-page": return diff --git a/components/Loyalty/Sidebar/MyPagesNavigation/index.tsx b/components/Loyalty/Sidebar/MyPagesNavigation/index.tsx deleted file mode 100644 index 587074062..000000000 --- a/components/Loyalty/Sidebar/MyPagesNavigation/index.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { serverClient } from "@/lib/trpc/server" - -import MyPagesSidebar from "@/components/MyPages/Sidebar" - -import { LangParams } from "@/types/params" - -export default async function MyPagesNavigation({ lang }: LangParams) { - const user = await serverClient().user.name() - - // Check if we have user, that means we are logged in. - if (!user) { - return null - } - - return -} diff --git a/components/Loyalty/Sidebar/index.tsx b/components/Loyalty/Sidebar/index.tsx index 1cdbe63bc..8f262fbf7 100644 --- a/components/Loyalty/Sidebar/index.tsx +++ b/components/Loyalty/Sidebar/index.tsx @@ -1,7 +1,7 @@ import JsonToHtml from "@/components/JsonToHtml" +import SidebarMyPages from "@/components/MyPages/Sidebar" import JoinLoyaltyContact from "./JoinLoyalty" -import MyPagesNavigation from "./MyPagesNavigation" import styles from "./sidebar.module.css" @@ -44,7 +44,7 @@ export default function SidebarLoyalty({ switch (block.dynamic_content.component) { case LoyaltySidebarDynamicComponentEnum.my_pages_navigation: return ( - diff --git a/components/MyPages/Blocks/Benefits/CurrentLevel/index.tsx b/components/MyPages/Blocks/Benefits/CurrentLevel/index.tsx index e955686d4..9a896a282 100644 --- a/components/MyPages/Blocks/Benefits/CurrentLevel/index.tsx +++ b/components/MyPages/Blocks/Benefits/CurrentLevel/index.tsx @@ -24,7 +24,7 @@ export default async function CurrentBenefitsBlock({ // TAKE NOTE: we need clarification on how benefits stack from different levels // in order to determine if a benefit is specific to a level or if it is a cumulative benefit // we might have to add a new boolean property "exclusive" or similar - if (!user) { + if (!user || "error" in user) { return null } const membership = getMembership(user.memberships) diff --git a/components/MyPages/Blocks/Benefits/NextLevel/index.tsx b/components/MyPages/Blocks/Benefits/NextLevel/index.tsx index 48136fd7a..8dbc96bf8 100644 --- a/components/MyPages/Blocks/Benefits/NextLevel/index.tsx +++ b/components/MyPages/Blocks/Benefits/NextLevel/index.tsx @@ -25,7 +25,7 @@ export default async function NextLevelBenefitsBlock({ }: AccountPageComponentProps) { const { formatMessage } = await getIntl() const user = await serverClient().user.get() - if (!user) { + if (!user || "error" in user) { return null } const nextLevel = getMembershipLevelObject( diff --git a/components/MyPages/Blocks/Overview/index.tsx b/components/MyPages/Blocks/Overview/index.tsx index aa1040b9d..74c863648 100644 --- a/components/MyPages/Blocks/Overview/index.tsx +++ b/components/MyPages/Blocks/Overview/index.tsx @@ -21,7 +21,7 @@ export default async function Overview({ lang, }: AccountPageComponentProps & LangParams) { const user = await serverClient().user.get() - if (!user) { + if (!user || "error" in user) { return null } diff --git a/components/MyPages/Blocks/Points/Overview/index.tsx b/components/MyPages/Blocks/Points/Overview/index.tsx index 0bd594352..1bdddc06a 100644 --- a/components/MyPages/Blocks/Points/Overview/index.tsx +++ b/components/MyPages/Blocks/Points/Overview/index.tsx @@ -21,7 +21,7 @@ export default async function PointsOverview({ lang, }: AccountPageComponentProps & LangParams) { const user = await serverClient().user.get() - if (!user) { + if (!user || "error" in user) { return null } diff --git a/components/MyPages/Sidebar/index.tsx b/components/MyPages/Sidebar/index.tsx index bf9280cd8..9baf25cef 100644 --- a/components/MyPages/Sidebar/index.tsx +++ b/components/MyPages/Sidebar/index.tsx @@ -12,7 +12,7 @@ import styles from "./sidebar.module.css" import type { LangParams } from "@/types/params" -export default async function Sidebar({ lang }: LangParams) { +export default async function SidebarMyPages({ lang }: LangParams) { const navigation = await serverClient().contentstack.myPages.navigation.get() const { formatMessage } = await getIntl() if (!navigation) { diff --git a/server/routers/user/query.ts b/server/routers/user/query.ts index aad0c08ca..7d5eac091 100644 --- a/server/routers/user/query.ts +++ b/server/routers/user/query.ts @@ -31,6 +31,12 @@ import type { } from "@/types/components/tracking" async function getVerifiedUser({ session }: { session: Session }) { + const now = Date.now() + + if (session.token.expires_at < now) { + return { error: true, cause: "token_expired" } as const + } + const apiResponse = await api.get(api.endpoints.v1.profile, { cache: "no-store", headers: { @@ -39,6 +45,11 @@ async function getVerifiedUser({ session }: { session: Session }) { }) if (!apiResponse.ok) { + if (apiResponse.status === 401) { + return { error: true, cause: "unauthorized" } as const + } else if (apiResponse.status === 403) { + return { error: true, cause: "forbidden" } as const + } return null } @@ -141,12 +152,18 @@ export const userQueryRouter = router({ get: protectedProcedure .input(getUserInputSchema) .query(async function getUser({ ctx, input }) { - const verifiedData = await getVerifiedUser({ session: ctx.session }) + const data = await getVerifiedUser({ session: ctx.session }) - if (!verifiedData) { + if (!data) { return null } + if ("error" in data) { + return data + } + + const verifiedData = data + const country = countries.find( (c) => c.code === verifiedData.data.address.countryCode ) @@ -199,7 +216,7 @@ export const userQueryRouter = router({ } const verifiedData = await getVerifiedUser({ session: ctx.session }) - if (!verifiedData) { + if (!verifiedData || "error" in verifiedData) { return null } return { @@ -213,7 +230,7 @@ export const userQueryRouter = router({ } const verifiedData = await getVerifiedUser({ session: ctx.session }) - if (!verifiedData) { + if (!verifiedData || "error" in verifiedData) { return null } @@ -230,7 +247,7 @@ export const userQueryRouter = router({ } const verifiedUserData = await getVerifiedUser({ session: ctx.session }) - if (!verifiedUserData) { + if (!verifiedUserData || "error" in verifiedUserData) { return notLoggedInUserTrackingData }