diff --git a/src/components/AuthRequired.tsx b/src/components/AuthRequired.tsx deleted file mode 100644 index 8da9261..0000000 --- a/src/components/AuthRequired.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import PATHS from "constants/paths"; -import { useSession } from "next-auth/react"; -import { useRouter } from "next/router"; - -// Component used to access to the session client side -export default function Auth({ children }) { - const router = useRouter(); - const { status } = useSession({ - required: true, - onUnauthenticated: () => - router.push( - `${PATHS.LOGIN}?info=${encodeURI( - "Vous devez être connecté pour accéder à cette page" - )}` - ), - }); - - if (status === "loading") { - return ( -
-

- Chargement de la session en cours -

-
- ); - } - - return children; -} diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 26fca70..b54c47b 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -5,7 +5,6 @@ import nProgress from "nprogress"; import { useEffect } from "react"; import { useHotkeys } from "react-hotkeys-hook"; -import AuthRequired from "components/AuthRequired"; import * as Keys from "constants/keys"; import PATHS from "constants/paths"; @@ -36,13 +35,7 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }) { return ( - {Component.authRequired ? ( - - - - ) : ( - - )} + ); } diff --git a/src/pages/category/create.tsx b/src/pages/category/create.tsx index b1cfdf2..63f2760 100644 --- a/src/pages/category/create.tsx +++ b/src/pages/category/create.tsx @@ -10,14 +10,17 @@ import TextBox from "components/TextBox"; import PATHS from "constants/paths"; import useAutoFocus from "hooks/useAutoFocus"; import getUserCategoriesCount from "lib/category/getUserCategoriesCount"; -import getUser from "lib/user/getUser"; import { redirectWithoutClientCache } from "utils/client"; import { HandleAxiosError } from "utils/front"; -import { getSession } from "utils/session"; +import { withAuthentication } from "utils/session"; import styles from "styles/form.module.scss"; -function CreateCategory({ categoriesCount }: { categoriesCount: number }) { +export default function PageCreateCategory({ + categoriesCount, +}: { + categoriesCount: number; +}) { const autoFocusRef = useAutoFocus(); const router = useRouter(); const info = useRouter().query?.info as string; @@ -75,24 +78,14 @@ function CreateCategory({ categoriesCount }: { categoriesCount: number }) { ); } -CreateCategory.authRequired = true; -export default CreateCategory; - -export async function getServerSideProps({ req, res }) { - const session = await getSession(req, res); - const user = await getUser(session); - if (!user) { +export const getServerSideProps = withAuthentication( + async ({ session, user }) => { + const categoriesCount = await getUserCategoriesCount(user); return { - redirect: { - destination: PATHS.HOME, + props: { + session, + categoriesCount, }, }; } - - const categoriesCount = await getUserCategoriesCount(user); - return { - props: { - categoriesCount, - }, - }; -} +); diff --git a/src/pages/category/edit/[cid].tsx b/src/pages/category/edit/[cid].tsx index 6e99dd8..80796da 100644 --- a/src/pages/category/edit/[cid].tsx +++ b/src/pages/category/edit/[cid].tsx @@ -10,14 +10,13 @@ import TextBox from "components/TextBox"; import PATHS from "constants/paths"; import useAutoFocus from "hooks/useAutoFocus"; import getUserCategory from "lib/category/getUserCategory"; -import getUser from "lib/user/getUser"; import { Category } from "types"; import { HandleAxiosError } from "utils/front"; -import { getSession } from "utils/session"; +import { withAuthentication } from "utils/session"; import styles from "styles/form.module.scss"; -function EditCategory({ category }: { category: Category }) { +export default function PageEditCategory({ category }: { category: Category }) { const autoFocusRef = useAutoFocus(); const router = useRouter(); @@ -73,34 +72,24 @@ function EditCategory({ category }: { category: Category }) { ); } -EditCategory.authRequired = true; -export default EditCategory; +export const getServerSideProps = withAuthentication( + async ({ query, session, user }) => { + const { cid } = query; -export async function getServerSideProps({ req, res, query }) { - const { cid } = query; + const category = await getUserCategory(user, Number(cid)); + if (!category) { + return { + redirect: { + destination: PATHS.HOME, + }, + }; + } - const session = await getSession(req, res); - const user = await getUser(session); - if (!user) { return { - redirect: { - destination: PATHS.HOME, + props: { + session, + category: JSON.parse(JSON.stringify(category)), }, }; } - - const category = await getUserCategory(user, Number(cid)); - if (!category) { - return { - redirect: { - destination: PATHS.HOME, - }, - }; - } - - return { - props: { - category: JSON.parse(JSON.stringify(category)), - }, - }; -} +); diff --git a/src/pages/category/remove/[cid].tsx b/src/pages/category/remove/[cid].tsx index fcb8d1a..b978a25 100644 --- a/src/pages/category/remove/[cid].tsx +++ b/src/pages/category/remove/[cid].tsx @@ -10,14 +10,17 @@ import TextBox from "components/TextBox"; import PATHS from "constants/paths"; import getUserCategory from "lib/category/getUserCategory"; -import getUser from "lib/user/getUser"; import { Category } from "types"; import { HandleAxiosError } from "utils/front"; -import { getSession } from "utils/session"; +import { withAuthentication } from "utils/session"; import styles from "styles/form.module.scss"; -function RemoveCategory({ category }: { category: Category }) { +export default function PageRemoveCategory({ + category, +}: { + category: Category; +}) { const router = useRouter(); const [error, setError] = useState( category.links.length > 0 @@ -80,34 +83,24 @@ function RemoveCategory({ category }: { category: Category }) { ); } -RemoveCategory.authRequired = true; -export default RemoveCategory; +export const getServerSideProps = withAuthentication( + async ({ query, session, user }) => { + const { cid } = query; -export async function getServerSideProps({ req, res, query }) { - const { cid } = query; + const category = await getUserCategory(user, Number(cid)); + if (!category) { + return { + redirect: { + destination: PATHS.HOME, + }, + }; + } - const session = await getSession(req, res); - const user = await getUser(session); - if (!user) { return { - redirect: { - destination: PATHS.HOME, + props: { + session, + category: JSON.parse(JSON.stringify(category)), }, }; } - - const category = await getUserCategory(user, Number(cid)); - if (!category) { - return { - redirect: { - destination: PATHS.HOME, - }, - }; - } - - return { - props: { - category: JSON.parse(JSON.stringify(category)), - }, - }; -} +); diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 28fcd95..f1f5a81 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -18,17 +18,16 @@ import PATHS from "constants/paths"; import { useMediaQuery } from "hooks/useMediaQuery"; import useModal from "hooks/useModal"; import getUserCategories from "lib/category/getUserCategories"; -import getUser from "lib/user/getUser"; import { Category, Link, SearchItem } from "types"; import { pushStateVanilla } from "utils/link"; -import { getSession } from "utils/session"; +import { withAuthentication } from "utils/session"; interface HomePageProps { categories: Category[]; currentCategory: Category | undefined; } -function Home(props: HomePageProps) { +export default function HomePage(props: HomePageProps) { const router = useRouter(); const searchModal = useModal(); @@ -193,40 +192,30 @@ function Home(props: HomePageProps) { ); } -export async function getServerSideProps({ req, res, query }) { - const queryCategoryId = (query?.categoryId as string) || ""; +export const getServerSideProps = withAuthentication( + async ({ query, session, user }) => { + const queryCategoryId = (query?.categoryId as string) || ""; - const session = await getSession(req, res); - const user = await getUser(session); - if (!user) { + const categories = await getUserCategories(user); + if (categories.length === 0) { + return { + redirect: { + destination: PATHS.CATEGORY.CREATE, + }, + }; + } + + const currentCategory = categories.find( + ({ id }) => id === Number(queryCategoryId) + ); return { - redirect: { - destination: PATHS.LOGIN, + props: { + session, + categories: JSON.parse(JSON.stringify(categories)), + currentCategory: currentCategory + ? JSON.parse(JSON.stringify(currentCategory)) + : null, }, }; } - - const categories = await getUserCategories(user); - if (categories.length === 0) { - return { - redirect: { - destination: PATHS.CATEGORY.CREATE, - }, - }; - } - - const currentCategory = categories.find( - ({ id }) => id === Number(queryCategoryId) - ); - return { - props: { - categories: JSON.parse(JSON.stringify(categories)), - currentCategory: currentCategory - ? JSON.parse(JSON.stringify(currentCategory)) - : null, - }, - }; -} - -Home.authRequired = true; -export default Home; +); diff --git a/src/pages/link/create.tsx b/src/pages/link/create.tsx index e6eb642..861c1e6 100644 --- a/src/pages/link/create.tsx +++ b/src/pages/link/create.tsx @@ -12,14 +12,17 @@ import TextBox from "components/TextBox"; import PATHS from "constants/paths"; import useAutoFocus from "hooks/useAutoFocus"; import getUserCategories from "lib/category/getUserCategories"; -import getUser from "lib/user/getUser"; import { Category, Link } from "types"; import { HandleAxiosError, IsValidURL } from "utils/front"; -import { getSession } from "utils/session"; +import { withAuthentication } from "utils/session"; import styles from "styles/form.module.scss"; -function CreateLink({ categories }: { categories: Category[] }) { +export default function PageCreateLink({ + categories, +}: { + categories: Category[]; +}) { const autoFocusRef = useAutoFocus(); const router = useRouter(); const categoryIdQuery = router.query?.categoryId as string; @@ -110,32 +113,22 @@ function CreateLink({ categories }: { categories: Category[] }) { ); } -CreateLink.authRequired = true; -export default CreateLink; +export const getServerSideProps = withAuthentication( + async ({ session, user }) => { + const categories = await getUserCategories(user); + if (categories.length === 0) { + return { + redirect: { + destination: PATHS.HOME, + }, + }; + } -export async function getServerSideProps({ req, res }) { - const session = await getSession(req, res); - const user = await getUser(session); - if (!user) { return { - redirect: { - destination: PATHS.HOME, + props: { + session, + categories: JSON.parse(JSON.stringify(categories)), }, }; } - - const categories = await getUserCategories(user); - if (categories.length === 0) { - return { - redirect: { - destination: PATHS.HOME, - }, - }; - } - - return { - props: { - categories: JSON.parse(JSON.stringify(categories)), - }, - }; -} +); diff --git a/src/pages/link/edit/[lid].tsx b/src/pages/link/edit/[lid].tsx index 117746c..c4f80d9 100644 --- a/src/pages/link/edit/[lid].tsx +++ b/src/pages/link/edit/[lid].tsx @@ -13,14 +13,13 @@ import PATHS from "constants/paths"; import useAutoFocus from "hooks/useAutoFocus"; import getUserCategories from "lib/category/getUserCategories"; import getUserLink from "lib/link/getUserLink"; -import getUser from "lib/user/getUser"; import { Category, Link } from "types"; import { HandleAxiosError, IsValidURL } from "utils/front"; -import { getSession } from "utils/session"; +import { withAuthentication } from "utils/session"; import styles from "styles/form.module.scss"; -function EditLink({ +export default function PageEditLink({ link, categories, }: { @@ -129,36 +128,26 @@ function EditLink({ ); } -EditLink.authRequired = true; -export default EditLink; +export const getServerSideProps = withAuthentication( + async ({ query, session, user }) => { + const { lid } = query; -export async function getServerSideProps({ req, res, query }) { - const { lid } = query; + const categories = await getUserCategories(user); + const link = await getUserLink(user, Number(lid)); + if (!link) { + return { + redirect: { + destination: PATHS.HOME, + }, + }; + } - const session = await getSession(req, res); - const user = await getUser(session); - if (!user) { return { - redirect: { - destination: PATHS.HOME, + props: { + session, + link: JSON.parse(JSON.stringify(link)), + categories: JSON.parse(JSON.stringify(categories)), }, }; } - - const categories = await getUserCategories(user); - const link = await getUserLink(user, Number(lid)); - if (!link) { - return { - redirect: { - destination: PATHS.HOME, - }, - }; - } - - return { - props: { - link: JSON.parse(JSON.stringify(link)), - categories: JSON.parse(JSON.stringify(categories)), - }, - }; -} +); diff --git a/src/pages/link/remove/[lid].tsx b/src/pages/link/remove/[lid].tsx index 0e4c249..64b8fe6 100644 --- a/src/pages/link/remove/[lid].tsx +++ b/src/pages/link/remove/[lid].tsx @@ -10,14 +10,13 @@ import TextBox from "components/TextBox"; import PATHS from "constants/paths"; import getUserLink from "lib/link/getUserLink"; -import getUser from "lib/user/getUser"; import { Link } from "types"; import { HandleAxiosError } from "utils/front"; -import { getSession } from "utils/session"; +import { withAuthentication } from "utils/session"; import styles from "styles/form.module.scss"; -function RemoveLink({ link }: { link: Link }) { +export default function PageRemoveLink({ link }: { link: Link }) { const router = useRouter(); const [error, setError] = useState(null); @@ -94,34 +93,24 @@ function RemoveLink({ link }: { link: Link }) { ); } -RemoveLink.authRequired = true; -export default RemoveLink; +export const getServerSideProps = withAuthentication( + async ({ query, session, user }) => { + const { lid } = query; -export async function getServerSideProps({ req, res, query }) { - const { lid } = query; + const link = await getUserLink(user, Number(lid)); + if (!link) { + return { + redirect: { + destination: PATHS.HOME, + }, + }; + } - const session = await getSession(req, res); - const user = await getUser(session); - if (!user) { return { - redirect: { - destination: PATHS.HOME, + props: { + session, + link: JSON.parse(JSON.stringify(link)), }, }; } - - const link = await getUserLink(user, Number(lid)); - if (!link) { - return { - redirect: { - destination: PATHS.HOME, - }, - }; - } - - return { - props: { - link: JSON.parse(JSON.stringify(link)), - }, - }; -} +); diff --git a/src/utils/session.ts b/src/utils/session.ts index 5dfe47c..3e88821 100644 --- a/src/utils/session.ts +++ b/src/utils/session.ts @@ -1,8 +1,36 @@ -import { NextApiRequest, NextApiResponse } from "next"; +import { + GetServerSidePropsContext, + NextApiRequest, + NextApiResponse, +} from "next"; import { getServerSession } from "next-auth/next"; +import PATHS from "constants/paths"; +import getUser from "lib/user/getUser"; import { authOptions } from "pages/api/auth/[...nextauth]"; export async function getSession(req: NextApiRequest, res: NextApiResponse) { return await getServerSession(req, res, authOptions); } + +export function withAuthentication(serverSidePropsFunc) { + return async (context: GetServerSidePropsContext) => { + const { req, res } = context; + + const session = await getSession( + req as NextApiRequest, + res as NextApiResponse + ); + const user = await getUser(session); + if (!session || !user) { + return { + redirect: { + destination: PATHS.LOGIN, + }, + }; + } + + // Continue on to call `getServerSideProps` logic + return await serverSidePropsFunc({ ...context, session, user }); + }; +}