diff --git a/src/assets/images/icons/error.svg b/src/assets/images/icons/error.svg new file mode 100644 index 0000000..3cc645e --- /dev/null +++ b/src/assets/images/icons/error.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/icons/success.svg b/src/assets/images/icons/success.svg new file mode 100644 index 0000000..cae29c3 --- /dev/null +++ b/src/assets/images/icons/success.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/AuthPages/ForgetPwdResponse.jsx b/src/components/AuthPages/ForgetPwdResponse.jsx new file mode 100644 index 0000000..013678f --- /dev/null +++ b/src/components/AuthPages/ForgetPwdResponse.jsx @@ -0,0 +1,37 @@ +import React from 'react' +import { useNavigate } from 'react-router-dom' +import localImgLoad from '../../lib/localImgLoad' + +const ForgetPwdResponse = ({title, message, type}) => { + const navigate = useNavigate() + return ( + <> +
+

+ {title} +

+
+
+ alert-banner +
+
+

+ {message} +

+
+
+
+ +
+
+ + ) +} + +export default ForgetPwdResponse \ No newline at end of file diff --git a/src/components/AuthPages/ForgotPassword/index.jsx b/src/components/AuthPages/ForgotPassword/index.jsx index e53214b..0eb7772 100644 --- a/src/components/AuthPages/ForgotPassword/index.jsx +++ b/src/components/AuthPages/ForgotPassword/index.jsx @@ -4,6 +4,8 @@ import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png"; import usersService from "../../../services/UsersService"; import InputCom from "../../Helpers/Inputs/InputCom"; import AuthLayout from "../AuthLayout"; +import EmailValidator from "../../../lib/EmailValidator"; +import ForgetPwdResponse from "../ForgetPwdResponse"; export default function ForgotPassword() { const [checked, setValue] = useState(false); @@ -11,7 +13,7 @@ export default function ForgotPassword() { // email const [email, setMail] = useState(""); const [msgError, setMsgError] = useState(""); - const [msgSuccess, setMsgSuccess] = useState(false); + const [msgSuccess, setMsgSuccess] = useState(null); const navigate = useNavigate(); const userApi = new usersService(); @@ -27,12 +29,26 @@ export default function ForgotPassword() { const resetHandler = async () => { if (email == "") { setMsgError("An email is required"); - } else if (!checked) { + return setTimeout(() => { + setMsgError(null); + }, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT); + } + if (!checked) { setMsgError("Check if you are human"); + return setTimeout(() => { + setMsgError(null); + }, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT); + } + + if(!EmailValidator(email)){ // CHECKS IF EMAIL IS VALID + setMsgError("Invalid Email"); + return setTimeout(() => { + setMsgError(null); + }, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT); } if (email !== "" && checked) { - const reqData = { email }; + const reqData = { email, action:11013 }; setResetLoading(true); try { const res = await userApi.StartResetPassword(reqData); @@ -41,8 +57,11 @@ export default function ForgotPassword() { setMail(""); setValue(false); setResetLoading(false); + }else{ + setMsgSuccess(false); } } catch (error) { + setMsgSuccess(false); setResetLoading(false); setMail(""); setMsgError("An error occurred"); @@ -53,9 +72,6 @@ export default function ForgotPassword() { }, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT); } } - setTimeout(() => { - setMsgError(null); - }, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT); }; return ( @@ -73,106 +89,102 @@ export default function ForgotPassword() {
-
-

- Forget Password -

