Compare commits

...
50 Commits
Author SHA1 Message Date
RaktimaNXG 69308e22d8 fix: error in auto-sign feature unexpected issue encountered - something went wrong 2024-08-08 15:06:43 +05:30
prafull-opensignlabsandGitHub f8c9c535a0 Merge pull request #1021 from OpenSignLabs/prafull-opensignlabs-patch-23
fix: not able to create user using add user form
2024-08-08 12:30:18 +05:30
prafull-opensignlabsandGitHub d22322be86 fix: not able to create user using add user form 2024-08-08 12:28:31 +05:30
prafull-opensignlabsandGitHub e931d06ed4 Merge pull request #1018 from OpenSignLabs/validation
fix: something went wrong error in signpdf
2024-08-07 13:56:40 +05:30
prafull-opensignlabs 76b90f9bc0 fix: something went wrong error in signpdf 2024-08-07 13:45:49 +05:30
prafull-opensignlabsandGitHub b4e5fedb51 Merge pull request #1016 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSign/npm_and_yarn-5105dbd604
build(deps-dev): bump postcss from 8.4.40 to 8.4.41 in /apps/OpenSign in the npm_and_yarn group
2024-08-07 10:09:41 +05:30
dependabot[bot]andGitHub 6a229aabaf build(deps-dev): bump postcss
Bumps the npm_and_yarn group in /apps/OpenSign with 1 update: [postcss](https://github.com/postcss/postcss).


Updates `postcss` from 8.4.40 to 8.4.41
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.40...8.4.41)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: direct:development
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-06 16:32:51 +00:00
ZathielandGitHub c55bdba948 Merge pull request #1010 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSign/lottiefiles/dotlottie-react-0.8.6 2024-08-06 11:10:15 +02:00
ZathielandGitHub 4f2dce0a03 Merge pull request #1014 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSignServer/axios-1.7.3 2024-08-06 11:09:51 +02:00
ZathielandGitHub 450a992b26 Merge pull request #1011 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSign/lint-staged-15.2.8 2024-08-06 11:07:53 +02:00
dependabot[bot]andGitHub 4284b2402b build(deps): bump axios from 1.7.2 to 1.7.3 in /apps/OpenSignServer
Bumps [axios](https://github.com/axios/axios) from 1.7.2 to 1.7.3.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.7.2...v1.7.3)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-06 09:06:27 +00:00
ZathielandGitHub 50c88f82f4 Merge pull request #1012 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSign/react-tooltip-5.28.0 2024-08-06 11:06:04 +02:00
ZathielandGitHub 7dff3dc658 Merge pull request #1013 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSign/react-router-dom-6.26.0 2024-08-06 11:04:59 +02:00
ZathielandGitHub adb3864ea9 Merge pull request #1015 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSignServer/aws-sdk-2.1667.0 2024-08-06 11:04:20 +02:00
dependabot[bot]andGitHub 65a800701c build(deps): bump aws-sdk in /apps/OpenSignServer
Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1665.0 to 2.1667.0.
- [Release notes](https://github.com/aws/aws-sdk-js/releases)
- [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1665.0...v2.1667.0)

---
updated-dependencies:
- dependency-name: aws-sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-05 00:57:47 +00:00
dependabot[bot]andGitHub 36dc1fb3e9 build(deps): bump react-router-dom in /apps/OpenSign
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.25.1 to 6.26.0.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.26.0/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-05 00:28:51 +00:00
dependabot[bot]andGitHub 99305b4185 build(deps): bump react-tooltip from 5.27.1 to 5.28.0 in /apps/OpenSign
Bumps [react-tooltip](https://github.com/ReactTooltip/react-tooltip) from 5.27.1 to 5.28.0.
- [Release notes](https://github.com/ReactTooltip/react-tooltip/releases)
- [Changelog](https://github.com/ReactTooltip/react-tooltip/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ReactTooltip/react-tooltip/compare/v5.27.1...v5.28.0)

---
updated-dependencies:
- dependency-name: react-tooltip
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-05 00:28:35 +00:00
dependabot[bot]andGitHub bd2e8be186 build(deps-dev): bump lint-staged in /apps/OpenSign
Bumps [lint-staged](https://github.com/lint-staged/lint-staged) from 15.2.7 to 15.2.8.
- [Release notes](https://github.com/lint-staged/lint-staged/releases)
- [Changelog](https://github.com/lint-staged/lint-staged/blob/master/CHANGELOG.md)
- [Commits](https://github.com/lint-staged/lint-staged/compare/v15.2.7...v15.2.8)

---
updated-dependencies:
- dependency-name: lint-staged
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-05 00:28:23 +00:00
dependabot[bot]andGitHub dc4c6ceff5 build(deps): bump @lottiefiles/dotlottie-react in /apps/OpenSign
Bumps [@lottiefiles/dotlottie-react](https://github.com/LottieFiles/dotlottie-web/tree/HEAD/packages/react) from 0.8.5 to 0.8.6.
- [Release notes](https://github.com/LottieFiles/dotlottie-web/releases)
- [Changelog](https://github.com/LottieFiles/dotlottie-web/blob/main/packages/react/CHANGELOG.md)
- [Commits](https://github.com/LottieFiles/dotlottie-web/commits/@lottiefiles/dotlottie-react@0.8.6/packages/react)

---
updated-dependencies:
- dependency-name: "@lottiefiles/dotlottie-react"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-05 00:28:12 +00:00
AndrewandGitHub de82188663 Merge pull request #1007 from OpenSignLabs/fix_self_host 2024-08-02 17:19:58 +05:30
prafull-opensignlabs 4aefe775f9 fix: initial routing error in self-hosting 2024-08-02 17:11:02 +05:30
prafull-opensignlabsandGitHub ee9f778725 Merge pull request #1003 from OpenSignLabs/fix_err_signpdf
fix: error handling of signing pdf digitally
2024-08-02 16:39:11 +05:30
prafull-opensignlabs ff0883c8e6 fix: error handling of signpdf function 2024-08-02 16:22:44 +05:30
prafull-opensignlabsandGitHub 375dc86f0a Merge pull request #998 from OpenSignLabs/input_text_darkmode
fix: type initials and signature looks blurry on download pdf
2024-08-01 18:47:01 +05:30
AndrewandGitHub d2f187f6c0 Merge pull request #1001 from OpenSignLabs/multiuser_issue 2024-08-01 18:42:51 +05:30
prafull-opensignlabs 5393ee9ba9 style: remove unncessary themes and change dropbox btn as per theme 2024-08-01 18:40:04 +05:30
AndrewandGitHub d4d2948455 Merge pull request #1000 from OpenSignLabs/multiuser_issue 2024-08-01 18:09:43 +05:30
prafull-opensignlabs 37617c04ad fix: x is not function and security issue 2024-08-01 18:08:34 +05:30
RaktimaNXG 10e0153018 fix: initial type signature bulry issue 2024-08-01 17:56:44 +05:30
RaktimaNXG 42cbe94af8 fix: initial type signature issue 2024-08-01 16:50:48 +05:30
AndrewandGitHub 8f95e53d9d Merge pull request #999 from OpenSignLabs/multiuser_issue 2024-08-01 16:49:44 +05:30
prafull-opensignlabs 0dae21dcf1 build(Deps): update depencencies and overide ws packge to resolve security issue 2024-08-01 16:39:37 +05:30
RaktimaNXG 912efeb5fd refactor-code 2024-08-01 15:50:48 +05:30
AmolandGitHub 3d9307f96d Merge pull request #997 from OpenSignLabs/multiuser_issue 2024-08-01 13:55:24 +05:30
prafull-opensignlabs 873f4b080a build(deps): update depencies 2024-08-01 13:52:07 +05:30
RaktimaNXG e337a79e2e fix: type initials and signature looks blurry on download pdf 2024-08-01 13:32:18 +05:30
AndrewandGitHub 980ce62bf6 Merge pull request #995 from OpenSignLabs/multiuser_issue 2024-07-31 22:10:21 +05:30
prafull-opensignlabs dccf757f56 fix: gmail adapter is not working 2024-07-31 21:26:14 +05:30
prafull-opensignlabsandGitHub 4a6b88328e Merge pull request #993 from OpenSignLabs/input_text_darkmode
fix: display wrong owner's ip address on certificate in bulk-send flow
2024-07-31 20:16:32 +05:30
RaktimaNXG 779a84cf0b fix: display wrong owner's ip addressin certificate in bulk-send flow 2024-07-31 20:15:07 +05:30
prafull-opensignlabsandGitHub aff409ba63 Merge pull request #992 from OpenSignLabs/input_text_darkmode
fix: all types of text widget background color issues in mobile dark mode.
2024-07-31 19:47:13 +05:30
RaktimaNXG 275167c0c4 fix: all types of text widget background color issues in mobile dark mode. 2024-07-31 16:56:11 +05:30
AndrewandGitHub 19b2af7f57 Merge pull request #990 from KrisIsNewxyz/staging 2024-07-31 03:02:57 +05:30
AndrewandGitHub 5050b9ee97 Merge pull request #991 from OpenSignLabs/multiuser_issue 2024-07-30 19:36:40 +05:30
prafull-opensignlabs 23da4be6b1 fix: err invalid protcol while sending file in mail 2024-07-30 18:15:16 +05:30
prafull-opensignlabs 299648b8e0 fix: getaddrinfo ENOTFOUND while creating admin 2024-07-30 16:53:36 +05:30
KrisIsNewxyz 86fa0c87ae repair broken conection to mongodb - Update .env.local_dev 2024-07-30 13:01:55 +02:00
prafull-opensignlabsandGitHub 9619eec40f Merge pull request #980 from OpenSignLabs/raktima-opensignlabs-patch-11
fix: issue with files opening in a new tab on download instead of direct download
2024-07-26 19:24:46 +05:30
RaktimaNXG 886161d65f refactor code 2024-07-26 18:47:57 +05:30
RaktimaNXG d5d646e6e0 fix: issue with files opening in a new tab on download instead of direct download 2024-07-26 18:37:48 +05:30
71 changed files with 5530 additions and 9508 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ appName=open_sign_server
# A 12 character long random secret key that allows access to all the data. It is used in Parse dashboard config to view all the data in the database. # A 12 character long random secret key that allows access to all the data. It is used in Parse dashboard config to view all the data in the database.
MASTER_KEY=XnAadwKxxByMr MASTER_KEY=XnAadwKxxByMr
# Mongodb URI to connect to # Mongodb URI to connect to
MONGODB_URI=mongodb://host.docker.internal:27018/OpenSignDB MONGODB_URI=mongodb://mongo-container:27017/OpenSignDB
# Path on which APIs should be mounted. Do not change this. This variable shall be removed & value hardcoded in the source code in coming versions. # Path on which APIs should be mounted. Do not change this. This variable shall be removed & value hardcoded in the source code in coming versions.
PARSE_MOUNT=/app PARSE_MOUNT=/app
# Set it to the URL from where APIs will be accessible to the NodeJS functions, for local development it should be localhost:3000/api/app (use your local port number instead) # Set it to the URL from where APIs will be accessible to the NodeJS functions, for local development it should be localhost:3000/api/app (use your local port number instead)
+2091 -5797
View File
File diff suppressed because it is too large Load Diff
+15 -15
View File
@@ -4,10 +4,10 @@
"private": true, "private": true,
"dependencies": { "dependencies": {
"@formkit/auto-animate": "^0.8.2", "@formkit/auto-animate": "^0.8.2",
"@lottiefiles/dotlottie-react": "^0.7.2", "@lottiefiles/dotlottie-react": "^0.8.6",
"@radix-ui/themes": "^3.1.1", "@radix-ui/themes": "^3.1.1",
"@react-pdf/renderer": "^3.4.4", "@react-pdf/renderer": "^3.4.4",
"@reduxjs/toolkit": "^2.2.6", "@reduxjs/toolkit": "^2.2.7",
"axios": "^1.7.2", "axios": "^1.7.2",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"jwt-decode": "^4.0.0", "jwt-decode": "^4.0.0",
@@ -20,8 +20,8 @@
"react": "^18.2.0", "react": "^18.2.0",
"react-bootstrap": "^2.10.4", "react-bootstrap": "^2.10.4",
"react-confetti": "^6.1.0", "react-confetti": "^6.1.0",
"react-cookie": "^7.1.4", "react-cookie": "^7.2.0",
"react-datepicker": "^7.2.0", "react-datepicker": "^7.3.0",
"react-dnd": "^16.0.1", "react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1", "react-dnd-html5-backend": "^16.0.1",
"react-dnd-multi-backend": "^8.0.3", "react-dnd-multi-backend": "^8.0.3",
@@ -34,19 +34,19 @@
"react-quill": "^2.0.0", "react-quill": "^2.0.0",
"react-redux": "^9.1.2", "react-redux": "^9.1.2",
"react-rnd": "^10.4.11", "react-rnd": "^10.4.11",
"react-router-dom": "^6.25.1", "react-router-dom": "^6.26.0",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"react-scrollbars-custom": "^4.1.1", "react-scrollbars-custom": "^4.1.1",
"react-select": "^5.8.0", "react-select": "^5.8.0",
"react-signature-canvas": "^1.0.6", "react-signature-canvas": "^1.0.6",
"react-tooltip": "^5.27.1", "react-tooltip": "^5.28.0",
"react-web-share": "^2.0.2", "react-web-share": "^2.0.2",
"reactour": "^1.19.4", "reactour": "^1.19.4",
"redux": "^5.0.1", "redux": "^5.0.1",
"redux-thunk": "^3.1.0", "redux-thunk": "^3.1.0",
"regex-parser": "^2.3.0", "regex-parser": "^2.3.0",
"serve": "^14.2.3", "serve": "^14.2.3",
"styled-components": "^4.4.1", "styled-components": "^5.3.0",
"web-vitals": "^4.2.2", "web-vitals": "^4.2.2",
"ws": "^8.18.0" "ws": "^8.18.0"
}, },
@@ -88,10 +88,10 @@
} }
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.24.6", "@babel/core": "^7.25.2",
"@babel/preset-env": "^7.24.6", "@babel/preset-env": "^7.25.3",
"@babel/preset-react": "^7.24.6", "@babel/preset-react": "^7.24.7",
"@babel/runtime-corejs2": "^7.24.7", "@babel/runtime-corejs2": "^7.25.0",
"autoprefixer": "^10.4.19", "autoprefixer": "^10.4.19",
"babel-loader": "^9.1.3", "babel-loader": "^9.1.3",
"clean-webpack-plugin": "^4.0.0", "clean-webpack-plugin": "^4.0.0",
@@ -102,14 +102,14 @@
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"dotenv-webpack": "^8.1.0", "dotenv-webpack": "^8.1.0",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.34.3", "eslint-plugin-react": "^7.34.3",
"lint-staged": "^15.2.7", "lint-staged": "^15.2.8",
"mini-css-extract-plugin": "^2.9.0", "mini-css-extract-plugin": "^2.9.0",
"postcss": "^8.4.39", "postcss": "^8.4.41",
"prettier": "^3.3.3", "prettier": "^3.3.3",
"pretty-quick": "^4.0.0", "pretty-quick": "^4.0.0",
"tailwindcss": "^3.4.6", "tailwindcss": "^3.4.7",
"terser-webpack-plugin": "^5.3.10", "terser-webpack-plugin": "^5.3.10",
"webpack-cli": "^5.1.4" "webpack-cli": "^5.1.4"
}, },
+2 -2
View File
@@ -125,10 +125,10 @@ const AddTeam = (props) => {
}; };
return ( return (
<div className="shadow-md rounded-box my-[1px] p-3 bg-[#ffffff]"> <div className="shadow-md rounded-box my-[1px] p-3 bg-base-100 relative">
<Title title="Add Team" /> <Title title="Add Team" />
{isLoader && ( {isLoader && (
<div className="fixed inset-0 flex justify-center items-center bg-black bg-opacity-30 z-50 rounded-box"> <div className="absolute w-full h-full inset-0 flex justify-center items-center bg-base-content/30 z-50">
<Loader /> <Loader />
</div> </div>
)} )}
@@ -23,17 +23,12 @@ const DashboardCard = (props) => {
sessionToken: localStorage.getItem("accesstoken") sessionToken: localStorage.getItem("accesstoken")
}; };
let body = {}; let body = {};
let currentUser;
let currentUser1 = Parse.User.current();
currentUser = currentUser1.id;
let res; let res;
if (localStorage.getItem("Extand_Class")) { if (localStorage.getItem("Extand_Class")) {
let data = JSON.parse(localStorage.getItem("Extand_Class")); let data = JSON.parse(localStorage.getItem("Extand_Class"));
res = data[0]; res = data[0];
} else { } else {
res = await Parse.Cloud.run("getUserDetails", { res = await Parse.Cloud.run("getUserDetails");
email: currentUser.get("email")
});
if (res) res = res.toJSON(); if (res) res = res.toJSON();
} }
if (res) { if (res) {
@@ -94,9 +89,7 @@ const DashboardCard = (props) => {
let data = JSON.parse(localStorage.getItem("Extand_Class")); let data = JSON.parse(localStorage.getItem("Extand_Class"));
resr = data[0]; resr = data[0];
} else { } else {
resr = await Parse.Cloud.run("getUserDetails", { resr = await Parse.Cloud.run("getUserDetails");
email: currentUser.get("email")
});
if (resr) resr = resr.toJSON(); if (resr) resr = resr.toJSON();
} }
@@ -218,15 +211,12 @@ const DashboardCard = (props) => {
if (restr.includes("#")) { if (restr.includes("#")) {
try { try {
const currentUser = Parse.User.current();
let res; let res;
if (localStorage.getItem("Extand_Class")) { if (localStorage.getItem("Extand_Class")) {
let data = JSON.parse(localStorage.getItem("Extand_Class")); let data = JSON.parse(localStorage.getItem("Extand_Class"));
res = data[0]; res = data[0];
} else { } else {
let resr = await Parse.Cloud.run("getUserDetails", { let resr = await Parse.Cloud.run("getUserDetails");
email: currentUser.get("email")
});
if (res) res = resr.toJSON(); if (res) res = resr.toJSON();
} }
@@ -1,9 +1,7 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { saveAs } from "file-saver";
import axios from "axios"; import axios from "axios";
import { getBase64FromUrl } from "../../constant/Utils"; import { handleDownloadPdf, handleToPrint } from "../../constant/Utils";
import { themeColor, emailRegex } from "../../constant/const"; import { themeColor, emailRegex } from "../../constant/const";
import printModule from "print-js";
import Loader from "../../primitives/Loader"; import Loader from "../../primitives/Loader";
import ModalUi from "../../primitives/ModalUi"; import ModalUi from "../../primitives/ModalUi";
@@ -12,7 +10,7 @@ function EmailComponent({
pdfUrl, pdfUrl,
setIsEmail, setIsEmail,
setSuccessEmail, setSuccessEmail,
pdfName, pdfDetails,
sender, sender,
setIsAlert, setIsAlert,
extUserId, extUserId,
@@ -22,8 +20,11 @@ function EmailComponent({
const [emailValue, setEmailValue] = useState(""); const [emailValue, setEmailValue] = useState("");
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [emailErr, setEmailErr] = useState(false); const [emailErr, setEmailErr] = useState(false);
const [isDownloading, setIsDownloading] = useState("");
const isAndroid = /Android/i.test(navigator.userAgent);
//function for send email //function for send email
const sendEmail = async () => { const sendEmail = async () => {
const pdfName = pdfDetails[0]?.Name;
setIsLoading(true); setIsLoading(true);
let sendMail; let sendMail;
@@ -138,43 +139,6 @@ function EmailComponent({
} }
} }
}; };
// function for print signed pdf
const handleToPrint = async (event) => {
event.preventDefault();
const pdf = await getBase64FromUrl(pdfUrl);
const isAndroidDevice = navigator.userAgent.match(/Android/i);
const isAppleDevice =
(/iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1)) &&
!window.MSStream;
if (isAndroidDevice || isAppleDevice) {
const byteArray = Uint8Array.from(
atob(pdf)
.split("")
.map((char) => char.charCodeAt(0))
);
const blob = new Blob([byteArray], { type: "application/pdf" });
const blobUrl = URL.createObjectURL(blob);
window.open(blobUrl, "_blank");
} else {
printModule({ printable: pdf, type: "pdf", base64: true });
}
};
//handle download signed pdf
const handleDownloadPdf = () => {
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
};
const sanitizeFileName = (pdfName) => {
// Replace spaces with underscore
return pdfName.replace(/ /g, "_");
};
const isAndroid = /Android/i.test(navigator.userAgent);
return ( return (
<div> <div>
{/* isEmail */} {/* isEmail */}
@@ -188,6 +152,11 @@ function EmailComponent({
</span> </span>
</div> </div>
)} )}
{isDownloading === "pdf" && (
<div className="fixed z-[200] inset-0 flex justify-center items-center bg-black bg-opacity-30">
<Loader />
</div>
)}
<div className="flex justify-between items-center py-[10px] px-[20px] border-b-[1px] border-base-content"> <div className="flex justify-between items-center py-[10px] px-[20px] border-b-[1px] border-base-content">
<span className="text-base-content font-semibold"> <span className="text-base-content font-semibold">
Successfully signed! Successfully signed!
@@ -195,7 +164,7 @@ function EmailComponent({
<div className="flex flex-row"> <div className="flex flex-row">
{!isAndroid && ( {!isAndroid && (
<button <button
onClick={handleToPrint} onClick={(e) => handleToPrint(e, pdfUrl, setIsDownloading)}
className="op-btn op-btn-neutral op-btn-sm text-[15px]" className="op-btn op-btn-neutral op-btn-sm text-[15px]"
> >
<i className="fa-light fa-print" aria-hidden="true"></i> <i className="fa-light fa-print" aria-hidden="true"></i>
@@ -204,7 +173,9 @@ function EmailComponent({
)} )}
<button <button
className="op-btn op-btn-primary op-btn-sm text-[15px] ml-2" className="op-btn op-btn-primary op-btn-sm text-[15px] ml-2"
onClick={() => handleDownloadPdf()} onClick={() =>
handleDownloadPdf(pdfDetails, pdfUrl, setIsDownloading)
}
> >
<i className="fa-light fa-download" aria-hidden="true"></i> <i className="fa-light fa-download" aria-hidden="true"></i>
Download Download
@@ -414,19 +414,15 @@ function Header({
</button> </button>
</div> </div>
) : isPublicTemplate ? ( ) : isPublicTemplate ? (
<>
<div className="flex"> <div className="flex">
<button <button
type="button" type="button"
className="op-btn op-btn-primary op-btn-sm shadow" className="op-btn op-btn-primary op-btn-sm shadow"
onClick={() => { onClick={() => embedWidgetsData()}
embedWidgetsData();
}}
> >
Sign Now Sign Now
</button> </button>
</div> </div>
</>
) : ( ) : (
<div className="flex"> <div className="flex">
<button <button
@@ -15,7 +15,7 @@ import "../../styles/signature.css";
import RegexParser from "regex-parser"; import RegexParser from "regex-parser";
import { emailRegex } from "../../constant/const"; import { emailRegex } from "../../constant/const";
const textWidgetCls = const textWidgetCls =
"w-full h-full md:min-w-full md:min-h-full z-[999] text-[12px] rounded-[2px] border-[1px] border-[#007bff] overflow-hidden resize-none outline-none text-base-content item-center whitespace-pre-wrap"; "w-full h-full md:min-w-full md:min-h-full z-[999] text-[12px] rounded-[2px] border-[1px] border-[#007bff] overflow-hidden resize-none outline-none text-base-content item-center whitespace-pre-wrap bg-white";
const selectWidgetCls = const selectWidgetCls =
"w-full h-full absolute left-0 top-0 border-[1px] border-[#007bff] rounded-[2px] focus:outline-none text-base-content"; "w-full h-full absolute left-0 top-0 border-[1px] border-[#007bff] rounded-[2px] focus:outline-none text-base-content";
function PlaceholderType(props) { function PlaceholderType(props) {
@@ -430,7 +430,7 @@ function PlaceholderType(props) {
case "dropdown": case "dropdown":
return props.data?.signerObjId === props.signerObjId ? ( return props.data?.signerObjId === props.signerObjId ? (
<select <select
className={`${selectWidgetCls} text-[12px]`} className={`${selectWidgetCls} text-[12px] bg-inherit`}
id="myDropdown" id="myDropdown"
value={selectOption} value={selectOption}
onChange={(e) => { onChange={(e) => {
@@ -579,7 +579,7 @@ function RenderPdf({
{/* this component for render pdf document is in middle of the component */} {/* this component for render pdf document is in middle of the component */}
<Document <Document
onLoadError={() => { onLoadError={() => {
pdfLoad(false); setPdfLoad(false);
}} }}
loading={"Loading Document.."} loading={"Loading Document.."}
onLoadSuccess={pageDetails} onLoadSuccess={pageDetails}
+10 -5
View File
@@ -1,6 +1,5 @@
import React, { useRef, useState, useEffect } from "react"; import React, { useRef, useState, useEffect } from "react";
import SignatureCanvas from "react-signature-canvas"; import SignatureCanvas from "react-signature-canvas";
function SignPad({ function SignPad({
isSignPad, isSignPad,
isStamp, isStamp,
@@ -99,7 +98,12 @@ function SignPad({
} else { } else {
if (isTab === "type") { if (isTab === "type") {
setIsSignImg(""); setIsSignImg("");
onSaveSign(null, false, textWidth, textHeight); onSaveSign(
null,
false,
!isInitial && textWidth > 150 ? 150 : textWidth,
!isInitial && textHeight > 35 ? 35 : textHeight
);
} else { } else {
setIsSignImg(""); setIsSignImg("");
canvasRef.current.clear(); canvasRef.current.clear();
@@ -211,11 +215,11 @@ function SignPad({
: fontSelect : fontSelect
? fontSelect ? fontSelect
: "Fasthand"; : "Fasthand";
const fontSizeValue = "40px";
//creating span for getting text content width //creating span for getting text content width
const span = document.createElement("span"); const span = document.createElement("span");
span.textContent = textContent; span.textContent = textContent;
span.style.font = `20px ${fontfamily}`; // here put your text size and font family span.style.font = `${fontSizeValue} ${fontfamily}`; // here put your text size and font family
span.style.color = color ? color : penColor; span.style.color = color ? color : penColor;
span.style.display = "hidden"; span.style.display = "hidden";
document.body.appendChild(span); // Replace 'container' with the ID of the container element document.body.appendChild(span); // Replace 'container' with the ID of the container element
@@ -225,7 +229,8 @@ function SignPad({
// Draw the text content on the canvas // Draw the text content on the canvas
const ctx = canvasElement.getContext("2d"); const ctx = canvasElement.getContext("2d");
const pixelRatio = window.devicePixelRatio || 1; const pixelRatio = window.devicePixelRatio || 1;
const width = span.offsetWidth; const addExtraWidth = isInitial ? 10 : 50;
const width = span.offsetWidth + addExtraWidth;
const height = span.offsetHeight; const height = span.offsetHeight;
setTextWidth(width); setTextWidth(width);
setTextHeight(height); setTextHeight(height);
@@ -54,7 +54,7 @@ export default function DropboxChooser({ children, onSuccess, onCancel }) {
return ( return (
<div onClick={handleChoose}> <div onClick={handleChoose}>
{children || ( {children || (
<button className="px-2 py-[2px] text-2xl rounded border-[1px] text-blue-400 border-gray-300 w-full"> <button className="cursor-pointer op-input op-input-bordered focus:outline-none hover:border-base-content max-h-[35px] max-w-[45px] flex justify-center items-center">
<i className="fa-brands fa-dropbox"></i> <i className="fa-brands fa-dropbox"></i>
</button> </button>
)} )}
+96 -69
View File
@@ -6,6 +6,7 @@ import Parse from "parse";
import { appInfo } from "./appinfo"; import { appInfo } from "./appinfo";
import { saveAs } from "file-saver"; import { saveAs } from "file-saver";
import printModule from "print-js"; import printModule from "print-js";
import { validplan } from "../json/plansArr";
export const fontsizeArr = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]; export const fontsizeArr = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28];
export const fontColorArr = ["red", "black", "blue", "yellow"]; export const fontColorArr = ["red", "black", "blue", "yellow"];
@@ -90,13 +91,7 @@ export async function checkIsSubscribedTeam() {
if (res.plan === "freeplan") { if (res.plan === "freeplan") {
return false; return false;
} else if (res.billingDate) { } else if (res.billingDate) {
const plan = const plan = validplan[res.plan] || false;
res.plan === "team-weekly" ||
res.plan === "team-yearly" ||
res.plan === "teams-monthly" ||
res.plan === "teams-yearly" ||
res.plan === "enterprise-monthly" ||
res.plan === "enterprise-yearly";
if (plan && new Date(res.billingDate) > new Date()) { if (plan && new Date(res.billingDate) > new Date()) {
return true; return true;
} else { } else {
@@ -192,32 +187,19 @@ export const pdfNewWidthFun = (divRef) => {
}; };
//`contractUsers` function is used to get contract_User details //`contractUsers` function is used to get contract_User details
export const contractUsers = async (email) => { export const contractUsers = async () => {
const data = { try {
email: email const userDetails = await Parse.Cloud.run("getUserDetails");
};
const userDetails = await axios
.post(`${localStorage.getItem("baseUrl")}functions/getUserDetails`, data, {
headers: {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
sessionToken: localStorage.getItem("accesstoken")
}
})
.then((Listdata) => {
const json = Listdata.data;
let data = []; let data = [];
if (json && json.result) { if (userDetails) {
data.push(json.result); const json = JSON.parse(JSON.stringify(userDetails));
data.push(json);
} }
return data; return data;
}) } catch (err) {
.catch((err) => {
console.log("Err in getUserDetails cloud function", err); console.log("Err in getUserDetails cloud function", err);
return "Error: Something went wrong!"; return "Error: Something went wrong!";
}); }
return userDetails;
}; };
//function for resize image and update width and height for mulitisigners //function for resize image and update width and height for mulitisigners
@@ -458,7 +440,7 @@ export const resizeBorderExtraWidth = () => {
return 20; return 20;
}; };
export async function getBase64FromUrl(url) { export async function getBase64FromUrl(url, autosign) {
const data = await fetch(url); const data = await fetch(url);
const blob = await data.blob(); const blob = await data.blob();
return new Promise((resolve) => { return new Promise((resolve) => {
@@ -466,8 +448,12 @@ export async function getBase64FromUrl(url) {
reader.readAsDataURL(blob); reader.readAsDataURL(blob);
reader.onloadend = function () { reader.onloadend = function () {
const pdfBase = this.result; const pdfBase = this.result;
if (autosign) {
resolve(pdfBase);
} else {
const suffixbase64 = pdfBase.split(",").pop(); const suffixbase64 = pdfBase.split(",").pop();
resolve(suffixbase64); resolve(suffixbase64);
}
}; };
}); });
} }
@@ -550,20 +536,17 @@ export const signPdfFun = async (
base64Url, base64Url,
documentId, documentId,
signerObjectId, signerObjectId,
setIsAlert,
objectId, objectId,
isSubscribed, isSubscribed,
activeMailAdapter, activeMailAdapter,
xyPosition widgets
) => { ) => {
let singleSign, let isCustomCompletionMail = false;
isCustomCompletionMail = false;
try { try {
//get tenant details //get tenant details
const tenantDetails = await getTenantDetails(objectId); const tenantDetails = await getTenantDetails(objectId);
if (tenantDetails && tenantDetails === "user does not exist!") { if (tenantDetails && tenantDetails === "user does not exist!") {
alert("User does not exist"); return { status: "error", message: "User does not exist." };
} else { } else {
if ( if (
tenantDetails?.CompletionBody && tenantDetails?.CompletionBody &&
@@ -577,7 +560,7 @@ export const signPdfFun = async (
// below for loop is used to get first signature of user to send if to signpdf // below for loop is used to get first signature of user to send if to signpdf
// for adding it in completion certificate // for adding it in completion certificate
let getSignature; let getSignature;
for (let item of xyPosition) { for (let item of widgets) {
if (!getSignature) { if (!getSignature) {
const typeExist = item.pos.some((data) => data?.type); const typeExist = item.pos.some((data) => data?.type);
if (typeExist) { if (typeExist) {
@@ -596,14 +579,15 @@ export const signPdfFun = async (
base64Sign = await fetchImageBase64(base64Sign); base64Sign = await fetchImageBase64(base64Sign);
} catch (e) { } catch (e) {
console.log("error", e); console.log("error", e);
return { status: "error", message: "something went wrong." };
} }
} }
//change image width and height to 104/44 in png base64 //change image width and height to 100/40 in png base64
const getNewse64 = await changeImageWH(base64Sign); const getNewse64 = await changeImageWH(base64Sign);
//remove suffiix of base64 //remove suffiix of base64
const suffixbase64 = getNewse64 && getNewse64.split(",").pop(); const suffixbase64 = getNewse64 && getNewse64.split(",").pop();
singleSign = { const params = {
mailProvider: activeMailAdapter, mailProvider: activeMailAdapter,
pdfFile: base64Url, pdfFile: base64Url,
docId: documentId, docId: documentId,
@@ -611,34 +595,25 @@ export const signPdfFun = async (
isCustomCompletionMail: isCustomCompletionMail, isCustomCompletionMail: isCustomCompletionMail,
signature: suffixbase64 signature: suffixbase64
}; };
const response = await axios const resSignPdf = await Parse.Cloud.run("signPdf", params);
.post(`${localStorage.getItem("baseUrl")}functions/signPdf`, singleSign, { if (resSignPdf) {
headers: { const signedPdf = JSON.parse(JSON.stringify(resSignPdf));
"Content-Type": "application/json", return signedPdf;
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
// sessionToken: localStorage.getItem("accesstoken")
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
} }
})
.then((Listdata) => {
const json = Listdata.data;
const res = json.result;
return res;
})
.catch((err) => {
console.log("Err in signPdf cloud function ", err);
setIsAlert({
isShow: true,
alertMessage: "something went wrong"
});
});
return response;
} catch (e) { } catch (e) {
setIsAlert({ console.log("Err in signPdf cloud function ", e.message);
isShow: true, if (e && e?.message?.includes("is encrypted.")) {
alertMessage: "something went wrong" return {
}); status: "error",
message: "Currently encrypted pdf files are not supported."
};
} else if (
e.message === "PKCS#12 MAC could not be verified. Invalid password?"
) {
return { status: "error", message: "PFX file password is invalid." };
} else {
return { status: "error", message: "something went wrong." };
}
} }
}; };
@@ -1238,9 +1213,8 @@ export const changeImageWH = async (base64Image) => {
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
canvas.width = newWidth; canvas.width = newWidth;
canvas.height = newHeight; canvas.height = newHeight;
ctx.imageSmoothingEnabled = false;
ctx.drawImage(img, 0, 0, newWidth, newHeight); ctx.drawImage(img, 0, 0, newWidth, newHeight);
const resizedBase64 = canvas.toDataURL("image/png", 1); const resizedBase64 = canvas.toDataURL("image/png", 1.0);
resolve(resizedBase64); resolve(resizedBase64);
}; };
img.onerror = (error) => { img.onerror = (error) => {
@@ -1260,14 +1234,14 @@ const calculateFontSize = (position, containerScale, signyourself) => {
}; };
//function for embed multiple signature using pdf-lib //function for embed multiple signature using pdf-lib
export const multiSignEmbed = async ( export const multiSignEmbed = async (
xyPositionArray, widgets,
pdfDoc, pdfDoc,
signyourself, signyourself,
scale, scale,
pdfOriginalWH, pdfOriginalWH,
containerWH containerWH
) => { ) => {
for (let item of xyPositionArray) { for (let item of widgets) {
const containerScale = getContainerScale( const containerScale = getContainerScale(
pdfOriginalWH, pdfOriginalWH,
item?.pageNumber, item?.pageNumber,
@@ -1979,6 +1953,20 @@ export const handleSendOTP = async (email) => {
alert(error.message); alert(error.message);
} }
}; };
export const fetchUrl = async (url, pdfName) => {
try {
const response = await fetch(url);
if (!response.ok) {
alert("something went wrong, please try again later.");
throw new Error("Network response was not ok");
}
const blob = await response.blob();
saveAs(blob, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
} catch (error) {
alert("something went wrong, please try again later.");
console.error("Error downloading the file:", error);
}
};
//handle download signed pdf //handle download signed pdf
export const handleDownloadPdf = async ( export const handleDownloadPdf = async (
pdfDetails, pdfDetails,
@@ -2001,7 +1989,7 @@ export const handleDownloadPdf = async (
} }
); );
const url = axiosRes.data.result; const url = axiosRes.data.result;
saveAs(url, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`); await fetchUrl(url, pdfName);
setIsDownloading(""); setIsDownloading("");
} catch (err) { } catch (err) {
console.log("err in getsignedurl", err); console.log("err in getsignedurl", err);
@@ -2241,3 +2229,42 @@ export const getContainerScale = (pdfOriginalWH, pageNumber, containerWH) => {
const containerScale = containerWH?.width / getPdfPageWidth?.width || 1; const containerScale = containerWH?.width / getPdfPageWidth?.width || 1;
return containerScale; return containerScale;
}; };
//function to get default signatur eof current user from `contracts_Signature` class
export const getDefaultSignature = async (objectId) => {
try {
const result = await axios.get(
`${localStorage.getItem(
"baseUrl"
)}classes/contracts_Signature?where={"UserId": {"__type": "Pointer","className": "_User", "objectId":"${objectId}"}}`,
{
headers: {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
}
}
);
const res = result.data?.results;
if (res[0] && res.length > 0) {
const defaultSignature = res[0]?.ImageURL
? await getBase64FromUrl(res[0]?.ImageURL, true)
: "";
const defaultInitial = res[0]?.Initials
? await getBase64FromUrl(res[0]?.Initials, true)
: "";
return {
status: "success",
res: {
defaultSignature: defaultSignature,
defaultInitial: defaultInitial
}
};
}
} catch (err) {
console.log("Error: error in fetch data in contracts_Signature", err);
return {
status: "error"
};
}
};
+8
View File
@@ -163,4 +163,12 @@ const plans = [
} }
]; ];
export const validplan = {
"team-weekly": true,
"team-yearly": true,
"teams-monthly": true,
"teams-yearly": true,
"enterprise-monthly": true,
"enterprise-yearly": true
};
export default plans; export default plans;
+1 -4
View File
@@ -212,10 +212,7 @@ const HomeLayout = () => {
}; };
async function checkTourStatus() { async function checkTourStatus() {
const currentUser = Parse.User.current(); const cloudRes = await Parse.Cloud.run("getUserDetails");
const cloudRes = await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
});
const res = { data: cloudRes.toJSON() }; const res = { data: cloudRes.toJSON() };
if (res.data && res.data.TourStatus && res.data.TourStatus.length > 0) { if (res.data && res.data.TourStatus && res.data.TourStatus.length > 0) {
const tourStatus = res.data.TourStatus; const tourStatus = res.data.TourStatus;
+1 -4
View File
@@ -165,10 +165,7 @@ const AddAdmin = () => {
// Check extended class user role and tenentId // Check extended class user role and tenentId
try { try {
const userSettings = appInfo.settings; const userSettings = appInfo.settings;
const currentUser = Parse.User.current(); const extUser = await Parse.Cloud.run("getUserDetails");
const extUser = await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
});
if (extUser) { if (extUser) {
const IsDisabled = extUser?.get("IsDisabled") || false; const IsDisabled = extUser?.get("IsDisabled") || false;
if (!IsDisabled) { if (!IsDisabled) {
+3 -3
View File
@@ -643,9 +643,9 @@ const Forms = (props) => {
<span className="text-red-500 text-[13px]">*</span> <span className="text-red-500 text-[13px]">*</span>
</label> </label>
{fileupload.length > 0 ? ( {fileupload.length > 0 ? (
<div className="flex gap-2 justify-center items-center"> <div className="flex gap-1 justify-center items-center">
<div className="flex justify-between items-center op-input op-input-bordered op-input-sm w-full h-full text-[13px]"> <div className="flex justify-between items-center op-input op-input-bordered op-input-sm w-full h-full text-[13px]">
<div className="break-all"> <div className="break-all cursor-default">
file selected: {getFileName(fileupload)} file selected: {getFileName(fileupload)}
</div> </div>
<div <div
@@ -663,7 +663,7 @@ const Forms = (props) => {
)} )}
</div> </div>
) : ( ) : (
<div className="flex gap-2 justify-center items-center "> <div className="flex gap-1 justify-center items-center">
<input <input
type="file" type="file"
className="op-file-input op-file-input-bordered op-file-input-sm focus:outline-none hover:border-base-content w-full text-xs" className="op-file-input op-file-input-bordered op-file-input-sm focus:outline-none hover:border-base-content w-full text-xs"
+2 -1
View File
@@ -124,8 +124,9 @@ function GuestLogin() {
setLoading(false); setLoading(false);
} else { } else {
let _user = user.data.result; let _user = user.data.result;
await Parse.User.become(_user.sessionToken);
const parseId = localStorage.getItem("parseAppId"); const parseId = localStorage.getItem("parseAppId");
const contractUserDetails = await contractUsers(_user.email); const contractUserDetails = await contractUsers();
localStorage.setItem("UserInformation", JSON.stringify(_user)); localStorage.setItem("UserInformation", JSON.stringify(_user));
localStorage.setItem( localStorage.setItem(
`Parse/${parseId}/currentUser`, `Parse/${parseId}/currentUser`,
+10 -18
View File
@@ -44,16 +44,11 @@ function Login() {
const [isLoginSSO, setIsLoginSSO] = useState(false); const [isLoginSSO, setIsLoginSSO] = useState(false);
useEffect(() => { useEffect(() => {
if (localStorage.getItem("accesstoken")) { checkUserExt();
setState({ ...state, loading: true });
GetLoginData();
}
dispatch(fetchAppInfo());
saveLogo();
// eslint-disable-next-line // eslint-disable-next-line
}, []); }, []);
const saveLogo = async () => { const checkUserExt = async () => {
const app = await getAppLogo(); const app = await getAppLogo();
if (!isEnableSubscription && app?.user === "not_exist") { if (!isEnableSubscription && app?.user === "not_exist") {
navigate("/addadmin"); navigate("/addadmin");
@@ -63,6 +58,11 @@ function Login() {
} else { } else {
setImage(appInfo?.applogo || undefined); setImage(appInfo?.applogo || undefined);
} }
if (localStorage.getItem("accesstoken")) {
setState({ ...state, loading: true });
GetLoginData();
}
dispatch(fetchAppInfo());
}; };
const handleChange = (event) => { const handleChange = (event) => {
const { name, value } = event.target; const { name, value } = event.target;
@@ -93,10 +93,7 @@ function Login() {
// Check extended class user role and tenentId // Check extended class user role and tenentId
try { try {
const userSettings = appInfo.settings; const userSettings = appInfo.settings;
const currentUser = Parse.User.current(); await Parse.Cloud.run("getUserDetails")
await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
})
.then(async (extUser) => { .then(async (extUser) => {
if (extUser) { if (extUser) {
const IsDisabled = extUser?.get("IsDisabled") || false; const IsDisabled = extUser?.get("IsDisabled") || false;
@@ -279,10 +276,7 @@ function Login() {
// Check extended class user role and tenentId // Check extended class user role and tenentId
try { try {
const userSettings = appInfo.settings; const userSettings = appInfo.settings;
const currentUser = Parse.User.current(); await Parse.Cloud.run("getUserDetails")
await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
})
.then(async (extUser) => { .then(async (extUser) => {
if (extUser) { if (extUser) {
const IsDisabled = extUser?.get("IsDisabled") || false; const IsDisabled = extUser?.get("IsDisabled") || false;
@@ -408,9 +402,7 @@ function Login() {
localStorage.setItem("profileImg", ""); localStorage.setItem("profileImg", "");
} }
const userSettings = appInfo.settings; const userSettings = appInfo.settings;
await Parse.Cloud.run("getUserDetails", { await Parse.Cloud.run("getUserDetails").then(async (extUser) => {
email: _user.email
}).then(async (extUser) => {
if (extUser) { if (extUser) {
const IsDisabled = extUser?.get("IsDisabled") || false; const IsDisabled = extUser?.get("IsDisabled") || false;
if (!IsDisabled) { if (!IsDisabled) {
+1 -4
View File
@@ -496,10 +496,7 @@ function Opensigndrive() {
}; };
//function to use check tour status of open sign drive //function to use check tour status of open sign drive
async function checkTourStatus() { async function checkTourStatus() {
const currentUser = Parse.User.current(); const cloudRes = await Parse.Cloud.run("getUserDetails");
const cloudRes = await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
});
const res = { data: cloudRes.toJSON() }; const res = { data: cloudRes.toJSON() };
if (res.data && res.data.TourStatus && res.data.TourStatus.length > 0) { if (res.data && res.data.TourStatus && res.data.TourStatus.length > 0) {
const tourStatus = res.data.TourStatus; const tourStatus = res.data.TourStatus;
+45 -82
View File
@@ -30,7 +30,8 @@ import {
contactBook, contactBook,
handleDownloadPdf, handleDownloadPdf,
handleToPrint, handleToPrint,
handleDownloadCertificate handleDownloadCertificate,
getDefaultSignature
} from "../constant/Utils"; } from "../constant/Utils";
import LoaderWithMsg from "../primitives/LoaderWithMsg"; import LoaderWithMsg from "../primitives/LoaderWithMsg";
import HandleError from "../primitives/HandleError"; import HandleError from "../primitives/HandleError";
@@ -337,6 +338,7 @@ function PdfRequestFiles(props) {
}; };
//function for get document details for perticular signer with signer'object id //function for get document details for perticular signer with signer'object id
const getDocumentDetails = async (docId, isNextUser) => { const getDocumentDetails = async (docId, isNextUser) => {
try {
const senderUser = localStorage.getItem( const senderUser = localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser` `Parse/${localStorage.getItem("parseAppId")}/currentUser`
); );
@@ -349,7 +351,8 @@ function PdfRequestFiles(props) {
const isCompleted = const isCompleted =
documentData[0].IsCompleted && documentData[0].IsCompleted; documentData[0].IsCompleted && documentData[0].IsCompleted;
const expireDate = documentData[0].ExpiryDate.iso; const expireDate = documentData[0].ExpiryDate.iso;
const declined = documentData[0].IsDeclined && documentData[0].IsDeclined; const declined =
documentData[0].IsDeclined && documentData[0].IsDeclined;
const expireUpdateDate = new Date(expireDate).getTime(); const expireUpdateDate = new Date(expireDate).getTime();
const currDate = new Date().getTime(); const currDate = new Date().getTime();
const getSigners = documentData[0].Signers; const getSigners = documentData[0].Signers;
@@ -422,7 +425,9 @@ function PdfRequestFiles(props) {
const audittrailData = const audittrailData =
documentData[0].AuditTrail && documentData[0].AuditTrail &&
documentData[0].AuditTrail.length > 0 && documentData[0].AuditTrail.length > 0 &&
documentData[0].AuditTrail.filter((data) => data.Activity === "Signed"); documentData[0].AuditTrail.filter(
(data) => data.Activity === "Signed"
);
const checkAlreadySign = const checkAlreadySign =
documentData[0].AuditTrail && documentData[0].AuditTrail &&
@@ -474,7 +479,8 @@ function PdfRequestFiles(props) {
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"), "X-Parse-Application-Id":
localStorage.getItem("parseAppId"),
sessiontoken: localStorage.getItem("accesstoken") sessiontoken: localStorage.getItem("accesstoken")
} }
} }
@@ -551,13 +557,8 @@ function PdfRequestFiles(props) {
setRequestSignTour(true); setRequestSignTour(true);
} else { } else {
//else condition to check current user exist in contracts_Users class and check tour message status //else condition to check current user exist in contracts_Users class and check tour message status
//if not then check user exist in contracts_Contactbook class and check tour message status //if not then check user exist in contracts_Contactbook class and check tour message statu
const localuser = localStorage.getItem( const res = await contractUsers();
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
);
const currentUser = JSON.parse(localuser);
const currentUserEmail = currentUser.email;
const res = await contractUsers(currentUserEmail);
if (res === "Error: Something went wrong!") { if (res === "Error: Something went wrong!") {
setHandleError("Error: Something went wrong!"); setHandleError("Error: Something went wrong!");
} else if (res[0] && res?.length) { } else if (res[0] && res?.length) {
@@ -609,42 +610,24 @@ function PdfRequestFiles(props) {
isLoad: false isLoad: false
}); });
} }
await axios //function to get default signatur eof current user from `contracts_Signature` class
.get( const defaultSignRes = await getDefaultSignature(jsonSender.objectId);
`${localStorage.getItem( if (defaultSignRes?.status === "success") {
"baseUrl" setDefaultSignImg(defaultSignRes?.res?.defaultSignature);
)}classes/contracts_Signature?where={"UserId": {"__type": "Pointer","className": "_User", "objectId":"${ setMyInitial(defaultSignRes?.res?.defaultInitial);
jsonSender?.objectId } else if (defaultSignRes?.status === "error") {
}"}}`,
{
headers: {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
}
}
)
.then((Listdata) => {
const json = Listdata.data;
const res = json.results;
if (res[0] && res.length > 0) {
setDefaultSignImg(res[0].ImageURL);
setMyInitial(res[0]?.Initials);
}
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
})
.catch((err) => {
console.log("Err in contracts_Signature class", err);
setHandleError("Error: Something went wrong!"); setHandleError("Error: Something went wrong!");
setIsLoading({ setIsLoading({
isLoad: false isLoad: false
}); });
}
} catch (err) {
console.log("Error: error in getDocumentDetails", err);
setHandleError("Error: Something went wrong!");
setIsLoading({
isLoad: false
}); });
}
}; };
//function for embed signature or image url in pdf //function for embed signature or image url in pdf
async function embedWidgetsData() { async function embedWidgetsData() {
@@ -819,8 +802,8 @@ function PdfRequestFiles(props) {
setWidgetsTour(true); setWidgetsTour(true);
} else { } else {
setIsUiLoading(true); setIsUiLoading(true);
// `widgets` is Used to return widgets details with page number of current user
const pngUrl = checkUser[0].placeHolder; const widgets = checkUser?.[0]?.placeHolder;
let pdfArrBuffer; let pdfArrBuffer;
//`contractDocument` function used to get updated SignedUrl //`contractDocument` function used to get updated SignedUrl
//resolved issue of sign document by multiple signers simultaneously //resolved issue of sign document by multiple signers simultaneously
@@ -858,7 +841,7 @@ function PdfRequestFiles(props) {
} }
//embed multi signature in pdf //embed multi signature in pdf
const pdfBytes = await multiSignEmbed( const pdfBytes = await multiSignEmbed(
pngUrl, widgets,
pdfDoc, pdfDoc,
isSignYourSelfFlow, isSignYourSelfFlow,
scale, scale,
@@ -869,32 +852,27 @@ function PdfRequestFiles(props) {
//get ExistUserPtr object id of user class to get tenantDetails //get ExistUserPtr object id of user class to get tenantDetails
const objectId = pdfDetails?.[0]?.ExtUserPtr?.UserId?.objectId; const objectId = pdfDetails?.[0]?.ExtUserPtr?.UserId?.objectId;
//get ExistUserPtr email to get userDetails //get ExistUserPtr email to get userDetails
const currentUserEmail = pdfDetails?.[0]?.ExtUserPtr?.Email; const res = await contractUsers();
const res = await contractUsers(currentUserEmail);
let activeMailAdapter = ""; let activeMailAdapter = "";
if (res === "Error: Something went wrong!") { if (res === "Error: Something went wrong!") {
setHandleError("Error: Something went wrong!"); setHandleError("Error: Something went wrong!");
setIsLoading({ setIsLoading({ isLoad: false });
isLoad: false
});
} else if (!res || res?.length === 0) { } else if (!res || res?.length === 0) {
activeMailAdapter = ""; activeMailAdapter = "";
} else if (res[0] && res.length) { } else if (res[0] && res.length) {
activeMailAdapter = res[0]?.active_mail_adapter; activeMailAdapter = res[0]?.active_mail_adapter;
} }
//function for call to embed signature in pdf and get digital signature pdf //function for call to embed signature in pdf and get digital signature pdf
try { const resSign = await signPdfFun(
const res = await signPdfFun(
pdfBytes, pdfBytes,
documentId, documentId,
signerObjectId, signerObjectId,
setIsAlert,
objectId, objectId,
isSubscribed, isSubscribed,
activeMailAdapter, activeMailAdapter,
pngUrl widgets
); );
if (res && res.status === "success") { if (resSign && resSign.status === "success") {
setPdfUrl(res.data); setPdfUrl(res.data);
setIsSigned(true); setIsSigned(true);
setSignedSigners([]); setSignedSigners([]);
@@ -1036,16 +1014,8 @@ function PdfRequestFiles(props) {
} }
} }
} else { } else {
setIsAlert({ setIsUiLoading(false);
isShow: true, setIsAlert({ isShow: true, alertMessage: resSign.message });
alertMessage: "something went wrong"
});
}
} catch (err) {
setIsAlert({
isShow: true,
alertMessage: "something went wrong"
});
} }
} catch (err) { } catch (err) {
setIsUiLoading(false); setIsUiLoading(false);
@@ -1558,7 +1528,8 @@ function PdfRequestFiles(props) {
} else { } else {
let _user = user.data.result; let _user = user.data.result;
const parseId = localStorage.getItem("parseAppId"); const parseId = localStorage.getItem("parseAppId");
const contractUserDetails = await contractUsers(_user.email); await Parse.User.become(_user.sessionToken);
const contractUserDetails = await contractUsers();
localStorage.setItem("UserInformation", JSON.stringify(_user)); localStorage.setItem("UserInformation", JSON.stringify(_user));
localStorage.setItem( localStorage.setItem(
`Parse/${parseId}/currentUser`, `Parse/${parseId}/currentUser`,
@@ -1657,26 +1628,19 @@ function PdfRequestFiles(props) {
requestSignTourFunction()} requestSignTourFunction()}
<ModalUi <ModalUi
isOpen={isAlert.isShow} isOpen={isAlert.isShow}
title={"Alert message"} title={"Alert"}
handleClose={() => { handleClose={() =>
setIsAlert({ setIsAlert({ isShow: false, alertMessage: "" })
isShow: false, }
alertMessage: ""
});
}}
> >
<div className="h-full p-[20px]"> <div className="h-full p-[20px]">
<p>{isAlert.alertMessage}</p> <p>{isAlert.alertMessage}</p>
<div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div>
<button <button
onClick={() => { onClick={() =>
setIsAlert({ setIsAlert({ isShow: false, alertMessage: "" })
isShow: false, }
alertMessage: ""
});
}}
type="button" type="button"
className="op-btn op-btn-primary" className="op-btn op-btn-primary mt-3 px-4"
> >
Ok Ok
</button> </button>
@@ -2180,7 +2144,6 @@ function PdfRequestFiles(props) {
{defaultSignImg && !alreadySign && currentSigner && ( {defaultSignImg && !alreadySign && currentSigner && (
<DefaultSignature <DefaultSignature
defaultSignImg={defaultSignImg} defaultSignImg={defaultSignImg}
setDefaultSignImg={setDefaultSignImg}
userObjectId={signerObjectId} userObjectId={signerObjectId}
setIsLoading={setIsLoading} setIsLoading={setIsLoading}
xyPostion={signerPos} xyPostion={signerPos}
+2 -7
View File
@@ -71,9 +71,7 @@ const PgSignUp = () => {
if (res) { if (res) {
localStorage.removeItem("userDetails"); localStorage.removeItem("userDetails");
try { try {
const extUser = await Parse.Cloud.run("getUserDetails", { const extUser = await Parse.Cloud.run("getUserDetails");
email: userDetails.email
});
const userRole = extUser?.get("UserRole"); const userRole = extUser?.get("UserRole");
const _currentRole = userRole; const _currentRole = userRole;
const _role = _currentRole.replace("contracts_", ""); const _role = _currentRole.replace("contracts_", "");
@@ -230,10 +228,7 @@ const PgSignUp = () => {
// Check extended class user role and tenentId // Check extended class user role and tenentId
try { try {
const userSettings = appInfo.settings; const userSettings = appInfo.settings;
const currentUser = Parse.User.current(); const extUser = await Parse.Cloud.run("getUserDetails");
const extUser = await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
});
if (extUser) { if (extUser) {
const IsDisabled = extUser?.get("IsDisabled") || false; const IsDisabled = extUser?.get("IsDisabled") || false;
if (!IsDisabled) { if (!IsDisabled) {
+1 -2
View File
@@ -404,8 +404,7 @@ function PlaceHolderSign() {
}; };
setIsLoading(loadObj); setIsLoading(loadObj);
} }
const currentUserEmail = documentData[0]?.ExtUserPtr?.Email; const res = await contractUsers();
const res = await contractUsers(currentUserEmail);
if (res === "Error: Something went wrong!") { if (res === "Error: Something went wrong!") {
const loadObj = { const loadObj = {
isLoad: false isLoad: false
+1 -4
View File
@@ -149,10 +149,7 @@ const SSOVerify = () => {
// Check extended class user role and tenentId // Check extended class user role and tenentId
try { try {
const userSettings = appInfo.settings; const userSettings = appInfo.settings;
const currentUser = Parse.User.current(); await Parse.Cloud.run("getUserDetails")
await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
})
.then(async (extUser) => { .then(async (extUser) => {
if (extUser) { if (extUser) {
const IsDisabled = extUser?.get("IsDisabled") || false; const IsDisabled = extUser?.get("IsDisabled") || false;
+1 -4
View File
@@ -192,10 +192,7 @@ const Signup = () => {
// Check extended class user role and tenentId // Check extended class user role and tenentId
try { try {
const userSettings = appInfo.settings; const userSettings = appInfo.settings;
const currentUser = Parse.User.current(); await Parse.Cloud.run("getUserDetails")
await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
})
.then(async (extUser) => { .then(async (extUser) => {
if (extUser) { if (extUser) {
const IsDisabled = extUser?.get("IsDisabled") || false; const IsDisabled = extUser?.get("IsDisabled") || false;
+50 -61
View File
@@ -33,7 +33,8 @@ import {
fetchImageBase64, fetchImageBase64,
changeImageWH, changeImageWH,
handleSendOTP, handleSendOTP,
getContainerScale getContainerScale,
getDefaultSignature
} from "../constant/Utils"; } from "../constant/Utils";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import Tour from "reactour"; import Tour from "reactour";
@@ -205,6 +206,7 @@ function SignYourSelf() {
}, [divRef.current, isHeader]); }, [divRef.current, isHeader]);
//function for get document details for perticular signer with signer'object id //function for get document details for perticular signer with signer'object id
const getDocumentDetails = async (showComplete) => { const getDocumentDetails = async (showComplete) => {
try {
let isCompleted; let isCompleted;
//getting document details //getting document details
const documentData = await contractDocument(documentId); const documentData = await contractDocument(documentId);
@@ -224,7 +226,8 @@ function SignYourSelf() {
} else { } else {
setHandleError("Error: Something went wrong!"); setHandleError("Error: Something went wrong!");
} }
isCompleted = documentData[0].IsCompleted && documentData[0].IsCompleted; isCompleted =
documentData[0].IsCompleted && documentData[0].IsCompleted;
if (isCompleted) { if (isCompleted) {
setIsCelebration(true); setIsCelebration(true);
setTimeout(() => { setTimeout(() => {
@@ -262,38 +265,20 @@ function SignYourSelf() {
}; };
setIsLoading(loadObj); setIsLoading(loadObj);
} }
await axios
.get( //function to get default signatur eof current user from `contracts_Signature` class
`${localStorage.getItem( const defaultSignRes = await getDefaultSignature(jsonSender.objectId);
"baseUrl" console.log("defaultSignRes", defaultSignRes);
)}classes/contracts_Signature?where={"UserId": {"__type": "Pointer","className": "_User", "objectId":"${ if (defaultSignRes?.status === "success") {
jsonSender.objectId setDefaultSignImg(defaultSignRes?.res?.defaultSignature);
}"}}`, setMyInitial(defaultSignRes?.res?.defaultInitial);
{ } else if (defaultSignRes?.status === "error") {
headers: {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
}
}
)
.then((Listdata) => {
const json = Listdata.data;
const res = json.results;
if (res[0] && res.length > 0) {
setDefaultSignImg(res[0].ImageURL);
setMyInitial(res[0]?.Initials);
}
})
.catch((err) => {
console.log("Err ", err);
const loadObj = {
isLoad: false
};
setHandleError("Error: Something went wrong!"); setHandleError("Error: Something went wrong!");
setIsLoading(loadObj); setIsLoading({
isLoad: false
}); });
const contractUsersRes = await contractUsers(jsonSender.email); }
const contractUsersRes = await contractUsers();
if (contractUsersRes === "Error: Something went wrong!") { if (contractUsersRes === "Error: Something went wrong!") {
const loadObj = { const loadObj = {
isLoad: false isLoad: false
@@ -349,7 +334,15 @@ function SignYourSelf() {
}; };
setIsLoading(loadObj); setIsLoading(loadObj);
} }
} catch (err) {
console.log("Error: error in getDocumentDetails", err);
setHandleError("Error: Something went wrong!");
setIsLoading({
isLoad: false
});
}
}; };
const getWidgetValue = (type) => { const getWidgetValue = (type) => {
switch (type) { switch (type) {
case "name": case "name":
@@ -710,22 +703,36 @@ function SignYourSelf() {
setIsUiLoading(false); setIsUiLoading(false);
if (err && err.message.includes("is encrypted.")) { if (err && err.message.includes("is encrypted.")) {
setIsAlert({ setIsAlert({
header: "Error",
isShow: true, isShow: true,
alertMessage: `Currently encrypted pdf files are not supported.` alertMessage: `Currently encrypted pdf files are not supported.`
}); });
} else { } else {
console.log("err in signing", err); console.log("err in signing", err.message);
if (
err.message ===
"PKCS#12 MAC could not be verified. Invalid password?"
) {
setIsAlert({ setIsAlert({
header: "Error",
isShow: true,
alertMessage: `PFX file password is invalid.`
});
} else {
setIsAlert({
header: "Error",
isShow: true, isShow: true,
alertMessage: `Something went wrong.` alertMessage: `Something went wrong.`
}); });
} }
} }
} }
}
} catch (err) { } catch (err) {
console.log("err in embedselfsign ", err); console.log("err in embedselfsign ", err);
setIsUiLoading(false); setIsUiLoading(false);
setIsAlert({ setIsAlert({
header: "Error",
isShow: true, isShow: true,
alertMessage: "something went wrong, please try again later." alertMessage: "something went wrong, please try again later."
}); });
@@ -771,39 +778,24 @@ function SignYourSelf() {
console.log("error", e); console.log("error", e);
} }
} }
//change image width and height to 104/44 in png base64 //change image width and height to 100/40 in png base64
const getNewse64 = await changeImageWH(base64Sign); const getNewse64 = await changeImageWH(base64Sign);
//remove suffiix of base64 //remove suffiix of base64
const suffixbase64 = getNewse64 && getNewse64.split(",").pop(); const suffixbase64 = getNewse64 && getNewse64.split(",").pop();
let singleSign = { const params = {
pdfFile: base64Url, pdfFile: base64Url,
docId: documentId, docId: documentId,
isCustomCompletionMail: isCustomCompletionMail, isCustomCompletionMail: isCustomCompletionMail,
mailProvider: activeMailAdapter, mailProvider: activeMailAdapter,
signature: suffixbase64 signature: suffixbase64
}; };
const resSignPdf = await Parse.Cloud.run("signPdf", params);
await axios if (resSignPdf) {
.post(`${localStorage.getItem("baseUrl")}functions/signPdf`, singleSign, { const signedpdf = JSON.parse(JSON.stringify(resSignPdf));
headers: { setPdfUrl(signedpdf);
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
// sessionToken: localStorage.getItem("accesstoken")
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
}
})
.then((Listdata) => {
const json = Listdata.data;
setPdfUrl(json.result.data);
if (json.result.data) {
getDocumentDetails(false); getDocumentDetails(false);
} }
})
.catch((err) => {
console.log("axois err ", err);
});
}; };
//function for save x and y position and show signature tab on that position //function for save x and y position and show signature tab on that position
@@ -1234,12 +1226,9 @@ function SignYourSelf() {
<ModalUi <ModalUi
isOpen={isAlert.isShow} isOpen={isAlert.isShow}
title={isAlert?.header || "Alert"} title={isAlert?.header || "Alert"}
handleClose={() => { handleClose={() =>
setIsAlert({ setIsAlert({ isShow: false, alertMessage: "" })
isShow: false, }
alertMessage: ""
});
}}
> >
<div className="p-[20px] h-full"> <div className="p-[20px] h-full">
<p>{isAlert.alertMessage}</p> <p>{isAlert.alertMessage}</p>
@@ -1314,12 +1303,12 @@ function SignYourSelf() {
isEmail={isEmail} isEmail={isEmail}
pdfUrl={pdfUrl} pdfUrl={pdfUrl}
setIsEmail={setIsEmail} setIsEmail={setIsEmail}
pdfName={pdfDetails[0] && pdfDetails[0].Name}
setSuccessEmail={setSuccessEmail} setSuccessEmail={setSuccessEmail}
sender={jsonSender} sender={jsonSender}
setIsAlert={setIsAlert} setIsAlert={setIsAlert}
extUserId={extUserId} extUserId={extUserId}
activeMailAdapter={activeMailAdapter} activeMailAdapter={activeMailAdapter}
pdfDetails={pdfDetails}
/> />
{/* pdf header which contain funish back button */} {/* pdf header which contain funish back button */}
<Header <Header
+7 -25
View File
@@ -153,14 +153,6 @@ const TemplatePlaceholder = () => {
const [fontColor, setFontColor] = useState(); const [fontColor, setFontColor] = useState();
const [zoomPercent, setZoomPercent] = useState(0); const [zoomPercent, setZoomPercent] = useState(0);
const [scale, setScale] = useState(1); const [scale, setScale] = useState(1);
const senderUser =
localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
) &&
localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
);
const jsonSender = JSON.parse(senderUser);
useEffect(() => { useEffect(() => {
fetchTemplate(); fetchTemplate();
@@ -317,7 +309,7 @@ const TemplatePlaceholder = () => {
setHandleError("Error: Something went wrong!"); setHandleError("Error: Something went wrong!");
} }
} }
const res = await contractUsers(jsonSender.email); const res = await contractUsers();
if (res[0] && res.length) { if (res[0] && res.length) {
setSignerUserId(res[0].objectId); setSignerUserId(res[0].objectId);
setCurrentEmail(res[0].Email); setCurrentEmail(res[0].Email);
@@ -1354,9 +1346,7 @@ const TemplatePlaceholder = () => {
{currentEmail.length > 0 && ( {currentEmail.length > 0 && (
<> <>
<button <button
onClick={() => { onClick={() => handleCreateDocModal()}
handleCreateDocModal();
}}
type="button" type="button"
className="op-btn op-btn-primary" className="op-btn op-btn-primary"
> >
@@ -1379,18 +1369,14 @@ const TemplatePlaceholder = () => {
{isCreateDoc && <LoaderWithMsg isLoading={isLoading} />} {isCreateDoc && <LoaderWithMsg isLoading={isLoading} />}
<ModalUi <ModalUi
isOpen={isShowEmail} isOpen={isShowEmail}
title={"signers alert"} title={"Signers alert"}
handleClose={() => { handleClose={() => setIsShowEmail(false)}
setIsShowEmail(false);
}}
> >
<div className="h-full p-[20px]"> <div className="h-full p-[20px]">
<p>Please select signer for add placeholder!</p> <p>Please select signer for add placeholder!</p>
<div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div> <div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div>
<button <button
onClick={() => { onClick={() => setIsShowEmail(false)}
setIsShowEmail(false);
}}
type="button" type="button"
className="op-btn op-btn-primary" className="op-btn op-btn-primary"
> >
@@ -1439,7 +1425,6 @@ const TemplatePlaceholder = () => {
allPages={allPages} allPages={allPages}
pageNumber={pageNumber} pageNumber={pageNumber}
signKey={signKey} signKey={signKey}
// signerObjId={signerObjId}
Id={uniqueId} Id={uniqueId}
/> />
{/* pdf header which contain funish back button */} {/* pdf header which contain funish back button */}
@@ -1551,10 +1536,8 @@ const TemplatePlaceholder = () => {
/> />
</div> </div>
) : ( ) : (
<div <div className="w-[23%] bg-base-100 min-h-screen overflow-y-auto hide-scrollbar">
className={`w-[23%] bg-[#FFFFFF] min-h-screen overflow-y-auto hide-scrollbar`} <div className="max-h-screen">
>
<div className={`max-h-screen`}>
<SignerListPlace <SignerListPlace
isMailSend={isMailSend} isMailSend={isMailSend}
signerPos={signerPos} signerPos={signerPos}
@@ -1601,7 +1584,6 @@ const TemplatePlaceholder = () => {
</div> </div>
</div> </div>
)} )}
<div data-tut="reactourAddbtn--observe"> <div data-tut="reactourAddbtn--observe">
<AddRoleModal <AddRoleModal
isModalRole={isModalRole} isModalRole={isModalRole}
+3 -3
View File
@@ -221,9 +221,9 @@ const UserList = () => {
<thead className="text-[14px]"> <thead className="text-[14px]">
<tr className="border-y-[1px]"> <tr className="border-y-[1px]">
{heading?.map((item, index) => ( {heading?.map((item, index) => (
<React.Fragment key={index}> <th key={index} className="px-4 py-2">
<th className="px-4 py-2">{item}</th> {item}
</React.Fragment> </th>
))} ))}
</tr> </tr>
</thead> </thead>
+1 -3
View File
@@ -313,9 +313,7 @@ function UserProfile() {
) : ( ) : (
<div className="flex justify-center items-center w-full relative"> <div className="flex justify-center items-center w-full relative">
{userNameError && ( {userNameError && (
<div <div className="z-[1000] fixed top-[50%] transform border-[1px] text-sm border-[#f0a8a8] bg-[#f4bebe] text-[#c42121] rounded py-[.75rem] px-[1.25rem]">
className={`z-[1000] fixed top-[50%] transform border-[1px] text-sm border-[#f0a8a8] bg-[#f4bebe] text-[#c42121] rounded py-[.75rem] px-[1.25rem]`}
>
{userNameError} {userNameError}
</div> </div>
)} )}
+1 -3
View File
@@ -32,14 +32,12 @@ function Webhook() {
}, []); }, []);
const fetchWebhook = async () => { const fetchWebhook = async () => {
const email = Parse.User.current().getEmail();
if (isEnableSubscription) { if (isEnableSubscription) {
const getIsSubscribe = await checkIsSubscribed(); const getIsSubscribe = await checkIsSubscribed();
setIsSubscribe(getIsSubscribe); setIsSubscribe(getIsSubscribe);
} }
const params = { email: email };
try { try {
const extRes = await Parse.Cloud.run("getUserDetails", params); const extRes = await Parse.Cloud.run("getUserDetails");
if (extRes) { if (extRes) {
setWebhook(extRes.get("Webhook")); setWebhook(extRes.get("Webhook"));
} }
@@ -10,10 +10,10 @@ import Tooltip from "./Tooltip";
import { RWebShare } from "react-web-share"; import { RWebShare } from "react-web-share";
import Tour from "reactour"; import Tour from "reactour";
import Parse from "parse"; import Parse from "parse";
import { saveAs } from "file-saver";
import { import {
checkIsSubscribedTeam, checkIsSubscribedTeam,
copytoData, copytoData,
fetchUrl,
replaceMailVaribles replaceMailVaribles
} from "../constant/Utils"; } from "../constant/Utils";
import Confetti from "react-confetti"; import Confetti from "react-confetti";
@@ -526,10 +526,7 @@ const ReportTable = (props) => {
}; };
async function checkTourStatus() { async function checkTourStatus() {
const currentUser = Parse.User.current(); const cloudRes = await Parse.Cloud.run("getUserDetails");
const cloudRes = await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
});
const res = { data: cloudRes.toJSON() }; const res = { data: cloudRes.toJSON() };
if (res.data && res.data.TourStatus && res.data.TourStatus.length > 0) { if (res.data && res.data.TourStatus && res.data.TourStatus.length > 0) {
const tourStatus = res.data.TourStatus; const tourStatus = res.data.TourStatus;
@@ -595,14 +592,18 @@ const ReportTable = (props) => {
// `handleDownload` is used to get valid doc url available in completed report // `handleDownload` is used to get valid doc url available in completed report
const handleDownload = async (item) => { const handleDownload = async (item) => {
setActLoader({ [`${item.objectId}`]: true });
const url = item?.SignedUrl || item?.URL || ""; const url = item?.SignedUrl || item?.URL || "";
const pdfName = item?.Name || "exported_file";
if (url) { if (url) {
try { try {
const signedUrl = await Parse.Cloud.run("getsignedurl", { url: url }); const signedUrl = await Parse.Cloud.run("getsignedurl", { url: url });
saveAs(signedUrl); await fetchUrl(signedUrl, pdfName);
setActLoader({});
} catch (err) { } catch (err) {
console.log("err in getsignedurl", err); console.log("err in getsignedurl", err);
alert("something went wrong, please try again later."); alert("something went wrong, please try again later.");
setActLoader({});
} }
} }
}; };
+2 -1
View File
@@ -8,13 +8,13 @@ const Validate = () => {
const [isUserValid, setIsUserValid] = useState(true); const [isUserValid, setIsUserValid] = useState(true);
useEffect(() => { useEffect(() => {
(async () => { (async () => {
if (localStorage.getItem("accesstoken")) {
try { try {
const userDetails = JSON.parse( const userDetails = JSON.parse(
localStorage.getItem( localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser` `Parse/${localStorage.getItem("parseAppId")}/currentUser`
) )
); );
// Use the session token to validate the user // Use the session token to validate the user
const userQuery = new Parse.Query(Parse.User); const userQuery = new Parse.Query(Parse.User);
const user = await userQuery.get(userDetails?.objectId, { const user = await userQuery.get(userDetails?.objectId, {
@@ -29,6 +29,7 @@ const Validate = () => {
// Session token is invalid or there was an error // Session token is invalid or there was an error
setIsUserValid(false); setIsUserValid(false);
} }
}
})(); })();
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
+17 -9
View File
@@ -4,6 +4,7 @@ import { Outlet } from "react-router-dom";
const ValidateRoute = () => { const ValidateRoute = () => {
useEffect(() => { useEffect(() => {
(async () => { (async () => {
if (localStorage.getItem("accesstoken")) {
try { try {
// Use the session token to validate the user // Use the session token to validate the user
const userQuery = new Parse.Query(Parse.User); const userQuery = new Parse.Query(Parse.User);
@@ -17,18 +18,25 @@ const ValidateRoute = () => {
console.log("err in validate route", error); console.log("err in validate route", error);
handlelogout(); handlelogout();
} }
}
})(); })();
}, []); }, []);
const handlelogout = async () => { const handlelogout = async () => {
try { let appdata = localStorage.getItem("userSettings");
// if (Parse?.User?.current()) { let applogo = localStorage.getItem("appLogo");
// Parse?.User?.logOut(); let defaultmenuid = localStorage.getItem("defaultmenuid");
// } let PageLanding = localStorage.getItem("PageLanding");
localStorage.removeItem("accesstoken"); let baseUrl = localStorage.getItem("baseUrl");
} catch (err) { let appid = localStorage.getItem("parseAppId");
console.log("err ", err);
localStorage.removeItem("accesstoken"); localStorage.clear();
}
localStorage.setItem("appLogo", applogo);
localStorage.setItem("defaultmenuid", defaultmenuid);
localStorage.setItem("PageLanding", PageLanding);
localStorage.setItem("userSettings", appdata);
localStorage.setItem("baseUrl", baseUrl);
localStorage.setItem("parseAppId", appid);
}; };
return <div>{<Outlet />}</div>; return <div>{<Outlet />}</div>;
}; };
-31
View File
@@ -8,38 +8,7 @@ module.exports = {
daisyui: { daisyui: {
// themes: true, // themes: true,
themes: [ themes: [
"light",
"dark", "dark",
"cupcake",
"bumblebee",
"emerald",
"corporate",
"synthwave",
"retro",
"cyberpunk",
"valentine",
"halloween",
"garden",
"forest",
"aqua",
"lofi",
"pastel",
"fantasy",
"wireframe",
"black",
"luxury",
"dracula",
"cmyk",
"autumn",
"business",
"acid",
"lemonade",
"night",
"coffee",
"winter",
"dim",
"nord",
"sunset",
{ {
opensigncss: { opensigncss: {
primary: "#002864", primary: "#002864",
+2 -1
View File
@@ -4,8 +4,9 @@ dotenv.config();
const appId = process.env.APP_ID; const appId = process.env.APP_ID;
const serverUrl = process.env.SERVER_URL; const serverUrl = process.env.SERVER_URL;
export const cloudServerUrl = 'http://localhost:8080/app';
export function customAPIurl() { export function customAPIurl() {
const url = new URL(process.env.SERVER_URL); const url = new URL(cloudServerUrl);
return url.pathname === '/api/app' ? url.origin + '/api' : url.origin; return url.pathname === '/api/app' ? url.origin + '/api' : url.origin;
} }
@@ -1,4 +1,5 @@
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
// `replaceMailVaribles` is used to replace variables from mail with there actual values // `replaceMailVaribles` is used to replace variables from mail with there actual values
function replaceMailVaribles(subject, body, variables) { function replaceMailVaribles(subject, body, variables) {
@@ -26,7 +27,7 @@ function replaceMailVaribles(subject, body, variables) {
async function sendMail(doc, signer) { async function sendMail(doc, signer) {
const subject = `{{sender_name}} has requested you to sign "{{document_title}}"`; const subject = `{{sender_name}} has requested you to sign "{{document_title}}"`;
const body = `<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body><p>Hi {{receiver_name}},</p><br><p>We hope this email finds you well. {{sender_name}}&nbsp;has requested you to review and sign&nbsp;<b>"{{document_title}}"</b>.</p><p>Your signature is crucial to proceed with the next steps as it signifies your agreement and authorization.</p><br><p>{{signing_url}}</p><br><p>If you have any questions or need further clarification regarding the document or the signing process, please contact the sender.</p><br><p>Thanks</p><p> Team OpenSign™</p><br></body> </html>`; const body = `<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body><p>Hi {{receiver_name}},</p><br><p>We hope this email finds you well. {{sender_name}}&nbsp;has requested you to review and sign&nbsp;<b>"{{document_title}}"</b>.</p><p>Your signature is crucial to proceed with the next steps as it signifies your agreement and authorization.</p><br><p>{{signing_url}}</p><br><p>If you have any questions or need further clarification regarding the document or the signing process, please contact the sender.</p><br><p>Thanks</p><p> Team OpenSign™</p><br></body> </html>`;
const url = `${process.env.SERVER_URL}/functions/sendmailv3`; const url = `${cloudServerUrl}/functions/sendmailv3`;
const headers = { const headers = {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-Parse-Application-Id': process.env.APP_ID, 'X-Parse-Application-Id': process.env.APP_ID,
@@ -1,6 +1,7 @@
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
const appId = process.env.APP_ID; const appId = process.env.APP_ID;
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
export default async function gooogleauth(request, response) { export default async function gooogleauth(request, response) {
const code = request.body.code; const code = request.body.code;
const baseUrl = new URL(process.env.SERVER_URL); const baseUrl = new URL(process.env.SERVER_URL);
@@ -3,7 +3,7 @@ import multer from 'multer';
import multerS3 from 'multer-s3'; import multerS3 from 'multer-s3';
import aws from 'aws-sdk'; import aws from 'aws-sdk';
import dotenv from 'dotenv'; import dotenv from 'dotenv';
import { useLocal } from '../../Utils.js'; import { cloudServerUrl, useLocal } from '../../Utils.js';
dotenv.config(); dotenv.config();
function sanitizeFileName(fileName) { function sanitizeFileName(fileName) {
@@ -49,7 +49,7 @@ async function uploadFile(req, res) {
const DO_SECRET_ACCESS_KEY = process.env.DO_SECRET_ACCESS_KEY; const DO_SECRET_ACCESS_KEY = process.env.DO_SECRET_ACCESS_KEY;
const DO_SPACE = process.env.DO_SPACE; const DO_SPACE = process.env.DO_SPACE;
const parseBaseUrl = process.env.SERVER_URL; const parseBaseUrl = cloudServerUrl; //process.env.SERVER_URL;
const parseAppId = process.env.APP_ID; const parseAppId = process.env.APP_ID;
let fileStorage; let fileStorage;
if (useLocal === 'true') { if (useLocal === 'true') {
@@ -1,5 +1,5 @@
import axios from 'axios'; import axios from 'axios';
import { customAPIurl, replaceMailVaribles } from '../../../../Utils.js'; import { cloudServerUrl, customAPIurl, replaceMailVaribles } from '../../../../Utils.js';
// `sendDoctoWebhook` is used to send res data of document on webhook // `sendDoctoWebhook` is used to send res data of document on webhook
async function sendDoctoWebhook(doc, WebhookUrl, userId) { async function sendDoctoWebhook(doc, WebhookUrl, userId) {
@@ -220,7 +220,7 @@ export default async function createDocumentWithTemplate(request, response) {
for (let i = 0; i < contactMail.length; i++) { for (let i = 0; i < contactMail.length; i++) {
try { try {
const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png'; const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png';
let url = `${process.env.SERVER_URL}/functions/sendmailv3/`; let url = `${cloudServerUrl}/functions/sendmailv3/`;
const headers = { const headers = {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-Parse-Application-Id': process.env.APP_ID, 'X-Parse-Application-Id': process.env.APP_ID,
@@ -6,6 +6,7 @@ import {
saveFileUsage, saveFileUsage,
formatWidgetOptions, formatWidgetOptions,
sanitizeFileName, sanitizeFileName,
cloudServerUrl,
} from '../../../../Utils.js'; } from '../../../../Utils.js';
// `sendDoctoWebhook` is used to send res data of document on webhook // `sendDoctoWebhook` is used to send res data of document on webhook
@@ -281,7 +282,7 @@ export default async function createDocumentwithCoordinate(request, response) {
for (let i = 0; i < contactMail.length; i++) { for (let i = 0; i < contactMail.length; i++) {
try { try {
const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png'; const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png';
let url = `${process.env.SERVER_URL}/functions/sendmailv3/`; let url = `${cloudServerUrl}/functions/sendmailv3/`;
const headers = { const headers = {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-Parse-Application-Id': process.env.APP_ID, 'X-Parse-Application-Id': process.env.APP_ID,
@@ -1,12 +1,13 @@
import axios from 'axios'; import axios from 'axios';
import reportJson from '../../../parsefunction/reportsJson.js'; import reportJson from '../../../parsefunction/reportsJson.js';
import dotenv from 'dotenv'; import dotenv from 'dotenv';
import { cloudServerUrl } from '../../../../Utils.js';
dotenv.config(); dotenv.config();
export default async function getDocumentList(request, response) { export default async function getDocumentList(request, response) {
const reqToken = request.headers['x-api-token']; const reqToken = request.headers['x-api-token'];
const appId = process.env.APP_ID; const appId = process.env.APP_ID;
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
if (!reqToken) { if (!reqToken) {
return response.status(400).json({ error: 'Please Provide API Token' }); return response.status(400).json({ error: 'Please Provide API Token' });
} }
@@ -1,10 +1,11 @@
import axios from 'axios'; import axios from 'axios';
import dotenv from 'dotenv'; import dotenv from 'dotenv';
import { cloudServerUrl } from '../../../../Utils.js';
dotenv.config(); dotenv.config();
export default async function getTemplatetList(request, response) { export default async function getTemplatetList(request, response) {
const reqToken = request.headers['x-api-token']; const reqToken = request.headers['x-api-token'];
const appId = process.env.APP_ID; const appId = process.env.APP_ID;
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
if (!reqToken) { if (!reqToken) {
return response.status(400).json({ error: 'Please Provide API Token' }); return response.status(400).json({ error: 'Please Provide API Token' });
} }
@@ -1,5 +1,5 @@
import axios from 'axios'; import axios from 'axios';
import { replaceMailVaribles } from '../../../../Utils.js'; import { cloudServerUrl, replaceMailVaribles } from '../../../../Utils.js';
export default async function resendMail(request, response) { export default async function resendMail(request, response) {
try { try {
@@ -44,7 +44,7 @@ export default async function resendMail(request, response) {
if (contact) { if (contact) {
try { try {
const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png'; const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png';
let url = `${process.env.SERVER_URL}/functions/sendmailv3/`; let url = `${cloudServerUrl}/functions/sendmailv3/`;
const headers = { const headers = {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-Parse-Application-Id': process.env.APP_ID, 'X-Parse-Application-Id': process.env.APP_ID,
@@ -1,5 +1,6 @@
import axios from 'axios'; import axios from 'axios';
const serverUrl = process.env.SERVER_URL; import { cloudServerUrl } from '../../Utils.js';
const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const APPID = process.env.APP_ID; const APPID = process.env.APP_ID;
const masterKEY = process.env.MASTER_KEY; const masterKEY = process.env.MASTER_KEY;
async function addTeamAndOrg(extUser) { async function addTeamAndOrg(extUser) {
@@ -1,8 +1,9 @@
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
async function AuthLoginAsMail(request) { async function AuthLoginAsMail(request) {
try { try {
//function for login user using user objectId without touching user's password //function for login user using user objectId without touching user's password
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const APPID = process.env.APP_ID; const APPID = process.env.APP_ID;
const masterKEY = process.env.MASTER_KEY; const masterKEY = process.env.MASTER_KEY;
@@ -4,7 +4,8 @@ async function DocumentAftersave(request) {
console.log('new entry is insert in contracts_Document'); console.log('new entry is insert in contracts_Document');
const createdAt = request.object.get('createdAt'); const createdAt = request.object.get('createdAt');
const Folder = request.object.get('Type'); const Folder = request.object.get('Type');
const ip = request?.headers?.['x-real-ip'] || request.object?.get('OriginIp') || ''; const ip = request?.headers?.['x-real-ip'] || '';
const originIp = request?.object?.get('OriginIp') || '';
if (createdAt && Folder === undefined) { if (createdAt && Folder === undefined) {
// console.log("IN If condition") // console.log("IN If condition")
const TimeToCompleteDays = request.object.get('TimeToCompleteDays') || 15; const TimeToCompleteDays = request.object.get('TimeToCompleteDays') || 15;
@@ -13,7 +14,9 @@ async function DocumentAftersave(request) {
const documentQuery = new Parse.Query('contracts_Document'); const documentQuery = new Parse.Query('contracts_Document');
const updateQuery = await documentQuery.get(request.object.id, { useMasterKey: true }); const updateQuery = await documentQuery.get(request.object.id, { useMasterKey: true });
updateQuery.set('ExpiryDate', ExpiryDate); updateQuery.set('ExpiryDate', ExpiryDate);
if (!originIp) {
updateQuery.set('OriginIp', ip); updateQuery.set('OriginIp', ip);
}
const AutoReminder = request?.object?.get('AutomaticReminders') || false; const AutoReminder = request?.object?.get('AutomaticReminders') || false;
if (AutoReminder) { if (AutoReminder) {
const RemindOnceInEvery = request?.object?.get('RemindOnceInEvery') || 5; const RemindOnceInEvery = request?.object?.get('RemindOnceInEvery') || 5;
@@ -29,7 +32,9 @@ async function DocumentAftersave(request) {
const documentQuery = new Parse.Query('contracts_Document'); const documentQuery = new Parse.Query('contracts_Document');
const updateQuery = await documentQuery.get(request.object.id, { useMasterKey: true }); const updateQuery = await documentQuery.get(request.object.id, { useMasterKey: true });
updateQuery.set('ExpiryDate', ExpiryDate); updateQuery.set('ExpiryDate', ExpiryDate);
if (!originIp) {
updateQuery.set('OriginIp', ip); updateQuery.set('OriginIp', ip);
}
const AutoReminder = request?.object?.get('AutomaticReminders') || false; const AutoReminder = request?.object?.get('AutomaticReminders') || false;
if (AutoReminder) { if (AutoReminder) {
const RemindOnceInEvery = request?.object?.get('RemindOnceInEvery') || 5; const RemindOnceInEvery = request?.object?.get('RemindOnceInEvery') || 5;
@@ -1,6 +1,7 @@
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const APPID = process.env.APP_ID; const APPID = process.env.APP_ID;
const masterKEY = process.env.MASTER_KEY; const masterKEY = process.env.MASTER_KEY;
@@ -22,11 +22,16 @@ async function GetPublicTemplate(request) {
templatQuery.notEqualTo('IsArchive', true); templatQuery.notEqualTo('IsArchive', true);
const getTemplate = await templatQuery.find({ useMasterKey: true }); const getTemplate = await templatQuery.find({ useMasterKey: true });
const extend_Res = await Parse.Cloud.run('getUserDetails', { const extcls = new Parse.Query('contracts_Users');
email: user.get('email'), extcls.equalTo('email', user.get('email'));
}); const res = await extcls.first({ useMasterKey: true });
if (extend_Res) { if (res) {
return { template: getTemplate, user: user, extend_User: extend_Res }; const _res = JSON.parse(JSON.stringify(_res));
return {
template: getTemplate,
user: user,
extend_User: { Tagline: _res?.Tagline || '', SearchIndex: _res?.SearchIndex || '' },
};
} else { } else {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Template not found'); throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Template not found');
} }
@@ -1,7 +1,8 @@
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
export default async function GetTemplate(request) { export default async function GetTemplate(request) {
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const templateId = request.params.templateId; const templateId = request.params.templateId;
const ispublic = request.params.ispublic; const ispublic = request.params.ispublic;
@@ -1,6 +1,7 @@
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const APPID = process.env.APP_ID; const APPID = process.env.APP_ID;
const masterKEY = process.env.MASTER_KEY; const masterKEY = process.env.MASTER_KEY;
@@ -1,10 +1,11 @@
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
export default async function callWebhook(request) { export default async function callWebhook(request) {
const event = request.params.event; const event = request.params.event;
const body = request.params.body; const body = request.params.body;
const docId = body.objectId; const docId = body.objectId;
const contactId = request.params.contactId; const contactId = request.params.contactId;
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const appId = process.env.APP_ID; const appId = process.env.APP_ID;
const userRes = await axios.get(serverUrl + '/users/me', { const userRes = await axios.get(serverUrl + '/users/me', {
headers: { headers: {
@@ -1,6 +1,7 @@
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const appId = process.env.APP_ID; const appId = process.env.APP_ID;
async function sendMail(document, sessionToken) { async function sendMail(document, sessionToken) {
@@ -1,7 +1,8 @@
import { generateApiKey } from 'generate-api-key'; import { generateApiKey } from 'generate-api-key';
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
export default async function generateApiToken(request) { export default async function generateApiToken(request) {
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
try { try {
const userRes = await axios.get(serverUrl + '/users/me', { const userRes = await axios.get(serverUrl + '/users/me', {
headers: { headers: {
@@ -1,7 +1,8 @@
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
export default async function getDocument(request) { export default async function getDocument(request) {
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const docId = request.params.docId; const docId = request.params.docId;
try { try {
@@ -1,6 +1,7 @@
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
export default async function getDrive(request) { export default async function getDrive(request) {
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const appId = process.env.APP_ID; const appId = process.env.APP_ID;
const limit = request.params.limit; const limit = request.params.limit;
const skip = request.params.skip; const skip = request.params.skip;
@@ -1,5 +1,6 @@
import axios from 'axios'; import axios from 'axios';
const serverUrl = process.env.SERVER_URL; import { cloudServerUrl } from '../../Utils.js';
const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const appId = process.env.APP_ID; const appId = process.env.APP_ID;
export default async function getInvoices(request) { export default async function getInvoices(request) {
const limit = request.params.limit || 100; const limit = request.params.limit || 100;
@@ -1,5 +1,6 @@
import axios from 'axios'; import axios from 'axios';
const serverUrl = process.env.SERVER_URL; import { cloudServerUrl } from '../../Utils.js';
const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const appId = process.env.APP_ID; const appId = process.env.APP_ID;
export default async function getPayments(request) { export default async function getPayments(request) {
const limit = request.params.limit || 100; const limit = request.params.limit || 100;
@@ -1,3 +1,4 @@
import { cloudServerUrl } from '../../Utils.js';
import reportJson from './reportsJson.js'; import reportJson from './reportsJson.js';
import axios from 'axios'; import axios from 'axios';
@@ -6,7 +7,7 @@ export default async function getReport(request) {
const limit = request.params.limit; const limit = request.params.limit;
const skip = request.params.skip; const skip = request.params.skip;
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const appId = process.env.APP_ID; const appId = process.env.APP_ID;
const masterKey = process.env.MASTER_KEY; const masterKey = process.env.MASTER_KEY;
try { try {
@@ -1,5 +1,6 @@
import axios from 'axios'; import axios from 'axios';
const serverUrl = process.env.SERVER_URL; import { cloudServerUrl } from '../../Utils.js';
const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const appId = process.env.APP_ID; const appId = process.env.APP_ID;
export default async function getSubscription(request) { export default async function getSubscription(request) {
const extUserId = request.params.extUserId || ''; const extUserId = request.params.extUserId || '';
@@ -1,19 +1,39 @@
async function getUserDetails(request) { async function getUserDetails(request) {
const reqEmail = request.params.email;
if (reqEmail || request.user) {
try { try {
const userId = request.params.userId; const userId = request.params.userId;
const userQuery = new Parse.Query('contracts_Users'); const userQuery = new Parse.Query('contracts_Users');
userQuery.equalTo('Email', request.params.email); if (request?.user) {
const email = request.user.get('email');
userQuery.equalTo('Email', email);
} else {
userQuery.equalTo('Email', reqEmail);
}
userQuery.include('TenantId'); userQuery.include('TenantId');
userQuery.include('UserId'); userQuery.include('UserId');
userQuery.exclude('google_refresh_token') userQuery.exclude('google_refresh_token');
if (userId) { if (userId) {
userQuery.equalTo('CreatedBy', { __type: 'Pointer', className: '_User', objectId: userId }); userQuery.equalTo('CreatedBy', { __type: 'Pointer', className: '_User', objectId: userId });
} }
const res = await userQuery.first({ useMasterKey: true }); const res = await userQuery.first({ useMasterKey: true });
if (res) {
if (reqEmail) {
return { objectId: res.id };
} else {
return res; return res;
}
} else {
return '';
}
} catch (err) { } catch (err) {
console.log('Err ', err); console.log('Err ', err);
return err; const code = err?.code || 400;
const msg = err?.message || 'Something went wrong.';
throw new Parse.Error(code, msg);
}
} else {
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.');
} }
} }
export default getUserDetails; export default getUserDetails;
@@ -1,6 +1,7 @@
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
export default async function getapitoken(request) { export default async function getapitoken(request) {
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
try { try {
const userRes = await axios.get(serverUrl + '/users/me', { const userRes = await axios.get(serverUrl + '/users/me', {
headers: { headers: {
@@ -4,9 +4,9 @@ import { SignPdf } from '@signpdf/signpdf';
import { P12Signer } from '@signpdf/signer-p12'; import { P12Signer } from '@signpdf/signer-p12';
import { pdflibAddPlaceholder } from '@signpdf/placeholder-pdf-lib'; import { pdflibAddPlaceholder } from '@signpdf/placeholder-pdf-lib';
import { PDFDocument } from 'pdf-lib'; import { PDFDocument } from 'pdf-lib';
import { replaceMailVaribles, saveFileUsage } from '../../../Utils.js'; import { cloudServerUrl, replaceMailVaribles, saveFileUsage } from '../../../Utils.js';
import GenerateCertificate from './GenerateCertificate.js'; import GenerateCertificate from './GenerateCertificate.js';
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; // process.env.SERVER_URL;
const APPID = process.env.APP_ID; const APPID = process.env.APP_ID;
const masterKEY = process.env.MASTER_KEY; const masterKEY = process.env.MASTER_KEY;
const eSignName = 'opensign'; const eSignName = 'opensign';
@@ -1,6 +1,7 @@
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
export default async function saveSubscription(request) { export default async function saveSubscription(request) {
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const appId = process.env.APP_ID; const appId = process.env.APP_ID;
const subscription = request.params.subscription; const subscription = request.params.subscription;
const SubscriptionId = subscription.data.subscription.subscription_id; const SubscriptionId = subscription.data.subscription.subscription_id;
@@ -1,6 +1,7 @@
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
export default async function savewebhook(request) { export default async function savewebhook(request) {
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
try { try {
const userRes = await axios.get(serverUrl + '/users/me', { const userRes = await axios.get(serverUrl + '/users/me', {
headers: { headers: {
@@ -2,6 +2,8 @@ import axios from 'axios';
import { google } from 'googleapis'; import { google } from 'googleapis';
import fs from 'node:fs'; import fs from 'node:fs';
import https from 'https'; import https from 'https';
import http from 'http';
import { useLocal } from '../../Utils.js';
const clientId = process.env.GOOGLE_CLIENT_ID; const clientId = process.env.GOOGLE_CLIENT_ID;
const clientSecret = process.env.GOOGLE_CLIENT_SECRET; const clientSecret = process.env.GOOGLE_CLIENT_SECRET;
// Function to create a Gmail client // Function to create a Gmail client
@@ -26,6 +28,7 @@ const refreshAccessToken = async refreshToken => {
// Function to create a raw email message // Function to create a raw email message
const makeEmail = async (to, from, subject, html, url, pdfName) => { const makeEmail = async (to, from, subject, html, url, pdfName) => {
const protocol = new URL(process.env.SERVER_URL);
const htmlContent = html; const htmlContent = html;
const boundary = 'boundary_' + Date.now().toString(16); const boundary = 'boundary_' + Date.now().toString(16);
let str; let str;
@@ -34,10 +37,17 @@ const makeEmail = async (to, from, subject, html, url, pdfName) => {
let Pdf = fs.createWriteStream('test.pdf'); let Pdf = fs.createWriteStream('test.pdf');
const writeToLocalDisk = () => { const writeToLocalDisk = () => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (useLocal !== 'true' && protocol.hostname !== 'localhost') {
https.get(url, async function (response) { https.get(url, async function (response) {
response.pipe(Pdf); response.pipe(Pdf);
response.on('end', () => resolve('success')); response.on('end', () => resolve('success'));
}); });
} else {
http.get(url, async function (response) {
response.pipe(Pdf);
response.on('end', () => resolve('success'));
});
}
}); });
}; };
// `writeToLocalDisk` is used to create pdf file from doc url // `writeToLocalDisk` is used to create pdf file from doc url
@@ -1,11 +1,13 @@
import fs from 'node:fs'; import fs from 'node:fs';
import https from 'https'; import https from 'https';
import http from 'http';
import formData from 'form-data'; import formData from 'form-data';
import Mailgun from 'mailgun.js'; import Mailgun from 'mailgun.js';
import { smtpenable, smtpsecure, updateMailCount } from '../../Utils.js'; import { smtpenable, smtpsecure, updateMailCount, useLocal } from '../../Utils.js';
import sendMailGmailProvider from './sendMailGmailProvider.js'; import sendMailGmailProvider from './sendMailGmailProvider.js';
import { createTransport } from 'nodemailer'; import { createTransport } from 'nodemailer';
async function sendMailProvider(req) { async function sendMailProvider(req) {
const protocol = new URL(process.env.SERVER_URL);
try { try {
let transporterSMTP; let transporterSMTP;
let mailgunClient; let mailgunClient;
@@ -32,10 +34,17 @@ async function sendMailProvider(req) {
let Pdf = fs.createWriteStream('test.pdf'); let Pdf = fs.createWriteStream('test.pdf');
const writeToLocalDisk = () => { const writeToLocalDisk = () => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (useLocal !== 'true' && protocol.hostname !== 'localhost') {
https.get(req.params.url, async function (response) { https.get(req.params.url, async function (response) {
response.pipe(Pdf); response.pipe(Pdf);
response.on('end', () => resolve('success')); response.on('end', () => resolve('success'));
}); });
} else {
http.get(req.params.url, async function (response) {
response.pipe(Pdf);
response.on('end', () => resolve('success'));
});
}
}); });
}; };
// `writeToLocalDisk` is used to create pdf file from doc url // `writeToLocalDisk` is used to create pdf file from doc url
@@ -1,6 +1,7 @@
import axios from 'axios'; import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
const serverUrl = process.env.SERVER_URL; const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const APPID = process.env.APP_ID; const APPID = process.env.APP_ID;
const masterKEY = process.env.MASTER_KEY; const masterKEY = process.env.MASTER_KEY;
const clientUrl = process.env.PUBLIC_URL; const clientUrl = process.env.PUBLIC_URL;
@@ -1,5 +1,6 @@
import axios from 'axios'; import axios from 'axios';
const serverUrl = process.env.SERVER_URL; import { cloudServerUrl } from '../../Utils.js';
const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const APPID = process.env.APP_ID; const APPID = process.env.APP_ID;
const masterKEY = process.env.MASTER_KEY; const masterKEY = process.env.MASTER_KEY;
+5 -5
View File
@@ -17,7 +17,7 @@ import { exec } from 'child_process';
import { createTransport } from 'nodemailer'; import { createTransport } from 'nodemailer';
import { app as v1 } from './cloud/customRoute/v1/apiV1.js'; import { app as v1 } from './cloud/customRoute/v1/apiV1.js';
import { PostHog } from 'posthog-node'; import { PostHog } from 'posthog-node';
import { smtpenable, smtpsecure, useLocal } from './Utils.js'; import { cloudServerUrl, smtpenable, smtpsecure, useLocal } from './Utils.js';
import { SSOAuth } from './auth/authadapter.js'; import { SSOAuth } from './auth/authadapter.js';
let fsAdapter; let fsAdapter;
if (useLocal !== 'true') { if (useLocal !== 'true') {
@@ -98,9 +98,9 @@ export const config = {
maxUploadSize: '30mb', maxUploadSize: '30mb',
masterKey: process.env.MASTER_KEY, //Add your master key here. Keep it secret! masterKey: process.env.MASTER_KEY, //Add your master key here. Keep it secret!
masterKeyIps: ['0.0.0.0/0', '::/0'], // '::1' masterKeyIps: ['0.0.0.0/0', '::/0'], // '::1'
serverURL: 'http://localhost:8080/app', // Don't forget to change to https if needed serverURL: cloudServerUrl, // Don't forget to change to https if needed
verifyUserEmails: false, verifyUserEmails: false,
publicServerURL: process.env.SERVER_URL || 'http://localhost:8080/app', publicServerURL: process.env.SERVER_URL || cloudServerUrl,
// Your apps name. This will appear in the subject and body of the emails that are sent. // Your apps name. This will appear in the subject and body of the emails that are sent.
appName: 'Opensign', appName: 'Opensign',
allowClientClassCreation: false, allowClientClassCreation: false,
@@ -219,8 +219,8 @@ if (!process.env.TESTING) {
// console.log('isWindows', isWindows); // console.log('isWindows', isWindows);
const migrate = isWindows const migrate = isWindows
? `set APPLICATION_ID=${process.env.APP_ID}&& set SERVER_URL=http://localhost:8080/app&& set MASTER_KEY=${process.env.MASTER_KEY}&& npx parse-dbtool migrate` ? `set APPLICATION_ID=${process.env.APP_ID}&& set SERVER_URL=${cloudServerUrl}&& set MASTER_KEY=${process.env.MASTER_KEY}&& npx parse-dbtool migrate`
: `APPLICATION_ID=${process.env.APP_ID} SERVER_URL=http://localhost:8080/app MASTER_KEY=${process.env.MASTER_KEY} npx parse-dbtool migrate`; : `APPLICATION_ID=${process.env.APP_ID} SERVER_URL=${cloudServerUrl} MASTER_KEY=${process.env.MASTER_KEY} npx parse-dbtool migrate`;
exec(migrate, (error, stdout, stderr) => { exec(migrate, (error, stdout, stderr) => {
if (error) { if (error) {
console.error(`Error: ${error.message}`); console.error(`Error: ${error.message}`);
+2452 -2643
View File
File diff suppressed because it is too large Load Diff
+13 -9
View File
@@ -24,39 +24,43 @@
"@signpdf/placeholder-pdf-lib": "^3.2.4", "@signpdf/placeholder-pdf-lib": "^3.2.4",
"@signpdf/signer-p12": "^3.2.4", "@signpdf/signer-p12": "^3.2.4",
"@signpdf/signpdf": "^3.2.4", "@signpdf/signpdf": "^3.2.4",
"aws-sdk": "^2.1659.0", "aws-sdk": "^2.1667.0",
"axios": "^1.7.2", "axios": "^1.7.3",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"express": "^4.19.2", "express": "^4.19.2",
"express-sse": "^0.5.3",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"generate-api-key": "^1.0.2", "generate-api-key": "^1.0.2",
"googleapis": "^140.0.1", "googleapis": "^140.0.1",
"jsonschema": "^1.4.1", "jsonschema": "^1.4.1",
"mailgun.js": "^10.2.3", "mailgun.js": "^10.2.3",
"mongoose": "^8.5.1", "mongoose": "^8.5.2",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"multer-s3": "^3.0.1", "multer-s3": "^3.0.1",
"node-forge": "^1.3.1", "node-forge": "^1.3.1",
"nodemailer": "^6.9.14", "nodemailer": "^6.9.14",
"parse": "^5.3.0", "parse": "^5.3.0",
"parse-dbtool": "^1.2.0", "parse-dbtool": "^1.2.0",
"parse-server": "^7.1.0", "parse-server": "^7.2.0",
"parse-server-api-mail-adapter": "^4.0.0", "parse-server-api-mail-adapter": "^4.0.0",
"pdf-lib": "^1.17.1", "pdf-lib": "^1.17.1",
"posthog-node": "^4.0.1" "posthog-node": "^4.0.1",
"ws": "^8.18.0"
}, },
"type": "module", "type": "module",
"devDependencies": { "devDependencies": {
"@babel/eslint-parser": "^7.24.8", "@babel/eslint-parser": "^7.25.1",
"eslint": "^9.7.0", "eslint": "^9.8.0",
"jasmine": "^5.1.0", "jasmine": "^5.2.0",
"mongodb-runner": "^5.6.4", "mongodb-runner": "^5.6.4",
"nodemon": "^3.1.4", "nodemon": "^3.1.4",
"nyc": "^17.0.0", "nyc": "^17.0.0",
"prettier": "^3.3.3" "prettier": "^3.3.3"
}, },
"overrides": {
"ws": "$ws",
"parse": "$parse"
},
"engines": { "engines": {
"node": ">=12.22.10 <21" "node": ">=12.22.10 <21"
} }
-37
View File
@@ -1,37 +0,0 @@
// const { exec } = require('child_process');
import { exec } from 'child_process';
const migrate =
'APPLICATION_ID=legadranaxn SERVER_URL=http://localhost:8080/app MASTER_KEY=XnAwPDRQQyMr npx parse-dbtool migrate';
// `APPLICATION_ID=${process.env.APP_ID} SERVER_URL=${process.env.SERVER_URL} MASTER_KEY=${process.env.MASTER_KEY} npx parse-dbtool migrate`;
exec(migrate, (error, stdout, stderr) => {
if (error) {
console.error(`Error: ${error.message}`);
return;
}
if (stderr) {
console.error(`Error: ${stderr}`);
return;
}
console.log(`Command output: ${stdout}`);
});
// const seeder =
// 'APPLICATION_ID=legadranaxn SERVER_URL=http://localhost:8080/app MASTER_KEY=XnAwPDRQQyMr npx parse-dbtool seed';
// exec(seeder, (error, stdout, stderr) => {
// if (error) {
// console.error(`Error: ${error.message}`);
// return;
// }
// if (stderr) {
// console.error(`Error: ${stderr}`);
// return;
// }
// console.log(`Command output: ${stdout}`);
// });