feat: add email verification in user profile

This commit is contained in:
prafull-opensignlabs
2024-04-29 21:12:54 +05:30
parent 3599fbee21
commit c279fd6525
4 changed files with 175 additions and 8 deletions
+121 -5
View File
@@ -8,9 +8,10 @@ import sanitizeFileName from "../primitives/sanitizeFileName";
import axios from "axios";
import PremiumAlertHeader from "../primitives/PremiumAlertHeader";
import Tooltip from "../primitives/Tooltip";
import { isEnableSubscription } from "../constant/const";
import { isEnableSubscription, rejectBtn, submitBtn } from "../constant/const";
import { checkIsSubscribed } from "../constant/Utils";
import Upgrade from "../primitives/Upgrade";
import ModalUi from "../primitives/ModalUi";
function UserProfile() {
const navigate = useNavigate();
@@ -32,12 +33,16 @@ function UserProfile() {
const [jobTitle, setJobTitle] = useState(
extendUser && extendUser?.[0]?.JobTitle
);
const [isVerifyModal, setIsVerifyModal] = useState(false);
const [otp, setOtp] = useState("");
const [otpLoader, setOtpLoader] = useState(false);
const [isEmailVerified, setIsEmailVerified] = useState(false);
useEffect(() => {
getUserDetail();
}, []);
const getUserDetail = async () => {
setIsLoader(true);
const extClass = localStorage.getItem("Extand_Class");
const jsonSender = JSON.parse(extClass);
const HeaderDocId = jsonSender[0]?.HeaderDocId;
@@ -48,6 +53,9 @@ function UserProfile() {
if (HeaderDocId) {
setIsDisableDocId(HeaderDocId);
}
const isEmailVerified = Parse.User.current()?.attributes?.emailVerified;
setIsEmailVerified(isEmailVerified);
setIsLoader(false);
};
const handleSubmit = async (e) => {
e.preventDefault();
@@ -177,6 +185,50 @@ function UserProfile() {
const handleDisableDocId = () => {
setIsDisableDocId((prevChecked) => !prevChecked);
};
const handleVerifyBtn = async () => {
setIsVerifyModal(true);
await handleSendOTP();
};
const handleCloseVerifyModal = async () => {
setIsVerifyModal(false);
};
const handleSendOTP = async () => {
try {
let url = `${parseBaseUrl}functions/SendOTPMailV1/`;
const headers = {
"Content-Type": "application/json",
"X-Parse-Application-Id": parseAppId
};
const body = { email: Parse.User.current().getEmail() };
await axios.post(url, body, { headers: headers });
} catch (error) {
alert(error.message);
}
};
const handleVerifyEmail = async (e) => {
e.preventDefault();
setOtpLoader(true);
try {
const resEmail = await Parse.Cloud.run("verifyemail", {
otp: otp,
email: Parse.User.current().getEmail()
});
alert(resEmail.message);
setIsVerifyModal(false);
} catch (error) {
alert(error.message);
} finally {
setOtpLoader(false);
}
};
const handleReset = async (e) => {
e.preventDefault();
setOtpLoader(true);
await handleSendOTP();
setOtpLoader(false);
alert("OTP sent on you email");
};
return (
<React.Fragment>
<Title title={"Profile"} />
@@ -310,9 +362,20 @@ function UserProfile() {
<li className="flex justify-between items-center border-t-[1px] border-gray-300 py-2 break-all">
<span className="font-semibold">Is Email verified:</span>{" "}
<span>
{UserProfile && UserProfile.emailVerified
? "Verified"
: "Not verified"}
{isEmailVerified ? (
"Verified"
) : (
<span>
Not verified(
<span
onClick={() => handleVerifyBtn()}
className="hover:underline text-blue-600 cursor-pointer"
>
verify
</span>
)
</span>
)}
</span>
</li>
<li className="border-y-[1px] border-gray-300 break-all">
@@ -399,6 +462,59 @@ function UserProfile() {
</button>
</div>
</div>
{isVerifyModal && (
<ModalUi
isOpen
title={"OTP verification"}
handleClose={handleCloseVerifyModal}
>
{otpLoader ? (
<div
style={{
height: "150px",
display: "flex",
alignItems: "center",
justifyContent: "center"
}}
>
<div
style={{
fontSize: "45px",
color: "#3dd3e0"
}}
className="loader-37"
></div>
</div>
) : (
<form onSubmit={(e) => handleVerifyEmail(e)}>
<div className="px-6 py-3">
<label className="mb-2">Enter OTP</label>
<input
type="tel"
pattern="[0-9]{4}"
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
placeholder="Enter OTP sent on mail"
value={otp}
onChange={(e) => setOtp(e.target.value)}
/>
</div>
<hr />
<div className="px-6 my-3">
<button type="submit" className={submitBtn}>
Verify
</button>
<button
className={`${rejectBtn} ml-2`}
onClick={(e) => handleReset(e)}
>
Resend
</button>
</div>
</form>
)}
</ModalUi>
)}
</div>
)}
</React.Fragment>
+4 -2
View File
@@ -33,7 +33,8 @@ import getInvoices from './parsefunction/getInvoices.js';
import getPayments from './parsefunction/getPayments.js';
import getSubscriptions from './parsefunction/getSubscriptions.js';
import TenantAterFind from './parsefunction/TenantAfterFind.js';
import saveSubscriptio from './parsefunction/saveSubscription.js';
import saveSubscription from './parsefunction/saveSubscription.js';
import VerifyEmail from './parsefunction/VerifyEmail.js';
Parse.Cloud.define('AddUserToRole', addUserToGroups);
Parse.Cloud.define('UserGroups', getUserGroups);
@@ -70,4 +71,5 @@ Parse.Cloud.afterFind('contracts_Document', DocumentBeforeFind);
Parse.Cloud.afterFind('contracts_Template', TemplateAfterFind);
Parse.Cloud.afterFind('contracts_Signature', SignatureAfterFind);
Parse.Cloud.afterFind('partners_Tenant', TenantAterFind);
Parse.Cloud.define('savesubscription', saveSubscriptio);
Parse.Cloud.define('savesubscription', saveSubscription);
Parse.Cloud.define('verifyemail', VerifyEmail);
@@ -0,0 +1,49 @@
export default async function VerifyEmail(request) {
try {
if (!request?.user) {
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.');
} else {
let otpN = request.params.otp;
let otp = parseInt(otpN);
let email = request.params.email;
//checking otp is correct or not which already save in defaultdata_Otp class
const checkOtp = new Parse.Query('defaultdata_Otp');
checkOtp.equalTo('Email', email);
checkOtp.equalTo('OTP', otp);
const res = await checkOtp.first({ useMasterKey: true });
if (res) {
// Fetch the user by their objectId
const isEmailVerified = request?.user?.get('emailVerified');
if (isEmailVerified) {
return { message: 'Email is already verified.' };
} else {
const userQuery = new Parse.Query(Parse.User);
const user = await userQuery.get(request?.user.id, {
sessionToken: request?.user.getSessionToken(),
});
// Update the emailVerified field to true
user.set('emailVerified', true);
// Save the user object
const res = await user.save(null, { useMasterKey: true });
if (res) {
return { message: 'Email is verified.' };
} else {
const error = new Error('Something went wrong, please try again later!');
error.code = 400; // Set the error code (e.g., 400 for bad request)
throw error;
}
}
} else {
const error = new Error('OTP is invalid.');
error.code = 400; // Set the error code (e.g., 400 for bad request)
throw error;
}
}
} catch (err) {
console.log('err ', err.code + ' ' + err.message);
throw err;
}
}
@@ -1,5 +1,5 @@
import axios from 'axios';
export default async function saveSubscriptio(request) {
export default async function saveSubscription(request) {
const serverUrl = process.env.SERVER_URL;
const appId = process.env.APP_ID;
const subscription = request.params.subscription;