- - Enter your email to reset your password. - -
-
-
- + {msgSuccess == null ? + <> +
+

+ Forget Password +

+ + Enter your email to reset your password. +
- {/* hCaptha clone for the time being */} -
-
-
- {/* Checkbox */} -
-
-
-
- +
+
+ +
+ {/* hCaptha clone for the time being */} +
+
+
+ {/* Checkbox */} +
+
+
+
+ +
-
-
-
-
+
+
+ {msgError && ( +
+ {msgError} +
+ )} +
+
+ +
- {msgError && ( -
- {msgError} -
- )} - {msgSuccess && ( -
- If we find your email, you will receive a link to reset your - password. Please use or{" "} - - contact form - {" "} - if you did not get our message after few minutes. -
- )} - -
-
- - -
-
-
+ + : + + }
diff --git a/src/components/AuthPages/VerifyPassword/index.jsx b/src/components/AuthPages/VerifyPassword/index.jsx index 7f8e88a..72a209e 100644 --- a/src/components/AuthPages/VerifyPassword/index.jsx +++ b/src/components/AuthPages/VerifyPassword/index.jsx @@ -1,16 +1,20 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { Link, useLocation, useNavigate } from "react-router-dom"; import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png"; import usersService from "../../../services/UsersService"; import InputCom from "../../Helpers/Inputs/InputCom"; import AuthLayout from "../AuthLayout"; +import ForgetPwdResponse from "../ForgetPwdResponse"; +import PasswordValidator from "../../../lib/PasswordValidator"; +import LoadingSpinner from "../../Spinners/LoadingSpinner"; const VerifyPassword = () => { const [password, setPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); + const [requestStatus, setRequestStatus] = useState({loading: true, status:false, data: []}) const [msgError, setMsgError] = useState(""); const [linkLoader, setLinkLoader] = useState(false); - const [linkSuccess, setLinkSuccess] = useState(true); + const [linkSuccess, setLinkSuccess] = useState(null); const [showPassword, setShowPassword] = useState(false); const navigate = useNavigate(); const location = useLocation(); @@ -23,11 +27,6 @@ const VerifyPassword = () => { setShowPassword(!showPassword); }; - // little checker for the validity of the token - if (token?.length != 64) { - setLinkSuccess(false); - } - // Password const handlePassword = (e) => { let { name, value } = e?.target; @@ -36,46 +35,60 @@ const VerifyPassword = () => { }; const completeReset = async () => { + if(!password || !confirmPassword){ // CHECKS IF PASSWORD IS EMPTY + setMsgError("Please fill in fields"); + return setTimeout(() => { + setMsgError(null); + }, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT); + } + if(password != confirmPassword){ // CHECKS IF PASSWORD EQUALS CONFIRM PASSWORD + setMsgError("Passwords does not match"); + return setTimeout(() => { + setMsgError(null); + }, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT); + } + if(password.length < 6){ // CHECKS IF PASSWORD LENGTH IS UPTO 6 CHARACTERS + setMsgError("Password must be upto six characters"); + return setTimeout(() => { + setMsgError(null); + }, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT); + } + if(!PasswordValidator(password)){ // CHECKS IF PASSWORD IS VALID + setMsgError("Password must contain alphanumeric, uppercase and special character: eg: Password1@"); + return setTimeout(() => { + setMsgError(null); + }, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT); + } try { - if (password !== "" && confirmPassword !== "") { - if (password === confirmPassword) { setLinkLoader(true); var reqData = { sessionid: "DUMMY-CANNOT_BE_EMPTY", reset_link: token, newpass: password, + m_uid: requestStatus.data?.m_uid || '', + reset_uid: requestStatus.data?.reset_uid || '', step: 300, action: 730, }; - const res = await userApi?.CompleteResetPassword(reqData); - if (res.status === 200) { + if (res.status == 200) { const { data } = res; - - if (data?.status > 0 && data?.email) { - setTimeout(() => { - navigate("/login", { replace: true }); - setLinkLoader(false); - }, 2000); - } else if (data && data?.status == "Invalid Request") { - setLinkLoader(false); - setLinkSuccess(false); + if (data?.internal_return >= 0) { + // setTimeout(() => { + // navigate("/login", { replace: true }); + // setLinkLoader(false); + // }, 2000); + setLinkSuccess(true); } else { setLinkLoader(false); setMsgError("An error occurred"); + setLinkSuccess(false); } } else { setLinkLoader(false); setLinkSuccess(false); } - } else { - setLinkLoader(false); - setMsgError("Passwords does not match"); - } - } else { - setMsgError("Please fill in fields"); - } } catch (error) { setLinkLoader(false); setLinkSuccess(false); @@ -87,6 +100,31 @@ const VerifyPassword = () => { } }; + const verifyResetPwd = () => { // FUNCTION TO VERIFY RESET PASSWORD LINK + setRequestStatus({loading: true, status:false, data: []}) + var reqData = { + sessionid: "DUMMY-CANNOT_BE_EMPTY", + reset_link: token, + step: 200, + action: 730, + }; + userApi.CompleteResetPassword(reqData).then(res => { + if(res.status != 200 || res.data.internal_return < 0){ + return setRequestStatus({loading: false, status:false, data: []}) + } + setRequestStatus({loading: false, status:true, data: res.data}) + }).catch(error => { + setRequestStatus({loading: false, status:false, data: []}) + }) + } + + useEffect(()=>{ + // little checker for the validity of the token + if (token==null || token?.length != 64) { + return setRequestStatus({loading: false, status:false, data: []}); + } + verifyResetPwd() + },[]) return ( <> @@ -101,39 +139,54 @@ const VerifyPassword = () => {
+ {requestStatus.loading ? + + : + !requestStatus.loading && requestStatus.status ?
-
-

- {linkSuccess ? "Password Reset" : "Invalid verification link"} -

- {linkSuccess && ( - - Enter a new password to reset - - )} - {linkSuccess && ( - - We'll send an email to confirm reset - - )} -
- {/* If the verification was a success */} - {linkSuccess ? ( - navigate("/login")} - /> - ) : ( - navigate("/login")} /> - )} + {linkSuccess == null ? + <> +
+

+ Password Reset +

+ + Enter a new password to reset + + + We'll send an email to confirm reset + +
+ navigate("/login")} + /> + + : + + }
+ : +
+ +
+ }
@@ -159,7 +212,7 @@ const SuccessfulComponent = ({
); - -const ErrorComponent = ({ onClick }) => ( -
-
-

- This error occurs because you have already used this link or the link - has broken/expired. Start with the reset process again. If it doesn't - work, try to create the account from the start. -

-
- -
- -
-
-); diff --git a/src/lib/EmailValidator.js b/src/lib/EmailValidator.js new file mode 100644 index 0000000..5521833 --- /dev/null +++ b/src/lib/EmailValidator.js @@ -0,0 +1,9 @@ +export default function EmailValidator(email) { + let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/; + if (regEx.test(email) == false) { + return false + }else{ + return true + } +} + \ No newline at end of file diff --git a/src/lib/PasswordValidator.js b/src/lib/PasswordValidator.js new file mode 100644 index 0000000..53b1a02 --- /dev/null +++ b/src/lib/PasswordValidator.js @@ -0,0 +1,9 @@ +export default function PasswordValidator(password) { + const regEx = /^[a-zA-Z0-9!@#$%^&*()_+{}\[\]:;<>,.?~\\/\-='"`|]+$/; + if (/[!@#$%^&*()_+{}\[\]:;<>,.?~\\/\-='"`|]/.test(password) == false || /[0-9]/.test(password)==false || /[A-Z]/.test(password)==false || /[a-z]/.test(password)==false) { + return false + }else{ + return true + } +} + \ No newline at end of file