From d4a5aa9074bd3df7cc1bf30fc02ce23c7ad28297 Mon Sep 17 00:00:00 2001 From: PhillipChn <37224508+PhillipChn@users.noreply.github.com> Date: Thu, 26 May 2022 11:14:50 -0700 Subject: [PATCH] Update Account Page (#131) * current updates * password checking + using userContext * refined form, update userData, err checking, fix blocking * fix eslint errors * fix monitorlog path * include both vers for ProtectedRoutes --- src/App.jsx | 7 +- src/common/ProtectedRoute.jsx | 15 +- src/common/auth_utils.jsx | 34 ++++ src/components/Navbar/Navbar.jsx | 8 +- src/components/Toast.jsx | 13 +- src/pages/AccountPage.jsx | 290 +++++++++++++------------------ 6 files changed, 182 insertions(+), 185 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 2fd9d2db..b2f5edd3 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -68,10 +68,9 @@ function App() { exact path="/account" element={ - + + + } /> { * @param {Cookies} cookies The user's current cookies * @returns The relevant path to redirect the user to depending on authentication state. */ -const ProtectedRoute = ({ Component, redirectPath, roles, cookies }) => { +const ProtectedRoute = ({ Component, children, redirectPath, roles, cookies }) => { const [isLoading, setIsLoading] = useState(true); const [isAuthenticated, setIsAuthenticated] = useState(false); const { setUserData } = useUserContext(); @@ -53,13 +55,20 @@ const ProtectedRoute = ({ Component, redirectPath, roles, cookies }) => { return

LOADING...

; } if (isAuthenticated) { - return ; + const childCount = React.Children.count(children); + return childCount ? children : ; } return ; }; +ProtectedRoute.defaultProps = { + Component: PropTypes.elementType, + children: PropTypes.node, +}; + ProtectedRoute.propTypes = { - Component: PropTypes.elementType.isRequired, + Component: PropTypes.elementType, + children: PropTypes.node, redirectPath: PropTypes.string.isRequired, roles: PropTypes.arrayOf(PropTypes.string).isRequired, cookies: instanceOf(Cookies).isRequired, diff --git a/src/common/auth_utils.jsx b/src/common/auth_utils.jsx index 2e3685d5..ba21f689 100644 --- a/src/common/auth_utils.jsx +++ b/src/common/auth_utils.jsx @@ -13,6 +13,9 @@ import { sendPasswordResetEmail, confirmPasswordReset, applyActionCode, + reauthenticateWithCredential, + EmailAuthProvider, + updatePassword, } from 'firebase/auth'; import { useNavigate } from 'react-router-dom'; @@ -299,6 +302,36 @@ const addAuthInterceptor = axiosInstance => { ); }; +/** + * Cross checks old password by reauthenticating with firebase and applying changes afterwards + * @param {string} newPassword Password that the user wants to change to + * @param {string} oldPassword Previous password used to check with firebase + */ +const updateUserPassword = async (newPassword, oldPassword) => { + const user = auth.currentUser; + + const cred = EmailAuthProvider.credential(user.email, oldPassword); + + try { + await reauthenticateWithCredential(user, cred); + // User entered correct credentials + // Update password + await updatePassword(auth.currentUser, newPassword); + console.log('password updated succesfully'); + return 'success'; + } catch (e) { + console.log(e.code, e.message); + // Could be incorrect credentials + if (e.code === 'auth/wrong-password') { + return 'password'; + } + if (e.code === 'auth/weak-password') { + return 'weak'; + } + return 'error'; + } +}; + addAuthInterceptor(OCHBackend); // -------- ADMIN INVITE ROUTES START HERE ------------------------------------------ @@ -343,4 +376,5 @@ export { confirmNewPassword, confirmVerifyEmail, initiateInviteProcess, + updateUserPassword, }; diff --git a/src/components/Navbar/Navbar.jsx b/src/components/Navbar/Navbar.jsx index 84cd0877..e959d784 100644 --- a/src/components/Navbar/Navbar.jsx +++ b/src/components/Navbar/Navbar.jsx @@ -61,8 +61,12 @@ const Navbar = ({ isAdmin, onAdminPortal, setOnAdminPortal, changesMade }) => { {/* TO DO: if user is not signed in, only logo */} {isAdmin && onAdminPortal - ? admin.map(a => ) - : volunteer.map(v => )} + ? admin.map(a => ( + + )) + : volunteer.map(v => ( + + ))} {(!isAdmin || (isAdmin && !onAdminPortal)) && (