diff --git a/src/components/auth/withAuth.tsx b/src/components/auth/withAuth.tsx new file mode 100644 index 00000000..93513504 --- /dev/null +++ b/src/components/auth/withAuth.tsx @@ -0,0 +1,27 @@ +import { GetServerSideProps } from "next"; +import { getSession } from "next-auth/react"; + +export function withAuth(gssp: GetServerSideProps): GetServerSideProps { + return async (context) => { + const { user } = (await getSession(context)) || {}; + + if (!user) { + return { + redirect: { statusCode: 302, destination: "/auth/login" }, + }; + } + // ssp (server side props) + const gsspData = await gssp(context); + + if (!("props" in gsspData)) { + throw new Error("invalid getSSP result"); + } + + return { + props: { + ...gsspData.props, + user, + }, + }; + }; +} diff --git a/src/pages/admin/index.tsx b/src/pages/admin/index.tsx index e94a4b9f..b553434a 100644 --- a/src/pages/admin/index.tsx +++ b/src/pages/admin/index.tsx @@ -7,7 +7,8 @@ import Controller from "./controller"; import Mail from "./mail"; import Notification from "./notification"; import { useTranslations } from "next-intl"; -import { type GetStaticPropsContext } from "next"; +import { GetServerSidePropsContext } from "next"; +import { withAuth } from "~/components/auth/withAuth"; const AdminSettings = () => { const router = useRouter(); @@ -74,7 +75,7 @@ const AdminSettings = () => { AdminSettings.getLayout = function getLayout(page: ReactElement) { return {page}; }; -export async function getStaticProps(context: GetStaticPropsContext) { +export const getServerSideProps = withAuth(async (context: GetServerSidePropsContext) => { return { props: { // You can get the messages from anywhere you like. The recommended @@ -84,5 +85,5 @@ export async function getStaticProps(context: GetStaticPropsContext) { messages: (await import(`../../locales/${context.locale}/common.json`)).default, }, }; -} +}); export default AdminSettings; diff --git a/src/pages/central/[id].tsx b/src/pages/central/[id].tsx index df6af203..8afeb376 100644 --- a/src/pages/central/[id].tsx +++ b/src/pages/central/[id].tsx @@ -19,9 +19,10 @@ import cn from "classnames"; import NetworkHelpText from "~/components/modules/networkHelp"; import { InviteMemberByMail } from "~/components/modules/inviteMemberbyMail"; import { useTranslations } from "next-intl"; -import { type GetStaticPropsContext } from "next/types"; +import { GetServerSidePropsContext } from "next/types"; import NetworkDescription from "../../components/modules/networkDescription"; import NetworkName from "~/components/modules/networkName"; +import { withAuth } from "~/components/auth/withAuth"; const CentralNetworkById = () => { const t = useTranslations("networkById"); @@ -266,7 +267,7 @@ CentralNetworkById.getLayout = function getLayout(page: ReactElement) { return {page}; }; -export async function getServerSideProps(context: GetStaticPropsContext) { +export const getServerSideProps = withAuth(async (context: GetServerSidePropsContext) => { return { props: { // You can get the messages from anywhere you like. The recommended @@ -276,5 +277,5 @@ export async function getServerSideProps(context: GetStaticPropsContext) { messages: (await import(`../../locales/${context.locale}/common.json`)).default, }, }; -} +}); export default CentralNetworkById; diff --git a/src/pages/central/index.tsx b/src/pages/central/index.tsx index 8fdb8de5..488aa529 100644 --- a/src/pages/central/index.tsx +++ b/src/pages/central/index.tsx @@ -7,6 +7,7 @@ import { CentralNetworkTable } from "../../components/modules/ztCentral/centralN import { globalSiteTitle } from "~/utils/global"; import { useTranslations } from "next-intl"; import { type GetServerSidePropsContext } from "next"; +import { withAuth } from "~/components/auth/withAuth"; const CentralNetworks: NextPageWithLayout = () => { const t = useTranslations("networks"); @@ -100,7 +101,7 @@ const CentralNetworks: NextPageWithLayout = () => { CentralNetworks.getLayout = function getLayout(page: ReactElement) { return {page}; }; -export async function getServerSideProps(context: GetServerSidePropsContext) { +export const getServerSideProps = withAuth(async (context: GetServerSidePropsContext) => { return { props: { // You can get the messages from anywhere you like. The recommended @@ -110,5 +111,5 @@ export async function getServerSideProps(context: GetServerSidePropsContext) { messages: (await import(`../../locales/${context.locale}/common.json`)).default, }, }; -} +}); export default CentralNetworks; diff --git a/src/pages/dashboard/index.tsx b/src/pages/dashboard/index.tsx index c720c96c..5343b70a 100644 --- a/src/pages/dashboard/index.tsx +++ b/src/pages/dashboard/index.tsx @@ -1,12 +1,14 @@ import Head from "next/head"; -import type { ReactElement } from "react"; +import { type ReactElement } from "react"; import { LayoutAuthenticated } from "~/components/layouts/layout"; import type { NextPageWithLayout } from "../_app"; import { globalSiteTitle } from "~/utils/global"; import { type GetServerSidePropsContext } from "next"; +import { withAuth } from "~/components/auth/withAuth"; const Dashboard: NextPageWithLayout = () => { const title = `${globalSiteTitle} - Dashboard`; + return ( <> @@ -57,7 +59,7 @@ Dashboard.getLayout = function getLayout(page: ReactElement) { return {page}; }; -export async function getServerSideProps(context: GetServerSidePropsContext) { +export const getServerSideProps = withAuth(async (context: GetServerSidePropsContext) => { return { props: { // You can get the messages from anywhere you like. The recommended @@ -67,5 +69,5 @@ export async function getServerSideProps(context: GetServerSidePropsContext) { messages: (await import(`../../locales/${context.locale}/common.json`)).default, }, }; -} +}); export default Dashboard; diff --git a/src/pages/network/[id].tsx b/src/pages/network/[id].tsx index 4dbac1c0..be659e4c 100644 --- a/src/pages/network/[id].tsx +++ b/src/pages/network/[id].tsx @@ -19,9 +19,10 @@ import cn from "classnames"; import NetworkHelpText from "~/components/modules/networkHelp"; import { InviteMemberByMail } from "~/components/modules/inviteMemberbyMail"; import { useTranslations } from "next-intl"; -import { type GetStaticPropsContext } from "next/types"; +import { GetServerSidePropsContext } from "next/types"; import NetworkName from "~/components/modules/networkName"; import NetworkDescription from "~/components/modules/networkDescription"; +import { withAuth } from "~/components/auth/withAuth"; // import DebugMirror from "~/components/modules/debugController"; const NetworkById = () => { @@ -299,7 +300,7 @@ NetworkById.getLayout = function getLayout(page: ReactElement) { return {page}; }; -export async function getServerSideProps(context: GetStaticPropsContext) { +export const getServerSideProps = withAuth(async (context: GetServerSidePropsContext) => { return { props: { // You can get the messages from anywhere you like. The recommended @@ -309,5 +310,5 @@ export async function getServerSideProps(context: GetStaticPropsContext) { messages: (await import(`../../locales/${context.locale}/common.json`)).default, }, }; -} +}); export default NetworkById; diff --git a/src/pages/network/index.tsx b/src/pages/network/index.tsx index e03e6030..be9d79f8 100644 --- a/src/pages/network/index.tsx +++ b/src/pages/network/index.tsx @@ -9,6 +9,7 @@ import { useTranslations } from "next-intl"; import { type GetServerSidePropsContext } from "next"; import toast from "react-hot-toast"; import { ErrorData } from "~/types/errorHandling"; +import { withAuth } from "~/components/auth/withAuth"; const Networks: NextPageWithLayout = () => { const t = useTranslations("networks"); @@ -120,7 +121,7 @@ const Networks: NextPageWithLayout = () => { Networks.getLayout = function getLayout(page: ReactElement) { return {page}; }; -export async function getServerSideProps(context: GetServerSidePropsContext) { +export const getServerSideProps = withAuth(async (context: GetServerSidePropsContext) => { return { props: { // You can get the messages from anywhere you like. The recommended @@ -130,5 +131,5 @@ export async function getServerSideProps(context: GetServerSidePropsContext) { messages: (await import(`../../locales/${context.locale}/common.json`)).default, }, }; -} +}); export default Networks; diff --git a/src/server/auth.ts b/src/server/auth.ts index 38f6aaf1..ccdbbcba 100644 --- a/src/server/auth.ts +++ b/src/server/auth.ts @@ -18,6 +18,7 @@ import { type User as IUser } from "@prisma/client"; declare module "next-auth" { interface Session extends DefaultSession { user: IUser; + error: string; update: { name?: string; email?: string; @@ -162,9 +163,19 @@ export const authOptions: NextAuthOptions = { } return token; }, - session: ({ session, token }) => { + session: async ({ session, token }) => { if (!token.id) return null; + // Check the user exists in the database + const user = await prisma.user.findFirst({ + where: { id: token.id }, + }); + + if (!user) { + // If the user does not exist, return null to log them out + return null; + } + session.user = { ...token } as IUser; return session; }, @@ -177,7 +188,7 @@ export const authOptions: NextAuthOptions = { }, }, pages: { - signIn: "/", + signIn: "/auth/login", }, debug: false, };