From 74bfd39abc25501e0d7c7ca05445a3f728572668 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs Date: Wed, 27 Mar 2024 16:07:26 +0530 Subject: [PATCH] feat: restrict guest route --- apps/OpenSign/src/App.js | 3 +- apps/OpenSign/src/constant/const.js | 1 + apps/OpenSign/src/layout/HomeLayout.js | 11 +- apps/OpenSign/src/pages/Login.js | 23 +- apps/OpenSign/src/pages/PdfRequestFiles.js | 923 ++++++++++-------- apps/OpenSign/src/pages/PlaceHolderSign.js | 22 +- apps/OpenSign/src/pages/Signup.js | 13 +- .../OpenSign/src/pages/TemplatePlaceholder.js | 23 +- apps/OpenSign/src/primitives/Validate.js | 26 +- apps/OpenSignServer/index.js | 8 + 10 files changed, 564 insertions(+), 489 deletions(-) diff --git a/apps/OpenSign/src/App.js b/apps/OpenSign/src/App.js index 7f4f587b1..929008576 100644 --- a/apps/OpenSign/src/App.js +++ b/apps/OpenSign/src/App.js @@ -15,6 +15,7 @@ import DraftDocument from "./components/pdf/DraftDocument"; import PlaceHolderSign from "./pages/PlaceHolderSign"; import PdfRequestFiles from "./pages/PdfRequestFiles"; import LazyPage from "./primitives/LazyPage"; +import { isEnableSubscription } from "./constant/const"; const DebugPdf = lazy(() => import("./pages/DebugPdf")); const ForgetPassword = lazy(() => import("./pages/ForgetPassword")); const GuestLogin = lazy(() => import("./pages/GuestLogin")); @@ -113,7 +114,7 @@ function App() { path="/forgetpassword" element={} /> - {process.env.REACT_APP_ENABLE_SUBSCRIPTION && ( + {isEnableSubscription && ( <> { const navigate = useNavigate(); @@ -50,12 +51,10 @@ const HomeLayout = () => { const user = await Parse.Cloud.run("getUserDetails", { email: currentUser.get("email") }); - const _user = user.toJSON(); - if (_user.TenantId) { - localStorage.setItem("TenetId", _user.TenantId.objectId); - } - if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) { - const billingDate = _user.Next_billing_date && _user.Next_billing_date; + if (isEnableSubscription) { + const billingDate = + user?.get("Next_billing_date") && user?.get("Next_billing_date"); + if (billingDate) { if (billingDate > new Date()) { setIsUserValid(true); diff --git a/apps/OpenSign/src/pages/Login.js b/apps/OpenSign/src/pages/Login.js index 8bbbce23f..8ddccaa1c 100644 --- a/apps/OpenSign/src/pages/Login.js +++ b/apps/OpenSign/src/pages/Login.js @@ -10,7 +10,11 @@ import { NavLink, useNavigate, useLocation } from "react-router-dom"; import login_img from "../assets/images/login_img.svg"; import { useWindowSize } from "../hook/useWindowSize"; import ModalUi from "../primitives/ModalUi"; -import { modalCancelBtnColor, modalSubmitBtnColor } from "../constant/const"; +import { + isEnableSubscription, + modalCancelBtnColor, + modalSubmitBtnColor +} from "../constant/const"; import Alert from "../primitives/Alert"; import { appInfo } from "../constant/appinfo"; import { fetchAppInfo } from "../redux/reducers/infoReducer"; @@ -239,10 +243,7 @@ function Login() { element.pageType ); setState({ ...state, loading: false }); - if ( - process.env - .REACT_APP_ENABLE_SUBSCRIPTION - ) { + if (isEnableSubscription) { const LocalUserDetails = { name: results[0].get("Name"), email: results[0].get("Email"), @@ -292,9 +293,7 @@ function Login() { element.pageType ); setState({ ...state, loading: false }); - if ( - process.env.REACT_APP_ENABLE_SUBSCRIPTION - ) { + if (isEnableSubscription) { const LocalUserDetails = { name: _user.name, email: email, @@ -571,7 +570,7 @@ function Login() { ); setThirdpartyLoader(false); setState({ ...state, loading: false }); - if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) { + if (isEnableSubscription) { if (billingDate) { if (billingDate > new Date()) { localStorage.removeItem("userDetails"); @@ -597,7 +596,7 @@ function Login() { localStorage.setItem("pageType", element.pageType); setState({ ...state, loading: false }); setThirdpartyLoader(false); - if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) { + if (isEnableSubscription) { if (billingDate) { if (billingDate > new Date()) { localStorage.removeItem("userDetails"); @@ -796,7 +795,7 @@ function Login() { setting.menuId ); localStorage.setItem("pageType", setting.pageType); - if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) { + if (isEnableSubscription) { const LocalUserDetails = { name: results[0].get("Name"), email: results[0].get("Email"), @@ -831,7 +830,7 @@ function Login() { localStorage.setItem("defaultmenuid", setting.menuId); localStorage.setItem("pageType", setting.pageType); setState({ ...state, loading: false }); - if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) { + if (isEnableSubscription) { const LocalUserDetails = { name: results[0].get("Name"), email: results[0].get("Email"), diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.js b/apps/OpenSign/src/pages/PdfRequestFiles.js index 7f2bf551d..d063a3c35 100644 --- a/apps/OpenSign/src/pages/PdfRequestFiles.js +++ b/apps/OpenSign/src/pages/PdfRequestFiles.js @@ -1,12 +1,12 @@ import React, { useState, useRef, useEffect } from "react"; -import { themeColor } from "../constant/const"; +import { isEnableSubscription, themeColor } from "../constant/const"; import { PDFDocument } from "pdf-lib"; import "../styles/signature.css"; import axios from "axios"; import loader from "../assets/images/loader2.gif"; import { DndProvider } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; -import { useParams } from "react-router-dom"; +import { useLocation, useNavigate, useParams } from "react-router-dom"; import SignPad from "../components/pdf/SignPad"; import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage"; import Tour from "reactour"; @@ -30,9 +30,12 @@ import PdfDeclineModal from "../primitives/PdfDeclineModal"; import Title from "../components/Title"; import DefaultSignature from "../components/pdf/DefaultSignature"; import ModalUi from "../primitives/ModalUi"; +import Parse from "parse"; function PdfRequestFiles() { const { docId } = useParams(); + const navigate = useNavigate(); + const location = useLocation(); const [pdfDetails, setPdfDetails] = useState([]); const [signedSigners, setSignedSigners] = useState([]); const [unsignedSigners, setUnSignedSigners] = useState([]); @@ -87,6 +90,7 @@ function PdfRequestFiles() { const [widgetsTour, setWidgetsTour] = useState(false); const [minRequiredCount, setminRequiredCount] = useState(); const [sendInOrder, setSendInOrder] = useState(false); + const [isSubscribed, setIsSubscribed] = useState(false); const divRef = useRef(null); const isMobile = window.innerWidth < 767; const rowLevel = @@ -126,12 +130,39 @@ function PdfRequestFiles() { // eslint-disable-next-line react-hooks/exhaustive-deps }, [divRef.current]); + async function checkIsSubscribed(email) { + const user = await Parse.Cloud.run("getUserDetails", { + email: email + }); + const billingDate = + user?.get("Next_billing_date") && user?.get("Next_billing_date"); + if (billingDate) { + if (billingDate > new Date()) { + return true; + } else { + if (location.pathname.includes("/load/")) { + setIsSubscribed(true); + } else { + navigate(`/subscription`); + } + } + } else { + if (location.pathname.includes("/load/")) { + setIsSubscribed(true); + } else { + navigate(`/subscription`); + } + } + } //function for get document details for perticular signer with signer'object id const getDocumentDetails = async () => { let currUserId; //getting document details const documentData = await contractDocument(documentId); if (documentData && documentData.length > 0) { + if (isEnableSubscription) { + await checkIsSubscribed(documentData[0]?.ExtUserPtr?.Email); + } const isCompleted = documentData[0].IsCompleted && documentData[0].IsCompleted; const expireDate = documentData[0].ExpiryDate.iso; @@ -307,7 +338,7 @@ function PdfRequestFiles() { `${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( "_appName" )}_Signature?where={"UserId": {"__type": "Pointer","className": "_User", "objectId":"${ - jsonSender.objectId + jsonSender?.objectId }"}}`, { headers: { @@ -894,152 +925,80 @@ function PdfRequestFiles() { return ( - {isLoading.isLoad ? ( - <Loader isLoading={isLoading} /> - ) : handleError ? ( - <HandleError handleError={handleError} /> + {isSubscribed ? ( + <ModalUi + title={"Subscription Expired"} + isOpen={isSubscribed} + showClose={false} + > + <div className="flex flex-col justify-center items-center py-4 md:py-5 gap-5"> + <p className="text-sm md:text-lg font-normal"> + Owner's subscription has expired. + </p> + </div> + </ModalUi> ) : ( - <div> - {isUiLoading && ( - <div - style={{ - position: "absolute", - height: "100vh", - width: "100%", - display: "flex", - justifyContent: "center", - flexDirection: "column", - alignItems: "center", - zIndex: "999", - backgroundColor: "#e6f2f2", - opacity: 0.8 - }} - > - <img - alt="no img" - src={loader} - style={{ width: "100px", height: "100px" }} - /> - <span style={{ fontSize: "13px", fontWeight: "bold" }}> - This might take some time - </span> - </div> - )} - - <div className="signatureContainer" ref={divRef}> - <ModalUi - headerColor={"#dc3545"} - isOpen={isAlert.isShow} - title={"Alert message"} - handleClose={() => { - setIsAlert({ - isShow: false, - alertMessage: "" - }); - }} - > - <div style={{ height: "100%", padding: 20 }}> - <p>{isAlert.alertMessage}</p> - + <> + {isLoading.isLoad ? ( + <Loader isLoading={isLoading} /> + ) : handleError ? ( + <HandleError handleError={handleError} /> + ) : ( + <div> + {isUiLoading && ( <div style={{ - height: "1px", - backgroundColor: "#9f9f9f", + position: "absolute", + height: "100vh", width: "100%", - marginTop: "15px", - marginBottom: "15px" + display: "flex", + justifyContent: "center", + flexDirection: "column", + alignItems: "center", + zIndex: "999", + backgroundColor: "#e6f2f2", + opacity: 0.8 }} - ></div> + > + <img + alt="no img" + src={loader} + style={{ width: "100px", height: "100px" }} + /> + <span style={{ fontSize: "13px", fontWeight: "bold" }}> + This might take some time + </span> + </div> + )} - <button - onClick={() => { + <div className="signatureContainer" ref={divRef}> + <ModalUi + headerColor={"#dc3545"} + isOpen={isAlert.isShow} + title={"Alert message"} + handleClose={() => { setIsAlert({ isShow: false, alertMessage: "" }); }} - type="button" - className="finishBtn cancelBtn" > - Ok - </button> - </div> - </ModalUi> + <div style={{ height: "100%", padding: 20 }}> + <p>{isAlert.alertMessage}</p> - <Tour - showNumber={false} - showNavigation={false} - showNavigationNumber={false} - onRequestClose={closeTour} - steps={tourConfig} - isOpen={widgetsTour} - rounded={5} - closeWithMask={false} - /> - - {/* this modal is used to show decline alert */} - <PdfDeclineModal - containerWH={containerWH} - show={isDecline.isDeclined} - headMsg="Document Declined" - bodyMssg={ - isDecline.currnt === "Sure" - ? "Are you sure want to decline this document ?" - : isDecline.currnt === "YouDeclined" - ? "You have declined this document!" - : isDecline.currnt === "another" && - "You cannot sign this document as it has been declined by one or more recipient(s)." - } - footerMessage={isDecline.currnt === "Sure"} - declineDoc={declineDoc} - setIsDecline={setIsDecline} - /> - {/* this modal is used for show expired alert */} - <PdfDeclineModal - containerWH={containerWH} - show={isExpired} - headMsg="Document Expired!" - bodyMssg="This Document is no longer available." - /> - - <ModalUi - headerColor={defaultSignImg ? themeColor : "#dc3545"} - isOpen={defaultSignAlert.isShow} - title={"Auto sign"} - handleClose={() => { - setDefaultSignAlert({ - isShow: false, - alertMessage: "" - }); - }} - > - <div style={{ height: "100%", padding: 20 }}> - <p>{defaultSignAlert.alertMessage}</p> - - <div - style={{ - height: "1px", - backgroundColor: "#9f9f9f", - width: "100%", - marginTop: "15px", - marginBottom: "15px" - }} - ></div> - {defaultSignImg ? ( - <> - <button - onClick={() => addDefaultSignature()} + <div style={{ - background: themeColor + height: "1px", + backgroundColor: "#9f9f9f", + width: "100%", + marginTop: "15px", + marginBottom: "15px" }} - type="button" - className="finishBtn" - > - Yes - </button> + ></div> + <button onClick={() => { - setDefaultSignAlert({ + setIsAlert({ isShow: false, alertMessage: "" }); @@ -1047,324 +1006,420 @@ function PdfRequestFiles() { type="button" className="finishBtn cancelBtn" > - Close + Ok </button> - </> - ) : ( - <button - onClick={() => { - setIsAlert({ - isShow: false, - alertMessage: "" - }); - }} - type="button" - className="finishBtn cancelBtn" - > - Ok - </button> - )} - </div> - </ModalUi> - {/* this component used to render all pdf pages in left side */} - <RenderAllPdfPage - signPdfUrl={pdfDetails[0].URL} - allPages={allPages} - setAllPages={setAllPages} - setPageNumber={setPageNumber} - pageNumber={pageNumber} - /> + </div> + </ModalUi> - {/* pdf render view */} - <div - style={{ - marginLeft: !isMobile && pdfOriginalWidth > 500 && "20px", - marginRight: !isMobile && pdfOriginalWidth > 500 && "20px" - }} - > - {/* this modal is used show this document is already sign */} - <ModalUi - isOpen={isCompleted.isModal} - title={"Sign Documents"} - handleClose={() => { - setIsCompleted({ isModal: false, isCertificate: true }); - }} - > - <div style={{ height: "100%", padding: 20 }}> - <p>This document has been signed by all Signers.</p> - - <div - style={{ - height: "1px", - backgroundColor: "#9f9f9f", - width: "100%", - marginTop: "15px", - marginBottom: "15px" - }} - ></div> - <button - type="button" - className="finishBtn cancelBtn" - onClick={() => - setIsCompleted({ isModal: false, isCertificate: true }) - } - > - Close - </button> - </div> - </ModalUi> - - {/* this component is used for signature pad modal */} - <SignPad - isSignPad={isSignPad} - isStamp={isStamp} - setIsImageSelect={setIsImageSelect} - setIsSignPad={setIsSignPad} - setImage={setImage} - isImageSelect={isImageSelect} - imageRef={imageRef} - onImageChange={onImageChange} - setSignature={setSignature} - image={image} - onSaveImage={saveImage} - onSaveSign={saveSign} - defaultSign={defaultSignImg} - myInitial={myInitial} - isInitial={isInitial} - setIsInitial={setIsInitial} - setIsStamp={setIsStamp} - /> - {/* pdf header which contain funish back button */} - <Header - isPdfRequestFiles={true} - pageNumber={pageNumber} - allPages={allPages} - changePage={changePage} - pdfDetails={pdfDetails} - signerPos={signerPos} - isSigned={isSigned} - isCompleted={isCompleted} - embedWidgetsData={embedWidgetsData} - isShowHeader={true} - setIsDecline={setIsDecline} - decline={true} - currentSigner={currentSigner} - pdfUrl={pdfUrl} - alreadySign={alreadySign} - /> - {containerWH && ( - <RenderPdf - pageNumber={pageNumber} - pdfOriginalWidth={pdfOriginalWidth} - pdfNewWidth={pdfNewWidth} - setIsSignPad={setIsSignPad} - setIsStamp={setIsStamp} - setSignKey={setSignKey} - pdfDetails={pdfDetails} - signerPos={signerPos} - successEmail={false} - pdfUrl={pdfUrl} - numPages={numPages} - pageDetails={pageDetails} - pdfRequest={true} - signerObjectId={signerObjectId} - signedSigners={signedSigners} - setCurrentSigner={setCurrentSigner} - setPdfLoadFail={setPdfLoadFail} - pdfLoadFail={pdfLoadFail} - setSignerPos={setSignerPos} - containerWH={containerWH} - setIsInitial={setIsInitial} - setValidateAlert={setValidateAlert} - unSignedWidgetId={unSignedWidgetId} - setSelectWidgetId={setSelectWidgetId} - selectWidgetId={selectWidgetId} + <Tour + showNumber={false} + showNavigation={false} + showNavigationNumber={false} + onRequestClose={closeTour} + steps={tourConfig} + isOpen={widgetsTour} + rounded={5} + closeWithMask={false} /> - )} - </div> - <div> - <div className="signerComponent"> - <div - style={{ maxHeight: window.innerHeight - 70 + "px" }} - className="autoSignScroll" - > - {signedSigners.length > 0 && ( - <> - <div - style={{ background: themeColor }} - className="signedStyle" - > - Signed by - </div> - <div style={{ marginTop: "2px" }}> - {signedSigners.map((obj, ind) => { - return ( - <div - style={{ - display: "flex", - flexDirection: "row", - alignItems: "center", - padding: "10px 0", - background: checkSignerBackColor(obj) - }} - key={ind} - > - <div - className="signerStyle" - style={{ - background: "#abd1d0", - width: 30, - height: 30, - display: "flex", - borderRadius: 30 / 2, - justifyContent: "center", - alignItems: "center", - margin: "0 10px 0 5px" - }} - > - <span - style={{ - fontSize: "12px", - textAlign: "center", - fontWeight: "bold", - color: "black", - textTransform: "uppercase" - }} - > - {getFirstLetter(obj.Name)} - </span> - </div> - <div - style={{ - display: "flex", - flexDirection: "column" - }} - > - <span className="userName">{obj.Name}</span> - <span className="useEmail">{obj.Email}</span> - </div> - </div> - ); - })} - </div> - </> - )} - {unsignedSigners.length > 0 && ( - <> + {/* this modal is used to show decline alert */} + <PdfDeclineModal + containerWH={containerWH} + show={isDecline.isDeclined} + headMsg="Document Declined" + bodyMssg={ + isDecline.currnt === "Sure" + ? "Are you sure want to decline this document ?" + : isDecline.currnt === "YouDeclined" + ? "You have declined this document!" + : isDecline.currnt === "another" && + "You cannot sign this document as it has been declined by one or more recipient(s)." + } + footerMessage={isDecline.currnt === "Sure"} + declineDoc={declineDoc} + setIsDecline={setIsDecline} + /> + {/* this modal is used for show expired alert */} + <PdfDeclineModal + containerWH={containerWH} + show={isExpired} + headMsg="Document Expired!" + bodyMssg="This Document is no longer available." + /> + + <ModalUi + headerColor={defaultSignImg ? themeColor : "#dc3545"} + isOpen={defaultSignAlert.isShow} + title={"Auto sign"} + handleClose={() => { + setDefaultSignAlert({ + isShow: false, + alertMessage: "" + }); + }} + > + <div style={{ height: "100%", padding: 20 }}> + <p>{defaultSignAlert.alertMessage}</p> + + <div + style={{ + height: "1px", + backgroundColor: "#9f9f9f", + width: "100%", + marginTop: "15px", + marginBottom: "15px" + }} + ></div> + {defaultSignImg ? ( + <> + <button + onClick={() => addDefaultSignature()} + style={{ + background: themeColor + }} + type="button" + className="finishBtn" + > + Yes + </button> + <button + onClick={() => { + setDefaultSignAlert({ + isShow: false, + alertMessage: "" + }); + }} + type="button" + className="finishBtn cancelBtn" + > + Close + </button> + </> + ) : ( + <button + onClick={() => { + setIsAlert({ + isShow: false, + alertMessage: "" + }); + }} + type="button" + className="finishBtn cancelBtn" + > + Ok + </button> + )} + </div> + </ModalUi> + {/* this component used to render all pdf pages in left side */} + <RenderAllPdfPage + signPdfUrl={pdfDetails[0].URL} + allPages={allPages} + setAllPages={setAllPages} + setPageNumber={setPageNumber} + pageNumber={pageNumber} + /> + + {/* pdf render view */} + <div + style={{ + marginLeft: !isMobile && pdfOriginalWidth > 500 && "20px", + marginRight: !isMobile && pdfOriginalWidth > 500 && "20px" + }} + > + {/* this modal is used show this document is already sign */} + <ModalUi + isOpen={isCompleted.isModal} + title={"Sign Documents"} + handleClose={() => { + setIsCompleted({ isModal: false, isCertificate: true }); + }} + > + <div style={{ height: "100%", padding: 20 }}> + <p>This document has been signed by all Signers.</p> + <div style={{ - background: themeColor, - color: "white", - padding: "5px", - fontFamily: "sans-serif", - marginTop: signedSigners.length > 0 && "20px" + height: "1px", + backgroundColor: "#9f9f9f", + width: "100%", + marginTop: "15px", + marginBottom: "15px" }} + ></div> + <button + type="button" + className="finishBtn cancelBtn" + onClick={() => + setIsCompleted({ + isModal: false, + isCertificate: true + }) + } > - Yet to sign - </div> - <div style={{ marginTop: "5px" }}> - {unsignedSigners.map((obj, ind) => { - return ( - <div - style={{ - display: "flex", - flexDirection: "row", - alignItems: "center", - padding: "10px 0", - background: checkSignerBackColor(obj) - }} - key={ind} - > - <div - className="signerStyle" - style={{ - background: "#abd1d0", - width: 30, - height: 30, - display: "flex", - borderRadius: 30 / 2, - justifyContent: "center", - alignItems: "center", - margin: "0 10px 0 5px" - }} - > - <span - style={{ - fontSize: "12px", - textAlign: "center", - fontWeight: "bold", - color: "black", - textTransform: "uppercase" - }} - > - {getFirstLetter(obj.Name)} - </span> - </div> - <div - style={{ - display: "flex", - flexDirection: "column" - }} - > - <span className="userName">{obj.Name}</span> - <span className="useEmail">{obj.Email}</span> - </div> - <hr /> - </div> - ); - })} - </div> - </> - )} - {defaultSignImg && !alreadySign && ( - <DefaultSignature - defaultSignImg={defaultSignImg} - setDefaultSignImg={setDefaultSignImg} - userObjectId={signerObjectId} - setIsLoading={setIsLoading} - xyPostion={signerPos} - setDefaultSignAlert={setDefaultSignAlert} + Close + </button> + </div> + </ModalUi> + + {/* this component is used for signature pad modal */} + <SignPad + isSignPad={isSignPad} + isStamp={isStamp} + setIsImageSelect={setIsImageSelect} + setIsSignPad={setIsSignPad} + setImage={setImage} + isImageSelect={isImageSelect} + imageRef={imageRef} + onImageChange={onImageChange} + setSignature={setSignature} + image={image} + onSaveImage={saveImage} + onSaveSign={saveSign} + defaultSign={defaultSignImg} + myInitial={myInitial} + isInitial={isInitial} + setIsInitial={setIsInitial} + setIsStamp={setIsStamp} + /> + {/* pdf header which contain funish back button */} + <Header + isPdfRequestFiles={true} + pageNumber={pageNumber} + allPages={allPages} + changePage={changePage} + pdfDetails={pdfDetails} + signerPos={signerPos} + isSigned={isSigned} + isCompleted={isCompleted} + embedWidgetsData={embedWidgetsData} + isShowHeader={true} + setIsDecline={setIsDecline} + decline={true} + currentSigner={currentSigner} + pdfUrl={pdfUrl} + alreadySign={alreadySign} + /> + {containerWH && ( + <RenderPdf + pageNumber={pageNumber} + pdfOriginalWidth={pdfOriginalWidth} + pdfNewWidth={pdfNewWidth} + setIsSignPad={setIsSignPad} + setIsStamp={setIsStamp} + setSignKey={setSignKey} + pdfDetails={pdfDetails} + signerPos={signerPos} + successEmail={false} + pdfUrl={pdfUrl} + numPages={numPages} + pageDetails={pageDetails} + pdfRequest={true} + signerObjectId={signerObjectId} + signedSigners={signedSigners} + setCurrentSigner={setCurrentSigner} + setPdfLoadFail={setPdfLoadFail} + pdfLoadFail={pdfLoadFail} + setSignerPos={setSignerPos} + containerWH={containerWH} + setIsInitial={setIsInitial} + setValidateAlert={setValidateAlert} + unSignedWidgetId={unSignedWidgetId} + setSelectWidgetId={setSelectWidgetId} + selectWidgetId={selectWidgetId} /> )} </div> + <div> + <div className="signerComponent"> + <div + style={{ maxHeight: window.innerHeight - 70 + "px" }} + className="autoSignScroll" + > + {signedSigners.length > 0 && ( + <> + <div + style={{ background: themeColor }} + className="signedStyle" + > + Signed by + </div> + <div style={{ marginTop: "2px" }}> + {signedSigners.map((obj, ind) => { + return ( + <div + style={{ + display: "flex", + flexDirection: "row", + alignItems: "center", + padding: "10px 0", + background: checkSignerBackColor(obj) + }} + key={ind} + > + <div + className="signerStyle" + style={{ + background: "#abd1d0", + width: 30, + height: 30, + display: "flex", + borderRadius: 30 / 2, + justifyContent: "center", + alignItems: "center", + margin: "0 10px 0 5px" + }} + > + <span + style={{ + fontSize: "12px", + textAlign: "center", + fontWeight: "bold", + color: "black", + textTransform: "uppercase" + }} + > + {getFirstLetter(obj.Name)} + </span> + </div> + <div + style={{ + display: "flex", + flexDirection: "column" + }} + > + <span className="userName">{obj.Name}</span> + <span className="useEmail"> + {obj.Email} + </span> + </div> + </div> + ); + })} + </div> + </> + )} + + {unsignedSigners.length > 0 && ( + <> + <div + style={{ + background: themeColor, + color: "white", + padding: "5px", + fontFamily: "sans-serif", + marginTop: signedSigners.length > 0 && "20px" + }} + > + Yet to sign + </div> + <div style={{ marginTop: "5px" }}> + {unsignedSigners.map((obj, ind) => { + return ( + <div + style={{ + display: "flex", + flexDirection: "row", + alignItems: "center", + padding: "10px 0", + background: checkSignerBackColor(obj) + }} + key={ind} + > + <div + className="signerStyle" + style={{ + background: "#abd1d0", + width: 30, + height: 30, + display: "flex", + borderRadius: 30 / 2, + justifyContent: "center", + alignItems: "center", + margin: "0 10px 0 5px" + }} + > + <span + style={{ + fontSize: "12px", + textAlign: "center", + fontWeight: "bold", + color: "black", + textTransform: "uppercase" + }} + > + {getFirstLetter(obj.Name)} + </span> + </div> + <div + style={{ + display: "flex", + flexDirection: "column" + }} + > + <span className="userName">{obj.Name}</span> + <span className="useEmail"> + {obj.Email} + </span> + </div> + <hr /> + </div> + ); + })} + </div> + </> + )} + {defaultSignImg && !alreadySign && ( + <DefaultSignature + defaultSignImg={defaultSignImg} + setDefaultSignImg={setDefaultSignImg} + userObjectId={signerObjectId} + setIsLoading={setIsLoading} + xyPostion={signerPos} + setDefaultSignAlert={setDefaultSignAlert} + /> + )} + </div> + </div> + </div> </div> </div> - </div> - </div> - )} + )} - <ModalUi - headerColor={"#dc3545"} - isOpen={validateAlert} - title={"Validation alert"} - handleClose={() => { - setValidateAlert(false); - }} - > - <div style={{ height: "100%", padding: 20 }}> - <p> - The input does not meet the criteria set by the regular expression. - </p> - - <div - style={{ - height: "1px", - backgroundColor: "#9f9f9f", - width: "100%", - marginTop: "15px", - marginBottom: "15px" + <ModalUi + headerColor={"#dc3545"} + isOpen={validateAlert} + title={"Validation alert"} + handleClose={() => { + setValidateAlert(false); }} - ></div> - <button - onClick={() => setValidateAlert(false)} - type="button" - className="finishBtn cancelBtn" > - Close - </button> - </div> - </ModalUi> + <div style={{ height: "100%", padding: 20 }}> + <p> + The input does not meet the criteria set by the regular + expression. + </p> + + <div + style={{ + height: "1px", + backgroundColor: "#9f9f9f", + width: "100%", + marginTop: "15px", + marginBottom: "15px" + }} + ></div> + <button + onClick={() => setValidateAlert(false)} + type="button" + className="finishBtn cancelBtn" + > + Close + </button> + </div> + </ModalUi> + </> + )} </DndProvider> ); } diff --git a/apps/OpenSign/src/pages/PlaceHolderSign.js b/apps/OpenSign/src/pages/PlaceHolderSign.js index 3228e963b..d46683711 100644 --- a/apps/OpenSign/src/pages/PlaceHolderSign.js +++ b/apps/OpenSign/src/pages/PlaceHolderSign.js @@ -3,7 +3,7 @@ import axios from "axios"; import Parse from "parse"; import "../styles/signature.css"; import { PDFDocument } from "pdf-lib"; -import { themeColor } from "../constant/const"; +import { isEnableSubscription, themeColor } from "../constant/const"; import { DndProvider } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; import { useDrag, useDrop } from "react-dnd"; @@ -108,7 +108,6 @@ function PlaceHolderSign() { status: false, message: "" }); - const isMobile = window.innerWidth < 767; const [, drop] = useDrop({ accept: "BOX", @@ -180,11 +179,30 @@ function PlaceHolderSign() { // eslint-disable-next-line react-hooks/exhaustive-deps }, [divRef.current]); + async function checkIsSubscribed(email) { + const user = await Parse.Cloud.run("getUserDetails", { + email: email + }); + const billingDate = + user?.get("Next_billing_date") && user?.get("Next_billing_date"); + if (billingDate) { + if (billingDate > new Date()) { + return true; + } else { + navigate(`/subscription`); + } + } else { + navigate(`/subscription`); + } + } //function for get document details const getDocumentDetails = async () => { //getting document details const documentData = await contractDocument(documentId); if (documentData && documentData.length > 0) { + if (isEnableSubscription) { + checkIsSubscribed(documentData[0]?.ExtUserPtr?.Email); + } const alreadyPlaceholder = documentData[0]?.SignedUrl; // Check if document is sent for signing if (alreadyPlaceholder) { diff --git a/apps/OpenSign/src/pages/Signup.js b/apps/OpenSign/src/pages/Signup.js index 620db1632..ace1b1f75 100644 --- a/apps/OpenSign/src/pages/Signup.js +++ b/apps/OpenSign/src/pages/Signup.js @@ -9,7 +9,8 @@ import Alert from "../primitives/Alert"; import { appInfo } from "../constant/appinfo"; import { useDispatch } from "react-redux"; import { fetchAppInfo } from "../redux/reducers/infoReducer"; -import { showTenant } from "../redux/reducers/ShowTenant"; +import { showTenant } from "../redux/reducers/ShowTenant"; +import { isEnableSubscription } from "../constant/const"; const Signup = () => { const { width } = useWindowSize(); const navigate = useNavigate(); @@ -259,9 +260,7 @@ const Signup = () => { }); if (tenentInfo.length) { dispatch( - showTenant( - tenentInfo[0].tenentName || "" - ) + showTenant(tenentInfo[0].tenentName || "") ); localStorage.setItem( "TenantName", @@ -325,7 +324,7 @@ const Signup = () => { element.pageType ); setState({ loading: false }); - if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) { + if (isEnableSubscription) { navigate(`/subscription`, { replace: true }); } else { alert("Registered user successfully"); @@ -343,7 +342,7 @@ const Signup = () => { ); localStorage.setItem("pageType", element.pageType); setState({ loading: false }); - if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) { + if (isEnableSubscription) { navigate(`/subscription`, { replace: true }); } else { navigate( @@ -661,4 +660,4 @@ const Signup = () => { ); }; -export default Signup +export default Signup; diff --git a/apps/OpenSign/src/pages/TemplatePlaceholder.js b/apps/OpenSign/src/pages/TemplatePlaceholder.js index 82fe4d40e..93fef3bb4 100644 --- a/apps/OpenSign/src/pages/TemplatePlaceholder.js +++ b/apps/OpenSign/src/pages/TemplatePlaceholder.js @@ -3,7 +3,7 @@ import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage"; import { useParams, useNavigate } from "react-router-dom"; import axios from "axios"; import "../styles/signature.css"; -import { themeColor } from "../constant/const"; +import { isEnableSubscription, themeColor } from "../constant/const"; import { DndProvider } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; import { useDrag, useDrop } from "react-dnd"; @@ -35,6 +35,7 @@ import AddRoleModal from "../components/pdf/AddRoleModal"; import PlaceholderCopy from "../components/pdf/PlaceholderCopy"; import TourContentWithBtn from "../primitives/TourContentWithBtn"; import DropdownWidgetOption from "../components/pdf/DropdownWidgetOption"; +import Parse from "parse"; const TemplatePlaceholder = () => { const navigate = useNavigate(); const { templateId } = useParams(); @@ -168,7 +169,22 @@ const TemplatePlaceholder = () => { } // eslint-disable-next-line react-hooks/exhaustive-deps }, [divRef.current]); - + async function checkIsSubscribed(email) { + const user = await Parse.Cloud.run("getUserDetails", { + email: email + }); + const billingDate = + user?.get("Next_billing_date") && user?.get("Next_billing_date"); + if (billingDate) { + if (billingDate > new Date()) { + return true; + } else { + navigate(`/subscription`); + } + } else { + navigate(`/subscription`); + } + } // `fetchTemplate` function in used to get Template from server and setPlaceholder ,setSigner if present const fetchTemplate = async () => { try { @@ -190,6 +206,9 @@ const TemplatePlaceholder = () => { : []; if (documentData && documentData.length > 0) { + if (isEnableSubscription) { + checkIsSubscribed(documentData[0]?.ExtUserPtr?.Email); + } setPdfDetails(documentData); setIsSigners(true); if (documentData[0].Signers && documentData[0].Signers.length > 0) { diff --git a/apps/OpenSign/src/primitives/Validate.js b/apps/OpenSign/src/primitives/Validate.js index 21fd208c5..c2920b631 100644 --- a/apps/OpenSign/src/primitives/Validate.js +++ b/apps/OpenSign/src/primitives/Validate.js @@ -15,7 +15,7 @@ const Validate = () => { sessionToken: localStorage.getItem("accesstoken") }); if (user) { - checkIsSubscribed(); + setIsUserValid(true); } else { setIsUserValid(false); } @@ -27,30 +27,6 @@ const Validate = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - async function checkIsSubscribed() { - const currentUser = Parse.User.current(); - console.log("currentUser ", currentUser) - const user = await Parse.Cloud.run("getUserDetails", { - email: currentUser.get("email") - }); - const _user = user?.toJSON(); - - if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) { - const billingDate = _user.Next_billing_date && _user.Next_billing_date; - if (billingDate) { - if (billingDate > new Date()) { - setIsUserValid(true); - return true; - } else { - // navigate(`/subscription`); - } - } else { - // navigate(`/subscription`); - } - } else { - setIsUserValid(true); - } - } const handleLoginBtn = () => { try { Parse.User.logOut(); diff --git a/apps/OpenSignServer/index.js b/apps/OpenSignServer/index.js index 7812b0c6d..9ae7cce6b 100644 --- a/apps/OpenSignServer/index.js +++ b/apps/OpenSignServer/index.js @@ -147,6 +147,14 @@ export const config = { google: { enabled: true, }, + ldap: { + enabled: true, + url: 'ldap://ldap.forumsys.com:389', + suffix: 'dc=example,dc=com', + // dn: 'ou=mathematicians, dc=example, dc=com', + groupCn: 'mathematicians', + groupFilter: '(&(uniqueMember=uid=,dc=example,dc=com)(objectClass=groupOfUniqueNames))', + }, }, }; // Client-keys like the javascript key or the .NET key are not necessary with parse-server