From 74dcba50f858086db7d536d5d014427b4c970019 Mon Sep 17 00:00:00 2001 From: ctc-devops <90984711+ctc-devops@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:36:10 -0700 Subject: [PATCH 1/5] Create a pull trequest for branch 85-login-errors-event-field-terminology From e67cec5320e085bf93d278edfc1a3d4cf7e96702 Mon Sep 17 00:00:00 2001 From: Lana Ramadan Date: Tue, 23 Apr 2024 14:58:51 -0700 Subject: [PATCH 2/5] Fixed login errors, event field terms, added a confirmation screen for forget password --- src/App.jsx | 4 + .../AddEventToPublishedScheduleForm.jsx | 2 +- .../Authentication/ForgotPassword.jsx | 176 ++++++++++-------- .../ForgotPasswordConfirmation.jsx | 41 ++++ src/components/Authentication/Login.jsx | 17 +- src/components/Authentication/SignUp.jsx | 10 +- src/pages/Catalog/Catalog.jsx | 4 +- 7 files changed, 163 insertions(+), 91 deletions(-) create mode 100644 src/components/Authentication/ForgotPasswordConfirmation.jsx diff --git a/src/App.jsx b/src/App.jsx index fdb9d98..f2c2372 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -8,6 +8,7 @@ import SignUp from './components/Authentication/SignUp'; import ForgotPassword from './components/Authentication/ForgotPassword'; import EmailAction from './components/Authentication/EmailAction'; import AwaitConfirmation from './components/Authentication/AwaitConfirmation'; +import ForgotPasswordConfirmation from './components/Authentication/ForgotPasswordConfirmation'; import AUTH_ROLES from './utils/auth_config'; import ProtectedRoute from './utils/ProtectedRoute'; import Catalog from './pages/Catalog/Catalog'; @@ -55,6 +56,9 @@ const App = () => { } /> } /> } /> + } /> + + { {/* SUBJECT */} - Topic + Subject { - const [email, setEmail] = useState(); + const [email, setEmail] = useState(''); + const [hasError, setHasError] = useState(false); const [errorMessage, setErrorMessage] = useState(); - const [confirmationMessage, setConfirmationMessage] = useState(); const handleForgotPassword = async e => { try { e.preventDefault(); await sendPasswordReset(email); - setConfirmationMessage( - 'If the email entered is associated with an account, you should receive an email to reset your password shortly.', - ); + setHasError(false); setErrorMessage(''); - setEmail(''); + window.location.replace("/forgotPasswordConfirmation"); } catch (err) { - setErrorMessage(err.message); + setHasError(true); + if (err.code === 'auth/invalid-email') { + setErrorMessage("Email could not be found. Please try again."); + } + else { + setErrorMessage(err.message); + } + console.log(err) } }; return ( -
- - Reset Password - Enter email address associated with account - {errorMessage &&

{errorMessage}

} -
- - - setEmail(target.value)} - placeholder="Email Address" - borderColor={"#CBD5E0"} - borderRadius= '3px' - /> - - + + + { hasError && + + { errorMessage } + + } + - - - - + + + + + - - - - -
- {confirmationMessage &&

{confirmationMessage}

} +
+ + + +
- ); }; diff --git a/src/components/Authentication/ForgotPasswordConfirmation.jsx b/src/components/Authentication/ForgotPasswordConfirmation.jsx new file mode 100644 index 0000000..1059667 --- /dev/null +++ b/src/components/Authentication/ForgotPasswordConfirmation.jsx @@ -0,0 +1,41 @@ +import { Button, Center, Link, Box, Heading, Text} from '@chakra-ui/react'; + +const ForgotPasswordConfirmation = () => { + return ( + +
+ + Instructions Sent + Please check inbox for password reset instructions. + + + + +
+
+ ); +}; + +export default ForgotPasswordConfirmation; diff --git a/src/components/Authentication/Login.jsx b/src/components/Authentication/Login.jsx index 54d1f60..44f191d 100644 --- a/src/components/Authentication/Login.jsx +++ b/src/components/Authentication/Login.jsx @@ -4,7 +4,7 @@ import { Cookies, withCookies } from '../../utils/cookie_utils'; import { logInWithEmailAndPassword, useNavigate } from '../../utils/auth_utils'; // import { logInWithEmailAndPassword , signInWithGoogle, useNavigate } from '../utils/auth_utils'; import { Box, Heading, Text, FormControl, Input, Button, Center, Link, Alert, AlertDescription } from '@chakra-ui/react'; -// import styles from +// import styles from const Login = ({ cookies }) => { const navigate = useNavigate(); @@ -20,7 +20,12 @@ const Login = ({ cookies }) => { window.location.reload(true); } catch (err) { setHasError(true); - setErrorMessage(err.message); + if (err.code === 'auth/invalid-credential') { + setErrorMessage("Account could not be found with given information. Please check your username or password and try again."); + } + else { + setErrorMessage(err.message); + } } }; @@ -28,7 +33,7 @@ const Login = ({ cookies }) => { { hasError && - { setEmail(target.value)} placeholder="Email" borderColor={"#CBD5E0"} @@ -68,6 +74,7 @@ const Login = ({ cookies }) => { setPassword(target.value)} placeholder="Password" borderColor={"#CBD5E0"} @@ -97,7 +104,7 @@ const Login = ({ cookies }) => { color={'#155696'} variant='outline' onMouseOver={(e) => { - e.target.style.backgroundColor = '#E0E0E0'; + e.target.style.backgroundColor = '#E0E0E0'; }} onMouseOut={(e) => { e.target.style.backgroundColor = '#FFFFFF'; @@ -119,7 +126,7 @@ const Login = ({ cookies }) => { backgroundColor={'#243268'} color={'#ffffff'} onMouseOver={(e) => { - e.target.style.backgroundColor = '#1A2559'; + e.target.style.backgroundColor = '#1A2559'; }} onMouseOut={(e) => { e.target.style.backgroundColor = '#243268'; diff --git a/src/components/Authentication/SignUp.jsx b/src/components/Authentication/SignUp.jsx index 95a1c98..7ea3319 100644 --- a/src/components/Authentication/SignUp.jsx +++ b/src/components/Authentication/SignUp.jsx @@ -21,7 +21,7 @@ const SignUp = () => { const [submitted, setSubmitted] = useState(false); const navigate = useNavigate(); - + const handleSubmit = async (e) => { e.preventDefault(); try { @@ -47,11 +47,11 @@ const SignUp = () => { // register email and password await registerWithEmailAndPassword(email, password, USER_ROLE, navigate, '/awaitConfirmation', firstName, lastName); - // send email to Debbie + // send email to Debbie const subject = "New User Created Account"; const newEmail = email; await sendEmail(subject, newEmail, emailtemplate); - + setSubmitted(true); } catch (error) { @@ -60,7 +60,7 @@ const SignUp = () => { setErrorMessage(error.message); } }; - + if (userType === null) { return (
@@ -140,7 +140,7 @@ const SignUp = () => { { hasError && - - - + + Date: Mon, 29 Apr 2024 19:58:07 -0700 Subject: [PATCH 3/5] reset + create new pwd, new pwd confirmation, account pending screen --- src/App.jsx | 7 + .../Authentication/AccountPendingApproval.jsx | 33 ++++ .../Authentication/CreateNewPassword.jsx | 145 ++++++++++++++++++ .../CreateNewPasswordConfirmation.jsx | 33 ++++ src/components/Authentication/EmailAction.jsx | 5 +- .../Authentication/ResetPassword.jsx | 59 ------- src/components/Authentication/SignUp.jsx | 44 +++--- 7 files changed, 242 insertions(+), 84 deletions(-) create mode 100644 src/components/Authentication/AccountPendingApproval.jsx create mode 100644 src/components/Authentication/CreateNewPassword.jsx create mode 100644 src/components/Authentication/CreateNewPasswordConfirmation.jsx delete mode 100644 src/components/Authentication/ResetPassword.jsx diff --git a/src/App.jsx b/src/App.jsx index f2c2372..cb3cad2 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -7,8 +7,11 @@ import Logout from './components/Authentication/Logout'; import SignUp from './components/Authentication/SignUp'; import ForgotPassword from './components/Authentication/ForgotPassword'; import EmailAction from './components/Authentication/EmailAction'; +import AccountPendingApproval from './components/Authentication/EmailAction'; import AwaitConfirmation from './components/Authentication/AwaitConfirmation'; import ForgotPasswordConfirmation from './components/Authentication/ForgotPasswordConfirmation'; +import CreateNewPasswordConfirmation from './components/Authentication/CreateNewPasswordConfirmation'; +import CreateNewPassword from './components/Authentication/CreateNewPassword'; import AUTH_ROLES from './utils/auth_config'; import ProtectedRoute from './utils/ProtectedRoute'; import Catalog from './pages/Catalog/Catalog'; @@ -54,9 +57,13 @@ const App = () => { } /> } /> } /> + } /> + } /> } /> } /> + } /> + } /> { + + return ( +
+ + Account Pending Approval +
+ + + +
+
+
+ ) +}; + +export default AccountPendingApproval; diff --git a/src/components/Authentication/CreateNewPassword.jsx b/src/components/Authentication/CreateNewPassword.jsx new file mode 100644 index 0000000..7c55dbc --- /dev/null +++ b/src/components/Authentication/CreateNewPassword.jsx @@ -0,0 +1,145 @@ +import { useState } from 'react'; +import PropTypes from 'prop-types'; +import { confirmNewPassword } from '../../utils/auth_utils'; +import { FormControl, Input, Button, Center, Link, Box, Heading, Text, Alert, AlertDescription} from '@chakra-ui/react'; + +const CreateNewPassword = ({ code }) => { + const [password, setPassword] = useState(''); + const [checkPassword, setCheckPassword] = useState(''); + const [hasError, setHasError] = useState(false); + const [errorMessage, setErrorMessage] = useState(); + + const handleResetPassword = async e => { + try { + e.preventDefault(); + setHasError(false); + if (password !== checkPassword) { + throw new Error("Passwords do not match."); + } + await confirmNewPassword(code, password); + setErrorMessage(''); + setPassword(''); + window.location.replace("/createNewPasswordConfirmation"); + } catch (err) { + setHasError(true); + console.log(err.message); + if (err.code === "auth/weak-password"){ + setErrorMessage("Password must be at least 6 characters."); + } else if (err.code === "auth/invalid-action-code"){ + setErrorMessage("Link has expired."); + } else { + setErrorMessage(err.message); + } + } + }; + return ( + + + { hasError && + + { errorMessage } + + } + + +
+ + Enter New Password + Please enter a new password. +
+ + + setPassword(target.value)} + placeholder="Enter new password" + borderColor={"#CBD5E0"} + borderRadius= '3px' + type="password" + /> + setCheckPassword(target.value)} + placeholder="Re-enter password" + borderColor={"#CBD5E0"} + borderRadius= '3px' + type="password" + /> + + + + + + + + + + +
+
+
+
+ ); +}; + +CreateNewPassword.propTypes = { + code: PropTypes.string.isRequired, +}; + +export default CreateNewPassword; diff --git a/src/components/Authentication/CreateNewPasswordConfirmation.jsx b/src/components/Authentication/CreateNewPasswordConfirmation.jsx new file mode 100644 index 0000000..449f544 --- /dev/null +++ b/src/components/Authentication/CreateNewPasswordConfirmation.jsx @@ -0,0 +1,33 @@ +import { Box, Heading, Button, Center, Link} from '@chakra-ui/react'; + +const CreateNewPasswordConfirmation = () => { + + return ( +
+ + Password Successfully Reset +
+ + + +
+
+
+ ) +}; + +export default CreateNewPasswordConfirmation; diff --git a/src/components/Authentication/EmailAction.jsx b/src/components/Authentication/EmailAction.jsx index 0014d09..d50744e 100644 --- a/src/components/Authentication/EmailAction.jsx +++ b/src/components/Authentication/EmailAction.jsx @@ -1,7 +1,7 @@ // import React from 'react'; import { useLocation, Navigate } from 'react-router-dom'; import PropTypes from 'prop-types'; -import ResetPassword from './ResetPassword'; +import CreateNewPassword from './CreateNewPassword'; import VerifyEmail from './VerifyEmail'; const EmailAction = ({ redirectPath }) => { @@ -12,7 +12,8 @@ const EmailAction = ({ redirectPath }) => { if (code === null) { return ; } - return mode === 'resetPassword' ? : ; + + return mode === 'resetPassword' ? : ; }; EmailAction.propTypes = { diff --git a/src/components/Authentication/ResetPassword.jsx b/src/components/Authentication/ResetPassword.jsx deleted file mode 100644 index 0c1ae26..0000000 --- a/src/components/Authentication/ResetPassword.jsx +++ /dev/null @@ -1,59 +0,0 @@ -import { useState } from 'react'; -import PropTypes from 'prop-types'; -import { confirmNewPassword } from '../../utils/auth_utils'; - -const ResetPassword = ({ code }) => { - const [password, setPassword] = useState(); - const [checkPassword, setCheckPassword] = useState(); - const [errorMessage, setErrorMessage] = useState(); - const [confirmationMessage, setConfirmationMessage] = useState(); - const handleResetPassword = async e => { - try { - e.preventDefault(); - if (password !== checkPassword) { - throw new Error("Passwords don't match"); - } - await confirmNewPassword(code, password); - setConfirmationMessage('Password changed. You can now sign in with your new password.'); - setErrorMessage(''); - setPassword(''); - } catch (err) { - setErrorMessage(err.message); - } - }; - return ( -
-

