From ee18f82fa928ea8e045f3c67fcf95f78f0afc583 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Fri, 3 May 2024 20:11:57 +0530 Subject: [PATCH 1/7] fix: verify email otp varification for inProgress reports --- apps/OpenSign/src/constant/Utils.js | 13 ++ apps/OpenSign/src/pages/PdfRequestFiles.js | 230 ++++++++++++++++++++- apps/OpenSign/src/pages/PlaceHolderSign.js | 165 +++++++++++++-- apps/OpenSign/src/pages/UserProfile.js | 17 +- 4 files changed, 404 insertions(+), 21 deletions(-) diff --git a/apps/OpenSign/src/constant/Utils.js b/apps/OpenSign/src/constant/Utils.js index ab4f4e9a6..8823a4863 100644 --- a/apps/OpenSign/src/constant/Utils.js +++ b/apps/OpenSign/src/constant/Utils.js @@ -2008,3 +2008,16 @@ export const convertPdfArrayBuffer = async (url) => { return "Error"; } }; +export const handleSendOTP = async (email) => { + try { + let url = `${localStorage.getItem("baseUrl")}functions/SendOTPMailV1`; + const headers = { + "Content-Type": "application/json", + "X-Parse-Application-Id": localStorage.getItem("parseAppId") + }; + const body = { email: email }; + await axios.post(url, body, { headers: headers }); + } catch (error) { + alert(error.message); + } +}; diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.js b/apps/OpenSign/src/pages/PdfRequestFiles.js index 50be8ced4..15a3dd903 100644 --- a/apps/OpenSign/src/pages/PdfRequestFiles.js +++ b/apps/OpenSign/src/pages/PdfRequestFiles.js @@ -1,7 +1,13 @@ import React, { useState, useRef, useEffect } from "react"; -import { isEnableSubscription, themeColor } from "../constant/const"; +import { + isEnableSubscription, + rejectBtn, + submitBtn, + themeColor +} from "../constant/const"; import { PDFDocument } from "pdf-lib"; import "../styles/signature.css"; +import Parse from "parse"; import axios from "axios"; import loader from "../assets/images/loader2.gif"; import { DndProvider } from "react-dnd"; @@ -25,7 +31,8 @@ import { replaceMailVaribles, fetchSubscription, convertPdfArrayBuffer, - contractUsers + contractUsers, + handleSendOTP } from "../constant/Utils"; import Loader from "../primitives/LoaderWithMsg"; import HandleError from "../primitives/HandleError"; @@ -57,10 +64,12 @@ function PdfRequestFiles() { const imageRef = useRef(null); const [handleError, setHandleError] = useState(); const [selectWidgetId, setSelectWidgetId] = useState(""); + const [otpLoader, setOtpLoader] = useState(false); const [isLoading, setIsLoading] = useState({ isLoad: true, message: "This might take some time" }); + const [defaultSignImg, setDefaultSignImg] = useState(); const [isDocId, setIsDocId] = useState(false); const [pdfNewWidth, setPdfNewWidth] = useState(); @@ -100,6 +109,9 @@ function PdfRequestFiles() { const [isSubscriptionExpired, setIsSubscriptionExpired] = useState(false); const [extUserId, setExtUserId] = useState(""); const [pdfArrayBuffer, setPdfArrayBuffer] = useState(""); + const [isEmailVerified, setIsEmailVerified] = useState(true); + const [isVerifyModal, setIsVerifyModal] = useState(false); + const [otp, setOtp] = useState(""); const divRef = useRef(null); const isMobile = window.innerWidth < 767; const rowLevel = @@ -139,6 +151,41 @@ function PdfRequestFiles() { // eslint-disable-next-line react-hooks/exhaustive-deps }, [divRef.current]); + const handleReset = async (e) => { + e.preventDefault(); + setOtpLoader(true); + await handleSendOTP(Parse.User.current().getEmail()); + setOtpLoader(false); + alert("OTP sent on you email"); + }; + const handleVerifyEmail = async (e) => { + e.preventDefault(); + setOtpLoader(true); + try { + const resEmail = await Parse.Cloud.run("verifyemail", { + otp: otp, + email: Parse.User.current().getEmail() + }); + if (resEmail?.message === "Email is verified.") { + setIsEmailVerified(true); + } else if (resEmail?.message === "Email is already verified.") { + setIsEmailVerified(true); + } + setOtp(""); + alert(resEmail.message); + setIsVerifyModal(false); + // handleRecipientSign(); + } catch (error) { + alert(error.message); + } finally { + setOtpLoader(false); + } + }; + + const handleVerifyBtn = async () => { + setIsVerifyModal(true); + await handleSendOTP(Parse.User.current().getEmail()); + }; async function checkIsSubscribed(extUserId, contactId) { const isGuestSign = location.pathname.includes("/load/") || false; const res = await fetchSubscription(extUserId, contactId, isGuestSign); @@ -238,6 +285,22 @@ function PdfRequestFiles() { setExpiredDate(expireDateFormat); } + const isGuestSign = location.pathname.includes("/load/"); + if ( + !isGuestSign && + !isCompleted && + !declined && + currDate < expireUpdateDate + ) { + const userQuery = new Parse.Query(Parse.User); + const user = await userQuery.get(jsonSender.objectId, { + sessionToken: localStorage.getItem("accesstoken") + }); + if (user) { + const isEmailVerified = user?.get("emailVerified"); + setIsEmailVerified(isEmailVerified); + } + } if (documentData.length > 0) { const checkDocIdExist = documentData[0].AuditTrail && @@ -1179,6 +1242,83 @@ function PdfRequestFiles() { headMsg="Document Expired!" bodyMssg={`This document expired on ${expiredDate} and is no longer available to sign.`} /> + {!isEmailVerified && ( +
+
+
+ OTP verification +
+ {isVerifyModal ? ( +
{ + setIsVerifyModal(false); + handleVerifyEmail(e); + }} + > +
+ + setOtp(e.target.value)} + /> +
+
+
+ + +
+
+ ) : otpLoader ? ( +
+
+
+ ) : ( +
+

Please verify your email !

+
+
+ +
+
+ )} +
+
+ )} + + {/* {isVerifyModal && ( + + {otpLoader ? ( +
+
+
+ ) : ( +
handleVerifyEmail(e)}> +
+ + setOtp(e.target.value)} + /> +
+
+
+ + +
+
+ )} +
+ )} */} + {/* {!isEmailVerified && ( + { + setValidateAlert(false); + }} + > +
+

Please verify your email !

+ +
+ +
+
+ )} */} )} diff --git a/apps/OpenSign/src/pages/PlaceHolderSign.js b/apps/OpenSign/src/pages/PlaceHolderSign.js index d161c032b..30b6071e6 100644 --- a/apps/OpenSign/src/pages/PlaceHolderSign.js +++ b/apps/OpenSign/src/pages/PlaceHolderSign.js @@ -3,7 +3,12 @@ import axios from "axios"; import Parse from "parse"; import "../styles/signature.css"; import { PDFDocument } from "pdf-lib"; -import { isEnableSubscription, themeColor } from "../constant/const"; +import { + isEnableSubscription, + rejectBtn, + submitBtn, + themeColor +} from "../constant/const"; import { DndProvider } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; import { useDrag, useDrop } from "react-dnd"; @@ -34,7 +39,8 @@ import { replaceMailVaribles, copytoData, fetchSubscription, - convertPdfArrayBuffer + convertPdfArrayBuffer, + handleSendOTP } from "../constant/Utils"; import RenderPdf from "../components/pdf/RenderPdf"; import { useNavigate } from "react-router-dom"; @@ -84,6 +90,7 @@ function PlaceHolderSign() { const [pdfOriginalWidth, setPdfOriginalWidth] = useState(); const [contractName, setContractName] = useState(""); const [containerWH, setContainerWH] = useState(); + const [otpLoader, setOtpLoader] = useState(false); const { docId } = useParams(); const signRef = useRef(null); const dragRef = useRef(null); @@ -124,6 +131,9 @@ function PlaceHolderSign() { const [requestBody, setRequestBody] = useState(""); const [pdfArrayBuffer, setPdfArrayBuffer] = useState(""); const [activeMailAdapter, setActiveMailAdapter] = useState(""); + const [isEmailVerified, setIsEmailVerified] = useState(false); + const [isVerifyModal, setIsVerifyModal] = useState(false); + const [otp, setOtp] = useState(""); const [isAlreadyPlace, setIsAlreadyPlace] = useState({ status: false, message: "" @@ -251,9 +261,63 @@ function PlaceHolderSign() { navigate(`/subscription`); } } + const handleVerifyBtn = async () => { + setIsVerifyModal(true); + await handleSendOTP(Parse.User.current().getEmail()); + }; + + const handleReset = async (e) => { + e.preventDefault(); + setOtpLoader(true); + await handleSendOTP(Parse.User.current().getEmail()); + setOtpLoader(false); + alert("OTP sent on you email"); + }; + const handleVerifyEmail = async (e) => { + e.preventDefault(); + setOtpLoader(true); + try { + const resEmail = await Parse.Cloud.run("verifyemail", { + otp: otp, + email: Parse.User.current().getEmail() + }); + if (resEmail?.message === "Email is verified.") { + setIsEmailVerified(true); + } else if (resEmail?.message === "Email is already verified.") { + setIsEmailVerified(true); + } + setOtp(""); + alert(resEmail.message); + setIsVerifyModal(false); + handleRecipientSign(); + } catch (error) { + alert(error.message); + } finally { + setOtpLoader(false); + } + }; + const handleCloseVerifyModal = async () => { + setIsVerifyModal(false); + }; //function for get document details const getDocumentDetails = async () => { fetchTenantDetails(); + + const jsonSender = JSON.parse( + localStorage.getItem( + `Parse/${localStorage.getItem("parseAppId")}/currentUser` + ) + ); + // const isEmailVerified = Parse.User.current()?.attributes?.emailVerified; + const userQuery = new Parse.Query(Parse.User); + const user = await userQuery.get(jsonSender.objectId, { + sessionToken: localStorage.getItem("accesstoken") + }); + if (user) { + const isEmailVerified = user?.get("emailVerified"); + setIsEmailVerified(isEmailVerified); + } + //getting document details const documentData = await contractDocument(documentId); if (documentData && documentData.length > 0) { @@ -1837,21 +1901,36 @@ function PlaceHolderSign() { marginBottom: "15px" }} > - {isCurrUser && ( - - )} + {isCurrUser && + (isEmailVerified ? ( + + ) : ( + + ))} + + + + )} + + )} ); diff --git a/apps/OpenSign/src/pages/UserProfile.js b/apps/OpenSign/src/pages/UserProfile.js index 69b491468..ff5e19d17 100644 --- a/apps/OpenSign/src/pages/UserProfile.js +++ b/apps/OpenSign/src/pages/UserProfile.js @@ -53,8 +53,21 @@ function UserProfile() { if (HeaderDocId) { setIsDisableDocId(HeaderDocId); } - const isEmailVerified = Parse.User.current()?.attributes?.emailVerified; - setIsEmailVerified(isEmailVerified); + const currentUser = JSON.parse( + localStorage.getItem( + `Parse/${localStorage.getItem("parseAppId")}/currentUser` + ) + ); + // const isEmailVerified = Parse.User.current()?.attributes?.emailVerified; + const userQuery = new Parse.Query(Parse.User); + const user = await userQuery.get(currentUser.objectId, { + sessionToken: localStorage.getItem("accesstoken") + }); + if (user) { + const isEmailVerified = user?.get("emailVerified"); + setIsEmailVerified(isEmailVerified); + } + setIsLoader(false); }; const handleSubmit = async (e) => { From 9daed4a5ed1b9ae9a29acd7d853032fa6310d34f Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Fri, 3 May 2024 20:19:38 +0530 Subject: [PATCH 2/7] refactor : remove commented code --- apps/OpenSign/src/pages/PdfRequestFiles.js | 86 ---------------------- 1 file changed, 86 deletions(-) diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.js b/apps/OpenSign/src/pages/PdfRequestFiles.js index 15a3dd903..eae720d62 100644 --- a/apps/OpenSign/src/pages/PdfRequestFiles.js +++ b/apps/OpenSign/src/pages/PdfRequestFiles.js @@ -1698,92 +1698,6 @@ function PdfRequestFiles() { - - {/* {isVerifyModal && ( - - {otpLoader ? ( -
-
-
- ) : ( -
handleVerifyEmail(e)}> -
- - setOtp(e.target.value)} - /> -
-
-
- - -
-
- )} -
- )} */} - {/* {!isEmailVerified && ( - { - setValidateAlert(false); - }} - > -
-

Please verify your email !

- -
- -
-
- )} */} )} From c240eb133d4f298bde71c0dfb9c1099826dcb4f6 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Sun, 5 May 2024 15:53:51 +0530 Subject: [PATCH 3/7] fix: add verify email otp verification in signyour-self flow --- .../src/components/pdf/VerifyEmail.js | 84 +++++++++ apps/OpenSign/src/pages/PdfRequestFiles.js | 93 ++-------- apps/OpenSign/src/pages/PlaceHolderSign.js | 164 ++---------------- apps/OpenSign/src/pages/SignyourselfPdf.js | 68 +++++++- 4 files changed, 180 insertions(+), 229 deletions(-) create mode 100644 apps/OpenSign/src/components/pdf/VerifyEmail.js diff --git a/apps/OpenSign/src/components/pdf/VerifyEmail.js b/apps/OpenSign/src/components/pdf/VerifyEmail.js new file mode 100644 index 000000000..1387efb42 --- /dev/null +++ b/apps/OpenSign/src/components/pdf/VerifyEmail.js @@ -0,0 +1,84 @@ +import React from "react"; +import { rejectBtn, submitBtn, themeColor } from "../../constant/const"; + +function VerifyEmail(props) { + return ( +
+
+
+ OTP verification +
+ {props.isVerifyModal ? ( +
{ + props.setIsVerifyModal(false); + props.handleVerifyEmail(e); + }} + > +
+ + props.setOtp(e.target.value)} + /> +
+
+
+ + +
+
+ ) : props.otpLoader ? ( +
+
+
+ ) : ( +
+

Please verify your email !

+
+
+ +
+
+ )} +
+
+ ); +} + +export default VerifyEmail; diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.js b/apps/OpenSign/src/pages/PdfRequestFiles.js index eae720d62..36c8c477f 100644 --- a/apps/OpenSign/src/pages/PdfRequestFiles.js +++ b/apps/OpenSign/src/pages/PdfRequestFiles.js @@ -1,10 +1,5 @@ import React, { useState, useRef, useEffect } from "react"; -import { - isEnableSubscription, - rejectBtn, - submitBtn, - themeColor -} from "../constant/const"; +import { isEnableSubscription, themeColor } from "../constant/const"; import { PDFDocument } from "pdf-lib"; import "../styles/signature.css"; import Parse from "parse"; @@ -42,6 +37,7 @@ import PdfDeclineModal from "../primitives/PdfDeclineModal"; import Title from "../components/Title"; import DefaultSignature from "../components/pdf/DefaultSignature"; import ModalUi from "../primitives/ModalUi"; +import VerifyEmail from "../components/pdf/VerifyEmail"; function PdfRequestFiles() { const { docId } = useParams(); @@ -1243,81 +1239,16 @@ function PdfRequestFiles() { bodyMssg={`This document expired on ${expiredDate} and is no longer available to sign.`} /> {!isEmailVerified && ( -
-
-
- OTP verification -
- {isVerifyModal ? ( -
{ - setIsVerifyModal(false); - handleVerifyEmail(e); - }} - > -
- - setOtp(e.target.value)} - /> -
-
-
- - -
-
- ) : otpLoader ? ( -
-
-
- ) : ( -
-

Please verify your email !

-
-
- -
-
- )} -
-
+ )} { - setIsVerifyModal(true); - await handleSendOTP(Parse.User.current().getEmail()); - }; - const handleReset = async (e) => { - e.preventDefault(); - setOtpLoader(true); - await handleSendOTP(Parse.User.current().getEmail()); - setOtpLoader(false); - alert("OTP sent on you email"); - }; - const handleVerifyEmail = async (e) => { - e.preventDefault(); - setOtpLoader(true); - try { - const resEmail = await Parse.Cloud.run("verifyemail", { - otp: otp, - email: Parse.User.current().getEmail() - }); - if (resEmail?.message === "Email is verified.") { - setIsEmailVerified(true); - } else if (resEmail?.message === "Email is already verified.") { - setIsEmailVerified(true); - } - setOtp(""); - alert(resEmail.message); - setIsVerifyModal(false); - handleRecipientSign(); - } catch (error) { - alert(error.message); - } finally { - setOtpLoader(false); - } - }; - const handleCloseVerifyModal = async () => { - setIsVerifyModal(false); - }; //function for get document details const getDocumentDetails = async () => { fetchTenantDetails(); - - const jsonSender = JSON.parse( - localStorage.getItem( - `Parse/${localStorage.getItem("parseAppId")}/currentUser` - ) - ); - // const isEmailVerified = Parse.User.current()?.attributes?.emailVerified; - const userQuery = new Parse.Query(Parse.User); - const user = await userQuery.get(jsonSender.objectId, { - sessionToken: localStorage.getItem("accesstoken") - }); - if (user) { - const isEmailVerified = user?.get("emailVerified"); - setIsEmailVerified(isEmailVerified); - } - //getting document details const documentData = await contractDocument(documentId); if (documentData && documentData.length > 0) { @@ -1901,36 +1838,21 @@ function PlaceHolderSign() { marginBottom: "15px" }} > - {isCurrUser && - (isEmailVerified ? ( - - ) : ( - - ))} + {isCurrUser && ( + + )} - - - - )} - - )} ); diff --git a/apps/OpenSign/src/pages/SignyourselfPdf.js b/apps/OpenSign/src/pages/SignyourselfPdf.js index 2b276d776..54ad8373f 100644 --- a/apps/OpenSign/src/pages/SignyourselfPdf.js +++ b/apps/OpenSign/src/pages/SignyourselfPdf.js @@ -1,6 +1,7 @@ import React, { useState, useRef, useEffect } from "react"; import { PDFDocument } from "pdf-lib"; import "../styles/signature.css"; +import Parse from "parse"; import { isEnableSubscription, themeColor } from "../constant/const"; import axios from "axios"; import Loader from "../primitives/LoaderWithMsg"; @@ -31,7 +32,8 @@ import { checkIsSubscribed, convertPdfArrayBuffer, fetchImageBase64, - changeImageWH + changeImageWH, + handleSendOTP } from "../constant/Utils"; import { useParams } from "react-router-dom"; import Tour from "reactour"; @@ -44,6 +46,7 @@ import TourContentWithBtn from "../primitives/TourContentWithBtn"; import Title from "../components/Title"; import ModalUi from "../primitives/ModalUi"; import DropdownWidgetOption from "../components/pdf/DropdownWidgetOption"; +import VerifyEmail from "../components/pdf/VerifyEmail"; //For signYourself inProgress section signer can add sign and complete doc sign. function SignYourSelf() { @@ -91,6 +94,7 @@ function SignYourSelf() { const [containerWH, setContainerWH] = useState({}); const [isPageCopy, setIsPageCopy] = useState(false); const [selectWidgetId, setSelectWidgetId] = useState(""); + const [otpLoader, setOtpLoader] = useState(false); const [showAlreadySignDoc, setShowAlreadySignDoc] = useState({ status: false }); @@ -107,6 +111,9 @@ function SignYourSelf() { const [isCompleted, setIsCompleted] = useState(false); const [pdfArrayBuffer, setPdfArrayBuffer] = useState(""); const [activeMailAdapter, setActiveMailAdapter] = useState(""); + const [isEmailVerified, setIsEmailVerified] = useState(true); + const [isVerifyModal, setIsVerifyModal] = useState(false); + const [otp, setOtp] = useState(""); const divRef = useRef(null); const nodeRef = useRef(null); const [, drop] = useDrop({ @@ -226,6 +233,17 @@ function SignYourSelf() { setSignBtnPosition([]); } } + + if (!isCompleted) { + const userQuery = new Parse.Query(Parse.User); + const user = await userQuery.get(jsonSender.objectId, { + sessionToken: localStorage.getItem("accesstoken") + }); + if (user) { + const isEmailVerified = user?.get("emailVerified"); + setIsEmailVerified(isEmailVerified); + } + } } else if ( documentData === "Error: Something went wrong!" || (documentData.result && documentData.result.error) @@ -533,6 +551,42 @@ function SignYourSelf() { setSelectWidgetId(key); setSignKey(key); }; + + const handleReset = async (e) => { + e.preventDefault(); + setOtpLoader(true); + await handleSendOTP(Parse.User.current().getEmail()); + setOtpLoader(false); + alert("OTP sent on you email"); + }; + const handleVerifyEmail = async (e) => { + e.preventDefault(); + setOtpLoader(true); + try { + const resEmail = await Parse.Cloud.run("verifyemail", { + otp: otp, + email: Parse.User.current().getEmail() + }); + if (resEmail?.message === "Email is verified.") { + setIsEmailVerified(true); + } else if (resEmail?.message === "Email is already verified.") { + setIsEmailVerified(true); + } + setOtp(""); + alert(resEmail.message); + setIsVerifyModal(false); + // handleRecipientSign(); + } catch (error) { + alert(error.message); + } finally { + setOtpLoader(false); + } + }; + + const handleVerifyBtn = async () => { + setIsVerifyModal(true); + await handleSendOTP(Parse.User.current().getEmail()); + }; //function for send placeholder's co-ordinate(x,y) position embed signature url or stamp url async function embedWidgetsData() { let showAlert = false; @@ -1037,6 +1091,18 @@ function SignYourSelf() { )}
+ {!isEmailVerified && ( + + )} {/* this component used for UI interaction and show their functionality */} {pdfLoadFail && !checkTourStatus && ( Date: Mon, 6 May 2024 11:32:30 +0530 Subject: [PATCH 4/7] refactor : add comment, handle unnecessary query call --- .../src/components/pdf/VerifyEmail.js | 3 +- apps/OpenSign/src/constant/Utils.js | 2 + apps/OpenSign/src/pages/PdfRequestFiles.js | 26 +++++++--- apps/OpenSign/src/pages/SignyourselfPdf.js | 29 +++++++---- apps/OpenSign/src/pages/UserProfile.js | 50 ++++++++----------- 5 files changed, 63 insertions(+), 47 deletions(-) diff --git a/apps/OpenSign/src/components/pdf/VerifyEmail.js b/apps/OpenSign/src/components/pdf/VerifyEmail.js index 1387efb42..48ed2b58b 100644 --- a/apps/OpenSign/src/components/pdf/VerifyEmail.js +++ b/apps/OpenSign/src/components/pdf/VerifyEmail.js @@ -21,6 +21,7 @@ function VerifyEmail(props) {
diff --git a/apps/OpenSign/src/constant/Utils.js b/apps/OpenSign/src/constant/Utils.js index 8823a4863..3b3286cf7 100644 --- a/apps/OpenSign/src/constant/Utils.js +++ b/apps/OpenSign/src/constant/Utils.js @@ -2008,6 +2008,8 @@ export const convertPdfArrayBuffer = async (url) => { return "Error"; } }; + +//function to use send otp on user email using `SendOTPMailV1` cloud function export const handleSendOTP = async (email) => { try { let url = `${localStorage.getItem("baseUrl")}functions/SendOTPMailV1`; diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.js b/apps/OpenSign/src/pages/PdfRequestFiles.js index 36c8c477f..211a50c68 100644 --- a/apps/OpenSign/src/pages/PdfRequestFiles.js +++ b/apps/OpenSign/src/pages/PdfRequestFiles.js @@ -147,13 +147,15 @@ function PdfRequestFiles() { // eslint-disable-next-line react-hooks/exhaustive-deps }, [divRef.current]); - const handleReset = async (e) => { + //function to use resend otp for email verification + const handleResend = async (e) => { e.preventDefault(); setOtpLoader(true); await handleSendOTP(Parse.User.current().getEmail()); setOtpLoader(false); alert("OTP sent on you email"); }; + //function to use verify email with otp const handleVerifyEmail = async (e) => { e.preventDefault(); setOtpLoader(true); @@ -178,6 +180,7 @@ function PdfRequestFiles() { } }; + //function to send otp on user mail const handleVerifyBtn = async () => { setIsVerifyModal(true); await handleSendOTP(Parse.User.current().getEmail()); @@ -288,13 +291,20 @@ function PdfRequestFiles() { !declined && currDate < expireUpdateDate ) { - const userQuery = new Parse.Query(Parse.User); - const user = await userQuery.get(jsonSender.objectId, { - sessionToken: localStorage.getItem("accesstoken") - }); - if (user) { - const isEmailVerified = user?.get("emailVerified"); + const currentUser = JSON.parse(JSON.stringify(Parse.User.current())); + let isEmailVerified; + isEmailVerified = currentUser?.emailVerified; + if (isEmailVerified) { setIsEmailVerified(isEmailVerified); + } else { + const userQuery = new Parse.Query(Parse.User); + const user = await userQuery.get(currentUser.objectId, { + sessionToken: localStorage.getItem("accesstoken") + }); + if (user) { + isEmailVerified = user?.get("emailVerified"); + setIsEmailVerified(isEmailVerified); + } } } if (documentData.length > 0) { @@ -1247,7 +1257,7 @@ function PdfRequestFiles() { otp={otp} otpLoader={otpLoader} handleVerifyBtn={handleVerifyBtn} - handleReset={handleReset} + handleResend={handleResend} /> )} diff --git a/apps/OpenSign/src/pages/SignyourselfPdf.js b/apps/OpenSign/src/pages/SignyourselfPdf.js index 54ad8373f..b281482bb 100644 --- a/apps/OpenSign/src/pages/SignyourselfPdf.js +++ b/apps/OpenSign/src/pages/SignyourselfPdf.js @@ -235,13 +235,21 @@ function SignYourSelf() { } if (!isCompleted) { - const userQuery = new Parse.Query(Parse.User); - const user = await userQuery.get(jsonSender.objectId, { - sessionToken: localStorage.getItem("accesstoken") - }); - if (user) { - const isEmailVerified = user?.get("emailVerified"); + //check current user email verified or not + const currentUser = JSON.parse(JSON.stringify(Parse.User.current())); + let isEmailVerified; + isEmailVerified = currentUser?.emailVerified; + if (isEmailVerified) { setIsEmailVerified(isEmailVerified); + } else { + const userQuery = new Parse.Query(Parse.User); + const user = await userQuery.get(currentUser.objectId, { + sessionToken: localStorage.getItem("accesstoken") + }); + if (user) { + isEmailVerified = user?.get("emailVerified"); + setIsEmailVerified(isEmailVerified); + } } } } else if ( @@ -552,13 +560,16 @@ function SignYourSelf() { setSignKey(key); }; - const handleReset = async (e) => { + //function to use resend otp for email verification + const handleResend = async (e) => { e.preventDefault(); setOtpLoader(true); await handleSendOTP(Parse.User.current().getEmail()); setOtpLoader(false); alert("OTP sent on you email"); }; + + //function to use verify email with otp const handleVerifyEmail = async (e) => { e.preventDefault(); setOtpLoader(true); @@ -582,7 +593,7 @@ function SignYourSelf() { setOtpLoader(false); } }; - + //function to send otp on user mail const handleVerifyBtn = async () => { setIsVerifyModal(true); await handleSendOTP(Parse.User.current().getEmail()); @@ -1100,7 +1111,7 @@ function SignYourSelf() { otp={otp} otpLoader={otpLoader} handleVerifyBtn={handleVerifyBtn} - handleReset={handleReset} + handleResend={handleResend} /> )} {/* this component used for UI interaction and show their functionality */} diff --git a/apps/OpenSign/src/pages/UserProfile.js b/apps/OpenSign/src/pages/UserProfile.js index ff5e19d17..9f7c4213a 100644 --- a/apps/OpenSign/src/pages/UserProfile.js +++ b/apps/OpenSign/src/pages/UserProfile.js @@ -9,7 +9,7 @@ import axios from "axios"; import PremiumAlertHeader from "../primitives/PremiumAlertHeader"; import Tooltip from "../primitives/Tooltip"; import { isEnableSubscription, rejectBtn, submitBtn } from "../constant/const"; -import { checkIsSubscribed } from "../constant/Utils"; +import { checkIsSubscribed, handleSendOTP } from "../constant/Utils"; import Upgrade from "../primitives/Upgrade"; import ModalUi from "../primitives/ModalUi"; @@ -53,19 +53,20 @@ function UserProfile() { if (HeaderDocId) { setIsDisableDocId(HeaderDocId); } - const currentUser = JSON.parse( - localStorage.getItem( - `Parse/${localStorage.getItem("parseAppId")}/currentUser` - ) - ); - // const isEmailVerified = Parse.User.current()?.attributes?.emailVerified; - const userQuery = new Parse.Query(Parse.User); - const user = await userQuery.get(currentUser.objectId, { - sessionToken: localStorage.getItem("accesstoken") - }); - if (user) { - const isEmailVerified = user?.get("emailVerified"); + const currentUser = JSON.parse(JSON.stringify(Parse.User.current())); + let isEmailVerified; + isEmailVerified = currentUser?.emailVerified; + if (isEmailVerified) { setIsEmailVerified(isEmailVerified); + } else { + const userQuery = new Parse.Query(Parse.User); + const user = await userQuery.get(currentUser.objectId, { + sessionToken: localStorage.getItem("accesstoken") + }); + if (user) { + isEmailVerified = user?.get("emailVerified"); + setIsEmailVerified(isEmailVerified); + } } setIsLoader(false); @@ -198,27 +199,16 @@ function UserProfile() { const handleDisableDocId = () => { setIsDisableDocId((prevChecked) => !prevChecked); }; + //function to send otp on user mail const handleVerifyBtn = async () => { setIsVerifyModal(true); - await handleSendOTP(); + await handleSendOTP(Parse.User.current().getEmail()); }; 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); - } - }; + //function to use verify email with otp const handleVerifyEmail = async (e) => { e.preventDefault(); setOtpLoader(true); @@ -241,7 +231,8 @@ function UserProfile() { setOtpLoader(false); } }; - const handleReset = async (e) => { + //function to use resend otp for email verification + const handleResend = async (e) => { e.preventDefault(); setOtpLoader(true); await handleSendOTP(); @@ -510,6 +501,7 @@ function UserProfile() {
From f6ce1b45fbcda2ed9c4cb6779f5e35f460ced200 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Mon, 6 May 2024 12:11:48 +0530 Subject: [PATCH 5/7] refactor: add comment for email verify functions --- apps/OpenSign/src/constant/Utils.js | 2 +- apps/OpenSign/src/pages/PdfRequestFiles.js | 22 +++++++++------- apps/OpenSign/src/pages/SignyourselfPdf.js | 25 ++++++++++-------- apps/OpenSign/src/pages/UserProfile.js | 30 ++++++++++++---------- 4 files changed, 44 insertions(+), 35 deletions(-) diff --git a/apps/OpenSign/src/constant/Utils.js b/apps/OpenSign/src/constant/Utils.js index 3b3286cf7..63289af0b 100644 --- a/apps/OpenSign/src/constant/Utils.js +++ b/apps/OpenSign/src/constant/Utils.js @@ -2009,7 +2009,7 @@ export const convertPdfArrayBuffer = async (url) => { } }; -//function to use send otp on user email using `SendOTPMailV1` cloud function +//`handleSendOTP` function is used to send otp on user's email using `SendOTPMailV1` cloud function export const handleSendOTP = async (email) => { try { let url = `${localStorage.getItem("baseUrl")}functions/SendOTPMailV1`; diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.js b/apps/OpenSign/src/pages/PdfRequestFiles.js index 211a50c68..4b4cb0781 100644 --- a/apps/OpenSign/src/pages/PdfRequestFiles.js +++ b/apps/OpenSign/src/pages/PdfRequestFiles.js @@ -155,7 +155,7 @@ function PdfRequestFiles() { setOtpLoader(false); alert("OTP sent on you email"); }; - //function to use verify email with otp + //`handleVerifyEmail` function is used to verify email with otp const handleVerifyEmail = async (e) => { e.preventDefault(); setOtpLoader(true); @@ -180,7 +180,7 @@ function PdfRequestFiles() { } }; - //function to send otp on user mail + //`handleVerifyBtn` function is used to send otp on user mail const handleVerifyBtn = async () => { setIsVerifyModal(true); await handleSendOTP(Parse.User.current().getEmail()); @@ -297,13 +297,17 @@ function PdfRequestFiles() { if (isEmailVerified) { setIsEmailVerified(isEmailVerified); } else { - const userQuery = new Parse.Query(Parse.User); - const user = await userQuery.get(currentUser.objectId, { - sessionToken: localStorage.getItem("accesstoken") - }); - if (user) { - isEmailVerified = user?.get("emailVerified"); - setIsEmailVerified(isEmailVerified); + try { + const userQuery = new Parse.Query(Parse.User); + const user = await userQuery.get(currentUser.objectId, { + sessionToken: localStorage.getItem("accesstoken") + }); + if (user) { + isEmailVerified = user?.get("emailVerified"); + setIsEmailVerified(isEmailVerified); + } + } catch (e) { + setHandleError("Error: Something went wrong!"); } } } diff --git a/apps/OpenSign/src/pages/SignyourselfPdf.js b/apps/OpenSign/src/pages/SignyourselfPdf.js index b281482bb..6ad106d93 100644 --- a/apps/OpenSign/src/pages/SignyourselfPdf.js +++ b/apps/OpenSign/src/pages/SignyourselfPdf.js @@ -242,13 +242,17 @@ function SignYourSelf() { if (isEmailVerified) { setIsEmailVerified(isEmailVerified); } else { - const userQuery = new Parse.Query(Parse.User); - const user = await userQuery.get(currentUser.objectId, { - sessionToken: localStorage.getItem("accesstoken") - }); - if (user) { - isEmailVerified = user?.get("emailVerified"); - setIsEmailVerified(isEmailVerified); + try { + const userQuery = new Parse.Query(Parse.User); + const user = await userQuery.get(currentUser.objectId, { + sessionToken: localStorage.getItem("accesstoken") + }); + if (user) { + isEmailVerified = user?.get("emailVerified"); + setIsEmailVerified(isEmailVerified); + } + } catch (e) { + setHandleError("Error: Something went wrong!"); } } } @@ -560,7 +564,7 @@ function SignYourSelf() { setSignKey(key); }; - //function to use resend otp for email verification + //`handleResend` function is used to resend otp for email verification const handleResend = async (e) => { e.preventDefault(); setOtpLoader(true); @@ -568,8 +572,7 @@ function SignYourSelf() { setOtpLoader(false); alert("OTP sent on you email"); }; - - //function to use verify email with otp + //`handleVerifyEmail` function is used to verify email with otp const handleVerifyEmail = async (e) => { e.preventDefault(); setOtpLoader(true); @@ -593,7 +596,7 @@ function SignYourSelf() { setOtpLoader(false); } }; - //function to send otp on user mail + //`handleVerifyBtn` function is used to send otp on user mail const handleVerifyBtn = async () => { setIsVerifyModal(true); await handleSendOTP(Parse.User.current().getEmail()); diff --git a/apps/OpenSign/src/pages/UserProfile.js b/apps/OpenSign/src/pages/UserProfile.js index 9f7c4213a..2e74770b0 100644 --- a/apps/OpenSign/src/pages/UserProfile.js +++ b/apps/OpenSign/src/pages/UserProfile.js @@ -54,22 +54,25 @@ function UserProfile() { setIsDisableDocId(HeaderDocId); } const currentUser = JSON.parse(JSON.stringify(Parse.User.current())); - let isEmailVerified; - isEmailVerified = currentUser?.emailVerified; + let isEmailVerified = currentUser?.emailVerified || false; if (isEmailVerified) { setIsEmailVerified(isEmailVerified); + setIsLoader(false); } else { - const userQuery = new Parse.Query(Parse.User); - const user = await userQuery.get(currentUser.objectId, { - sessionToken: localStorage.getItem("accesstoken") - }); - if (user) { - isEmailVerified = user?.get("emailVerified"); - setIsEmailVerified(isEmailVerified); + try { + const userQuery = new Parse.Query(Parse.User); + const user = await userQuery.get(currentUser.objectId, { + sessionToken: localStorage.getItem("accesstoken") + }); + if (user) { + isEmailVerified = user?.get("emailVerified"); + setIsEmailVerified(isEmailVerified); + setIsLoader(false); + } + } catch (e) { + alert("something went wrong!"); } } - - setIsLoader(false); }; const handleSubmit = async (e) => { e.preventDefault(); @@ -199,7 +202,7 @@ function UserProfile() { const handleDisableDocId = () => { setIsDisableDocId((prevChecked) => !prevChecked); }; - //function to send otp on user mail + //`handleVerifyBtn` function is used to send otp on user mail const handleVerifyBtn = async () => { setIsVerifyModal(true); await handleSendOTP(Parse.User.current().getEmail()); @@ -207,8 +210,7 @@ function UserProfile() { const handleCloseVerifyModal = async () => { setIsVerifyModal(false); }; - - //function to use verify email with otp + //`handleVerifyEmail` function is used to verify email with otp const handleVerifyEmail = async (e) => { e.preventDefault(); setOtpLoader(true); From 09fb01862db851d4fde1ab9518ffa12d8cecb695 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs Date: Mon, 6 May 2024 13:29:31 +0530 Subject: [PATCH 6/7] feat: handle encrypted pdf --- apps/OpenSign/src/pages/Form.js | 487 +++++++++++++++++++++----------- apps/OpenSignServer/index.js | 1 - 2 files changed, 328 insertions(+), 160 deletions(-) diff --git a/apps/OpenSign/src/pages/Form.js b/apps/OpenSign/src/pages/Form.js index fd3e521f0..8441cb817 100644 --- a/apps/OpenSign/src/pages/Form.js +++ b/apps/OpenSign/src/pages/Form.js @@ -14,7 +14,8 @@ import { SaveFileSize } from "../constant/saveFileSize"; import { getFileName, toDataUrl } from "../constant/Utils"; import { PDFDocument } from "pdf-lib"; import axios from "axios"; -import { isEnableSubscription } from "../constant/const"; +import { isEnableSubscription, submitBtn } from "../constant/const"; +import ModalUi from "../primitives/ModalUi"; // `Form` render all type of Form on this basis of their provided in path function Form() { @@ -43,7 +44,9 @@ const Forms = (props) => { Description: "", Note: "", TimeToCompleteDays: 15, - SendinOrder: "false" + SendinOrder: "false", + password: "", + file: "" }); const [fileupload, setFileUpload] = useState(""); const [fileload, setfileload] = useState(false); @@ -52,6 +55,8 @@ const Forms = (props) => { const [isAlert, setIsAlert] = useState(false); const [isSubmit, setIsSubmit] = useState(false); const [isErr, setIsErr] = useState(""); + const [isPassword, setIsPassword] = useState(false); + const [isDecrypting, setIsDecrypting] = useState(false); const handleStrInput = (e) => { setFormData({ ...formData, [e.target.name]: e.target.value }); }; @@ -80,6 +85,7 @@ const Forms = (props) => { setpercentage(0); try { let files = e.target.files; + setFormData((prev) => ({ ...prev, file: e.target.files[0] })); if (typeof files[0] !== "undefined") { const mb = Math.round(files[0].size / Math.pow(1024, 2)); if (mb > maxFileSize) { @@ -96,16 +102,83 @@ const Forms = (props) => { await PDFDocument.load(res); handleFileUpload(files[0]); } catch (err) { - alert(`Currently encrypted pdf files are not supported.`); - setFileUpload(""); - e.target.value = ""; - console.log("err ", err); - try { - await Parse.Cloud.run("encryptedpdf", { - email: Parse.User.current().getEmail() - }); - } catch (err) { - console.log("err in sending posthog encryptedpdf", err); + if (err?.message?.includes("is encrypted")) { + try { + await Parse.Cloud.run("encryptedpdf", { + email: Parse.User.current().getEmail() + }); + } catch (err) { + console.log("err in sending posthog encryptedpdf", err); + } + // console.log("err ", err); + try { + setIsDecrypting(true); + const fileName = files?.[0].name; + const size = files?.[0].size; + const name = sanitizeFileName(fileName); + const url = "https://ai.nxglabs.in/decryptpdf"; //"https://ai.nxglabs.in/decryptpdf"; // + let formData = new FormData(); + formData.append("file", files[0]); + formData.append("password", ""); + const config = { + headers: { + "content-type": "multipart/form-data" + // sessiontoken: Parse.User.current().getSessionToken() + }, + responseType: "blob" + }; + const response = await axios.post(url, formData, config); + const pdfBlob = new Blob([response.data], { + type: "application/pdf" + }); + const pdfFile = new File([pdfBlob], name, { + type: "application/pdf" + }); + setIsDecrypting(false); + setfileload(true); + + // Upload the file to Parse Server + const parseFile = new Parse.File( + name, + pdfFile, + "application/pdf" + ); + + await parseFile.save({ + progress: (progressValue, loaded, total, { type }) => { + if (type === "upload" && progressValue !== null) { + const percentCompleted = Math.round( + (loaded * 100) / total + ); + setpercentage(percentCompleted); + } + } + }); + + // Retrieve the URL of the uploaded file + if (parseFile.url()) { + console.log("parseFile.url() ", parseFile.url()); + setFileUpload(parseFile.url()); + setfileload(false); + const tenantId = localStorage.getItem("TenantId"); + SaveFileSize(size, parseFile.url(), tenantId); + return parseFile.url(); + } + } catch (err) { + console.log("Error uploading file: ", err?.response); + setfileload(false); + setpercentage(0); + if (err?.response?.status === 401) { + setIsPassword(true); + } else { + setIsDecrypting(false); + e.target.value = ""; + } + } + } else { + console.log("err ", err); + setFileUpload(""); + e.target.value = ""; } } } else { @@ -174,7 +247,7 @@ const Forms = (props) => { if (isEnableSubscription) { try { setfileload(true); - const url = "http://tools.opensignlabs.com/docxtopdf"; + const url = "https://ai.nxglabs.in/docxtopdf"; let formData = new FormData(); formData.append("file", files[0]); const config = { @@ -387,7 +460,68 @@ const Forms = (props) => { setpercentage(0); setTimeout(() => setIsReset(false), 50); }; + const handlePasswordSubmit = async (e) => { + e.preventDefault(); + setIsPassword(false); + setfileload(true); + try { + const fileName = formData?.file?.name; + const size = formData?.file?.size; + const name = sanitizeFileName(fileName); + const url = "https://ai.nxglabs.in/decryptpdf"; // + let Data = new FormData(); + Data.append("file", formData?.file); + Data.append("password", formData.password); + const config = { + headers: { + "content-type": "multipart/form-data" + // sessiontoken: Parse.User.current().getSessionToken() + }, + responseType: "blob" + }; + const response = await axios.post(url, Data, config); + const pdfBlob = new Blob([response.data], { + type: "application/pdf" + }); + const pdfFile = new File([pdfBlob], name, { + type: "application/pdf" + }); + setIsDecrypting(false); + // Upload the file to Parse Server + const parseFile = new Parse.File(name, pdfFile, "application/pdf"); + await parseFile.save({ + progress: (progressValue, loaded, total, { type }) => { + if (type === "upload" && progressValue !== null) { + const percentCompleted = Math.round((loaded * 100) / total); + setpercentage(percentCompleted); + } + } + }); + + // Retrieve the URL of the uploaded file + if (parseFile.url()) { + setFormData((prev) => ({ ...prev, password: "" })); + console.log("parseFile.url() ", parseFile.url()); + setFileUpload(parseFile.url()); + setfileload(false); + const tenantId = localStorage.getItem("TenantId"); + SaveFileSize(size, parseFile.url(), tenantId); + return parseFile.url(); + } + } catch (err) { + console.log("Error uploading file: ", err?.response); + setfileload(false); + setpercentage(0); + setFormData((prev) => ({ ...prev, password: "" })); + if (err?.response?.status === 401) { + setIsPassword(true); + } else { + setIsDecrypting(false); + e.target.value = ""; + } + } + }; return (
@@ -411,173 +545,208 @@ const Forms = (props) => { ></div> </div> ) : ( - <form onSubmit={handleSubmit}> - <h1 className="text-[20px] font-semibold mb-4">{props?.title}</h1> - {fileload && ( - <div className="flex items-center gap-x-2"> - <div className="h-2 rounded-full w-[200px] md:w-[400px] bg-gray-200"> - <div - className="h-2 rounded-full bg-blue-500" - style={{ width: `${percentage}%` }} - ></div> - </div> - <span className="text-black text-sm">{percentage}%</span> - </div> - )} - <div className="text-xs"> - <label className="block"> - {`File (pdf, png, jpg, jpeg${ - isEnableSubscription ? ", docx)" : ")" - }`} - <span className="text-red-500 text-[13px]">*</span> - </label> - {fileupload.length > 0 ? ( - <div className="flex gap-2 justify-center items-center"> - <div className="flex justify-between items-center px-2 py-2 w-full font-bold rounded border-[1px] border-[#ccc] text-gray-500 bg-white text-[13px]"> - <div className="break-all"> - file selected : {getFileName(fileupload)} - </div> - <div - onClick={() => setFileUpload("")} - className="cursor-pointer px-[10px] text-[20px] font-bold bg-white text-red-500" - > - <i className="fa-solid fa-xmark"></i> - </div> - </div> - {process.env.REACT_APP_DROPBOX_API_KEY && ( - <DropboxChooser - onSuccess={dropboxSuccess} - onCancel={dropboxCancel} - /> - )} - </div> - ) : ( - <div className="flex gap-2 justify-center items-center"> + <> + <ModalUi isOpen={isPassword} title={"Enter Pdf Password"}> + <form onSubmit={handlePasswordSubmit}> + <div className="px-6 py-3"> + {/* <label className="mb-2">Enter OTP</label> */} <input - type="file" - className="bg-white px-2 py-1.5 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs" - onChange={(e) => handleFileInput(e)} - accept={ - isEnableSubscription - ? "application/pdf,application/vnd.openxmlformats-officedocument.wordprocessingml.document,image/png,image/jpeg" - : "application/pdf,image/png,image/jpeg" - } + type="text" + name="password" + value={formData.password} + onChange={(e) => handleStrInput(e)} + className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs" + placeholder="Enter pdf password" required /> - {process.env.REACT_APP_DROPBOX_API_KEY && ( - <DropboxChooser - onSuccess={dropboxSuccess} - onCancel={dropboxCancel} - /> - )} + </div> + <hr /> + <div className="px-6 my-3"> + <button type="submit" className={submitBtn}> + Submit + </button> + </div> + </form> + </ModalUi> + <form onSubmit={handleSubmit}> + <h1 className="text-[20px] font-semibold mb-4">{props?.title}</h1> + {fileload && ( + <div className="flex items-center gap-x-2"> + <div className="h-2 rounded-full w-[200px] md:w-[400px] bg-gray-200"> + <div + className="h-2 rounded-full bg-blue-500" + style={{ width: `${percentage}%` }} + ></div> + </div> + <span className="text-black text-sm">{percentage}%</span> </div> )} - </div> - <div className="text-xs mt-2"> - <label className="block"> - {props.title === "New Template" - ? "Template Title" - : "Document Title"} - <span className="text-red-500 text-[13px]">*</span> - </label> - <input - name="Name" - className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs" - value={formData.Name} - onChange={(e) => handleStrInput(e)} - required - /> - </div> - <div className="text-xs mt-2"> - <label className="block">Description</label> - <input - name="Description" - className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs" - value={formData.Description} - onChange={(e) => handleStrInput(e)} - /> - </div> - {props.signers && ( - <SignersInput onChange={handleSigners} isReset={isReset} required /> - )} - <div className="text-xs mt-2"> - <label className="block"> - Note<span className="text-red-500 text-[13px]">*</span> - </label> - <input - name="Note" - className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs" - value={formData.Note} - onChange={(e) => handleStrInput(e)} - required - /> - </div> - <SelectFolder - onSuccess={handleFolder} - folderCls={props.Cls} - isReset={isReset} - /> - - {props.title === "Request Signatures" && ( + {isDecrypting && ( + <div className="flex items-center gap-x-2"> + <span className="text-black text-sm"> + Decrypting pdf please wait... + </span> + </div> + )} + <div className="text-xs"> + <label className="block"> + {`File (pdf, png, jpg, jpeg${ + isEnableSubscription ? ", docx)" : ")" + }`} + <span className="text-red-500 text-[13px]">*</span> + </label> + {fileupload.length > 0 ? ( + <div className="flex gap-2 justify-center items-center"> + <div className="flex justify-between items-center px-2 py-2 w-full font-bold rounded border-[1px] border-[#ccc] text-gray-500 bg-white text-[13px]"> + <div className="break-all"> + file selected : {getFileName(fileupload)} + </div> + <div + onClick={() => setFileUpload("")} + className="cursor-pointer px-[10px] text-[20px] font-bold bg-white text-red-500" + > + <i className="fa-solid fa-xmark"></i> + </div> + </div> + {process.env.REACT_APP_DROPBOX_API_KEY && ( + <DropboxChooser + onSuccess={dropboxSuccess} + onCancel={dropboxCancel} + /> + )} + </div> + ) : ( + <div className="flex gap-2 justify-center items-center"> + <input + type="file" + className="bg-white px-2 py-1.5 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs" + onChange={(e) => handleFileInput(e)} + accept={ + isEnableSubscription + ? "application/pdf,application/vnd.openxmlformats-officedocument.wordprocessingml.document,image/png,image/jpeg" + : "application/pdf,image/png,image/jpeg" + } + required + /> + {process.env.REACT_APP_DROPBOX_API_KEY && ( + <DropboxChooser + onSuccess={dropboxSuccess} + onCancel={dropboxCancel} + /> + )} + </div> + )} + </div> <div className="text-xs mt-2"> <label className="block"> - Time To Complete (Days) + {props.title === "New Template" + ? "Template Title" + : "Document Title"} <span className="text-red-500 text-[13px]">*</span> </label> <input - type="number" - name="TimeToCompleteDays" + name="Name" className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs" - value={formData.TimeToCompleteDays} + value={formData.Name} onChange={(e) => handleStrInput(e)} required /> </div> - )} - {props.title !== "Sign Yourself" && ( <div className="text-xs mt-2"> - <label className="block">Send In Order</label> - <div className="flex items-center gap-2 ml-2 mb-1"> + <label className="block">Description</label> + <input + name="Description" + className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs" + value={formData.Description} + onChange={(e) => handleStrInput(e)} + /> + </div> + {props.signers && ( + <SignersInput + onChange={handleSigners} + isReset={isReset} + required + /> + )} + <div className="text-xs mt-2"> + <label className="block"> + Note<span className="text-red-500 text-[13px]">*</span> + </label> + <input + name="Note" + className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs" + value={formData.Note} + onChange={(e) => handleStrInput(e)} + required + /> + </div> + <SelectFolder + onSuccess={handleFolder} + folderCls={props.Cls} + isReset={isReset} + /> + + {props.title === "Request Signatures" && ( + <div className="text-xs mt-2"> + <label className="block"> + Time To Complete (Days) + <span className="text-red-500 text-[13px]">*</span> + </label> <input - type="radio" - value={"true"} - name="SendinOrder" - checked={formData.SendinOrder === "true"} - className="" - onChange={handleStrInput} + type="number" + name="TimeToCompleteDays" + className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs" + value={formData.TimeToCompleteDays} + onChange={(e) => handleStrInput(e)} + required /> - <div className="text-center">Yes</div> </div> - <div className="flex items-center gap-2 ml-2 mb-1"> - <input - type="radio" - value={"false"} - name="SendinOrder" - checked={formData.SendinOrder === "false"} - onChange={handleStrInput} - /> - <div className="text-center">No</div> + )} + {props.title !== "Sign Yourself" && ( + <div className="text-xs mt-2"> + <label className="block">Send In Order</label> + <div className="flex items-center gap-2 ml-2 mb-1"> + <input + type="radio" + value={"true"} + name="SendinOrder" + checked={formData.SendinOrder === "true"} + className="" + onChange={handleStrInput} + /> + <div className="text-center">Yes</div> + </div> + <div className="flex items-center gap-2 ml-2 mb-1"> + <input + type="radio" + value={"false"} + name="SendinOrder" + checked={formData.SendinOrder === "false"} + onChange={handleStrInput} + /> + <div className="text-center">No</div> + </div> + </div> + )} + <div className="flex items-center mt-3 gap-2 text-white"> + <button + className={`${ + isSubmit && "cursor-progress" + } bg-[#1ab6ce] rounded-sm shadow-md text-[13px] font-semibold uppercase text-white py-1.5 px-2.5 focus:outline-none`} + type="submit" + disabled={isSubmit} + > + Next + </button> + <div + className="cursor-pointer bg-[#188ae2] rounded-sm shadow-md text-[13px] font-semibold uppercase text-white py-1.5 px-2.5 text-center ml-[2px] focus:outline-none" + onClick={() => handleReset()} + > + Reset </div> </div> - )} - <div className="flex items-center mt-3 gap-2 text-white"> - <button - className={`${ - isSubmit && "cursor-progress" - } bg-[#1ab6ce] rounded-sm shadow-md text-[13px] font-semibold uppercase text-white py-1.5 px-2.5 focus:outline-none`} - type="submit" - disabled={isSubmit} - > - Next - </button> - <div - className="cursor-pointer bg-[#188ae2] rounded-sm shadow-md text-[13px] font-semibold uppercase text-white py-1.5 px-2.5 text-center ml-[2px] focus:outline-none" - onClick={() => handleReset()} - > - Reset - </div> - </div> - </form> + </form> + </> )} </div> ); diff --git a/apps/OpenSignServer/index.js b/apps/OpenSignServer/index.js index 2d51c739f..d6ba7ad9b 100644 --- a/apps/OpenSignServer/index.js +++ b/apps/OpenSignServer/index.js @@ -166,7 +166,6 @@ app.use(cors()); app.use(express.json({ limit: '50mb' })); app.use(express.urlencoded({ limit: '50mb', extended: true })); app.use(function (req, res, next) { - console.log('ip', getUserIP(req)); req.headers['x-real-ip'] = getUserIP(req); next(); }); From 7b4fa4fe233e905021495ef0a12fa8c55ef7378c Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Mon, 6 May 2024 13:55:15 +0530 Subject: [PATCH 7/7] fix: design of verify email --- apps/OpenSign/src/components/pdf/VerifyEmail.js | 12 ++++++------ apps/OpenSign/src/pages/UserProfile.js | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/OpenSign/src/components/pdf/VerifyEmail.js b/apps/OpenSign/src/components/pdf/VerifyEmail.js index 48ed2b58b..1b40614a1 100644 --- a/apps/OpenSign/src/components/pdf/VerifyEmail.js +++ b/apps/OpenSign/src/components/pdf/VerifyEmail.js @@ -25,7 +25,7 @@ function VerifyEmail(props) { 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" + placeholder="Enter OTP received over email" value={props.otp} onChange={(e) => props.setOtp(e.target.value)} /> @@ -61,10 +61,10 @@ function VerifyEmail(props) { ></div> </div> ) : ( - <div className="p-[15px]"> - <p>Please verify your email !</p> - <div className="h-[1px] bg-[#9f9f9f] w-full"></div> - <div className="m-[15px] "> + <div className="px-6 py-3"> + <p className="mb-2">Please verify your email !</p> + <hr /> + <div className="px-0 mt-3"> <button className={submitBtn} type="submit" @@ -72,7 +72,7 @@ function VerifyEmail(props) { props.handleVerifyBtn(); }} > - Verify + Send OTP </button> </div> </div> diff --git a/apps/OpenSign/src/pages/UserProfile.js b/apps/OpenSign/src/pages/UserProfile.js index 2e74770b0..3d3f6f483 100644 --- a/apps/OpenSign/src/pages/UserProfile.js +++ b/apps/OpenSign/src/pages/UserProfile.js @@ -507,7 +507,7 @@ function UserProfile() { 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" + placeholder="Enter OTP received over email" value={otp} onChange={(e) => setOtp(e.target.value)} />