From 883956a0ae3b7326d05efdfaa88cdcc2757f41a9 Mon Sep 17 00:00:00 2001 From: John Paul Banera <93037350+impaulintech@users.noreply.github.com> Date: Mon, 7 Nov 2022 12:28:04 +0800 Subject: [PATCH] [BarClerk-551] - [FE] Implement Route Protection (#9) --- README.md | 48 +++++++++++++++-- client/pages/forgot-password.tsx | 1 + client/pages/index.tsx | 1 + client/pages/sign-in.tsx | 1 + client/pages/sign-up.tsx | 1 + client/utils/getServerSideProps.ts | 83 ++++++++++++++++++++++++++++++ 6 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 client/utils/getServerSideProps.ts diff --git a/README.md b/README.md index b7e16fd..133826f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,43 @@ -## BARCLERK -### API -- https://barclerk.herokuapp.com/api -### Client: -- https://barclerk.vercel.app +## BARCLERK +# Description + +This tool/application aims to solve problems faced by legal practitioners in Western Australia particularly when it comes to matters from Legal Aid. Such problems include tracking the list of all the matters from Legal Aid, as well as billing. + +## 🔗 Links + +- Client :: https://barclerk.vercel.app +- Server :: https://barclerk.herokuapp.com/api + +## Developers + +- [@AJ](https://github.com/abduljalilpalala) +- [@John](https://github.com/johnpaul-sun) +- [@Joshua](https://github.com/jsvelte) + +## Quality Assurance + +- [@AJ](https://github.com/abduljalilpalala) +- [@John](https://github.com/johnpaul-sun) +- [@Joshua](https://github.com/jsvelte) + +## License + +[![MIT License](https://img.shields.io/apm/l/atomic-design-ui.svg?)](https://github.com/tterb/atomic-design-ui/blob/master/LICENSEs) +[![AGPL License](https://img.shields.io/badge/license-AGPL-blue.svg)](http://www.gnu.org/licenses/agpl-3.0) +[![GPLv3 License](https://img.shields.io/badge/License-GPL%20v3-yellow.svg)](https://opensource.org/licenses/) + +## Tech Stack + +**Client:** +- Next.js +- Redux Toolkit +- Redux Thunk +- TailwindCSS + +**Server:** +- Laravel +- MySQL + +## Appendix + +Any additional information goes here diff --git a/client/pages/forgot-password.tsx b/client/pages/forgot-password.tsx index 1d7828f..9e4d332 100644 --- a/client/pages/forgot-password.tsx +++ b/client/pages/forgot-password.tsx @@ -129,4 +129,5 @@ const ForgotPassword = () => { ); }; +export { authCheck as getServerSideProps } from 'utils/getServerSideProps'; export default ForgotPassword; diff --git a/client/pages/index.tsx b/client/pages/index.tsx index 26706e6..5321c0a 100644 --- a/client/pages/index.tsx +++ b/client/pages/index.tsx @@ -12,3 +12,4 @@ export default function Home() { ) } +export { authCheck as getServerSideProps } from 'utils/getServerSideProps'; diff --git a/client/pages/sign-in.tsx b/client/pages/sign-in.tsx index ed5c563..2769473 100644 --- a/client/pages/sign-in.tsx +++ b/client/pages/sign-in.tsx @@ -100,4 +100,5 @@ const SignIn = () => { ); }; +export { SignInUpAuthChecker as getServerSideProps } from 'utils/getServerSideProps'; export default SignIn; diff --git a/client/pages/sign-up.tsx b/client/pages/sign-up.tsx index 5a63021..e608d61 100644 --- a/client/pages/sign-up.tsx +++ b/client/pages/sign-up.tsx @@ -99,4 +99,5 @@ const SignUp = () => { ); }; +export { SignInUpAuthChecker as getServerSideProps } from 'utils/getServerSideProps'; export default SignUp; diff --git a/client/utils/getServerSideProps.ts b/client/utils/getServerSideProps.ts new file mode 100644 index 0000000..8443324 --- /dev/null +++ b/client/utils/getServerSideProps.ts @@ -0,0 +1,83 @@ +import { GetServerSideProps } from 'next'; + +import { setAuth } from 'redux/auth/authSlice'; +import { wrapper } from 'redux/store'; +import { axios } from 'shared/lib/axios'; + +export const SignInUpAuthChecker: GetServerSideProps = + wrapper.getServerSideProps((store) => async ({ req }) => { + const token = req.cookies['token']; + const config = { headers: { Authorization: `Bearer ${token}` } }; + + try { + const res = await axios.get('/auth', config); + + if (res.data) { + store.dispatch(setAuth(res.data)); + + return { + redirect: { + permanent: false, + destination: '/', + }, + props: req, + }; + } + } catch (error: any) {} + + return { + props: {}, + }; + }); + +export const authCheck: GetServerSideProps = wrapper.getServerSideProps( + (store) => + async ({ req, params }) => { + const token = req.cookies['token']; + const config = { headers: { Authorization: `Bearer ${token}` } }; + + try { + const res = await axios.get('/auth', config); + store.dispatch(setAuth(res.data)); + + const forgotPasswordPage = req.url?.includes('forgot-password'); + const linkClicked = + req.url?.includes('user') && req.url?.includes('verified'); + + if (forgotPasswordPage) { + if (!token) return { props: {} }; + if (linkClicked) return { props: {} }; + + return { + redirect: { + permanent: false, + destination: '/', + }, + }; + } + } catch (error: any) { + const forgotPasswordPage = req.url?.includes('forgot-password'); + + if (forgotPasswordPage) return { props: {} }; + if (error.response.status === 404) { + return { + notFound: true, + }; + } + if (error.response.status === 500) { + throw new Error('Internal Server Error'); + } + return { + redirect: { + permanent: false, + destination: '/sign-in', + }, + props: {}, + }; + } + + return { + props: {}, + }; + } +);