Reset Password

- {errorMessage &&

{errorMessage}

} - {!confirmationMessage && ( -
- setPassword(target.value)} - placeholder="New Password" - /> -
- setCheckPassword(target.value)} - placeholder="Re-enter Password" - /> -
- -
- )} - {confirmationMessage && ( -
-

{confirmationMessage}

- Back to Login -
- )} -
- ); -}; - -ResetPassword.propTypes = { - code: PropTypes.string.isRequired, -}; - -export default ResetPassword; diff --git a/src/components/Authentication/SignUp.jsx b/src/components/Authentication/SignUp.jsx index c43bb23..b444fd3 100644 --- a/src/components/Authentication/SignUp.jsx +++ b/src/components/Authentication/SignUp.jsx @@ -6,7 +6,7 @@ import emailtemplate from '../EmailTemplates/emailtemplate'; import { Box, Heading, Text, FormControl, Button, Center, Link, Input, Alert, AlertDescription } from '@chakra-ui/react'; import AUTH_ROLES from '../../utils/auth_config'; -const { ADMIN_ROLE, USER_ROLE } = AUTH_ROLES.AUTH_ROLES; +const { USER_ROLE } = AUTH_ROLES.AUTH_ROLES; const SignUp = () => { const [firstName, setFirstName] = useState(); @@ -24,28 +24,14 @@ const SignUp = () => { const handleSubmit = async (e) => { e.preventDefault(); + setHasError(false); try { - if (firstName === undefined) { - throw new Error("Must enter a first name."); - } - if (lastName === undefined) { - throw new Error("Must enter a last name."); - } - if (email === undefined) { - throw new Error("Must enter an email"); - } - if (password === undefined) { - throw new Error("Must enter a password."); - } if (password !== checkPassword) { throw new Error("Passwords don't match."); } - if (password.length < 6) { - throw new Error("Password must be at least 6 characters."); - } // register email and password - await registerWithEmailAndPassword(email, password, userType, navigate, '/awaitConfirmation', firstName, lastName); + await registerWithEmailAndPassword(email, password, USER_ROLE, navigate, '/awaitConfirmation', firstName, lastName); // send email to Debbie const subject = "New User Created Account"; @@ -54,10 +40,17 @@ const SignUp = () => { setSubmitted(true); - } catch (error) { - console.log(error); - setHasError(true) - setErrorMessage(error.message); + } catch (err) { + setHasError(true); + if (err.code === 'auth/email-already-in-use') { + setErrorMessage("Account associated with email exists."); + } + else if (err.code === 'auth/weak-password') { + setErrorMessage("Password must be at least 6 characters."); + } + else { + setErrorMessage(err.message); + } } }; @@ -86,7 +79,7 @@ const SignUp = () => { }} > + +
+
+ +
+); }; VerifyEmail.propTypes = { From 957dd1f32b6beaa5b10de08027b5ece320a4dcb6 Mon Sep 17 00:00:00 2001 From: Lana Ramadan Date: Mon, 29 Apr 2024 20:14:35 -0700 Subject: [PATCH 5/5] remove createnewpassword from app.jsx --- src/App.jsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index cb3cad2..c1528d0 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -11,7 +11,6 @@ import AccountPendingApproval from './components/Authentication/EmailAction'; import AwaitConfirmation from './components/Authentication/AwaitConfirmation'; import ForgotPasswordConfirmation from './components/Authentication/ForgotPasswordConfirmation'; import CreateNewPasswordConfirmation from './components/Authentication/CreateNewPasswordConfirmation'; -import CreateNewPassword from './components/Authentication/CreateNewPassword'; import AUTH_ROLES from './utils/auth_config'; import ProtectedRoute from './utils/ProtectedRoute'; import Catalog from './pages/Catalog/Catalog'; @@ -58,14 +57,11 @@ const App = () => { } /> } /> } /> - } /> } /> } /> - } /> } /> -