From d85074b127812a81f2cdc96a34c53de966afe580 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Wed, 29 May 2024 18:17:07 +0530 Subject: [PATCH] fix: username issue to get details from GetPublicUserNmae cloud function --- apps/OpenSign/src/constant/const.js | 3 +- apps/OpenSign/src/pages/PdfRequestFiles.js | 5 +- apps/OpenSign/src/pages/UserProfile.js | 93 +++-- .../src/primitives/GetReportDisplay.js | 344 ++++++++++++------ apps/OpenSign/src/primitives/ModalUi.js | 4 +- apps/OpenSignServer/cloud/main.js | 7 +- .../parsefunction/CreatePublicTemplate.js | 69 ++-- .../cloud/parsefunction/GetPublicTemplate.js | 29 ++ .../cloud/parsefunction/GetPublicUserName.js | 4 +- .../cloud/parsefunction/reportsJson.js | 1 + 10 files changed, 366 insertions(+), 193 deletions(-) create mode 100644 apps/OpenSignServer/cloud/parsefunction/GetPublicTemplate.js diff --git a/apps/OpenSign/src/constant/const.js b/apps/OpenSign/src/constant/const.js index a046b4ae1..abfcce0ae 100644 --- a/apps/OpenSign/src/constant/const.js +++ b/apps/OpenSign/src/constant/const.js @@ -9,4 +9,5 @@ export const modalSubmitBtnColor = "#17a2b8"; export const modalCancelBtnColor = "white"; export const themeColor = "#47a3ad"; export const iconColor = "#686968"; -export const isEnableSubscription = process.env.REACT_APP_ENABLE_SUBSCRIPTION; +export const isEnableSubscription = false; +// process.env.REACT_APP_ENABLE_SUBSCRIPTION; diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.js b/apps/OpenSign/src/pages/PdfRequestFiles.js index b0be26095..3c17139fd 100644 --- a/apps/OpenSign/src/pages/PdfRequestFiles.js +++ b/apps/OpenSign/src/pages/PdfRequestFiles.js @@ -1578,7 +1578,10 @@ function PdfRequestFiles() { handleClose={() => { setIsCompleted((prev) => ({ ...prev, isModal: false })); }} - reduceWidth={!isCompleted?.message} + reduceWidth={ + !isCompleted?.message && + "md:min-w-[440px] md:max-w-[400px]" + } >
{isCompleted?.message ? ( diff --git a/apps/OpenSign/src/pages/UserProfile.js b/apps/OpenSign/src/pages/UserProfile.js index a3211f357..3803e43cf 100644 --- a/apps/OpenSign/src/pages/UserProfile.js +++ b/apps/OpenSign/src/pages/UserProfile.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useRef } from "react"; import { Navigate, useNavigate } from "react-router-dom"; import Parse from "parse"; import { SaveFileSize } from "../constant/saveFileSize"; @@ -28,8 +28,9 @@ function UserProfile() { const [isDisableDocId, setIsDisableDocId] = useState(false); const [isSubscribe, setIsSubscribe] = useState(false); const [publicUserName, setPublicUserName] = useState( - (extendUser && extendUser?.[0]?.UserName) || "" + extendUser && extendUser?.[0]?.UserName ); + const previousStateValueRef = useRef(publicUserName); const [company, setCompany] = useState( extendUser && extendUser?.[0]?.Company ); @@ -81,8 +82,8 @@ function UserProfile() { const handleCheckPublicUserName = async () => { try { - const res = await Parse.Cloud.run("getPublicUserName", { - userName: publicUserName + const res = await Parse.Cloud.run("getpublicusername", { + username: publicUserName }); if (res) { setIsLoader(false); @@ -98,15 +99,19 @@ function UserProfile() { }; const handleSubmit = async (e) => { e.preventDefault(); - setIsLoader(true); - let phn = Phone; - const res = await handleCheckPublicUserName(); + let phn = Phone, + res; + + if (previousStateValueRef.current !== publicUserName) { + res = await handleCheckPublicUserName(); + } + if (!res) { + setIsLoader(true); try { - const tour = Parse.Object.extend("_User"); - const query = new Parse.Query(tour); - + const userQuery = Parse.Object.extend("_User"); + const query = new Parse.Query(userQuery); await query.get(UserProfile.objectId).then((object) => { object.set("name", name); object.set("ProfilePic", Image); @@ -148,15 +153,26 @@ function UserProfile() { const extClass = localStorage.getItem("extended_class"); const extData = JSON.parse(localStorage.getItem("Extand_Class")); const ExtUserId = extData[0].objectId; + let body; + if (publicUserName) { + body = { + Phone: obj.Phone, + Name: obj.Name, + HeaderDocId: isDisableDocId, + JobTitle: jobTitle, + Company: company, + UserName: publicUserName + }; + } else { + body = { + Phone: obj.Phone, + Name: obj.Name, + HeaderDocId: isDisableDocId, + JobTitle: jobTitle, + Company: company + }; + } - const body = { - Phone: obj.Phone, - Name: obj.Name, - HeaderDocId: isDisableDocId, - JobTitle: jobTitle, - Company: company, - UserName: publicUserName - }; await axios.put( parseBaseUrl + "classes/" + extClass + "/" + ExtUserId, body, @@ -267,7 +283,15 @@ function UserProfile() { alert("OTP sent on you email"); }; const handlePublicUrl = (e) => { - setPublicUserName(e.target.value); + const value = e.target.value; + if (value.length > 6 && !isSubscribe) { + setUserNameError("Please upgrade to allow more than 6 characters."); + setTimeout(() => { + setUserNameError(""); + }, 2000); + } else { + setPublicUserName(e.target.value); + } }; return ( @@ -291,10 +315,9 @@ function UserProfile() {
) : (
- {/* {alertMsg.message} */} {userNameError && (
{userNameError}
@@ -426,20 +449,22 @@ function UserProfile() { )} -
  • - Public profile: -
    - opensign.me/ + {!isEnableSubscription && ( +
  • + Public profile: +
    + opensign.me/ - -
    -
  • + +
    + + )}
  • diff --git a/apps/OpenSign/src/primitives/GetReportDisplay.js b/apps/OpenSign/src/primitives/GetReportDisplay.js index 34a81763b..8cf06e6b0 100644 --- a/apps/OpenSign/src/primitives/GetReportDisplay.js +++ b/apps/OpenSign/src/primitives/GetReportDisplay.js @@ -4,14 +4,18 @@ import { useNavigate } from "react-router-dom"; import axios from "axios"; import ModalUi from "./ModalUi"; import AddSigner from "../components/AddSigner"; -import { modalSubmitBtnColor, modalCancelBtnColor } from "../constant/const"; +import { + modalSubmitBtnColor, + modalCancelBtnColor, + isEnableSubscription +} from "../constant/const"; import Alert from "./Alert"; import Tooltip from "./Tooltip"; import { RWebShare } from "react-web-share"; import Tour from "reactour"; import Parse from "parse"; import { saveAs } from "file-saver"; -import { replaceMailVaribles } from "../constant/Utils"; +import { copytoData, replaceMailVaribles } from "../constant/Utils"; import Confetti from "react-confetti"; import EditorToolbar, { module1, @@ -48,7 +52,9 @@ const ReportTable = (props) => { const [role, setRole] = useState([]); const [selectedPublicRole, setSelectedPublicRole] = useState(""); const [isCelebration, setIsCelebration] = useState(false); - + const [isPublic, setIsPublic] = useState({}); + const [isPublicProfile, setIsPublicProfile] = useState({}); + const [publicUserName, setIsPublicUserName] = useState("raktima"); const [isViewShare, setIsViewShare] = useState({}); const startIndex = (currentPage - 1) * props.docPerPage; const { isMoreDocs, setIsNextRecord } = props; @@ -235,17 +241,6 @@ const ReportTable = (props) => { setIsResendMail({ [item.objectId]: true }); } else if (act.action === "bulksend") { handleBulkSend(item); - } else if (act.action === "public") { - const getRole = []; - const getPlaceholder = item.Placeholders; - getPlaceholder.map((data) => { - getRole.push(data.Role); - }); - if (getRole.length === 1) { - setSelectedPublicRole(getRole[0]); - } - setRole(getRole); - setIsMakePublic({ [item.objectId]: true }); } }; // Get current list @@ -318,6 +313,9 @@ const ReportTable = (props) => { setIsRevoke({}); setIsDeleteModal({}); setIsMakePublic({}); + setSelectedPublicRole(""); + setIsPublic({}); + setIsPublicProfile({}); }; const handleShare = (item) => { @@ -711,50 +709,35 @@ const ReportTable = (props) => { if (selectedPublicRole) { setActLoader({ [item.objectId]: true }); setIsMakePublic(false); - let params = { - templateId: item.objectId - }; - let url = `${localStorage.getItem( - "baseUrl" - )}functions/createPublicTemplate/`; - const headers = { - "Content-Type": "application/json", - "X-Parse-Application-Id": localStorage.getItem("parseAppId"), - sessionToken: localStorage.getItem("accesstoken") - }; try { - const res = await axios.post(url, params, { headers: headers }); - if (res.data.result.status === "success") { - const data = { - PublicRole: [selectedPublicRole] - }; - const res = await axios.put( - `${localStorage.getItem("baseUrl")}classes/contracts_Template/${ - item.objectId - }`, - data, - { - headers: { - "Content-Type": "application/json", - "X-Parse-Application-Id": localStorage.getItem("parseAppId"), - "X-Parse-Session-Token": localStorage.getItem("accesstoken") - } - } - ); - if (res) { - setIsAlert(true); + const res = await Parse.Cloud.run("createpublictemplate", { + templateid: item.objectId, + ispublic: isPublic[item.objectId], + publicrole: [selectedPublicRole] + }); + + if (res.status === "success") { + setIsAlert(true); + setTimeout(() => setIsAlert(false), 1500); + if (isPublic[item.objectId]) { setAlertMsg({ type: "success", message: "You have successfully made the template public." }); - setTimeout(() => setIsAlert(false), 1500); setIsCelebration(true); setTimeout(() => { setIsCelebration(false); }, 5000); + setIsPublicProfile({ [item.objectId]: isPublic[item.objectId] }); + } else { + setAlertMsg({ + type: "success", + message: "You have successfully made the template private." + }); + setSelectedPublicRole(""); - setActLoader({}); } + setActLoader({}); } } catch (e) { console.log("save public template error", e); @@ -768,10 +751,50 @@ const ReportTable = (props) => { setTimeout(() => setIsAlert(false), 1500); } }; - const handleViewSigners = (item) => { setIsViewShare({ [item.objectId]: true }); }; + const handlePublicChange = async (e, item) => { + const getPlaceholder = item?.Placeholders; + if (getPlaceholder && getPlaceholder.length > 0) { + let extendUser = JSON.parse(localStorage.getItem("Extand_Class")); + const userName = extendUser[0]?.UserName; + setIsPublicUserName(extendUser[0]?.UserName); + if (userName) { + setIsPublic({ [item.objectId]: e.target.checked }); + const getRole = []; + getPlaceholder.map((data) => { + getRole.push(data.Role); + }); + if (getRole.length === 1) { + setSelectedPublicRole(getRole[0]); + } + setRole(getRole); + setIsMakePublic({ [item.objectId]: true }); + } else { + setIsPublicProfile({ [item.objectId]: true }); + } + } else { + setIsAlert(true); + setAlertMsg({ + type: "danger", + message: "Please assign at least one role to make this template public." + }); + setTimeout(() => setIsAlert(false), 3000); + } + }; + + const copytoProfileLink = () => { + const url = `https://opensign.me/${publicUserName}`; + copytoData(url); + setIsAlert(true); + setAlertMsg({ + type: "success", + message: "Copied." + }); + setTimeout(() => setIsAlert(false), 1500); + }; + return (
    {Object.keys(actLoader)?.length > 0 && ( @@ -834,6 +857,9 @@ const ReportTable = (props) => { {props.actions?.length > 0 && ( Action )} + {props.ReportName === "Templates" && !isEnableSubscription && ( + Public + )} @@ -1272,84 +1298,168 @@ const ReportTable = (props) => {
    )} - {isMakePublic[item.objectId] && ( - { - setIsMakePublic({}); - }} - > -
    -
    -

    - {" "} - Are you sure you want to make this template - public? -

    -
    -

    Public role :

    - {role.length > 1 ? ( - handlePublicChange(e, item)} + type="checkbox" + value="" + className="sr-only peer" + /> +
    + +
    + )} + {isMakePublic[item.objectId] && ( + { + setIsMakePublic({}); + setSelectedPublicRole(""); + setIsPublic({}); + }} + > +
    +
    +

    + {" "} + {isPublic[item.objectId] + ? `Are you sure you want to make this template + public ?` + : `Are you sure you want to make this template + private ?`} +

    + {isPublic[item.objectId] && ( +
    +

    + Public role :{" "} +

    + {role.length > 1 ? ( + - ) : ( -
    - {role} + {role.map((data, ind) => { + return ( + + ); + })} + + ) : ( +
    + {role} +
    + )}
    )}
    -
    -
    -
    - - +
    +
    + + +
    -
    -
    - )} - + + )} + {isPublicProfile[item.objectId] && ( + { + setIsPublicProfile({}); + }} + reduceWidth={"md:min-w-[440px] md:max-w-[400px]"} + > +
    + {publicUserName ? ( +
    +

    + Here’s your public URL. Copy or share it + with the signer, and you will be able to + see all your publicly set templates. +

    +
    + + Public Url :{" "} + + copytoProfileLink()} + className="underline underline-offset-2 cursor-pointer" + >{`https://opensign.me/${publicUserName}`} +
    +
    + ) : ( +
    +

    + Please add your public URL, and you will + be able to make a public template. +

    + +
    + )} +
    +
    + )} + + )} ) )} diff --git a/apps/OpenSign/src/primitives/ModalUi.js b/apps/OpenSign/src/primitives/ModalUi.js index 778d483d1..b0413b430 100644 --- a/apps/OpenSign/src/primitives/ModalUi.js +++ b/apps/OpenSign/src/primitives/ModalUi.js @@ -19,9 +19,7 @@ const ModalUi = ({
    {showHeader && ( diff --git a/apps/OpenSignServer/cloud/main.js b/apps/OpenSignServer/cloud/main.js index 283e5eb3d..6de2c181a 100644 --- a/apps/OpenSignServer/cloud/main.js +++ b/apps/OpenSignServer/cloud/main.js @@ -40,6 +40,8 @@ import { getSignedUrl } from './parsefunction/getSignedUrl.js'; import createBatchDocs from './parsefunction/createBatchDocs.js'; import linkContactToDoc from './parsefunction/linkContactToDoc.js'; import CreatePublicTemplate from './parsefunction/CreatePublicTemplate.js'; +import GetPublicUserName from './parsefunction/GetPublicUserName.js'; +import GetPublicTemplate from './parsefunction/GetPublicTemplate.js'; // This afterSave function triggers after an object is added or updated in the specified class, allowing for post-processing logic. Parse.Cloud.afterSave('contracts_Document', DocumentAftersave); @@ -89,5 +91,6 @@ Parse.Cloud.define('encryptedpdf', encryptedpdf); Parse.Cloud.define('getsignedurl', getSignedUrl); Parse.Cloud.define('batchdocuments', createBatchDocs); Parse.Cloud.define('linkcontacttodoc', linkContactToDoc); -Parse.Cloud.define('createPublicTemplate', CreatePublicTemplate); -Parse.Cloud.define('getPublicUserName', GetPublicUserName); +Parse.Cloud.define('createpublictemplate', CreatePublicTemplate); +Parse.Cloud.define('getpublicusername', GetPublicUserName); +Parse.Cloud.define('getpublictemplate', GetPublicTemplate); diff --git a/apps/OpenSignServer/cloud/parsefunction/CreatePublicTemplate.js b/apps/OpenSignServer/cloud/parsefunction/CreatePublicTemplate.js index 0da7fb0b7..b7b5fb0b8 100644 --- a/apps/OpenSignServer/cloud/parsefunction/CreatePublicTemplate.js +++ b/apps/OpenSignServer/cloud/parsefunction/CreatePublicTemplate.js @@ -1,39 +1,42 @@ -import axios from 'axios'; export default async function CreatePublicTemplate(request) { - const templateId = request.params.templateId; - const serverUrl = process.env.SERVER_URL; - const appId = process.env.APP_ID; - + const templateid = request.params.templateid; + const ispublic = request.params.ispublic; + const publicrole = request.params.publicrole; try { - const userRes = await axios.get(serverUrl + '/users/me', { - headers: { - 'X-Parse-Application-Id': appId, - 'X-Parse-Session-Token': request.headers['sessiontoken'], - }, - }); - const userId = userRes.data && userRes.data.objectId; - if (userId) { - const Query = new Parse.Query('contracts_Template'); - Query.equalTo('CreatedBy', { - __type: 'Pointer', - className: '_User', - objectId: userId, - }); - const updateACL = await Query.get(templateId, { useMasterKey: true }); - const newACL = new Parse.ACL(); - newACL.setPublicReadAccess(true); - newACL.setPublicWriteAccess(true); - updateACL.setACL(newACL); - updateACL.save(null, { useMasterKey: true }); - return { - status: 'success', - }; + console.log('session token', request); + if (!request?.user) { + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.'); + } else { + const userId = request?.user && request?.user?.id; + if (userId) { + const updateTemplate = new Parse.Object('contracts_Template'); + updateTemplate.id = templateid; + if (ispublic) { + updateTemplate.set('PublicRole', publicrole); + } + updateTemplate.set('IsPublic', ispublic); + const Acl = new Parse.ACL(); + if (ispublic) { + Acl.setPublicReadAccess(true); + } + Acl.setReadAccess(userId, true); + Acl.setWriteAccess(userId, true); + updateTemplate.setACL(Acl); + const savedObject = await updateTemplate.save(null, { useMasterKey: true }); + const res = savedObject.toJSON(); + if (res) { + return { + status: 'success', + }; + } + } else { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User does not exist.'); + } } } catch (err) { - if (err.code == 209) { - return { error: 'Invalid session token' }; - } else { - return { error: "You don't have access of this document!" }; - } + const code = err.code || 400; + const msg = err.message; + const error = new Parse.Error(code, msg); + throw error; } } diff --git a/apps/OpenSignServer/cloud/parsefunction/GetPublicTemplate.js b/apps/OpenSignServer/cloud/parsefunction/GetPublicTemplate.js new file mode 100644 index 000000000..33c2a1050 --- /dev/null +++ b/apps/OpenSignServer/cloud/parsefunction/GetPublicTemplate.js @@ -0,0 +1,29 @@ +async function GetPublicTemplate(request) { + try { + const username = request.params.username; + if (username) { + const extUserQuery = new Parse.Query('contracts_Users'); + extUserQuery.equalTo('UserName', username); + const res = await extUserQuery.first({ useMasterKey: true }); + const userId = res.get('UserId').id; + if (userId) { + const templatQuery = new Parse.Query('contracts_Template'); + templatQuery.equalTo('CreatedBy', { + __type: 'Pointer', + className: '_User', + objectId: userId, + }); + templatQuery.equalTo('IsPublic', true); + const getTemplate = await templatQuery.find({ useMasterKey: true }); + return getTemplate; + } + return { error: "You don't have access of this document!" }; + } else { + return { error: 'Please provide username!' }; + } + } catch (err) { + console.log('error', err); + return { error: "You don't have access of this document!" }; + } +} +export default GetPublicTemplate; diff --git a/apps/OpenSignServer/cloud/parsefunction/GetPublicUserName.js b/apps/OpenSignServer/cloud/parsefunction/GetPublicUserName.js index 3397739fc..eb927521c 100644 --- a/apps/OpenSignServer/cloud/parsefunction/GetPublicUserName.js +++ b/apps/OpenSignServer/cloud/parsefunction/GetPublicUserName.js @@ -1,8 +1,8 @@ async function GetPublicUserName(request) { try { - const userName = request.params.userName; + const username = request.params.username; const userQuery = new Parse.Query('contracts_Users'); - userQuery.equalTo('UserName', userName); + userQuery.equalTo('UserName', username); const res = await userQuery.first({ useMasterKey: true }); return res; } catch (err) { diff --git a/apps/OpenSignServer/cloud/parsefunction/reportsJson.js b/apps/OpenSignServer/cloud/parsefunction/reportsJson.js index 64c5cf522..37b53b95a 100644 --- a/apps/OpenSignServer/cloud/parsefunction/reportsJson.js +++ b/apps/OpenSignServer/cloud/parsefunction/reportsJson.js @@ -334,6 +334,7 @@ export default function reportJson(id, userId) { 'Signers.Email', 'Signers.Phone', 'Placeholders', + 'IsPublic', ], }; default: