Compare commits

..
139 Commits
Author SHA1 Message Date
AmolandGitHub a20bd407a8 Merge pull request #224 from prafull-opensignlabs/auth_user
chore:code refactor
2023-11-23 19:25:11 +05:30
prafull-opensignlabs 5630dd45a7 chore:code refactor 2023-11-23 19:23:35 +05:30
AmolandGitHub 20220dd8c9 Merge pull request #223 from raktima-opensignlabs/horizontal-pdf2
fix: two modal overlap at a time in signyourself flow
2023-11-23 19:23:17 +05:30
RaktimaNXG db4b8ec0ee fix two modal overlap during signyourself flow 2023-11-23 19:19:57 +05:30
RaktimaandGitHub 2ee9ae16fb Merge pull request #25 from OpenSignLabs/staging
update
2023-11-23 18:18:24 +05:30
prafull-opensignlabsandGitHub e50a55403d Merge pull request #48 from OpenSignLabs/staging
sync fork
2023-11-23 18:10:28 +05:30
AmolandGitHub 23ae72738d chore: syntax issue 2023-11-23 18:07:22 +05:30
AmolandGitHub 8619021f30 chore: syntax issue 2023-11-23 17:57:00 +05:30
AmolandGitHub 6c579178c0 chore: syntax issue 2023-11-23 17:51:10 +05:30
AmolandGitHub 01e19632a9 fix: syntax issue 2023-11-23 17:49:43 +05:30
AmolandGitHub 79ff8fd71d Merge pull request #191 from raktima-opensignlabs/transparent-img
fix:  #165 - transparent PNG signature issue
2023-11-23 17:36:30 +05:30
AmolandGitHub 8700fd837d Merge branch 'staging' into transparent-img 2023-11-23 17:36:10 +05:30
AmolandGitHub cdc8eb5bf6 Merge pull request #189 from rishabjasrotia/issue/126
#126 - Fix UI layout issue after signing a document from mobile
2023-11-23 17:27:43 +05:30
AmolandGitHub 95200e234f Merge pull request #216 from rishabjasrotia/issue/204
#204 - Fix issue due to Signature URL validation
2023-11-23 17:26:44 +05:30
AmolandGitHub d94527e31a Merge branch 'staging' into issue/204 2023-11-23 17:26:35 +05:30
prafull-opensignlabsandGitHub 903066e6fa Merge pull request #47 from OpenSignLabs/staging
sync fork
2023-11-23 17:25:16 +05:30
AmolandGitHub 8c8015fe4a Merge pull request #188 from rishabjasrotia/issue/168
#168 - Align Modal to Center of PDF if Signed
2023-11-23 17:19:01 +05:30
AmolandGitHub a002ac779c Merge pull request #222 from prafull-opensignlabs/auth_user 2023-11-23 13:47:12 +05:30
prafull-opensignlabs 5c9bfbbdfe fix: signature slighty move from top and bottom 2023-11-23 13:36:35 +05:30
RishabandGitHub 4a1e6d1318 Merge branch 'OpenSignLabs:staging' into issue/168 2023-11-23 12:56:50 +05:30
RaktimaandGitHub 90dc7c738a Merge pull request #24 from OpenSignLabs/staging
update
2023-11-23 11:14:50 +05:30
prafull-opensignlabsandGitHub 777028f3a7 Merge pull request #46 from OpenSignLabs/staging
Merge pull request #221 from prafull-opensignlabs/auth_user
2023-11-22 20:46:57 +05:30
AmolandGitHub c5a0ff4021 Merge pull request #221 from prafull-opensignlabs/auth_user
change sequence in add signer form
2023-11-22 20:42:58 +05:30
prafull-opensignlabs bf9f42e94d change sequence in add signer form 2023-11-22 20:41:55 +05:30
prafull-opensignlabsandGitHub 5556de2ef5 Merge pull request #45 from OpenSignLabs/staging
sync fork
2023-11-22 20:32:28 +05:30
rishabjasrotia 1b3508a9ef Replace npm package with manual valiadation 2023-11-22 18:57:18 +05:30
RishabandGitHub 3992a9be94 Merge branch 'OpenSignLabs:staging' into issue/204 2023-11-22 18:54:53 +05:30
AmolandGitHub eaf875be06 Merge pull request #220 from OpenSignLabs/add-verificaiton-branding
Add "OpenSign" branding to verification email
2023-11-22 17:27:53 +05:30
AmolandGitHub e62897e729 Add "OpenSign" branding to verification email 2023-11-22 16:57:44 +05:30
AmolandGitHub 4c58fe2040 Merge pull request #219 from prafull-opensignlabs/auth_user
add parameter verifyUserEmails in server
2023-11-22 16:34:26 +05:30
prafull-opensignlabs 298068207e add parameter verifyUserEmails in server 2023-11-22 16:33:18 +05:30
prafull-opensignlabsandGitHub d0abe615cb Merge pull request #44 from OpenSignLabs/staging
Merge pull request #215 from prafull-opensignlabs/auth_user
2023-11-22 16:32:06 +05:30
Rishab 87c65e4bea #204 - Fix issue due to Signature URL validation 2023-11-22 06:20:02 +00:00
RishabandGitHub be49cb9d6d Merge branch 'staging' into issue/168 2023-11-22 08:52:17 +05:30
AmolandGitHub 2b73087b7e Merge pull request #215 from prafull-opensignlabs/auth_user 2023-11-22 00:13:04 +05:30
prafull-opensignlabs d11dff2987 fix: google sign in mobile & add progress in profile pic upload 2023-11-22 00:09:28 +05:30
prafull-opensignlabsandGitHub 8ac82b1214 Merge pull request #43 from OpenSignLabs/staging
Merge pull request #214 from prafull-opensignlabs/auth_user
2023-11-21 23:07:08 +05:30
RaktimaandGitHub c46fa19bbb Merge pull request #23 from OpenSignLabs/staging
update
2023-11-21 20:56:29 +05:30
AmolandGitHub 2fa2f56bac Merge pull request #214 from prafull-opensignlabs/auth_user 2023-11-21 19:35:42 +05:30
prafull-opensignlabs ef50aaa417 fix google sign in 2023-11-21 19:34:11 +05:30
prafull-opensignlabsandGitHub a1d7275fcd Merge pull request #42 from OpenSignLabs/staging
sync fork
2023-11-21 19:17:55 +05:30
AmolandGitHub 080acc9ed6 Merge pull request #213 from raktima-opensignlabs/signer-login
fix:  no data found issue on signers login page
2023-11-21 16:36:10 +05:30
prafull-opensignlabsandGitHub 30b888f3a0 Merge pull request #41 from OpenSignLabs/staging
sync fork
2023-11-21 15:35:30 +05:30
prafull-opensignlabs df11a77971 Merge branch 'auth_user' of https://github.com/prafull-opensignlabs/OpenSign into auth_user 2023-11-21 15:28:41 +05:30
prafull-opensignlabs 03e660527d security improvement 2023-11-21 15:23:26 +05:30
RaktimaNXG f7bd439df5 remove contracts_contactbook class query from placeholderSign.js 2023-11-21 14:14:01 +05:30
RaktimaNXG 2a55c03788 fix no data found on signers login page 2023-11-21 13:36:42 +05:30
RaktimaandGitHub f712532793 Merge pull request #22 from OpenSignLabs/staging
update
2023-11-21 10:27:00 +05:30
AmolandGitHub cbdeaf8cc9 Merge pull request #212 from raktima-opensignlabs/email-message 2023-11-21 10:24:29 +05:30
RaktimaNXG 6bb353fd1f fix spelling mistake of email message beeen to been after signed by all parties 2023-11-21 10:22:16 +05:30
RaktimaandGitHub 523dd43b4d Merge pull request #21 from OpenSignLabs/staging
update
2023-11-21 09:55:49 +05:30
AmolandGitHub bd0216fc39 Merge pull request #197 from rishabjasrotia/issue/170 2023-11-21 03:09:16 +05:30
prafull-opensignlabsandGitHub 50c40bfec1 Merge pull request #40 from OpenSignLabs/staging
Merge pull request #211 from prafull-opensignlabs/auth_user
2023-11-20 23:03:35 +05:30
AmolandGitHub 0e2b6ee180 Merge pull request #211 from prafull-opensignlabs/auth_user 2023-11-20 23:01:49 +05:30
prafull-opensignlabs 359d86e17b fix: sendmail functionality not working 2023-11-20 23:00:07 +05:30
prafull-opensignlabsandGitHub 0b19c87a50 Merge pull request #37 from OpenSignLabs/staging
sync fork
2023-11-20 22:25:28 +05:30
AmolandGitHub 4a35eab7c6 Merge pull request #209 from raktima-opensignlabs/cloud-function 2023-11-20 22:14:20 +05:30
RaktimaNXG b178a3c91e handle condition of no data for contracts_Document and contracts_ContactBook classes 2023-11-20 21:57:26 +05:30
prafull-opensignlabsandGitHub 9fb0fecba4 Merge pull request #36 from OpenSignLabs/staging
sync fork
2023-11-20 20:18:32 +05:30
AmolandGitHub cfc7408a52 Merge pull request #210 from prafull-opensignlabs/auth_user
add getReport cloud function
2023-11-20 19:21:19 +05:30
prafull-opensignlabs aed0b8a3db add getReport cloud function 2023-11-20 19:11:46 +05:30
RaktimaNXG 910bd801ac remove contracts_Document & contracts_Users query from frontend and call cloud function 2023-11-20 16:46:27 +05:30
AmolandGitHub 22dad33b2e Merge pull request #208 from prafull-opensignlabs/auth_user
security changes in getDocument function & add getDrive cloud function
2023-11-20 14:14:31 +05:30
prafull-opensignlabs 4d3ed0232e security changes in getDocument function & add getDrive function 2023-11-20 14:11:32 +05:30
prafull-opensignlabsandGitHub 6d83f05b13 Merge pull request #34 from OpenSignLabs/staging
sync fork
2023-11-20 12:51:41 +05:30
AmolandGitHub 66cc2e1f2f Merge pull request #203 from rishabjasrotia/feature/certificate_update 2023-11-20 12:36:32 +05:30
AmolandGitHub f773fc6e3c Merge pull request #207 from prafull-opensignlabs/auth_user 2023-11-20 12:33:34 +05:30
prafull-opensignlabs dc83f21f5e Merge branch 'auth_user' of https://github.com/prafull-opensignlabs/OpenSign into auth_user 2023-11-20 12:04:06 +05:30
prafull-opensignlabsandGitHub 0186c48d59 Update getDocument.js 2023-11-20 12:00:41 +05:30
prafull-opensignlabs 43f20508ae Merge branch 'auth_user' of https://github.com/prafull-opensignlabs/OpenSign into auth_user 2023-11-20 11:54:18 +05:30
prafull-opensignlabs f678dd02cb change in getDoucment cloud function 2023-11-20 11:54:04 +05:30
prafull-opensignlabsandGitHub 5c2d6cddcb Merge pull request #33 from OpenSignLabs/staging
Merge pull request #205 from prafull-opensignlabs/auth_user
2023-11-20 11:53:02 +05:30
AmolandGitHub 1bbf64fe83 Merge pull request #205 from prafull-opensignlabs/auth_user
create getDocument cloud function & minor UI changes
2023-11-20 11:14:21 +05:30
prafull-opensignlabs 296f43101e comment getinProgessReport 2023-11-20 11:13:24 +05:30
prafull-opensignlabs ed6f44fd62 create getDocument cloud function & minor UI changes 2023-11-20 10:42:20 +05:30
prafull-opensignlabsandGitHub 776b1a7b43 Merge pull request #32 from OpenSignLabs/staging
sync fork
2023-11-20 10:25:08 +05:30
RaktimaandGitHub 06cdb660b3 Merge pull request #20 from OpenSignLabs/staging
update
2023-11-20 10:22:25 +05:30
rishabjasrotia db9268e1af Include the Signer Email Address 2023-11-18 20:21:17 +05:30
nxglabs 83ce3a1c21 update local cert setup 2023-11-18 01:52:20 +05:30
prafull-opensignlabsandGitHub bda31de345 add parse-dbtool package (#201) 2023-11-17 20:12:51 +05:30
prafull-opensignlabs cdfc952a3f add parse-dbtool package 2023-11-17 20:00:43 +05:30
prafull-opensignlabsandGitHub 9434315775 migration db changes (#200) 2023-11-17 19:58:01 +05:30
prafull-opensignlabsandGitHub 47bb4cac38 migration db changes (#200) 2023-11-17 19:37:44 +05:30
prafull-opensignlabs 11d3e6c696 migration db changes 2023-11-17 19:36:11 +05:30
prafull-opensignlabsandGitHub 0173727bc5 Merge branch 'OpenSignLabs:staging' into auth_user 2023-11-17 19:35:13 +05:30
prafull-opensignlabsandGitHub 3cfa2639e5 migrate db changes (#199) 2023-11-17 18:29:41 +05:30
prafull-opensignlabs 502400ee56 rename file from create_setclp to update_setclp 2023-11-17 18:27:34 +05:30
prafull-opensignlabs 4a3276f4e3 check migration functionality in staging app 2023-11-17 18:07:26 +05:30
prafull-opensignlabsandGitHub 750e48ca2e Merge pull request #27 from OpenSignLabs/staging
sync fork
2023-11-17 16:21:37 +05:30
prafull-opensignlabsandGitHub 823e6a9e2f update schema of contracts_users (#196) 2023-11-17 15:39:18 +05:30
Rishab 642ef334f6 #170 - Fix While dragging sign placeholder in mobile view the drawbox pops up unexpectedly 2023-11-17 09:21:31 +00:00
prafull-opensignlabsandGitHub 939a67b2c5 fix: resolve user not able to login/signup (#195) 2023-11-17 14:03:33 +05:30
prafull-opensignlabsandGitHub e1f8481aa2 Merge pull request #24 from prafull-opensignlabs/staging
sync fork'
2023-11-17 10:08:55 +05:30
rishabjasrotia b8e8cd127a Remove duplicate code 2023-11-16 20:14:32 +05:30
rishabjasrotia 876a2d78d5 enhancement 2023-11-16 20:06:57 +05:30
rishabjasrotia 16f287fdc0 Added backdrop to modal 2023-11-16 20:03:59 +05:30
prafull-opensignlabsandGitHub d396a4f71d Merge pull request #22 from OpenSignLabs/staging
fix: sendmail cloud function is not working (#194)
2023-11-16 19:57:02 +05:30
prafull-opensignlabsandGitHub 6bee566d8d fix: sendmail cloud function is not working (#194) 2023-11-16 19:25:57 +05:30
RaktimaandGitHub 79acd8ae13 Merge pull request #19 from OpenSignLabs/staging
update
2023-11-16 17:04:03 +05:30
prafull-opensignlabsandGitHub 01666b49cf Merge pull request #21 from OpenSignLabs/staging
change in in class level permission of contracts_User class (#192)
2023-11-16 11:24:18 +05:30
prafull-opensignlabsandGitHub a20ebbf08f change in in class level permission of contracts_User class (#192) 2023-11-16 11:19:34 +05:30
prafull-opensignlabsandGitHub 26cf9c5310 Merge pull request #20 from OpenSignLabs/staging
security improvement (#190)
2023-11-16 11:18:44 +05:30
prafull-opensignlabs 3ad58ee52b update url of migrate 2023-11-16 11:16:28 +05:30
prafull-opensignlabs 2b67af6097 change create, update clp of contracts_Users class 2023-11-16 11:09:56 +05:30
prafull-opensignlabsandGitHub f61dae35ff Merge pull request #19 from OpenSignLabs/staging
security improvement (#190)
2023-11-16 11:08:57 +05:30
prafull-opensignlabsandGitHub dead3088d6 security improvement (#190) 2023-11-16 11:02:38 +05:30
prafull-opensignlabs 45d65cfbe2 change cloud function name getContractUser to getUserDetails 2023-11-16 11:00:49 +05:30
RaktimaNXG 6d2010facb fix transparent PNG signature issue 2023-11-16 10:59:26 +05:30
prafull-opensignlabsandGitHub 48d3166049 Merge pull request #18 from prafull-opensignlabs/staging
sync fork
2023-11-16 10:52:47 +05:30
prafull-opensignlabsandGitHub 82992d324d Merge pull request #17 from OpenSignLabs/staging
sync fork
2023-11-16 10:51:50 +05:30
prafull-opensignlabs 9a549fa35d Merge branch 'auth_user' of https://github.com/prafull-opensignlabs/OpenSign into auth_user 2023-11-16 10:50:01 +05:30
prafull-opensignlabs 93a891c8b6 feat: add migration code for contracts_users class 2023-11-16 10:47:11 +05:30
RaktimaandGitHub 2ede742b10 Merge pull request #18 from OpenSignLabs/staging
update
2023-11-16 10:32:15 +05:30
Rishab c43690faa8 #126 - Fix UI layout issue after signing a document from mobile 2023-11-16 04:08:12 +00:00
Rishab a482a92d34 #168 - Align Modal to Center of PDF if Signed 2023-11-16 04:02:34 +00:00
prafull-opensignlabsandGitHub 1d429cbe36 Merge pull request #16 from OpenSignLabs/staging
sync fork
2023-11-15 17:14:46 +05:30
AmolandGitHub 0a36550907 Update README.md 2023-11-15 02:21:26 +05:30
Mathieu VigneandGitHub 09610112fc Feature/use smtp to send email (#182) 2023-11-14 20:55:45 +05:30
RaktimaandGitHub a14454227c fix Completion certificate issues (#184) 2023-11-14 20:31:19 +05:30
AmolandGitHub 0d8767ee98 Revert "fix: #172 - Location of requested signature placeholders shift to slight right on mobile view in "Request Signatures" flow (#185)" (#186)
This reverts commit f463dc7af7.
2023-11-14 20:30:40 +05:30
RaktimaandGitHub f463dc7af7 fix: #172 - Location of requested signature placeholders shift to slight right on mobile view in "Request Signatures" flow (#185) 2023-11-14 20:09:51 +05:30
RaktimaandGitHub 407b01565a Merge pull request #17 from OpenSignLabs/staging
Update main
2023-11-14 15:50:20 +05:30
RaktimaandGitHub 6c565a144a fix need your sign report document signature issue (#183) 2023-11-14 15:29:00 +05:30
RaktimaandGitHub 141351de49 Merge pull request #16 from OpenSignLabs/staging
update main branch
2023-11-14 10:14:48 +05:30
nxglabs edecf3ea23 chore: configure husky & prettier 2023-11-13 18:21:49 +05:30
prafull-opensignlabsandGitHub e708dad596 add shipping country code param in subscriptions url (#181) 2023-11-13 16:17:40 +05:30
prafull-opensignlabsandGitHub 48012c9343 Merge pull request #13 from OpenSignLabs/staging
sync fork
2023-11-13 16:00:03 +05:30
prafull-opensignlabsandGitHub 009a24e943 Merge pull request #15 from OpenSignLabs/staging
sync fork
2023-11-13 15:59:51 +05:30
RaktimaandGitHub 04a3251968 fix issue of mulitple annotation in signyourself (#174) 2023-11-13 14:29:14 +05:30
prafull-opensignlabsandGitHub 82694a24f2 replace modal title login with additional info and verification mail alert (#179) 2023-11-13 13:22:10 +05:30
prafull-opensignlabsandGitHub 748cc042dd Merge pull request #14 from OpenSignLabs/staging
sync fork
2023-11-13 10:59:43 +05:30
RishabandGitHub 6b8bca0802 #167 - Sanitize Output filename (#176) 2023-11-11 13:25:04 +05:30
AmolandGitHub fed1cff0cb Update features in README.md 2023-11-11 02:45:53 +05:30
AmolandGitHub b2eba6409f Main (#175) 2023-11-10 20:12:35 +05:30
RaktimaandGitHub 81af6a6c61 Merge pull request #15 from OpenSignLabs/staging
update
2023-11-10 10:28:02 +05:30
prafull-opensignlabsandGitHub b5dbc69188 Merge pull request #12 from OpenSignLabs/staging
sync fork
2023-11-09 20:54:17 +05:30
prafull-opensignlabs db4494c463 security improvment 2023-11-09 17:08:57 +05:30
RaktimaandGitHub d208a90107 Merge pull request #14 from OpenSignLabs/staging
update
2023-11-09 15:48:38 +05:30
prafull-opensignlabsandGitHub f81f72a147 Merge pull request #11 from OpenSignLabs/staging
sync fork
2023-11-09 12:28:51 +05:30
63 changed files with 3270 additions and 2449 deletions
+3 -4
View File
@@ -1,5 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx eslint '**/*.{js,jsx}'
npx pretty-quick --staged '**/*.{js,jsx}'
npm run lint-staged-changes
+3
View File
@@ -0,0 +1,3 @@
{
"*.js": "prettier --write"
}
+4 -5
View File
@@ -1,8 +1,7 @@
<h1 align="center"><a href='https://www.opensignlabs.com'>OpenSign™</a></h1>
<div align="center">
<h1 align="center"><a href='https://www.opensignlabs.com'><img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/e518cc9c-5de3-47da-950b-f93336b9f14e></a>
</h1><div align="center">
The free and open source alternative to DocuSign
[The free and open source alternative to DocuSign](https://www.opensignlabs.com)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/opensignlabs/opensign.svg)](http://isitmaintained.com/project/opensignlabs/opensign "Average time to resolve an issue")
[![All Contributors](https://img.shields.io/github/all-contributors/opensignlabs/opensign?color=ee8449&style=flat-square)](#contributors)
@@ -23,7 +22,7 @@ The free and open source alternative to DocuSign
<a href="https://www.linkedin.com/company/opensign%E2%84%A2/about/">LinkedIn</a>
## An open-source document e-signing solution
## The open-source document e-signing solution
---
</div>
+1
View File
@@ -10,6 +10,7 @@
# production
/build
/mfbuild
# misc
.env
@@ -241,26 +241,6 @@ const AppendFormInForm = (props) => {
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
/>
</div>
<div className="mb-3">
<label
htmlFor="phone"
className="block text-xs text-gray-700 font-semibold"
>
Phone
<span style={{ color: "red", fontSize: 13 }}> *</span>
</label>
<input
type="text"
id="phone"
value={phone}
onChange={(e) => setPhone(e.target.value)}
required
disabled={addYourself}
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
/>
</div>
<div className="mb-3">
<label
htmlFor="email"
@@ -279,6 +259,24 @@ const AppendFormInForm = (props) => {
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
/>
</div>
<div className="mb-3">
<label
htmlFor="phone"
className="block text-xs text-gray-700 font-semibold"
>
Phone
<span style={{ color: "red", fontSize: 13 }}> *</span>
</label>
<input
type="text"
id="phone"
value={phone}
onChange={(e) => setPhone(e.target.value)}
required
disabled={addYourself}
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
/>
</div>
<div className="mt-4 flex justify-start">
<button
+15 -12
View File
@@ -27,14 +27,14 @@ const LoginFacebook = ({
setThirdpartyLoader(true);
const details = {
Email: response.email,
Name: response.name,
Name: response.name
};
setUserDetails({ ...userDetails, ...details });
const fDetails = {
Id: response.userID,
AccessToken: response.accessToken,
Name: response.name,
Email: response.email,
Email: response.email
};
setFBDetails({ ...fBDetails, ...fDetails });
const res = await checkExtUser(fDetails);
@@ -42,9 +42,11 @@ const LoginFacebook = ({
};
const checkExtUser = async (details) => {
const extUser = new Parse.Query("contracts_Users");
extUser.equalTo("Email", details.Email);
const extRes = await extUser.first();
// const extUser = new Parse.Query("contracts_Users");
// extUser.equalTo("Email", details.Email);
// const extRes = await extUser.first();
const params = { email: details.Email };
const extRes = await Parse.Cloud.run("getUserDetails", params);
// console.log("extRes ", extRes);
if (extRes) {
const params = { ...details, Phone: extRes.get("Phone") };
@@ -209,18 +211,19 @@ const LoginFacebook = ({
<div>
<button
type="button"
className="btn btn-secondary"
onClick={() => setIsModal(false)}
style={{ marginRight: 10, width: 90 }}
onClick={() => handleSubmitbtn()}
className="btn btn-info"
style={{ marginRight: 10 }}
>
Cancel
Sign up
</button>
<button
type="button"
onClick={() => handleSubmitbtn()}
className="btn btn-info"
className="btn btn-secondary"
onClick={() => setIsModal(false)}
style={{ width: 90 }}
>
Sign up
Cancel
</button>
</div>
</form>
+51 -13
View File
@@ -42,7 +42,42 @@ const GoogleSignInBtn = ({
width: "187px"
});
});
const clearStorage = async () => {
await Parse.User.logOut();
let baseUrl = localStorage.getItem("BaseUrl12");
let appid = localStorage.getItem("AppID12");
let applogo = localStorage.getItem("appLogo");
let domain = localStorage.getItem("domain");
let appversion = localStorage.getItem("appVersion");
let appTitle = localStorage.getItem("appTitle");
let defaultmenuid = localStorage.getItem("defaultmenuid");
let PageLanding = localStorage.getItem("PageLanding");
let _appName = localStorage.getItem("_appName");
let _app_objectId = localStorage.getItem("_app_objectId");
let appName = localStorage.getItem("appName");
let userSettings = localStorage.getItem("userSettings");
localStorage.clear();
localStorage.setItem("BaseUrl12", baseUrl);
localStorage.setItem("AppID12", appid);
localStorage.setItem("appLogo", applogo);
localStorage.setItem("domain", domain);
localStorage.setItem("appversion", appversion);
localStorage.setItem("appTitle", appTitle);
localStorage.setItem("defaultmenuid", defaultmenuid);
localStorage.setItem("PageLanding", PageLanding);
localStorage.setItem("_appName", _appName);
localStorage.setItem("_app_objectId", _app_objectId);
localStorage.setItem("appName", appName);
localStorage.setItem("userSettings", userSettings);
localStorage.setItem("baseUrl", baseUrl);
localStorage.setItem("parseAppId", appid);
};
const responseGoogle = async (response) => {
clearStorage();
setThirdpartyLoader(true);
// console.log("response ", response);
if (response.credential) {
@@ -66,9 +101,11 @@ const GoogleSignInBtn = ({
}
};
const checkExtUser = async (details) => {
const extUser = new Parse.Query("contracts_Users");
extUser.equalTo("Email", details.Gmail);
const extRes = await extUser.first();
// const extUser = new Parse.Query("contracts_Users");
// extUser.equalTo("Email", details.Gmail);
// const extRes = await extUser.first();
const params = { email: details.Gmail };
const extRes = await Parse.Cloud.run("getUserDetails", params);
// console.log("extRes ", extRes);
if (extRes) {
const params = { ...details, Phone: extRes.get("Phone") };
@@ -261,17 +298,17 @@ const GoogleSignInBtn = ({
</div>
<div className="form-group">
<label
htmlFor="Destination"
htmlFor="JobTitle"
style={{ display: "flex" }}
className="col-form-label"
>
Destination{" "}
Job Title{" "}
<span style={{ fontSize: 13, color: "red" }}>*</span>
</label>
<input
type="text"
className="form-control"
id="Destination"
id="JobTitle"
value={userDetails.Destination}
onChange={(e) =>
setUserDetails({
@@ -285,18 +322,19 @@ const GoogleSignInBtn = ({
<div>
<button
type="button"
className="bg-[#6c757d] p-2 text-white rounded"
onClick={handleCloseModal}
style={{ marginRight: 10, width: 90 }}
className="bg-[#17a2b8] p-2 text-white rounded"
onClick={() => handleSubmitbtn()}
style={{ marginRight: 10 }}
>
Cancel
Sign up
</button>
<button
type="button"
className="bg-[#17a2b8] p-2 text-white rounded"
onClick={() => handleSubmitbtn()}
className="bg-[#6c757d] p-2 text-white rounded"
onClick={handleCloseModal}
style={{ width: 90 }}
>
Sign up
Cancel
</button>
</div>
</form>
+16 -17
View File
@@ -49,12 +49,9 @@ const TreeWidget = (props) => {
let data = JSON.parse(localStorage.getItem("Extand_Class"));
res = data[0];
} else {
var emp = Parse.Object.extend(
localStorage.getItem("extended_class")
);
var q = new Parse.Query(emp);
q.equalTo("UserId", currentUser);
res = await q.first();
res = await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
});
if (res) res = res.toJSON();
}
if (res) {
@@ -79,12 +76,9 @@ const TreeWidget = (props) => {
let data = JSON.parse(localStorage.getItem("Extand_Class"));
res = data[0];
} else {
emp = Parse.Object.extend(
localStorage.getItem("extended_class")
);
q = new Parse.Query(emp);
q.equalTo("UserId", currentUser);
res = await q.first();
res = await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
});
if (res) res = res.toJSON();
}
@@ -121,10 +115,15 @@ const TreeWidget = (props) => {
let data = JSON.parse(localStorage.getItem("Extand_Class"));
res = data[0];
} else {
emp = Parse.Object.extend(localStorage.getItem("extended_class"));
q = new Parse.Query(emp);
q.equalTo("UserId", currentUser);
res = await q.first();
// emp = Parse.Object.extend(localStorage.getItem("extended_class"));
// q = new Parse.Query(emp);
// q.equalTo("UserId", currentUser);
// res = await q.first();
// if (res) res = res.toJSON();
const currentUser = Parse.User.current();
res = await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
});
if (res) res = res.toJSON();
}
@@ -532,7 +531,7 @@ const TreeWidget = (props) => {
padding: 0
},
overlay: {
width:"100%",
width: "100%",
backgroundColor: "rgba(0, 0, 0, 0.75)",
zIndex: 50
}
@@ -1,7 +1,6 @@
import React, { useState, useEffect } from "react";
import axios from "axios";
import Parse from "parse";
import onSearchFilter from "../../constant/searchQuery";
import getReplacedHashQuery from "../../constant/getReplacedHashQuery";
import "../../styles/loader.css";
import { useNavigate } from "react-router-dom";
@@ -35,14 +34,9 @@ const DashboardCard = (props) => {
let data = JSON.parse(localStorage.getItem("Extand_Class"));
res = data[0];
} else {
var emp = Parse.Object.extend(localStorage.getItem("extended_class"));
var q = new Parse.Query(emp);
q.equalTo("UserId", {
__type: "Pointer",
className: "_User",
objectId: currentUser
res = await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
});
res = await q.first();
if (res) res = res.toJSON();
}
if (res) {
@@ -50,12 +44,7 @@ const DashboardCard = (props) => {
var reg = /(\#.*?\#)/gi; // eslint-disable-line
var str = props.Data.query;
var test = "";
if (str.includes("#filterCondition#")) {
str = str.replace(
"#filterCondition#",
onSearchFilter(props.DefaultQuery)
);
}
if (props.Data.extendkey) {
let a = props.Data.extendkey.split(".");
if (a.length > 0) {
@@ -110,13 +99,10 @@ const DashboardCard = (props) => {
let data = JSON.parse(localStorage.getItem("Extand_Class"));
resr = data[0];
} else {
let emp = Parse.Object.extend(
localStorage.getItem("extended_class")
);
let q = new Parse.Query(emp);
q.equalTo("UserId", currentUser);
let t = await q.first();
resr = t.toJSON();
resr = await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
});
if (resr) resr = resr.toJSON();
}
let json = resr;
@@ -150,47 +136,65 @@ const DashboardCard = (props) => {
"X-Parse-Application-Id": parseAppId,
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
};
await axios.get(url, { headers: headers }).then((res) => {
if (res.data.results.length > 0) {
setLoading(false);
if (props.Data.key !== "count") {
setresponse(res.data.results[0][props.Data.key]);
} else {
if (props.Label === "Need your Signature") {
const listData = res.data?.results.filter(
(x) => x.Signers.length > 0
// handle need your sign report count
if (props.Data.Redirect_id === "4Hhwbp482K") {
const params = {
reportId: props.Data.Redirect_id,
skip: 0,
limit: 200
};
const url = `${parseBaseUrl}/functions/getReport`;
await axios
.post(url, params, {
headers: {
"Content-Type": "application/json",
"X-Parse-Application-Id": parseAppId,
sessiontoken: localStorage.getItem("accesstoken")
}
})
.then((res) => {
const listData = res.data?.result.filter(
(x) => x.Signers.length > 0
);
let arr = [];
for (const obj of listData) {
const isSigner = obj.Signers.some(
(item) => item.UserId.objectId === currentUser.id
);
let arr = [];
for (const obj of listData) {
const isSigner = obj.Signers.some(
(item) => item.UserId.objectId === currentUser.id
);
if (isSigner) {
let isRecord;
if (obj?.AuditTrail && obj?.AuditTrail.length > 0) {
isRecord = obj?.AuditTrail.some(
(item) =>
item?.UserPtr?.UserId?.objectId === currentUser.id &&
item.Activity === "Signed"
);
} else {
isRecord = false;
}
if (isRecord === false) {
arr.push(obj);
}
if (isSigner) {
let isRecord;
if (obj?.AuditTrail && obj?.AuditTrail.length > 0) {
isRecord = obj?.AuditTrail.some(
(item) =>
item?.UserPtr?.UserId?.objectId === currentUser.id &&
item.Activity === "Signed"
);
} else {
isRecord = false;
}
if (isRecord === false) {
arr.push(obj);
}
}
setresponse(arr.length);
}
setresponse(arr.length);
setLoading(false);
});
} else {
await axios.get(url, { headers: headers }).then((res) => {
if (res.data.results.length > 0) {
setLoading(false);
if (props.Data.key !== "count") {
setresponse(res.data.results[0][props.Data.key]);
} else {
setresponse(res.data[props.Data.key]);
}
} else {
setresponse(0);
setLoading(false);
}
} else {
setresponse(0);
setLoading(false);
}
});
});
}
} catch (e) {
console.error("Problem", e);
setLoading(false);
@@ -227,13 +231,10 @@ const DashboardCard = (props) => {
let data = JSON.parse(localStorage.getItem("Extand_Class"));
res = data[0];
} else {
var emp = Parse.Object.extend(
localStorage.getItem("extended_class")
);
var q = new Parse.Query(emp);
q.equalTo("UserId", currentUser);
let resr = await q.first();
res = resr.toJSON();
let resr = await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
});
if (res) res = resr.toJSON();
}
let json = res;
@@ -9,39 +9,58 @@ function DashboardReport(props) {
const [isLoader, setIsLoader] = useState(true);
const [reportName, setReportName] = useState("");
const [actions, setActions] = useState([]);
const [isNextRecord, setIsNextRecord] = useState(false);
const [isMoreDocs, setIsMoreDocs] = useState(true);
const abortController = new AbortController();
const docPerPage = 5;
useEffect(() => {
setReportName("");
getReportData(props.Record.reportId);
// Function returned from useEffect is called on unmount
return () => {
setIsLoader(true);
setList([]);
setIsNextRecord(false);
// Here it'll abort the fetch
abortController.abort();
};
// eslint-disable-next-line
}, [props.Record.reportId]);
const getReportData = async (id) => {
// below useEffect call when isNextRecord state is true and fetch next record
useEffect(() => {
if (isNextRecord) {
getReportData(props.Record.reportId, List.length, 200);
}
// eslint-disable-next-line
}, [isNextRecord]);
const getReportData = async (id, skipUserRecord = 0, limit = 200) => {
setIsLoader(true);
const json = reportJson(id);
if (json) {
setActions(json.actions);
setReportName(json.reportName);
const { className, params, keys, orderBy } = json;
Parse.serverURL = localStorage.getItem("BaseUrl12");
Parse.initialize(localStorage.getItem("AppID12"));
const serverURL =
localStorage.getItem("BaseUrl12") + "classes/" + className;
const currentUser = Parse.User.current().id;
const strParams = JSON.stringify(params);
const strKeys = keys.join();
const headers = {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
sessiontoken: localStorage.getItem("accesstoken")
};
try {
const url = `${serverURL}?where=${strParams}&keys=${strKeys}&order=${orderBy}&include=AuditTrail.UserPtr`;
const res = await axios.get(url, { headers: headers });
// console.log("res ", res.data?.results);
const params = { reportId: id, skip: skipUserRecord, limit: limit };
const url = `${localStorage.getItem("BaseUrl12")}/functions/getReport`;
const res = await axios.post(url, params, {
headers: headers,
signal: abortController.signal // is used to cancel fetch query
});
if (id === "5Go51Q7T8r") {
const currentUser = Parse.User.current().id;
const listData = res.data?.results.filter(
(x) => x.Signers.length > 0
);
const listData = res.data?.result.filter((x) => x.Signers.length > 0);
let arr = [];
for (const obj of listData) {
const isSigner = obj.Signers.some(
@@ -63,14 +82,34 @@ function DashboardReport(props) {
}
}
}
setList(arr);
if (arr.length === docPerPage) {
setIsMoreDocs(true);
} else {
setIsMoreDocs(false);
}
setList((prevRecord) =>
prevRecord.length > 0 ? [...prevRecord, ...arr] : arr
);
} else {
setList(res.data?.results);
if (res.data.result.length === docPerPage) {
setIsMoreDocs(true);
} else {
setIsMoreDocs(false);
}
setIsNextRecord(false);
setList((prevRecord) =>
prevRecord.length > 0
? [...prevRecord, ...res.data.result]
: res.data.result
);
}
setIsLoader(false);
} catch (err) {
console.log("err ", err);
setIsLoader(false);
const isCancel = axios.isCancel(err);
if (!isCancel) {
console.log("err ", err);
setIsLoader(false);
}
}
} else {
setIsLoader(false);
@@ -101,8 +140,10 @@ function DashboardReport(props) {
<ReportTable
ReportName={reportName}
List={List}
act={"Sign"}
actions={actions}
setIsNextRecord={setIsNextRecord}
isMoreDocs={isMoreDocs}
docPerPage={docPerPage}
/>
) : (
<div className="flex items-center justify-center h-[100px] w-full bg-white rounded">
@@ -1,5 +1,4 @@
import React, { useState, Suspense, lazy } from "react";
import moment from "moment";
import React, { Suspense, lazy } from "react";
import ErrorBoundary from "../ErrorBoundary";
const DashboardCard = lazy(() => import("./DashboardCard"));
@@ -7,258 +6,6 @@ const DashboardCard = lazy(() => import("./DashboardCard"));
const DashboardReport = lazy(() => import("./DashboardReport"));
const GetDashboard = (props) => {
const [filter, setfilter] = useState("");
const [option, setoption] = useState("");
const onSearchFilter = (e) => {
let _search = e.target.value;
localStorage.setItem("DashboardDefaultFilter", _search);
switch (_search) {
case "Today": {
let d = new Date();
let formDate = new Date(
Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0)
).toISOString();
let Todate = new Date(
Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59)
).toISOString();
let Query = `'$gte':'${formDate}','$lte':'${Todate}'`;
setfilter(Query);
setoption(_search);
break;
}
case "Yesterday": {
let d1 = new Date();
d1.setDate(d1.getDate() - 1);
let yesFrDate = new Date(
Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate(), 0, 0, 0)
).toISOString();
let YesTodate = new Date(
Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate(), 23, 59, 59)
).toISOString();
let Query1 = `'$gte':'${yesFrDate}','$lte':'${YesTodate}'`;
setfilter(Query1);
setoption(_search);
break;
}
case "This week": {
let oneDay = 24 * 60 * 60 * 1000;
let curr = new Date(); // get current date
let first = curr.getDate() - curr.getDay(); // First day is the day of the month - the day of the week
let firstday = new Date(
new Date(
Date.UTC(
curr.getFullYear(),
curr.getMonth(),
curr.getDate(),
0,
0,
0
)
).setDate(first)
).toISOString();
let diffDays = Math.round(
Math.abs(
(new Date(
Date.UTC(
curr.getFullYear(),
curr.getMonth(),
curr.getDate(),
23,
59,
59
)
) -
new Date(firstday)) /
oneDay
)
); //Days since last week
let last = first + diffDays;
let lastday = new Date(
new Date(
Date.UTC(
curr.getFullYear(),
curr.getMonth(),
curr.getDate(),
23,
59,
59
)
).setDate(last)
).toISOString();
let Query2 = `'$gte':'${firstday}','$lte':'${lastday}'`;
setfilter(Query2);
setoption(_search);
break;
}
case "Last 7 days": {
let d7 = new Date();
let d7l = new Date();
d7.setDate(d7.getDate() - 7);
let l7t = new Date(
Date.UTC(d7l.getFullYear(), d7l.getMonth(), d7l.getDate(), 23, 59, 59)
).toISOString();
let date7 = new Date(
Date.UTC(d7.getFullYear(), d7.getMonth(), d7.getDate(), 0, 0, 0)
).toISOString();
let Query7 = `'$gte':'${date7}','$lte':'${l7t}'`;
setfilter(Query7);
setoption(_search);
break;
}
case "Last 14 days": {
let d14 = new Date();
let d14l = new Date();
let l14t = new Date(
Date.UTC(
d14l.getFullYear(),
d14l.getMonth(),
d14l.getDate(),
23,
59,
59
)
).toISOString();
d14.setDate(d14.getDate() - 14);
let date14 = new Date(
Date.UTC(d14.getFullYear(), d14.getMonth(), d14.getDate(), 0, 0, 0)
).toISOString();
let Query14 = `'$gte':'${date14}','$lte':'${l14t}'`;
setfilter(Query14);
setoption(_search);
break;
}
case "Last 30 days": {
let d30 = new Date();
let d30l = new Date();
let l30t = new Date(
Date.UTC(
d30l.getFullYear(),
d30l.getMonth(),
d30l.getDate(),
23,
59,
59
)
).toISOString();
d30.setDate(d30.getDate() - 30);
let date30 = new Date(
Date.UTC(d30.getFullYear(), d30.getMonth(), d30.getDate(), 0, 0, 0)
).toISOString();
let Query30 = `'$gte':'${date30}','$lte':'${l30t}'`;
setfilter(Query30);
setoption(_search);
break;
}
case "Last week": {
const from_date = moment().startOf("week").subtract(7, "days");
const to_date = moment().endOf("week").subtract(7, "days");
let Queryl = `'$gte':'${from_date.toISOString()}','$lte':'${to_date.toISOString()}'`;
setfilter(Queryl);
setoption(_search);
break;
}
case "This month": {
const tdate = new Date();
let tfirstDay = new Date(
tdate.getFullYear(),
tdate.getMonth(),
1
).toISOString();
let tlastDay = new Date(
tdate.getFullYear(),
tdate.getMonth() + 1,
0
).toISOString();
let Querylt = `'$gte':'${tfirstDay}','$lte':'${tlastDay}'`;
setfilter(Querylt);
setoption(_search);
break;
}
case "Last month": {
const ldate = new Date();
var lfirstDay = new Date(
ldate.getFullYear(),
ldate.getMonth() - 1,
2
).toISOString();
var llastDay = new Date(
ldate.getFullYear(),
ldate.getMonth(),
1
).toISOString();
let Queryltl = `'$gte':'${lfirstDay}','$lte':'${llastDay}'`;
setfilter(Queryltl);
setoption(_search);
break;
}
case "All": {
let fall = new Date(
new Date().getFullYear() - 100,
0,
1,
0,
0,
0
).toISOString();
let fall_year = `'$gte':'${fall}'`;
setfilter(fall_year);
setoption(_search);
break;
}
case "This year": {
let fcy = new Date(
new Date().getFullYear(),
0,
1,
0,
0,
0
).toISOString();
let lcy = new Date(
new Date().getFullYear(),
11,
31,
23,
59,
59
).toISOString();
let cur_year = `'$gte':'${fcy}','$lte':'${lcy}'`;
setfilter(cur_year);
setoption(_search);
break;
}
case "Last year": {
let fly = new Date(
new Date().getFullYear() - 1,
0,
1,
0,
0,
0
).toISOString();
let lly = new Date(
new Date().getFullYear() - 1,
11,
31,
23,
59,
59
).toISOString();
let last_year = `'$gte':'${fly}','$lte':'${lly}'`;
setfilter(last_year);
setoption(_search);
break;
}
default: {
setoption(_search);
break;
}
}
};
const renderSwitchWithTour = (col) => {
switch (col.widget.type) {
case "Card":
@@ -272,7 +19,6 @@ const GetDashboard = (props) => {
<DashboardCard
Icon={col.widget.icon}
Label={col.widget.label}
Filter={filter}
Format={col.widget.format && col.widget.format}
Data={col.widget.data}
FilterData={col.widget.filter}
@@ -281,50 +27,12 @@ const GetDashboard = (props) => {
</Suspense>
</div>
);
case "customeHtml":
return (
<div data-tut={col.widget.data.tourSection}>
<select
id="searchFiltr"
className="form-control"
value={
option ||
localStorage.getItem("DashboardDefaultFilter") ||
col.widget.data[0].default
}
onChange={onSearchFilter}
>
{col.widget.data[0].options.map((opt) => (
<option key={opt} value={opt}>
{opt}
</option>
))}
</select>
<br />
</div>
);
case "customeTag":
return (
<h3
data-tut={col.widget.data.tourSection}
style={{
marginBottom: "4px",
color: "currentColor",
marginLeft: "4px"
}}
>
{col.widget.label}
</h3>
);
case "report": {
let _filter = `${col.widget.filterKey}:${filter}`;
return (
<div data-tut={col.widget.data.tourSection}>
<Suspense fallback={<div>please wait</div>}>
<div className="mb-4 md:mb-0">
<DashboardReport Filter={_filter} Record={col.widget} />
<DashboardReport Record={col.widget} />
</div>
</Suspense>
</div>
@@ -346,7 +54,6 @@ const GetDashboard = (props) => {
<DashboardCard
Icon={col.widget.icon}
Label={col.widget.label}
Filter={filter}
Format={col.widget.format && col.widget.format}
Data={col.widget.data}
FilterData={col.widget.filter}
@@ -355,48 +62,11 @@ const GetDashboard = (props) => {
</Suspense>
</div>
);
case "customeHtml":
return (
<div>
<select
id="searchFiltr"
className="form-control"
value={
option ||
localStorage.getItem("DashboardDefaultFilter") ||
col.widget.data[0].default
}
onChange={onSearchFilter}
>
{col.widget.data[0].options.map((opt) => (
<option key={opt} value={opt}>
{opt}
</option>
))}
</select>
<br />
</div>
);
case "customeTag":
return (
<h3
style={{
marginBottom: "4px",
color: "currentColor",
marginLeft: "4px"
}}
>
{col.widget.label}
</h3>
);
case "report": {
let _filter = `${col.widget.filterKey}:${filter}`;
return (
<Suspense fallback={<div>please wait</div>}>
<div className="mb-4 md:mb-0">
<DashboardReport Filter={_filter} Record={col.widget} />
<DashboardReport Record={col.widget} />
</div>
</Suspense>
);
@@ -1,6 +1,6 @@
import React, { Component } from "react";
import Parse from "parse";
import axios from "axios";
// import axios from "axios";
export class HiddenField extends Component {
state = {
@@ -37,31 +37,46 @@ export class HiddenField extends Component {
this.setState({ _fields: custome_Filed });
} else {
if (currentUser) {
let url = `${this.state.baseUrl}classes/${localStorage.getItem(
"extended_class"
)}?where={"UserId":{"__type":"Pointer","className":"_User","objectId":"${
currentUser.id
}"}}&keys=${this.props.schema.data.valueKey}`;
const headers = {
"Content-Type": "application/json",
"X-Parse-Application-Id": this.state.parseAppId
};
await axios.get(url, { headers: headers }).then((res) => {
let custome_Filed = "";
let _rdata = res.data.results;
let splitArray = this.props.schema.data.valueKey.split(".");
if (splitArray.length > 1) {
custome_Filed = _rdata[0][splitArray[0]][splitArray[1]];
} else {
console.log(_rdata[0][splitArray[0]]);
custome_Filed = _rdata[0][splitArray[0]];
}
this.setState({ _fields: custome_Filed });
// let url = `${this.state.baseUrl}classes/${localStorage.getItem(
// "extended_class"
// )}?where={"UserId":{"__type":"Pointer","className":"_User","objectId":"${
// currentUser.id
// }"}}&keys=${this.props.schema.data.valueKey}`;
// const headers = {
// "Content-Type": "application/json",
// "X-Parse-Application-Id": this.state.parseAppId
// };
// await axios.get(url, { headers: headers }).then((res) => {
// let custome_Filed = "";
// let _rdata = res.data.results;
// let splitArray = this.props.schema.data.valueKey.split(".");
// if (splitArray.length > 1) {
// custome_Filed = _rdata[0][splitArray[0]][splitArray[1]];
// } else {
// console.log(_rdata[0][splitArray[0]]);
// custome_Filed = _rdata[0][splitArray[0]];
// }
// this.setState({ _fields: custome_Filed });
// });
const res = await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
});
let custome_Filed = "";
const result = res.toJSON();
let _rdata = [result];
let splitArray = this.props.schema.data.valueKey.split(".");
if (splitArray.length > 1) {
custome_Filed = _rdata[0][splitArray[0]][splitArray[1]];
} else {
console.log(_rdata[0][splitArray[0]]);
custome_Filed = _rdata[0][splitArray[0]];
}
this.setState({ _fields: custome_Filed });
}
}
} catch (error) {
console.log('err', error)
console.log("err", error);
}
}
};
@@ -120,12 +120,10 @@ const Level1Dropdown = (props) => {
let data = JSON.parse(localStorage.getItem("Extand_Class"));
res = data[0];
} else {
var emp = Parse.Object.extend(
localStorage.getItem("extended_class")
);
var q = new Parse.Query(emp);
q.equalTo("UserId", currentUser);
res = await q.first();
const currentUser = Parse.User.current();
res = await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
});
if (res) res = res.toJSON();
}
@@ -339,7 +337,7 @@ const Level1Dropdown = (props) => {
x.className = x.className.replace("show", "");
}, 5000);
} catch (error) {
console.log("Err", error)
console.log("Err", error);
}
}
};
-210
View File
@@ -1,210 +0,0 @@
import moment from "moment";
export default function onSearchFilter(_search) {
switch (_search) {
case "Today": {
let d = new Date();
let formDate = new Date(
Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0)
).toISOString();
let Todate = new Date(
Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59)
).toISOString();
let Query = `'$gte':'${formDate}','$lte':'${Todate}'`;
return Query;
}
case "Yesterday": {
let d1 = new Date();
d1.setDate(d1.getDate() - 1);
let yesFrDate = new Date(
Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate(), 0, 0, 0)
).toISOString();
let YesTodate = new Date(
Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate(), 23, 59, 59)
).toISOString();
let Query1 = `'$gte':'${yesFrDate}','$lte':'${YesTodate}'`;
return Query1;
}
case "This week": {
let oneDay = 24 * 60 * 60 * 1000;
let curr = new Date(); // get current date
let first = curr.getDate() - curr.getDay(); // First day is the day of the month - the day of the week
let firstday = new Date(
new Date(
Date.UTC(curr.getFullYear(), curr.getMonth(), curr.getDate(), 0, 0, 0)
).setDate(first)
).toISOString();
let diffDays = Math.round(
Math.abs(
(new Date(
Date.UTC(
curr.getFullYear(),
curr.getMonth(),
curr.getDate(),
23,
59,
59
)
) -
new Date(firstday)) /
oneDay
)
); //Days since last week
let last = first + diffDays;
let lastday = new Date(
new Date(
Date.UTC(
curr.getFullYear(),
curr.getMonth(),
curr.getDate(),
23,
59,
59
)
).setDate(last)
).toISOString();
let Query2 = `'$gte':'${firstday}','$lte':'${lastday}'`;
return Query2;
}
case "Last 7 days": {
let d7 = new Date();
let d7l = new Date();
d7.setDate(d7.getDate() - 7);
let l7t = new Date(
Date.UTC(d7l.getFullYear(), d7l.getMonth(), d7l.getDate(), 23, 59, 59)
).toISOString();
let date7 = new Date(
Date.UTC(d7.getFullYear(), d7.getMonth(), d7.getDate(), 0, 0, 0)
).toISOString();
let Query7 = `'$gte':'${date7}','$lte':'${l7t}'`;
return Query7;
}
case "Last 14 days": {
let d14 = new Date();
let d14l = new Date();
let l14t = new Date(
Date.UTC(
d14l.getFullYear(),
d14l.getMonth(),
d14l.getDate(),
23,
59,
59
)
).toISOString();
d14.setDate(d14.getDate() - 14);
let date14 = new Date(
Date.UTC(d14.getFullYear(), d14.getMonth(), d14.getDate(), 0, 0, 0)
).toISOString();
let Query14 = `'$gte':'${date14}','$lte':'${l14t}'`;
return Query14;
}
case "Last 30 days": {
let d30 = new Date();
let d30l = new Date();
let l30t = new Date(
Date.UTC(
d30l.getFullYear(),
d30l.getMonth(),
d30l.getDate(),
23,
59,
59
)
).toISOString();
d30.setDate(d30.getDate() - 30);
let date30 = new Date(
Date.UTC(d30.getFullYear(), d30.getMonth(), d30.getDate(), 0, 0, 0)
).toISOString();
return `'$gte':'${date30}','$lte':'${l30t}'`;
}
case "Last week": {
const from_date = moment().startOf("week").subtract(7, "days");
const to_date = moment().endOf("week").subtract(7, "days");
return `'$gte':'${from_date.toISOString()}','$lte':'${to_date.toISOString()}'`;
}
case "This month": {
var tdate = new Date();
var tfirstDay = new Date(
tdate.getFullYear(),
tdate.getMonth(),
1
).toISOString();
var tlastDay = new Date(
tdate.getFullYear(),
tdate.getMonth() + 1,
0
).toISOString();
let Querylt = `'$gte':'${tfirstDay}','$lte':'${tlastDay}'`;
return Querylt;
}
case "Last month": {
var ldate = new Date();
var lfirstDay = new Date(
ldate.getFullYear(),
ldate.getMonth() - 1,
2
).toISOString();
var llastDay = new Date(
ldate.getFullYear(),
ldate.getMonth(),
1
).toISOString();
let Queryltl = `'$gte':'${lfirstDay}','$lte':'${llastDay}'`;
return Queryltl;
}
case "All": {
let fall = new Date(
new Date().getFullYear() - 100,
0,
1,
0,
0,
0
).toISOString();
let fall_year = `'$gte':'${fall}'`;
return fall_year;
}
case "This year": {
let fcy = new Date(new Date().getFullYear(), 0, 1, 0, 0, 0).toISOString();
let lcy = new Date(
new Date().getFullYear(),
11,
31,
23,
59,
59
).toISOString();
let cur_year = `'$gte':'${fcy}','$lte':'${lcy}'`;
return cur_year;
}
case "Last year": {
let fly = new Date(
new Date().getFullYear() - 1,
0,
1,
0,
0,
0
).toISOString();
let lly = new Date(
new Date().getFullYear() - 1,
11,
31,
23,
59,
59
).toISOString();
let last_year = `'$gte':'${fly}','$lte':'${lly}'`;
return last_year;
}
default:
return "";
}
}
-245
View File
@@ -1,6 +1,4 @@
import Parse from "parse";
export default function reportJson(id) {
const currentUserId = Parse.User.current().id;
// console.log("json ", json);
switch (id) {
@@ -8,28 +6,6 @@ export default function reportJson(id) {
case "ByHuevtCFY":
return {
reportName: "Draft Documents",
className: "contracts_Document",
params: {
Type: null,
$or: [
{ Signers: null, SignedUrl: null },
{ Signers: { $exists: true }, Placeholders: null }
],
CreatedBy: {
__type: "Pointer",
className: "_User",
objectId: currentUserId
}
},
keys: [
"Name",
"Note",
"Folder.Name",
"URL",
"ExtUserPtr.Name",
"Signers.Name"
],
orderBy: "-updatedAt",
actions: [
{
btnLabel: "sign",
@@ -45,27 +21,6 @@ export default function reportJson(id) {
case "4Hhwbp482K":
return {
reportName: "Need your sign",
className: "contracts_Document",
params: {
Type: { $ne: "Folder" },
IsCompleted: { $ne: true },
IsDeclined: { $ne: true },
ExpiryDate: {
$gt: { __type: "Date", iso: new Date().toISOString() }
},
Placeholders: { $ne: null }
},
keys: [
"Name",
"Note",
"Folder.Name",
"URL",
"ExtUserPtr.Name",
"Signers.Name",
"Signers.UserId",
"AuditTrail"
],
orderBy: "-updatedAt",
actions: [
{
btnLabel: "sign",
@@ -81,31 +36,6 @@ export default function reportJson(id) {
case "1MwEuxLEkF":
return {
reportName: "In-progress documents",
className: "contracts_Document",
params: {
Type: { $ne: "Folder" },
Signers: { $ne: null },
Placeholders: { $ne: null },
IsCompleted: { $ne: true },
IsDeclined: { $ne: true },
CreatedBy: {
__type: "Pointer",
className: "_User",
objectId: currentUserId
},
ExpiryDate: {
$gt: { __type: "Date", iso: new Date().toISOString() }
}
},
keys: [
"Name",
"Note",
"Folder.Name",
"URL",
"ExtUserPtr.Name",
"Signers.Name"
],
orderBy: "-updatedAt",
actions: [
{
btnLabel: "View",
@@ -121,27 +51,6 @@ export default function reportJson(id) {
case "kQUoW4hUXz":
return {
reportName: "Completed Documents",
className: "contracts_Document",
params: {
Type: null,
IsCompleted: true,
CreatedBy: {
__type: "Pointer",
className: "_User",
objectId: currentUserId
},
IsDeclined: { $ne: true }
},
keys: [
"Name",
"Note",
"Folder.Name",
"URL",
"ExtUserPtr.Name",
"Signers.Name",
"TimeToCompleteDays"
],
orderBy: "-updatedAt",
actions: [
{
btnLabel: "View",
@@ -153,63 +62,10 @@ export default function reportJson(id) {
}
]
};
// OpenSignDrive™ documents Drafts
case "VRFDmUmw5B":
return {
reportName: "OpenSignDrive™ Drafts",
className: "contracts_Document",
params: {
Type: "AIDoc",
$or: [
{ Signers: null, SignedUrl: null },
{ Signers: { $exists: true }, Placeholders: null }
],
CreatedBy: {
__type: "Pointer",
className: "_User",
objectId: currentUserId
}
},
keys: [
"Name",
"Note",
"Folder.Name",
"URL",
"ExtUserPtr.Name",
"Signers.Name"
],
orderBy: "-updatedAt",
actions: [
{
btnLabel: "edit",
btnColor: "#3ac9d6",
textColor: "white",
btnIcon: "fa fa-plus",
redirectUrl:
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9MZWdhR2VuaWUtTWljcm9hcHBWMi9yZW1vdGVFbnRyeS5qcw==&moduleToLoad=AppRoutes&remoteName=legageniemicroapp/legagenie"
}
]
};
// declined documents report
case "UPr2Fm5WY3":
return {
reportName: "Declined Documents",
className: "contracts_Document",
params: { Type: null, IsDeclined: true },
CreatedBy: {
__type: "Pointer",
className: "_User",
objectId: currentUserId
},
keys: [
"Name",
"Note",
"Folder.Name",
"URL",
"ExtUserPtr.Name",
"Signers.Name"
],
orderBy: "-updatedAt",
actions: [
{
btnLabel: "View",
@@ -225,39 +81,6 @@ export default function reportJson(id) {
case "zNqBHXHsYH":
return {
reportName: "Expired Documents",
className: "contracts_Document",
params: {
IsCompleted: { $ne: true },
IsDeclined: { $ne: true },
Type: { $ne: "Folder" },
$and: [
{
$or: [
{ Signers: { $ne: null }, SignedUrl: { $ne: null } },
{ Placeholders: { $ne: null } }
]
},
{
ExpiryDate: {
$lt: { __type: "Date", iso: new Date().toISOString() }
}
}
],
CreatedBy: {
__type: "Pointer",
className: "_User",
objectId: currentUserId
}
},
keys: [
"Name",
"Note",
"Folder.Name",
"URL",
"ExtUserPtr.Name",
"Signers.Name"
],
orderBy: "-updatedAt",
actions: [
{
btnLabel: "View",
@@ -273,31 +96,6 @@ export default function reportJson(id) {
case "d9k3UfYHBc":
return {
reportName: "Recently sent for signatures",
className: "contracts_Document",
params: {
Type: { $ne: "Folder" },
Signers: { $ne: null },
Placeholders: { $ne: null },
IsCompleted: { $ne: true },
IsDeclined: { $ne: true },
CreatedBy: {
__type: "Pointer",
className: "_User",
objectId: currentUserId
},
ExpiryDate: {
$gt: { __type: "Date", iso: new Date().toISOString() }
}
},
keys: [
"Name",
"Note",
"Folder.Name",
"URL",
"ExtUserPtr.Name",
"Signers.Name"
],
orderBy: "-updatedAt",
actions: [
{
btnLabel: "View",
@@ -313,27 +111,6 @@ export default function reportJson(id) {
case "5Go51Q7T8r":
return {
reportName: "Recent signature requests",
className: "contracts_Document",
params: {
Type: { $ne: "Folder" },
IsCompleted: { $ne: true },
IsDeclined: { $ne: true },
ExpiryDate: {
$gt: { __type: "Date", iso: new Date().toISOString() }
},
Placeholders: { $ne: null }
},
keys: [
"Name",
"Note",
"Folder.Name",
"URL",
"ExtUserPtr.Name",
"Signers.Name",
"Signers.UserId",
"AuditTrail"
],
orderBy: "-updatedAt",
actions: [
{
btnLabel: "Sign",
@@ -349,28 +126,6 @@ export default function reportJson(id) {
case "kC5mfynCi4":
return {
reportName: "Drafts",
className: "contracts_Document",
params: {
Type: null,
$or: [
{ Signers: null, SignedUrl: null },
{ Signers: { $exists: true }, Placeholders: null }
],
CreatedBy: {
__type: "Pointer",
className: "_User",
objectId: currentUserId
}
},
keys: [
"Name",
"Note",
"Folder.Name",
"URL",
"ExtUserPtr.Name",
"Signers.Name"
],
orderBy: "-updatedAt",
actions: [
{
btnLabel: "sign",
+4 -1
View File
@@ -6,6 +6,7 @@
"subtitle": "Free for life One click install.",
"btnText": "Visit github",
"url": "https://github.com/opensignlabs/opensign",
"target": "_blank",
"benefits": [
"Sign Unlimited Documents",
"S3 Doc Storage",
@@ -26,9 +27,10 @@
"planName": "THANKS PLAN",
"currency": "$",
"price": "29.99",
"subtitle": "Use code 'FREEBETA' to get this for free(First 100 users)",
"subtitle": "Use code 'FREEBETA' to get this for free(First 1000 users)",
"btnText": "Subscribe",
"url": "https://subscriptions.zoho.in/subscribe/ef798486e6a0a11ea65f2bae8f2af901dbadf3175d495584fd25b9af5d2f2b9e/thanks",
"target": "_self",
"benefits": [
"Sign Unlimited Documents",
"Unlimited Secure Doc Storage with OpenSignDrive",
@@ -50,6 +52,7 @@
"subtitle": "Customization available Priority support.",
"btnText": "Contact us",
"url": "https://www.opensignlabs.com/contact-us",
"target": "_self",
"benefits": [
"All features",
"Custom domain",
+6 -15
View File
@@ -6,7 +6,7 @@ import { useWindowSize } from "../hook/useWindowSize";
import Tour from "reactour";
import axios from "axios";
import { useSelector } from "react-redux";
import Parse from "parse";
const HomeLayout = ({ children }) => {
const { width } = useWindowSize();
const [isOpen, setIsOpen] = useState(false);
@@ -124,20 +124,11 @@ const HomeLayout = ({ children }) => {
};
async function checkTourStatus() {
const serverUrl = localStorage.getItem("baseUrl");
const appId = localStorage.getItem("AppID12");
const extUserClass = localStorage.getItem("extended_class");
const json = JSON.parse(localStorage.getItem("Extand_Class"));
const extUserId = json && json.length > 0 && json[0].objectId;
// console.log("extUserId ", extUserId);
const res = await axios.get(
serverUrl + "classes/" + extUserClass + "/" + extUserId,
{
headers: {
"X-Parse-Application-Id": appId
}
}
);
const currentUser = Parse.User.current();
const cloudRes = await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
});
const res = { data: cloudRes.toJSON() };
if (res.data && res.data.TourStatus && res.data.TourStatus.length > 0) {
const tourStatus = res.data.TourStatus;
// console.log("res ", res.data.TourStatus);
@@ -7,11 +7,11 @@ const ReportTable = ({
List,
actions,
setIsNextRecord,
isMoreDocs
isMoreDocs,
docPerPage
}) => {
const navigate = useNavigate();
const [currentPage, setCurrentPage] = useState(1);
const docPerPage = 10;
// const pageNumbers = [];
// For loop is used to calculate page numbers visible below table
@@ -22,7 +22,7 @@ const ReportTable = ({
calculatedPageNumbers.push(i);
}
return calculatedPageNumbers;
}, [List]);
}, [List, docPerPage]);
// below useEffect reset currenpage to 1 if user change route
useEffect(() => {
return () => setCurrentPage(1);
@@ -154,7 +154,7 @@ const ReportTable = ({
</tbody>
</table>
<div className="flex flex-wrap items-center gap-2 p-2 ">
{List.length > 10 && (
{List.length > docPerPage && (
<>
{currentPage > 1 && (
<button
@@ -178,7 +178,7 @@ const ReportTable = ({
{isMoreDocs && (
<button className="text-black rounded px-1 py-2">...</button>
)}
{List.length > 10 && (
{List.length > docPerPage && (
<>
{pageNumbers.includes(currentPage + 1) && (
<button
+8 -12
View File
@@ -11,7 +11,8 @@ export const fetchAppInfo = (str, burl, app_id) => async (dispatch) => {
let _base = ""; // Define _base here and initialize it to an empty string
if (response && response.baseurl) {
_base = response.baseurl.charAt(response.baseurl.length - 1);
} localStorage.removeItem("baseUrl");
}
localStorage.removeItem("baseUrl");
localStorage.setItem("_appName", response.appname);
localStorage.setItem("_app_objectId", response.objectId);
if (_base === "/") {
@@ -120,16 +121,11 @@ export const login = (username, password) => async (dispatch) => {
localStorage.setItem("_user_role", _role);
}
try {
const tour = Parse.Object.extend(
localStorage.getItem("extended_class")
);
let _tour = new Parse.Query(tour);
_tour.equalTo("UserId", {
__type: "Pointer",
className: "_User",
objectId: resultjson.objectId
});
await _tour.first().then(
const currentUser = Parse.User.current();
await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
})
.then(
(results) => {
let userinfo = results.toJSON();
if (userinfo.TenantId) {
@@ -142,7 +138,7 @@ export const login = (username, password) => async (dispatch) => {
}
);
} catch (error) {
console.log("err ", error)
console.log("err ", error);
}
}
});
+66 -85
View File
@@ -10,9 +10,11 @@ import GoogleSignInBtn from "../components/LoginGoogle";
// import LoginFacebook from "../components/LoginFacebook";
import { NavLink, useNavigate } from "react-router-dom";
import login_img from "../assets/images/login_img.svg";
import { useWindowSize } from "../hook/useWindowSize";
function Login(props) {
const navigate = useNavigate();
const { width } = useWindowSize();
const [state, setState] = useState({
email: "",
toastColor: "#5cb85c",
@@ -21,7 +23,6 @@ function Login(props) {
passwordVisible: false,
mobile: "",
phone: "",
hideNav: "",
scanResult: "",
baseUrl: localStorage.getItem("baseUrl"),
parseAppId: localStorage.getItem("parseAppId"),
@@ -47,26 +48,11 @@ function Login(props) {
);
// eslint-disable-next-line
}, []);
useEffect(() => {
resize();
window.addEventListener("resize", resize());
return () => {
window.removeEventListener("resize", resize());
};
// eslint-disable-next-line
}, []);
const handleChange = (event) => {
const { name, value } = event.target;
setState({ ...state, [name]: value });
};
const resize = () => {
let currentHideNav = window.innerWidth <= 760;
if (currentHideNav !== state.hideNav) {
setState({ ...state, hideNav: currentHideNav });
}
};
const handleSubmit = async (event) => {
localStorage.removeItem("accesstoken");
event.preventDefault();
@@ -162,15 +148,13 @@ function Login(props) {
element.userpointer
);
const extendedClass = Parse.Object.extend(
element.extended_class
);
let query = new Parse.Query(extendedClass);
query.equalTo("UserId", Parse.User.current());
query.include("TenantId");
await query.find().then(
(results) => {
const currentUser = Parse.User.current();
await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
}).then(
(result) => {
let tenentInfo = [];
const results = [result];
if (results) {
let extendedInfo_stringify =
JSON.stringify(results);
@@ -280,10 +264,14 @@ function Login(props) {
`/${element.pageType}/${element.pageId}`
);
} else {
navigate(`/subscription`);
navigate(`/subscription`, {
replace: true
});
}
} else {
navigate(`/subscription`);
navigate(`/subscription`, {
replace: true
});
}
} else {
navigate(
@@ -320,7 +308,9 @@ function Login(props) {
);
const billingDate = "";
if (billingDate) {
navigate(`/subscription`);
navigate(`/subscription`, {
replace: true
});
}
} else {
navigate(
@@ -334,23 +324,6 @@ function Login(props) {
sessionToken: user.getSessionToken()
};
handleSubmitbtn(payload);
// setState({
// ...state,
// loading: false,
// toastColor: "#d9534f",
// toastDescription:
// "You dont have access to this application."
// });
// const x = document.getElementById("snackbar");
// x.className = "show";
// setTimeout(function () {
// x.className = x.className.replace(
// "show",
// ""
// );
// }, 2000);
// localStorage.setItem("accesstoken", null);
console.error(
"Error while fetching Follow",
error
@@ -502,16 +475,13 @@ function Login(props) {
element.extended_class
);
localStorage.setItem("userpointer", element.userpointer);
const extendedClass = Parse.Object.extend(
element.extended_class
);
let query = new Parse.Query(extendedClass);
query.equalTo("UserId", Parse.User.current());
query.include("TenantId");
await query.find().then(
(results) => {
const currentUser = Parse.User.current();
await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
}).then(
(result) => {
let tenentInfo = [];
const results = [result];
if (results) {
let extendedInfo_stringify =
JSON.stringify(results);
@@ -596,20 +566,26 @@ function Login(props) {
setThirdpartyLoader(false);
setState({ ...state, loading: false });
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
if (billingDate) {
if (billingDate > new Date()) {
localStorage.removeItem("userDetails");
navigate(
`/${element.pageType}/${element.pageId}`
);
if (billingDate) {
if (billingDate > new Date()) {
localStorage.removeItem("userDetails");
navigate(
`/${element.pageType}/${element.pageId}`
);
} else {
navigate(`/subscription`, {
replace: true
});
}
} else {
navigate(`/subscription`);
navigate(`/subscription`, { replace: true });
}
} else {
navigate(`/subscription`);
navigate(
`/${element.pageType}/${element.pageId}`
);
}
}
}
} else {
localStorage.setItem("PageLanding", element.pageId);
localStorage.setItem(
@@ -620,21 +596,25 @@ function Login(props) {
setState({ ...state, loading: false });
setThirdpartyLoader(false);
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
if (billingDate) {
if (billingDate > new Date()) {
localStorage.removeItem("userDetails");
navigate(
`/${element.pageType}/${element.pageId}`
);
if (billingDate) {
if (billingDate > new Date()) {
localStorage.removeItem("userDetails");
navigate(
`/${element.pageType}/${element.pageId}`
);
} else {
navigate(`/subscription`, { replace: true });
}
} else {
navigate(`/subscription`);
navigate(`/subscription`, { replace: true });
}
} else {
navigate(`/subscription`);
navigate(
`/${element.pageType}/${element.pageId}`
);
}
}
}
},
},
(error) => {
const payload = {
sessionToken: sessionToken
@@ -716,9 +696,10 @@ function Login(props) {
await axios
.post(url, JSON.stringify(body), { headers: headers1 })
.then((roles) => {
.then((axiosres) => {
const roles = axiosres.data.result;
if (roles) {
userRoles = roles.data.result;
userRoles = roles;
let _currentRole = "";
if (userRoles.length > 1) {
if (
@@ -766,15 +747,13 @@ function Login(props) {
element.extended_class
);
const extendedClass = Parse.Object.extend(
element.extended_class
);
let query = new Parse.Query(extendedClass);
query.equalTo("UserId", Parse.User.current());
query.include("TenantId");
await query.find().then(
(results) => {
const currentUser = Parse.User.current();
await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
}).then(
(result) => {
let tenentInfo = [];
const results = [result];
if (results) {
let extendedInfo_stringify = JSON.stringify(results);
let extendedInfo = JSON.parse(extendedInfo_stringify);
@@ -1065,7 +1044,7 @@ function Login(props) {
<NavLink
className="rounded-sm cursor-pointer bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] w-full py-3 shadow uppercase"
to="/signup"
style={state.hideNav ? { textAlign: "center" } : {}}
style={width < 768 ? { textAlign: "center" } : {}}
>
Create Account
</NavLink>
@@ -1133,7 +1112,7 @@ function Login(props) {
</div>
</div>
</div>
{!state.hideNav && (
{width >= 768 && (
<div className="self-center">
<div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]">
<img
@@ -1170,7 +1149,9 @@ function Login(props) {
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title font-semibold">Additional Info</h5>
<h5 className="modal-title font-semibold">
Additional Info
</h5>
<span>
<span></span>
</span>
+13 -22
View File
@@ -67,9 +67,8 @@ const PgSignUp = (props) => {
const userSettings = JSON.parse(localStorage.getItem("userSettings"));
const extClass = userSettings[0].extended_class;
// console.log("extClass ", extClass);
const checkUser = new Parse.Query(extClass);
checkUser.equalTo("Email", userDetails.email);
const res = await checkUser.first();
const params = { email: userDetails.email };
const res = await Parse.Cloud.run("getUserDetails", params);
// console.log("res", res);
if (res) {
const checkUser = new Parse.Query(extClass);
@@ -152,6 +151,7 @@ const PgSignUp = (props) => {
if (res) {
const params = {
userDetails: {
jobTitle: zohoRes.data.result.jobTitle,
company: zohoRes.data.result.company,
name: zohoRes.data.result.name,
email: zohoRes.data.result.email,
@@ -279,13 +279,6 @@ const PgSignUp = (props) => {
""
);
localStorage.setItem("_user_role", _role);
if (element.enableCart) {
localStorage.setItem("EnableCart", element.enableCart);
props.setEnableCart(element.enableCart);
} else {
localStorage.removeItem("EnableCart");
}
// Get TenentID from Extendend Class
localStorage.setItem(
"extended_class",
@@ -293,14 +286,12 @@ const PgSignUp = (props) => {
);
localStorage.setItem("userpointer", element.userpointer);
const extendedClass = Parse.Object.extend(
element.extended_class
);
let query = new Parse.Query(extendedClass);
query.equalTo("UserId", Parse.User.current());
query.include("TenantId");
await query.find().then(
(results) => {
const currentUser = Parse.User.current();
await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
}).then(
(result) => {
const results = [result];
let tenentInfo = [];
if (results) {
let extendedInfo_stringify =
@@ -415,7 +406,7 @@ const PgSignUp = (props) => {
}
})
.catch((err) => {
console.log('err', err)
console.log("err", err);
setIsLoader(false);
});
}
@@ -448,10 +439,10 @@ const PgSignUp = (props) => {
) : (
<form id="signup" className="pgsignup-content" onSubmit={handleSubmit}>
<div className="pgsignup-container">
<h1 className="text-4xl font-bold">Choose Password</h1>
<h1 className="text-2xl md:text-3xl font-bold">Choose Password</h1>
<hr className="hrt" />
<label htmlFor="password">
<b>Password</b>
<b className="text-[13px]">Password</b>
</label>
<input
type="password"
@@ -464,7 +455,7 @@ const PgSignUp = (props) => {
/>
<label htmlFor="confirmPassword">
<b>Confirm Password</b>
<b className="text-[13px]">Confirm Password</b>
</label>
<input
type="password"
+19 -16
View File
@@ -2,14 +2,14 @@ import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router";
import { NavLink } from "react-router-dom";
import checkmark from "../assets/images/checkmark.png";
import plansArr from '../json/plansArr.json'
import plansArr from "../json/plansArr.json";
import Title from "../components/Title";
const listItemStyle = {
paddingLeft: '20px', // Add padding to create space for the image
paddingLeft: "20px", // Add padding to create space for the image
backgroundImage: `url(${checkmark})`, // Set your image as the list style image
backgroundPosition: 'left',
backgroundRepeat: 'no-repeat',
backgroundSize: '16px 16px', // Adjust the size of the image
backgroundPosition: "left",
backgroundRepeat: "no-repeat",
backgroundSize: "16px 16px" // Adjust the size of the image
};
const PlanSubscriptions = () => {
@@ -28,7 +28,12 @@ const PlanSubscriptions = () => {
: "";
const phone =
userDetails && userDetails.phone ? "&mobile=" + userDetails.phone : "";
const details = "?shipping_country_code=US&" + name + email + company + phone;
const details =
"?shipping_country_code=US&billing_country_code=US&billing_state_code=CA&" +
name +
email +
company +
phone;
useEffect(() => {
if (localStorage.getItem("accesstoken")) {
setIsLoader(false);
@@ -41,7 +46,7 @@ const PlanSubscriptions = () => {
return (
<>
<Title title={"Subscriptions"} />
<Title title={"Subscriptions"} />
{isLoader ? (
<div
style={{
@@ -131,15 +136,13 @@ const PlanSubscriptions = () => {
<p>{item.subtitle}</p>
</div>
</div>
<div className="bg-[#002862] w-full text-white py-2 rounded">
<NavLink
to={item.url + details}
className="rounded uppercase hover:no-underline hover:text-white"
target="_self"
>
{item.btnText}
</NavLink>
</div>
<NavLink
to={item.url + details}
className="bg-[#002862] w-full text-white py-2 rounded uppercase hover:no-underline hover:text-white"
target={item.target}
>
{item.btnText}
</NavLink>
</div>
<hr className="w-full bg-gray-300 p-[.5px]" />
<ul className="mx-1 p-3 text-left break-words text-sm list-none">
+11 -16
View File
@@ -15,6 +15,7 @@ const Report = () => {
const [isNextRecord, setIsNextRecord] = useState(false);
const [isMoreDocs, setIsMoreDocs] = useState(true);
const abortController = new AbortController();
const docPerPage = 10;
// below useEffect is call when id param change
useEffect(() => {
@@ -47,30 +48,24 @@ const Report = () => {
if (json) {
setActions(json.actions);
setReportName(json.reportName);
const { className, params, keys, orderBy } = json;
Parse.serverURL = localStorage.getItem("BaseUrl12");
Parse.initialize(localStorage.getItem("AppID12"));
const currentUser = Parse.User.current().id;
const serverURL =
localStorage.getItem("BaseUrl12") + "classes/" + className;
const strParams = JSON.stringify(params);
const strKeys = keys.join();
const headers = {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
sessiontoken: localStorage.getItem("accesstoken")
};
try {
const url = `${serverURL}?where=${strParams}&keys=${strKeys}&order=${orderBy}&skip=${skipUserRecord}&limit=${limit}&include=AuditTrail.UserPtr`;
const res = await axios.get(url, {
const params = { reportId: id, skip: skipUserRecord, limit: limit };
const url = `${localStorage.getItem("BaseUrl12")}/functions/getReport`;
const res = await axios.post(url, params, {
headers: headers,
signal: abortController.signal // is used to cancel fetch query
});
if (id === "4Hhwbp482K") {
const listData = res.data?.results.filter(
(x) => x.Signers.length > 0
);
const listData = res.data?.result.filter((x) => x.Signers.length > 0);
let arr = [];
for (const obj of listData) {
const isSigner = obj.Signers.some(
@@ -92,7 +87,7 @@ const Report = () => {
}
}
}
if (arr.length === 10) {
if (arr.length === docPerPage) {
setIsMoreDocs(true);
} else {
setIsMoreDocs(false);
@@ -101,17 +96,16 @@ const Report = () => {
prevRecord.length > 0 ? [...prevRecord, ...arr] : arr
);
} else {
if (res.data.results.length === 10) {
if (res.data.result.length === docPerPage) {
setIsMoreDocs(true);
console.log("here");
} else {
setIsMoreDocs(false);
}
setIsNextRecord(false);
setList((prevRecord) =>
prevRecord.length > 0
? [...prevRecord, ...res.data.results]
: res.data.results
? [...prevRecord, ...res.data.result]
: res.data.result
);
}
setIsLoader(false);
@@ -155,6 +149,7 @@ const Report = () => {
actions={actions}
setIsNextRecord={setIsNextRecord}
isMoreDocs={isMoreDocs}
docPerPage={docPerPage}
/>
) : (
<div className="flex items-center justify-center h-screen w-full bg-white rounded">
+32 -79
View File
@@ -6,8 +6,10 @@ import Title from "../components/Title";
import { fetchAppInfo, showTenantName } from "../redux/actions";
import { useNavigate, NavLink } from "react-router-dom";
import login_img from "../assets/images/login_img.svg";
import { useWindowSize } from "../hook/useWindowSize";
const Signup = (props) => {
const { width } = useWindowSize();
const navigate = useNavigate();
const [name, setName] = useState("");
const [phone, setPhone] = useState("");
@@ -18,7 +20,6 @@ const Signup = (props) => {
const [company, setCompany] = useState("");
const [jobTitle, setJobTitle] = useState("");
const [state, setState] = useState({
hideNav: "",
loading: false,
toastColor: "#5cb85c",
toastDescription: ""
@@ -52,58 +53,34 @@ const Signup = (props) => {
res
.then(async (r) => {
if (r) {
let roleurl = `${parseBaseUrl}functions/AddUserToRole`;
const headers = {
"Content-Type": "application/json",
"X-Parse-Application-Id": parseAppId,
sessionToken:
r.getSessionToken() || localStorage.getItem("accesstoken")
};
let body = {
appName: props.appInfo.appname,
roleName: props.appInfo.defaultRole,
userId: r.id
};
await axios.post(roleurl, body, { headers: headers });
let roleData = props.appInfo.settings;
if (roleData && roleData.length > 0) {
roleData.forEach((rld) => {
if (rld.role === props.appInfo.defaultRole) {
const extCls = Parse.Object.extend(rld.extended_class);
const newObj = new extCls();
newObj.set("UserId", {
__type: "Pointer",
className: "_User",
objectId: r.id
});
newObj.set("UserRole", props.appInfo.defaultRole);
newObj.set("Email", email);
newObj.set("Name", name);
newObj.set("Phone", phone);
newObj.set("Company", company);
newObj.set("JobTitle", jobTitle);
newObj
.save()
.then((ex) => {
if (ex) {
handleNavigation(r.getSessionToken());
}
})
.catch((err) => {
alert(err.message);
setState({ loading: false });
});
const params = {
userDetails: {
jobTitle: jobTitle,
company: company,
name: name,
email: email,
phone: phone,
role: props.appInfo.defaultRole
}
});
};
try {
const usersignup = await Parse.Cloud.run("usersignup", params);
if (usersignup) {
handleNavigation(r.getSessionToken());
}
} catch (err) {
alert(err.message);
setState({ loading: false });
}
}
}
})
.catch(async (err) => {
if (err.code === 202) {
const userQuery = new Parse.Query("contracts_Users");
userQuery.equalTo("Email", email);
const res = await userQuery.first();
const params = { email: email };
const res = await Parse.Cloud.run("getUserDetails", params);
// console.log("Res ", res);
if (res) {
alert("User already exists with this username!");
@@ -208,13 +185,6 @@ const Signup = (props) => {
""
);
localStorage.setItem("_user_role", _role);
if (element.enableCart) {
localStorage.setItem("EnableCart", element.enableCart);
props.setEnableCart(element.enableCart);
} else {
localStorage.removeItem("EnableCart");
}
// Get TenentID from Extendend Class
localStorage.setItem(
"extended_class",
@@ -222,15 +192,12 @@ const Signup = (props) => {
);
localStorage.setItem("userpointer", element.userpointer);
const extendedClass = Parse.Object.extend(
element.extended_class
);
let query = new Parse.Query(extendedClass);
query.equalTo("UserId", Parse.User.current());
query.include("TenantId");
await query.find().then(
(results) => {
await Parse.Cloud.run("getUserDetails", {
email: email
}).then(
(result) => {
let tenentInfo = [];
const results = [result];
if (results) {
let extendedInfo_stringify =
JSON.stringify(results);
@@ -318,7 +285,7 @@ const Signup = (props) => {
);
setState({ loading: false });
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
navigate("/subscription");
navigate(`/subscription`, { replace: true });
} else {
alert("Registered user successfully");
navigate(
@@ -336,7 +303,7 @@ const Signup = (props) => {
localStorage.setItem("pageType", element.pageType);
setState({ loading: false });
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
navigate("/subscription");
navigate(`/subscription`, { replace: true });
} else {
navigate(
`/${element.pageType}/${element.pageId}`
@@ -421,24 +388,14 @@ const Signup = (props) => {
}
};
useEffect(() => {
window.addEventListener("resize", resize);
props.fetchAppInfo(
localStorage.getItem("domain"),
localStorage.getItem("BaseUrl12"),
localStorage.getItem("AppID12")
);
return () => {
window.removeEventListener("resize", resize);
};
// eslint-disable-next-line
}, []);
const resize = () => {
let currentHideNav = window.innerWidth <= 760;
if (currentHideNav !== state.hideNav) {
setState({ hideNav: currentHideNav });
}
};
return (
<div className="bg-white">
{state.loading && (
@@ -472,11 +429,7 @@ const Signup = (props) => {
<div>
<div className="md:m-10 lg:m-16 md:p-4 lg:p-10 p-5 bg-[#ffffff] md:border-[1px] md:border-gray-400 ">
<div className="w-[250px] h-[66px] inline-block">
{state.hideNav ? (
<img src={image} width="100%" alt="" />
) : (
<img src={image} width="100%" alt="" />
)}
<img src={image} width="100%" alt="" />
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
<div className="">
@@ -584,14 +537,14 @@ const Signup = (props) => {
<NavLink
className="rounded-sm cursor-pointer bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] w-full py-3 shadow uppercase"
to="/"
style={state.hideNav ? { textAlign: "center" } : {}}
style={width < 768 ? { textAlign: "center" } : {}}
>
Login
</NavLink>
</div>
</form>
</div>
{!state.hideNav && (
{width >= 768 && (
<div className="self-center">
<div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]">
<img src={login_img} alt="bisec" width="100%" />
+59 -31
View File
@@ -5,7 +5,7 @@ import { SaveFileSize } from "../constant/saveFileSize";
import dp from "../assets/images/dp.png";
import Title from "../components/Title";
import sanitizeFileName from "../primitives/sanitizeFileName";
import axios from "axios";
function UserProfile() {
const navigate = useNavigate();
let UserProfile = JSON.parse(localStorage.getItem("UserInformation"));
@@ -16,6 +16,8 @@ function UserProfile() {
const [Phone, SetPhone] = useState(UserProfile && UserProfile.phone);
const [Image, setImage] = useState(localStorage.getItem("profileImg"));
const [isLoader, setIsLoader] = useState(false);
const [percentage, setpercentage] = useState(0);
Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId);
const handleSubmit = async (e) => {
@@ -44,7 +46,7 @@ function UserProfile() {
await updateExtUser({ Name: res.name, Phone: res.phone });
alert("Profile updated successfully.");
setEditMode(false);
navigate("/");
navigate("/dashboard/35KBoSgoAK");
}
},
(error) => {
@@ -64,18 +66,24 @@ function UserProfile() {
const extClass = localStorage.getItem("extended_class");
const extData = JSON.parse(localStorage.getItem("Extand_Class"));
const ExtUserId = extData[0].objectId;
// console.log("extData ", extData);
// console.log("UserId ", ExtUserId);
const body = { Phone: obj.Phone, Name: obj.Name };
await axios.put(
parseBaseUrl + "classes/" + extClass + "/" + ExtUserId,
body,
{
headers: {
"Content-Type": "application/json",
"X-Parse-Application-Id": parseAppId,
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
}
}
);
const res = await Parse.Cloud.run("getUserDetails", {
email: extData[0].Email
});
const extQuery = new Parse.Query(extClass);
const update = await extQuery.get(ExtUserId);
// console.log("update ", update);
update.set("Phone", obj.Phone);
update.set("Name", obj.Name);
const updateRes = await update.save();
const json = JSON.parse(JSON.stringify([updateRes]));
const json = JSON.parse(JSON.stringify([res]));
const extRes = JSON.stringify(json);
localStorage.setItem("Extand_Class", extRes);
@@ -96,7 +104,15 @@ function UserProfile() {
const parseFile = new Parse.File(name, pdfFile);
try {
const response = await parseFile.save();
const response = await parseFile.save({
progress: (progressValue, loaded, total, { type }) => {
if (type === "upload" && progressValue !== null) {
const percentCompleted = Math.round((loaded * 100) / total);
// console.log("percentCompleted ", percentCompleted);
setpercentage(percentCompleted);
}
}
});
// // The response object will contain information about the uploaded file
// console.log("File uploaded:", response);
@@ -105,6 +121,7 @@ function UserProfile() {
if (response.url()) {
setImage(response.url());
localStorage.setItem("profileImg", response.url());
setpercentage(0);
SaveFileSize(size, response.url());
return response.url();
}
@@ -154,14 +171,25 @@ function UserProfile() {
<input
type="file"
className="max-w-[270px] text-sm py-1 px-2 mt-4 border-[1px] border-[#15b4e9] text-black rounded"
accept="image/png, image/gif, image/jpeg"
onChange={(e) => {
let files = e.target.files;
fileUpload(files[0]);
}}
/>
)}
{percentage !== 0 && (
<div className="flex items-center gap-x-2">
<div className="h-2 rounded-full w-[200px] md:w-[400px] bg-gray-200">
<div
className="h-2 rounded-full bg-blue-500"
style={{ width: `${percentage}%` }}
></div>
</div>
<span className="text-black text-sm">{percentage}%</span>
</div>
)}
<div className="text-base font-semibold pt-4">
{" "}
{localStorage.getItem("_user_role")}
</div>
</div>
@@ -214,26 +242,11 @@ function UserProfile() {
</li>
</ul>
<div className="flex justify-center pb-4">
<button
type="button"
onClick={() => {
if (editmode) {
setEditMode(false);
} else {
navigate("/changepassword");
}
}}
className={`rounded shadow text-white bg-[#3598dc] mr-4 ${
editmode ? "px-4 py-2 " : "p-2"
}`}
>
{editmode ? "Cancel" : "Change Password"}
</button>
{editmode ? (
<button
type="button"
onClick={handleSubmit}
className="rounded bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] px-4 py-2"
className="rounded bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] px-4 py-2 mr-4"
>
Save
</button>
@@ -243,11 +256,26 @@ function UserProfile() {
onClick={() => {
setEditMode(true);
}}
className="rounded shadow text-white bg-[#e7505a] px-4 py-2"
className="rounded shadow text-white bg-[#e7505a] px-4 py-2 mr-4"
>
Edit
</button>
)}
<button
type="button"
onClick={() => {
if (editmode) {
setEditMode(false);
} else {
navigate("/changepassword");
}
}}
className={`rounded shadow text-white bg-[#3598dc] ${
editmode ? "px-4 py-2 " : "p-2"
}`}
>
{editmode ? "Cancel" : "Change Password"}
</button>
</div>
</div>
)}
+29 -9
View File
@@ -1,12 +1,14 @@
/* Full-width input fields */
.inputt {
width: 100%;
padding: 15px;
margin: 5px 0 22px 0;
padding: 8px;
margin-bottom: 10px;
/* margin: 5px 0 14px 0; */
display: inline-block;
border: none;
background: #f1f1f1;
color: black;
font-size: 12px;
}
/* Add a background color when the inputs get focus */
@@ -18,11 +20,12 @@
.confirmInputt {
width: 100%;
padding: 15px;
margin: 5px 0 1px 0;
padding: 8px;
/* margin: 5px 0 14px 0; */
display: inline-block;
background: #f1f1f1;
color: black;
font-size: 12px;
}
.inputt::placeholder,
@@ -42,11 +45,10 @@
.signupbtn {
background-color: #15b4e9;
color: white;
padding: 14px 20px;
padding: 12px 12px;
margin: 8px 0;
border: none;
cursor: pointer;
width: 100%;
opacity: 0.9;
float: left;
width: 50%;
@@ -87,7 +89,7 @@
margin: 5% auto 15% auto;
/* 5% from the top, 15% from the bottom and centered */
border: 1px solid #888;
width: 80%;
width: 50%;
/* Could be more or less, depending on screen size */
}
@@ -111,8 +113,26 @@
}
/* Change styles for cancel button and signup button on extra small screens */
@media screen and (max-width: 300px) {
@media screen and (max-width: 768px) {
/* pgsignup Content/Box */
.pgsignup-content {
background-color: #fefefe;
margin: 5% auto 15% auto;
/* 5% from the top, 15% from the bottom and centered */
border: 1px solid #888;
width: 90%;
/* Could be more or less, depending on screen size */
}
.signupbtn {
width: 100%;
font-size: 16px;
}
}
/* Style the horizontal ruler */
.hrt {
border: 1px solid #f1f1f1;
margin-bottom: 16px;
}
}
+8
View File
@@ -13,6 +13,10 @@ import sendMailOTPv1 from './parsefunction/SendMailOTPv1.js';
import SendMailv1 from './parsefunction/SendMailv1.js';
import AuthLoginAsMail from './parsefunction/AuthLoginAsMail.js';
import getUserId from './parsefunction/getUserId.js';
import getUserDetails from './parsefunction/getUserDetails.js';
import getDocument from './parsefunction/getDocument.js';
import getDrive from './parsefunction/getDrive.js';
import getReport from './parsefunction/getReport.js';
Parse.Cloud.define('AddUserToRole', addUserToGroups);
Parse.Cloud.define('UserGroups', getUserGroups);
@@ -29,3 +33,7 @@ Parse.Cloud.define('SendOTPMailV1', sendMailOTPv1);
Parse.Cloud.define('sendmail', SendMailv1);
Parse.Cloud.define('AuthLoginAsMail', AuthLoginAsMail);
Parse.Cloud.define('getUserId', getUserId);
Parse.Cloud.define('getUserDetails', getUserDetails);
Parse.Cloud.define('getDocument', getDocument);
Parse.Cloud.define('getDrive', getDrive)
Parse.Cloud.define('getReport', getReport)
@@ -5,7 +5,7 @@ async function SendMailv1(request) {
const recipient = request.params.email;
const otp = request.params.otp;
const res = await Parse.Cloud.sendEmail({
from: 'Test user' + ' <' + process.env.MAILGUN_SENDER + '>',
from: 'Test user' + ' <' + process.env.SMTP_ENABLE ? process.env.SMTP_USER_EMAIL : process.env.MAILGUN_SENDER + '>',
recipient: recipient,
subject: 'Your OpenSign™ OTP',
text: 'This email is a test.',
@@ -46,15 +46,20 @@ export default async function ZohoDetails(request) {
(userData.data.data.subscription.customer &&
userData.data.data.subscription.customer.company_name) ||
'';
const jobTitle =
(userData.data.data.subscription.customer &&
userData.data.data.subscription.customer.cd_job_title) ||
'';
const resData = {
phone: userData.data.data.subscription.contactpersons[0].mobile,
name: first_name + ' ' + last_name,
email: userData.data.data.subscription.contactpersons[0].email,
nextBillingDate: userData.data.expiring_time,
nextBillingDate: userData.data.data.subscription.next_billing_at,
company: company_name,
plan: userData.data.data.subscription.plan,
customer_id: userData.data.data.subscription.customer_id,
subscription_id: userData.data.data.subscription.subscription_id,
jobTitle: jobTitle,
};
return resData;
}
@@ -0,0 +1,50 @@
import axios from 'axios';
export default async function getDocument(request) {
const serverUrl = process.env.SERVER_URL;
const docId = request.params.docId;
try {
const userRes = await axios.get(serverUrl + '/users/me', {
headers: {
'X-Parse-Application-Id': process.env.APP_ID,
'X-Parse-Session-Token': request.headers['sessiontoken'],
},
});
const userId = userRes.data && userRes.data.objectId;
if (docId && userId) {
try {
const query = new Parse.Query('contracts_Document');
query.equalTo('objectId', docId);
query.include('ExtUserPtr');
query.include('CreatedBy');
query.include('Signers');
query.include('AuditTrail.UserPtr');
query.include('Placeholders');
const res = await query.first({ useMasterKey: true });
if (res) {
const acl = res.getACL();
if (acl && acl.getReadAccess(userId)) {
return res;
} else {
return { error: "You don't have access of this document!" };
}
} else {
return { error: "You don't have access of this document!" };
}
} catch (err) {
console.log('err', err);
return err;
}
} else {
return { error: 'Please pass required parameters!' };
}
} catch (err) {
console.log('err');
if (err.code == 209) {
return { error: 'Invalid session token' };
} else {
return { error: "You don't have access of this document!" };
}
}
}
@@ -0,0 +1,51 @@
import axios from 'axios';
export default async function getDrive(request) {
const serverUrl = process.env.SERVER_URL;
const appId = process.env.APP_ID;
const classUrl = serverUrl + '/classes/contracts_Document';
const docId = request.params.docId;
try {
const userRes = await axios.get(serverUrl + '/users/me', {
headers: {
'X-Parse-Application-Id': appId,
'X-Parse-Session-Token': request.headers['sessiontoken'],
},
});
const userId = userRes.data && userRes.data.objectId;
if (userId) {
let url;
if (docId) {
url = `${classUrl}?where={"Folder":{"__type":"Pointer","className":"contracts_Document","objectId":"${docId}"},"$or":[{"CreatedBy":{"$exists":false}},{"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"}}]}&include=ExtUserPtr,Signers,Folder`;
} else {
url = `${classUrl}?where={"Folder":{"$exists":false},"$or":[{"CreatedBy":{"$exists":false}},{"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"}}]}&include=ExtUserPtr,Signers`;
}
try {
const res = await axios.get(url, {
headers: {
'X-Parse-Application-Id': appId,
'X-Parse-Master-key': process.env.MASTER_KEY,
},
});
// console.log('res.data.results ', res.data.results);
if (res.data && res.data.results) {
return res.data.results;
} else {
return [];
}
} catch (err) {
console.log('err', err);
return { error: "You don't have access to drive" };
}
} else {
return { error: 'Please provide required parameter!' };
}
} catch (err) {
console.log('err', err);
if (err.code == 209) {
return { error: 'Invalid session token' };
} else {
return { error: "You don't have access!" };
}
}
}
@@ -0,0 +1,51 @@
import reportJson from './reportsJson.js';
import axios from 'axios'
export default async function getReport(request) {
const reportId = request.params.reportId;
const limit = request.params.limit;
const skip = request.params.skip;
const serverUrl = process.env.SERVER_URL;
const appId = process.env.APP_ID;
try {
const userRes = await axios.get(serverUrl + '/users/me', {
headers: {
'X-Parse-Application-Id': appId,
'X-Parse-Session-Token': request.headers['sessiontoken'],
},
});
const userId = userRes.data && userRes.data.objectId;
if (userId) {
const json = reportId && reportJson(reportId, userId);
if (json) {
const { params, keys } = json;
const orderBy = '-updatedAt';
const strParams = JSON.stringify(params);
const strKeys = keys.join();
const headers = {
'Content-Type': 'application/json',
'X-Parse-Application-Id': appId,
'X-Parse-Master-Key': process.env.MASTER_KEY,
};
const url = `${serverUrl}/classes/contracts_Document?where=${strParams}&keys=${strKeys}&order=${orderBy}&skip=${skip}&limit=${limit}&include=AuditTrail.UserPtr`;
const res = await axios.get(url, { headers: headers });
if (res.data && res.data.results) {
return res.data.results;
} else {
return [];
}
} else {
return { error: 'Report is not available!' };
}
}
} catch (err) {
console.log('err', err);
if (err.code == 209) {
return { error: 'Invalid session token' };
} else {
return { error: "You don't have access!" };
}
}
}
@@ -0,0 +1,14 @@
async function getUserDetails(request) {
try {
const userQuery = new Parse.Query('contracts_Users');
userQuery.equalTo('Email', request.params.email);
userQuery.include('TenantId');
userQuery.include('UserId')
const res = await userQuery.first({ useMasterKey: true });
return res;
} catch (err) {
console.log('Err ', err);
return err;
}
}
export default getUserDetails;
+4 -4
View File
@@ -79,7 +79,7 @@ async function sendCompletedMail(e) {
url: a,
from: 'OpenSign™',
recipient: e.receiver,
subject: `Document ${s} has beeen signed by all parties`,
subject: `Document ${s} has been signed by all parties`,
pdfName: s,
html:
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body> <div style='background-color:#f5f5f5;padding:20px'> <div style='box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background-color:white;'> <div><img src=https://qikinnovation.ams3.digitaloceanspaces.com/logo.png height='50' style='padding:20px'/> </div><div style='padding:2px;font-family:system-ui; background-color: #47a3ad;'> <p style='font-size:20px;font-weight:400;color:white;padding-left:20px',> Document sign successfully</p></div><div><p style='padding:20px;font-family:system-ui;font-size:14px'>All parties have successfully signed the document" +
@@ -105,7 +105,7 @@ async function PDF(s, r) {
headers: {
'Content-Type': 'application/json',
'X-Parse-Application-Id': APPID,
'X-Parse-Session-Token': s.headers.sessiontoken,
'X-Parse-Master-Key': masterKEY,
},
}),
d = await axios.get(serverUrl + '/users/me', {
@@ -132,7 +132,7 @@ async function PDF(s, r) {
: ((a = await axios.get(serverUrl + '/classes/contracts_Users?where=' + m, {
headers: {
'X-Parse-Application-Id': APPID,
'X-Parse-Session-Token': s.headers.sessiontoken,
'X-Parse-Master-Key': masterKEY,
},
})),
'contracts_Users')
@@ -142,7 +142,7 @@ async function PDF(s, r) {
(c = await axios.get(serverUrl + '/classes/contracts_Users?where=' + p, {
headers: {
'X-Parse-Application-Id': APPID,
'X-Parse-Session-Token': s.headers.sessiontoken,
'X-Parse-Master-Key': masterKEY,
},
})).data && 0 < c.data.results.length
? ((a = c), 'contracts_Users')
@@ -1,28 +1,28 @@
import{DEFAULT_BYTE_RANGE_PLACEHOLDER,DEFAULT_SIGNATURE_LENGTH,SUBFILTER_ADOBE_PKCS7_DETACHED}from"./const.min.js";import PDFKitReferenceMock from"./PDFKitReferenceMock.min.js";import PNG from"png-js";import zlib from"zlib";import fs from"node:fs";const specialCharacters=["á","Á","é","É","í","Í","ó","Ó","ö","Ö","ő","Ő","ú","Ú","ű","Ű"],MARKERS=[65472,65473,65474,65475,65477,65478,65479,65480,65481,65482,65483,65484,65485,65486,65487],COLOR_SPACE_MAP={1:"DeviceGray",3:"DeviceRGB",4:"DeviceCMYK"};function getImage(e,t){let n;if(255===e[0]&&216===e[1])n=getJpgImage(t,e);else{if(137!==e[0]||"PNG"!==e.toString("ascii",1,4))throw new Error("Unknown image format.");n=getPngImage(t,e)}return n}function getAnnotationApparance(e,t,n){return e.ref({CropBox:[0,0,197,70],Type:"XObject",FormType:1,BBox:[0,0,197,70],Resources:`<</XObject <<
import{DEFAULT_BYTE_RANGE_PLACEHOLDER,DEFAULT_SIGNATURE_LENGTH,SUBFILTER_ADOBE_PKCS7_DETACHED}from"./const.min.js";import PDFKitReferenceMock from"./PDFKitReferenceMock.min.js";import PNG from"png-js";import zlib from"zlib";const specialCharacters=["á","Á","é","É","í","Í","ó","Ó","ö","Ö","ő","Ő","ú","Ú","ű","Ű"],MARKERS=[65472,65473,65474,65475,65477,65478,65479,65480,65481,65482,65483,65484,65485,65486,65487],COLOR_SPACE_MAP={1:"DeviceGray",3:"DeviceRGB",4:"DeviceCMYK"};function getImage(e,t){let n;if(255===e[0]&&216===e[1])n=getJpgImage(t,e);else{if(137!==e[0]||"PNG"!==e.toString("ascii",1,4))throw new Error("Unknown image format.");n=getPngImage(t,e)}return n}function getAnnotationApparance(e,t,n){return e.ref({CropBox:[0,10,200,60],Type:"XObject",FormType:1,BBox:[0,10,200,60],Resources:`<</XObject <<
/Img${t.index} ${t.index} 0 R
>>
/Font <<
/f1 ${n.index} 0 R
>>
>>`,MediaBox:[0,0,197,70],Subtype:"Form"},null,getStream(t.index))}const getStream=e=>getConvertedText(`
1.0 1.0 1.0 rg
0.0 0.0 0.0 RG
q
q
200 0 0 50 0 10 cm
/Img${e} Do
Q
0 0 0 rg
BT
0 Tr
/f1 10.0 Tf
1.4 0 0 1 20 45.97412 Tm
ET
BT
0 Tr
/f1 10.0 Tf
1.4 0 0 1 20 33.56006 Tm
ET
Q`),getFont=(e,t)=>e.ref({Type:"Font",BaseFont:t,Encoding:"WinAnsiEncoding",Subtype:"Type1"}),getJpgImage=(e,t)=>{if(65496!==t.readUInt16BE(0))throw"SOI not found in JPEG";let n=2,a;for(;n<t.length&&(a=t.readUInt16BE(n),n+=2,!MARKERS.includes(a));)n+=t.readUInt16BE(n);if(!MARKERS.includes(a))throw"Invalid JPEG.";n+=2;var r=t[n++],o=t.readUInt16BE(n),i=(n+=2,t.readUInt16BE(n)),l=(n+=2,t[n++]),l=COLOR_SPACE_MAP[l],r={Type:"XObject",Subtype:"Image",BitsPerComponent:r,Width:i,Height:o,ColorSpace:l,Filter:"DCTDecode"},i=("DeviceCMYK"===l&&(r.Decode=[1,0,1,0,1,0,1,0]),e.ref(r,null,t));return i},getPngImage=(e,t)=>{var t=new PNG(t),n=t.hasAlphaChannel,a={Type:"XObject",Subtype:"Image",BitsPerComponent:n?8:t.bits,Width:t.width,Height:t.height,Filter:"FlateDecode"};if(n||(r=e.ref({Predictor:15,Colors:t.colors,BitsPerComponent:t.bits,Columns:t.width}),a.DecodeParms=r),0===t.palette.length?a.ColorSpace=t.colorSpace:(r=e.ref({stream:new Buffer(t.palette)}),a.ColorSpace=["Indexed","DeviceRGB",t.palette.length/3-1,r]),null!=t.transparency.grayscale){var r=t.transparency.grayscale;a.Mask=[r,r]}else if(t.transparency.rgb){var o,r=t.transparency["rgb"],i=[];for(o of r)i.push(o,o);a.Mask=i}else t.transparency.indexed?loadIndexedAlphaChannel(t):n&&(splitAlphaChannel(t),r=getSmask(e,t),a.Mask=r);return e.ref(a,null,t.imgData)},loadIndexedAlphaChannel=e=>{const o=e.transparency.indexed;return e.decodePixels(n=>{var a=new Buffer(e.width*e.height);let r=0;for(let e=0,t=n.length;e<t;e++)a[r++]=o[n[e]];e.alphaChannel=zlib.deflateSync(a)})},splitAlphaChannel=d=>{d.decodePixels(t=>{let e,n;var a=d.colors,r=d.width*d.height,o=new Buffer(r*a),i=new Buffer(r);let l=n=e=0;for(var g=t.length,c=16===d.bits?1:0;l<g;){for(let e=0;e<a;e++)o[n++]=t[l++],l+=c;i[e++]=t[l++],l+=c}d.imgData=zlib.deflateSync(o),d.alphaChannel=zlib.deflateSync(i)})},getSmask=(e,t)=>{let n;return console.log("image.hasAlphaChannel ",t.hasAlphaChannel),t.hasAlphaChannel&&(console.log("image.alphaChannel ",t.alphaChannel),n=e.ref({Type:"XObject",Subtype:"Image",Height:t.height,Width:t.width,BitsPerComponent:8,Filter:"FlateDecode",ColorSpace:"DeviceGray",Decode:[0,1],stream:t.alphaChannel})),n},getConvertedText=e=>e.split("").map(e=>specialCharacters.includes(e)?getOctalCodeFromCharacter(e):e).join(""),getOctalCodeFromCharacter=e=>"\\"+e.charCodeAt(0).toString(8),pdfkitAddPlaceholder=({pdf:e,pdfBuffer:a,reason:r,contactInfo:t="emailfromp1289@gmail.com",name:n="Name from p12",location:o="Location from p12",signatureLength:i=DEFAULT_SIGNATURE_LENGTH,byteRangePlaceholder:l=DEFAULT_BYTE_RANGE_PLACEHOLDER,subFilter:g=SUBFILTER_ADOBE_PKCS7_DETACHED,sign:c})=>{var d=getFont(e,"Helvetica"),s=getFont(e,"ZapfDingbats"),f=getFont(e,"Helvetica"),p=c.Base64,p=getAnnotationApparance(e,getImage(Buffer.from(p,"base64"),e),f),f=e.ref({Type:"Sig",Filter:"Adobe.PPKLite",SubFilter:g,ByteRange:[0,l,l,l],Contents:Buffer.from(String.fromCharCode(0).repeat(i)),Reason:new String(r),M:new Date,ContactInfo:new String(t),Name:new String(n),Location:new String(o)}),h=a.lastIndexOf("/Type /AcroForm"),g=-1!==h;let m=[],C;if(g){let e=h;var S=h-10;let t="",n=11;for(n;n<22;n+=1){var A=a.slice(h-n,S).toString();if("\n"===A[0])break;t=A,e=h-n}l=a.slice(e),i=l.slice(0,l.indexOf("endobj")).toString(),r=(C=parseInt(t),i.slice(i.indexOf("/Fields [")+9,i.indexOf("]")));m=r.split(" ").filter((e,t)=>t%3==0).map(e=>new PDFKitReferenceMock(e))}m.length;t=c.Left,n=c.Bottom,o=t+c.Width,l=n+c.Height,i=e.ref({Type:"Annot",Subtype:"Widget",FT:"Sig",Rect:[t,n,o,l],V:f,T:new String("Signature"+(m.length+1)),F:4,P:e.page.dictionary,AP:`<</N ${p.index} 0 R>>`,DA:new String("/Helvetica 0 Tf 0 g")});e.page.dictionary.data.Annots=[i];let T;return T=g?e.ref({Type:"AcroForm",SigFlags:3,Fields:[...m,i],DR:`<</Font
>>`,MediaBox:[0,10,200,60],Subtype:"Form"},null,getStream(t.index))}const getStream=e=>getConvertedText(`
1.0 1.0 1.0 rg
0.0 0.0 0.0 RG
q
q
200 0 0 50 0 10 cm
/Img${e} Do
Q
0 0 0 rg
BT
0 Tr
/f1 10.0 Tf
1.4 0 0 1 20 45.97412 Tm
ET
BT
0 Tr
/f1 10.0 Tf
1.4 0 0 1 20 33.56006 Tm
ET
Q`),getFont=(e,t)=>e.ref({Type:"Font",BaseFont:t,Encoding:"WinAnsiEncoding",Subtype:"Type1"}),getJpgImage=(e,t)=>{if(65496!==t.readUInt16BE(0))throw"SOI not found in JPEG";let n=2,a;for(;n<t.length&&(a=t.readUInt16BE(n),n+=2,!MARKERS.includes(a));)n+=t.readUInt16BE(n);if(!MARKERS.includes(a))throw"Invalid JPEG.";n+=2;var r=t[n++],o=t.readUInt16BE(n),i=(n+=2,t.readUInt16BE(n)),l=(n+=2,t[n++]),l=COLOR_SPACE_MAP[l],r={Type:"XObject",Subtype:"Image",BitsPerComponent:r,Width:i,Height:o,ColorSpace:l,Filter:"DCTDecode"},i=("DeviceCMYK"===l&&(r.Decode=[1,0,1,0,1,0,1,0]),e.ref(r,null,t));return i},getPngImage=(e,t)=>{var t=new PNG(t),n=t.hasAlphaChannel,a={Type:"XObject",Subtype:"Image",BitsPerComponent:n?8:t.bits,Width:t.width,Height:t.height,Filter:"FlateDecode"};if(n||(r=e.ref({Predictor:15,Colors:t.colors,BitsPerComponent:t.bits,Columns:t.width}),a.DecodeParms=r),0===t.palette.length?a.ColorSpace=t.colorSpace:(r=e.ref({stream:new Buffer(t.palette)}),a.ColorSpace=["Indexed","DeviceRGB",t.palette.length/3-1,r]),null!=t.transparency.grayscale){var r=t.transparency.grayscale;a.Mask=[r,r]}else if(t.transparency.rgb){var o,r=t.transparency["rgb"],i=[];for(o of r)i.push(o,o);a.Mask=i}else t.transparency.indexed?loadIndexedAlphaChannel(t):n&&(splitAlphaChannel(t),r=getSmask(e,t),a.Mask=r);return e.ref(a,null,t.imgData)},loadIndexedAlphaChannel=e=>{const o=e.transparency.indexed;return e.decodePixels(n=>{var a=new Buffer(e.width*e.height);let r=0;for(let e=0,t=n.length;e<t;e++)a[r++]=o[n[e]];e.alphaChannel=zlib.deflateSync(a)})},splitAlphaChannel=d=>{d.decodePixels(t=>{let e,n;var a=d.colors,r=d.width*d.height,o=new Buffer(r*a),i=new Buffer(r);let l=n=e=0;for(var c=t.length,g=16===d.bits?1:0;l<c;){for(let e=0;e<a;e++)o[n++]=t[l++],l+=g;i[e++]=t[l++],l+=g}d.imgData=zlib.deflateSync(o),d.alphaChannel=zlib.deflateSync(i)})},getSmask=(e,t)=>{let n;return console.log("image.hasAlphaChannel ",t.hasAlphaChannel),t.hasAlphaChannel&&(console.log("image.alphaChannel ",t.alphaChannel),n=e.ref({Type:"XObject",Subtype:"Image",Height:t.height,Width:t.width,BitsPerComponent:8,Filter:"FlateDecode",ColorSpace:"DeviceGray",Decode:[0,1],stream:t.alphaChannel})),n},getConvertedText=e=>e.split("").map(e=>specialCharacters.includes(e)?getOctalCodeFromCharacter(e):e).join(""),getOctalCodeFromCharacter=e=>"\\"+e.charCodeAt(0).toString(8),pdfkitAddPlaceholder=({pdf:e,pdfBuffer:a,reason:r,contactInfo:t="emailfromp1289@gmail.com",name:n="Name from p12",location:o="Location from p12",signatureLength:i=DEFAULT_SIGNATURE_LENGTH,byteRangePlaceholder:l=DEFAULT_BYTE_RANGE_PLACEHOLDER,subFilter:c=SUBFILTER_ADOBE_PKCS7_DETACHED,sign:g})=>{var d=getFont(e,"Helvetica"),s=getFont(e,"ZapfDingbats"),p=getFont(e,"Helvetica"),f=g.Base64,f=getAnnotationApparance(e,getImage(Buffer.from(f,"base64"),e),p,g),p=e.ref({Type:"Sig",Filter:"Adobe.PPKLite",SubFilter:c,ByteRange:[0,l,l,l],Contents:Buffer.from(String.fromCharCode(0).repeat(i)),Reason:new String(r),M:new Date,ContactInfo:new String(t),Name:new String(n),Location:new String(o)}),h=a.lastIndexOf("/Type /AcroForm"),c=-1!==h;let m=[],C;if(c){let e=h;var S=h-10;let t="",n=11;for(n;n<22;n+=1){var A=a.slice(h-n,S).toString();if("\n"===A[0])break;t=A,e=h-n}l=a.slice(e),i=l.slice(0,l.indexOf("endobj")).toString(),r=(C=parseInt(t),i.slice(i.indexOf("/Fields [")+9,i.indexOf("]")));m=r.split(" ").filter((e,t)=>t%3==0).map(e=>new PDFKitReferenceMock(e))}t=g.Left,n=g.Bottom,o=t+g.Width,l=n+g.Height,i=e.ref({Type:"Annot",Subtype:"Widget",FT:"Sig",Rect:[t,n,o,l],V:p,T:new String("Signature"+(m.length+1)),F:4,P:e.page.dictionary,AP:`<</N ${f.index} 0 R>>`,DA:new String("/Helvetica 0 Tf 0 g")});e.page.dictionary.data.Annots=[i];let T;return T=c?e.ref({Type:"AcroForm",SigFlags:3,Fields:[...m,i],DR:`<</Font
<</Helvetica ${d.index} 0 R/ZapfDingbats ${s.index} 0 R>>
>>`},C):e.ref({Type:"AcroForm",SigFlags:3,Fields:[...m,i]}),{signature:f,form:e._root.data.AcroForm=T,widget:i}};export default pdfkitAddPlaceholder;
>>`},C):e.ref({Type:"AcroForm",SigFlags:3,Fields:[...m,i]}),{signature:p,form:e._root.data.AcroForm=T,widget:i}};export default pdfkitAddPlaceholder;
@@ -0,0 +1,204 @@
export default function reportJson(id, userId) {
const currentUserId = userId;
switch (id) {
// draft documents report
case 'ByHuevtCFY':
return {
reportName: 'Draft Documents',
params: {
Type: null,
$or: [
{ Signers: null, SignedUrl: null },
{ Signers: { $exists: true }, Placeholders: null },
],
CreatedBy: {
__type: 'Pointer',
className: '_User',
objectId: currentUserId,
},
},
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
};
// Need your sign report
case '4Hhwbp482K':
return {
reportName: 'Need your sign',
params: {
Type: { $ne: 'Folder' },
IsCompleted: { $ne: true },
IsDeclined: { $ne: true },
ExpiryDate: {
$gt: { __type: 'Date', iso: new Date().toISOString() },
},
Placeholders: { $ne: null },
},
keys: [
'Name',
'Note',
'Folder.Name',
'URL',
'ExtUserPtr.Name',
'Signers.Name',
'Signers.UserId',
'AuditTrail',
],
};
// In progess report
case '1MwEuxLEkF':
return {
reportName: 'In-progress documents',
params: {
Type: { $ne: 'Folder' },
Signers: { $ne: null },
Placeholders: { $ne: null },
IsCompleted: { $ne: true },
IsDeclined: { $ne: true },
CreatedBy: {
__type: 'Pointer',
className: '_User',
objectId: currentUserId,
},
ExpiryDate: {
$gt: { __type: 'Date', iso: new Date().toISOString() },
},
},
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
};
// completed documents report
case 'kQUoW4hUXz':
return {
reportName: 'Completed Documents',
params: {
Type: null,
IsCompleted: true,
CreatedBy: {
__type: 'Pointer',
className: '_User',
objectId: currentUserId,
},
IsDeclined: { $ne: true },
},
keys: [
'Name',
'Note',
'Folder.Name',
'URL',
'ExtUserPtr.Name',
'Signers.Name',
'TimeToCompleteDays',
],
};
// declined documents report
case 'UPr2Fm5WY3':
return {
reportName: 'Declined Documents',
params: {
Type: null,
IsDeclined: true,
CreatedBy: {
__type: 'Pointer',
className: '_User',
objectId: currentUserId,
},
},
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
};
// Expired Documents report
case 'zNqBHXHsYH':
return {
reportName: 'Expired Documents',
params: {
IsCompleted: { $ne: true },
IsDeclined: { $ne: true },
Type: { $ne: 'Folder' },
$and: [
{
$or: [
{ Signers: { $ne: null }, SignedUrl: { $ne: null } },
{ Placeholders: { $ne: null } },
],
},
{
ExpiryDate: {
$lt: { __type: 'Date', iso: new Date().toISOString() },
},
},
],
CreatedBy: {
__type: 'Pointer',
className: '_User',
objectId: currentUserId,
},
},
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
};
// Recently sent for signatures report show on dashboard
case 'd9k3UfYHBc':
return {
reportName: 'Recently sent for signatures',
params: {
Type: { $ne: 'Folder' },
Signers: { $ne: null },
Placeholders: { $ne: null },
IsCompleted: { $ne: true },
IsDeclined: { $ne: true },
CreatedBy: {
__type: 'Pointer',
className: '_User',
objectId: currentUserId,
},
ExpiryDate: {
$gt: { __type: 'Date', iso: new Date().toISOString() },
},
},
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
};
// Recent signature requests report show on dashboard
case '5Go51Q7T8r':
return {
reportName: 'Recent signature requests',
params: {
Type: { $ne: 'Folder' },
IsCompleted: { $ne: true },
IsDeclined: { $ne: true },
ExpiryDate: {
$gt: { __type: 'Date', iso: new Date().toISOString() },
},
Placeholders: { $ne: null },
},
keys: [
'Name',
'Note',
'Folder.Name',
'URL',
'ExtUserPtr.Name',
'Signers.Name',
'Signers.UserId',
'AuditTrail',
],
};
// Drafts report show on dashboard
case 'kC5mfynCi4':
return {
reportName: 'Drafts',
params: {
Type: null,
$or: [
{ Signers: null, SignedUrl: null },
{ Signers: { $exists: true }, Placeholders: null },
],
CreatedBy: {
__type: 'Pointer',
className: '_User',
objectId: currentUserId,
},
},
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
};
default:
return null;
}
}
@@ -1,14 +1,30 @@
import fs from 'node:fs';
import https from 'https';
import formData from 'form-data';
import Mailgun from 'mailgun.js';
import https from 'https';
import { createTransport } from 'nodemailer';
const mailgun = new Mailgun(formData);
const mailgunClient = mailgun.client({
username: 'api',
key: process.env.MAILGUN_API_KEY,
});
const mailgunDomain = process.env.MAILGUN_DOMAIN;
let transporterSMTP;
let mailgunClient;
let mailgunDomain;
if (process.env.SMTP_ENABLE) {
transporterSMTP = createTransport({
host: process.env.SMTP_HOST,
port: process.env.SMTP_PORT || 465,
secure: process.env.SMTP_SECURE || true,
auth: {
user: process.env.SMTP_USER_EMAIL,
pass: process.env.SMTP_PASS,
},
});
} else {
const mailgun = new Mailgun(formData);
mailgunClient = mailgun.client({
username: 'api',
key: process.env.MAILGUN_API_KEY,
});
mailgunDomain = process.env.MAILGUN_DOMAIN;
}
async function sendmail(req) {
try {
@@ -38,22 +54,67 @@ async function sendmail(req) {
const pdfName = req.params.pdfName && `${req.params.pdfName}.pdf`;
const file = {
filename: pdfName || 'exported.pdf',
data: PdfBuffer, //fs.readFileSync('./exports/exported_file_1223.pdf'),
content: process.env.SMTP_ENABLE ? PdfBuffer : undefined, //fs.readFileSync('./exports/exported_file_1223.pdf'),
data: process.env.SMTP_ENABLE ? undefined : PdfBuffer,
};
// const html = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body style='text-align: center;'> <p style='font-weight: bolder; font-size: large;'>Hello!</p> <p>This is a html checking mail</p><p><button style='background-color: lightskyblue; cursor: pointer; border-radius: 5px; padding: 10px; border-style: solid; border-width: 2px; text-decoration: none; font-weight: bolder; color:blue'>Verify email</button></p></body></html>"
const from = req.params.from || '';
const mailsender = process.env.SMTP_ENABLE
? process.env.SMTP_USER_EMAIL
: process.env.MAILGUN_SENDER;
const messageParams = {
from: from + ' <' + process.env.MAILGUN_SENDER + '>',
from: from + ' <' + mailsender + '>',
to: req.params.recipient,
subject: req.params.subject,
text: req.params.text || 'mail',
html: req.params.html || '',
attachment: file,
attachments: process.env.SMTP_ENABLE ? [file] : undefined,
attachment: process.env.SMTP_ENABLE ? undefined : file,
};
if (transporterSMTP) {
const res = await transporterSMTP.sendMail(messageParams);
console.log('Res ', res);
if (!res.err) {
return {
status: 'success',
};
}
} else {
const res = await mailgunClient.messages.create(mailgunDomain, messageParams);
console.log('Res ', res);
if (res.status === 200) {
return {
status: 'success',
};
}
}
}
} else {
const from = req.params.from || '';
const mailsender = process.env.SMTP_ENABLE
? process.env.SMTP_USER_EMAIL
: process.env.MAILGUN_SENDER;
const messageParams = {
from: from + ' <' + mailsender + '>',
to: req.params.recipient,
subject: req.params.subject,
text: req.params.text || 'mail',
html: req.params.html || '',
};
if (transporterSMTP) {
const res = await transporterSMTP.sendMail(messageParams);
console.log('Res ', res);
if (!res.err) {
return {
status: 'success',
};
}
} else {
const res = await mailgunClient.messages.create(mailgunDomain, messageParams);
console.log('Res ', res);
if (res.status === 200) {
@@ -62,23 +123,6 @@ async function sendmail(req) {
};
}
}
} else {
const from = req.params.from || '';
const messageParams = {
from: from + ' <' + process.env.MAILGUN_SENDER + '>',
to: req.params.recipient,
subject: req.params.subject,
text: req.params.text || 'mail',
html: req.params.html || '',
};
const res = await mailgunClient.messages.create(mailgunDomain, messageParams);
console.log('Res ', res);
if (res.status === 200) {
return {
status: 'success',
};
}
}
} catch (err) {
console.log('err ', err);
@@ -0,0 +1,47 @@
/**
*
* @param {Parse} Parse
*/
exports.up = async Parse => {
// TODO: set className here
const className = 'contracts_Users';
const schema = new Parse.Schema(className);
// schema.addString('Name');
// schema.addString('Phone');
// schema.addString('JobTitle');
// schema.addString('Email');
// schema.addString('Company');
// schema.addString('UserRole');
// schema.addObject('Plan');
// schema.addString('Customer_id');
// schema.addString('Subscription_id');
// schema.addString('Next_billing_date');
// schema.addBoolean('IsContactEntry');
// schema.addBoolean('ShareWithTeam');
// schema.addPointer('TenantId', 'partners_Tenant');
// schema.addPointer('UserId', '_User');
// schema.addPointer('CreatedBy', '_User');
schema.setCLP({
get: {},
find: {},
count: {},
create: { '*': true },
update: { '*': true },
delete: {},
addField: {},
});
return schema.update();
};
/**
*
* @param {Parse} Parse
*/
exports.down = async Parse => {
// TODO: set className here
const className = 'contracts_Users';
const schema = new Parse.Schema(className);
return schema.purge().then(() => schema.delete());
};
@@ -10,7 +10,7 @@
<br />
<p><a href="{{{link}}}" style="background-color: lightskyblue; cursor: pointer; border-radius: 5px; padding: 10px; border-style: solid; border-width: 2px; text-decoration: none; font-weight: bolder; color:blue">Verify email</a></p>
<br />
<p>ExampleApp</p>
<p><a href="https://www.opensignlabs.com">OpenSign™</a></p>
</body>
</html>
</html>
+64 -31
View File
@@ -17,10 +17,11 @@ import S3Adapter from 'parse-server-s3-adapter';
import FSFilesAdapter from 'parse-server-fs-adapter';
import AWS from 'aws-sdk';
import { app as customRoute } from './cloud/customRoute/customApp.js';
import { exec } from 'child_process';
const spacesEndpoint = new AWS.Endpoint(process.env.DO_ENDPOINT);
// console.log("configuration ", configuration);
if (process.env.USE_LOCAL !== "TRUE") {
if (process.env.USE_LOCAL !== 'TRUE') {
const s3Options = {
bucket: process.env.DO_SPACE, // globalConfig.S3FilesAdapter.bucket,
baseUrl: process.env.DO_BASEURL,
@@ -36,18 +37,31 @@ if (process.env.USE_LOCAL !== "TRUE") {
var fsAdapter = new S3Adapter(s3Options);
} else {
var fsAdapter = new FSFilesAdapter({
"filesSubDirectory": "files" // optional, defaults to ./files
filesSubDirectory: 'files', // optional, defaults to ./files
});
}
let transporterMail;
let mailgunClient;
let mailgunDomain;
if (process.env.MAILGUN_API_KEY) {
if (process.env.SMTP_ENABLE) {
transporterMail = createTransport({
host: process.env.SMTP_HOST,
port: process.env.SMTP_PORT || 465,
secure: process.env.SMTP_SECURE || true,
auth: {
user: process.env.SMTP_USER_EMAIL,
pass: process.env.SMTP_PASS,
},
});
} else if (process.env.MAILGUN_API_KEY) {
const mailgun = new Mailgun(formData);
mailgunClient = mailgun.client({
username: 'api',
key: process.env.MAILGUN_API_KEY,
});
mailgunDomain = process.env.MAILGUN_DOMAIN;
}
@@ -59,41 +73,46 @@ export const config = {
masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it secret!
masterKeyIps: ['0.0.0.0/0', '::1'], // '::1'
serverURL: process.env.SERVER_URL || 'http://localhost:8080/app', // Don't forget to change to https if needed
// verifyUserEmails: true,
verifyUserEmails: true,
publicServerURL: process.env.SERVER_URL || 'http://localhost:8080/app',
// Your apps name. This will appear in the subject and body of the emails that are sent.
appName: 'Open Sign',
allowClientClassCreation: false,
emailAdapter: process.env.MAILGUN_API_KEY
? {
module: 'parse-server-api-mail-adapter',
options: {
// The email address from which emails are sent.
sender: process.env.MAILGUN_SENDER,
// The email templates.
templates: {
// The template used by Parse Server to send an email for password
// reset; this is a reserved template name.
passwordResetEmail: {
subjectPath: './files/password_reset_email_subject.txt',
textPath: './files/password_reset_email.txt',
htmlPath: './files/password_reset_email.html',
emailAdapter:
process.env.SMTP_ENABLE || process.env.MAILGUN_API_KEY
? {
module: 'parse-server-api-mail-adapter',
options: {
// The email address from which emails are sent.
sender: process.env.SMTP_ENABLE
? process.env.SMTP_USER_EMAIL
: process.env.MAILGUN_SENDER,
// The email templates.
templates: {
// The template used by Parse Server to send an email for password
// reset; this is a reserved template name.
passwordResetEmail: {
subjectPath: './files/password_reset_email_subject.txt',
textPath: './files/password_reset_email.txt',
htmlPath: './files/password_reset_email.html',
},
// The template used by Parse Server to send an email for email
// address verification; this is a reserved template name.
verificationEmail: {
subjectPath: './files/verification_email_subject.txt',
textPath: './files/verification_email.txt',
htmlPath: './files/verification_email.html',
},
},
// The template used by Parse Server to send an email for email
// address verification; this is a reserved template name.
verificationEmail: {
subjectPath: './files/verification_email_subject.txt',
textPath: './files/verification_email.txt',
htmlPath: './files/verification_email.html',
apiCallback: async ({ payload, locale }) => {
if (mailgunClient) {
const mailgunPayload = ApiPayloadConverter.mailgun(payload);
await mailgunClient.messages.create(mailgunDomain, mailgunPayload);
} else if (transporterMail) await transporterMail.sendMail(payload);
},
},
apiCallback: async ({ payload, locale }) => {
const mailgunPayload = ApiPayloadConverter.mailgun(payload);
await mailgunClient.messages.create(mailgunDomain, mailgunPayload);
},
},
}
: null,
}
: null,
filesAdapter: fsAdapter,
auth: {
google: {
@@ -164,6 +183,20 @@ if (!process.env.TESTING) {
httpServer.headersTimeout = 100000; // in milliseconds
httpServer.listen(port, function () {
console.log('parse-server-example running on port ' + port + '.');
const migrate = `APPLICATION_ID=${process.env.APP_ID} SERVER_URL=http://localhost:8080/app 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}`);
});
});
// This will enable the Live Query real-time server
await ParseServer.createLiveQueryServer(httpServer);
+334 -11
View File
@@ -18,16 +18,19 @@
"express-sse": "^0.5.3",
"form-data": "^4.0.0",
"jsonschema": "^1.4.1",
"mailgun.js": "^9.0.1",
"mailgun.js": "^9.3.0",
"mongoose": "^7.2.1",
"multer": "^1.4.5-lts.1",
"multer-s3": "^2.10.0",
"node-forge": "^1.3.1",
"node-signpdf": "^1.5.1",
"nodemailer": "^6.9.7",
"openai": "^4.8.0",
"parse": "4.1.0",
"parse-dbtool": "^1.2.0",
"parse-server": "6.3.1",
"parse-server-api-mail-adapter": "^3.0.0",
"parse-server-fs-adapter": "1.0.1",
"parse-server-s3-adapter": "^1.2.0",
"pdf-lib": "^1.16.0",
"pdfkit": "^0.13.0",
@@ -2145,7 +2148,6 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"dependencies": {
"fill-range": "^7.0.1"
},
@@ -2794,6 +2796,37 @@
"node": ">=0.10"
}
},
"node_modules/date-fns": {
"version": "2.30.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
"integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
"dependencies": {
"@babel/runtime": "^7.21.0"
},
"engines": {
"node": ">=0.11"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/date-fns"
}
},
"node_modules/date-fns/node_modules/@babel/runtime": {
"version": "7.23.2",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz",
"integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/date-fns/node_modules/regenerator-runtime": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
"integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
},
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -3900,6 +3933,32 @@
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"node_modules/fast-glob": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
"integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
"glob-parent": "^5.1.2",
"merge2": "^1.3.0",
"micromatch": "^4.0.4"
},
"engines": {
"node": ">=8.6.0"
}
},
"node_modules/fast-glob/node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dependencies": {
"is-glob": "^4.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -3999,7 +4058,6 @@
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"
},
@@ -4335,7 +4393,6 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true,
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
@@ -5091,7 +5148,6 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"engines": {
"node": ">=0.12.0"
}
@@ -6016,9 +6072,9 @@
}
},
"node_modules/mailgun.js": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-9.0.1.tgz",
"integrity": "sha512-bVZ1zGh5UfQcChqIwIAil99hzoTeB3aHqAUbqmIBLMLcKfx+FF2qvhbc00WtwrFhe5dBQqQw6zPj0QBlqV4nXg==",
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-9.3.0.tgz",
"integrity": "sha512-iRqCglCdi+Q5anFpeRKHiytT/i34E14p/WtTE57VSeq5bATK+zQ8UnpFgPRaqGGTJqyGjqcO9m5YDRRB4/qirw==",
"dependencies": {
"axios": "^1.3.3",
"base-64": "^1.0.0",
@@ -6087,6 +6143,14 @@
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
},
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
"engines": {
"node": ">= 8"
}
},
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@@ -6095,6 +6159,18 @@
"node": ">= 0.6"
}
},
"node_modules/micromatch": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
"dependencies": {
"braces": "^3.0.2",
"picomatch": "^2.3.1"
},
"engines": {
"node": ">=8.6"
}
},
"node_modules/mime": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
@@ -6799,6 +6875,14 @@
"node-forge": "^1.2.1"
}
},
"node_modules/nodemailer": {
"version": "6.9.7",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.7.tgz",
"integrity": "sha512-rUtR77ksqex/eZRLmQ21LKVH5nAAsVicAtAYudK7JgwenEDZ0UIQ1adUGqErz7sMkWYxWTTU1aeP2Jga6WQyJw==",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/nodemon": {
"version": "2.0.22",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
@@ -7328,6 +7412,234 @@
"crypto-js": "4.1.1"
}
},
"node_modules/parse-dbtool": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/parse-dbtool/-/parse-dbtool-1.2.0.tgz",
"integrity": "sha512-APRMPdQ2jyJ7SBouPYZsCD4BjB0zIrSEgALgeYZsVSDrrtoqXhUHJHi42tF/0ocTA/nolteUMzlHT+msrqPvjQ==",
"dependencies": {
"chalk": "^4.1.1",
"date-fns": "^2.21.3",
"dotenv": "^10.0.0",
"fast-glob": "^3.2.5",
"parse": "^3.2.0",
"ts-dedent": "^2.1.1",
"yargs": "^17.0.1"
},
"bin": {
"parse-dbtool": "src/parse-dbtool.js"
}
},
"node_modules/parse-dbtool/node_modules/@babel/runtime": {
"version": "7.18.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.0.tgz",
"integrity": "sha512-YMQvx/6nKEaucl0MY56mwIG483xk8SDNdlUwb2Ts6FUpr7fm85DxEmsY18LXBNhcTz6tO6JwZV8w1W06v8UKeg==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/parse-dbtool/node_modules/@babel/runtime-corejs3": {
"version": "7.17.8",
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.8.tgz",
"integrity": "sha512-ZbYSUvoSF6dXZmMl/CYTMOvzIFnbGfv4W3SEHYgMvNsFTeLaF2gkGAF4K2ddmtSK4Emej+0aYcnSC6N5dPCXUQ==",
"dependencies": {
"core-js-pure": "^3.20.2",
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/parse-dbtool/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/parse-dbtool/node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/parse-dbtool/node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/parse-dbtool/node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/parse-dbtool/node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/parse-dbtool/node_modules/dotenv": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==",
"engines": {
"node": ">=10"
}
},
"node_modules/parse-dbtool/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"engines": {
"node": ">=8"
}
},
"node_modules/parse-dbtool/node_modules/idb-keyval": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.0.3.tgz",
"integrity": "sha512-yh8V7CnE6EQMu9YDwQXhRxwZh4nv+8xm/HV4ZqK4IiYFJBWYGjJuykADJbSP+F/GDXUBwCSSNn/14IpGL81TuA==",
"dependencies": {
"safari-14-idb-fix": "^3.0.0"
}
},
"node_modules/parse-dbtool/node_modules/parse": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/parse/-/parse-3.5.1.tgz",
"integrity": "sha512-uxkLVNfbqgZ/pStg/jIQGh09tOUkPZorzDIqz9vSFjZ3iIZzgvNk6VBbjXjcMWsR8LyFPOR1ROR6/y9Dedn3/w==",
"dependencies": {
"@babel/runtime": "7.18.0",
"@babel/runtime-corejs3": "7.17.8",
"idb-keyval": "6.0.3",
"react-native-crypto-js": "1.0.0",
"uuid": "3.4.0",
"ws": "8.6.0",
"xmlhttprequest": "1.8.0"
},
"optionalDependencies": {
"crypto-js": "4.1.1"
}
},
"node_modules/parse-dbtool/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/parse-dbtool/node_modules/uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
"deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
"bin": {
"uuid": "bin/uuid"
}
},
"node_modules/parse-dbtool/node_modules/wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/parse-dbtool/node_modules/ws": {
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz",
"integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/parse-dbtool/node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"engines": {
"node": ">=10"
}
},
"node_modules/parse-dbtool/node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dependencies": {
"cliui": "^8.0.1",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.3",
"y18n": "^5.0.5",
"yargs-parser": "^21.1.1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/parse-dbtool/node_modules/yargs-parser": {
"version": "21.1.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"engines": {
"node": ">=12"
}
},
"node_modules/parse-server": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/parse-server/-/parse-server-6.3.1.tgz",
@@ -7403,6 +7715,12 @@
"node": ">=12"
}
},
"node_modules/parse-server-fs-adapter": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parse-server-fs-adapter/-/parse-server-fs-adapter-1.0.1.tgz",
"integrity": "sha512-5IRKAT2QkzHrYrBESY4E8jsV1sl+XVBTKGyUvBPgBR2QzsTTqiyU/lFZD8PAJavA+TH1BLyLTUMZbhZhswNVbQ==",
"deprecated": "use @parse/fs-files-adapter"
},
"node_modules/parse-server-s3-adapter": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/parse-server-s3-adapter/-/parse-server-s3-adapter-1.2.0.tgz",
@@ -7881,7 +8199,6 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"engines": {
"node": ">=8.6"
},
@@ -8455,7 +8772,6 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -9221,7 +9537,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"dependencies": {
"is-number": "^7.0.0"
},
@@ -9283,6 +9598,14 @@
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
},
"node_modules/ts-dedent": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz",
"integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==",
"engines": {
"node": ">=6.10"
}
},
"node_modules/tslib": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz",
+4 -2
View File
@@ -27,18 +27,20 @@
"express-sse": "^0.5.3",
"form-data": "^4.0.0",
"jsonschema": "^1.4.1",
"mailgun.js": "^9.0.1",
"mailgun.js": "^9.3.0",
"mongoose": "^7.2.1",
"multer": "^1.4.5-lts.1",
"multer-s3": "^2.10.0",
"node-forge": "^1.3.1",
"node-signpdf": "^1.5.1",
"nodemailer": "^6.9.7",
"openai": "^4.8.0",
"parse": "4.1.0",
"parse-dbtool": "^1.2.0",
"parse-server": "6.3.1",
"parse-server-api-mail-adapter": "^3.0.0",
"parse-server-s3-adapter": "^1.2.0",
"parse-server-fs-adapter": "1.0.1",
"parse-server-s3-adapter": "^1.2.0",
"pdf-lib": "^1.16.0",
"pdfkit": "^0.13.0",
"razorpay": "^2.8.6",
+37
View File
@@ -0,0 +1,37 @@
// 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}`);
// });
Binary file not shown.
@@ -40,7 +40,7 @@
"id": "c1935cc0-28d4-3d73-b72a-8c1e3d18a17f",
"queryType": "",
"class": "contracts_Document",
"query": "where={\"CreatedBy\":{\"__type\":\"Pointer\",\"className\":\"_User\",\"objectId\":\"#UserId.objectId#\"},\"IsCompleted\":{\"$ne\":true},\"IsDeclined\":{\"$ne\":true},\"Type\":{\"$ne\":\"Folder\"},\"Placeholders\":{\"$ne\":null},\"ExpiryDate\":{\"#*gt\":{\"__type\":\"#Date#\",\"iso\":\"#today#\"}}}&count=1",
"query": "where={\"IsDeclined\":{\"$ne\":true},\"IsCompleted\":{\"$ne\":true},\"Type\":{\"$ne\":\"Folder\"},\"Placeholders\":{\"$ne\":null},\"ExpiryDate\":{\"#*gt\":{\"__type\":\"#Date#\",\"iso\":\"#today#\"}}}&include=Signers,AuditTrail.UserPtr",
"key": "count",
"Redirect_type": "Report",
"Redirect_id": "1MwEuxLEkF",
+20
View File
@@ -36,6 +36,7 @@
"react-scrollbars-custom": "^4.1.1",
"react-signature-canvas": "^1.0.6",
"reactour": "^1.19.1",
"select-dom": "^9.0.0",
"web-vitals": "^2.1.4"
}
},
@@ -18702,6 +18703,20 @@
"resolved": "https://registry.npmjs.org/scrollparent/-/scrollparent-2.0.1.tgz",
"integrity": "sha512-HSdN78VMvFCSGCkh0oYX/tY4R3P1DW61f8+TeZZ4j2VLgfwvw0bpRSOv4PCVKisktIwbzHCfZsx+rLbbDBqIBA=="
},
"node_modules/select-dom": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/select-dom/-/select-dom-9.0.0.tgz",
"integrity": "sha512-AD1NfASSwJQc1Sy713R1vT9CMmUSUo2tg0j1FtkRGIxllTphDrkuH2pYYvhRlGaoq3pS6tcKkKS/diEZLy+7BQ==",
"dependencies": {
"typed-query-selector": "^2.11.0"
},
"engines": {
"node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/fregante"
}
},
"node_modules/select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@@ -20203,6 +20218,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/typed-query-selector": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.11.0.tgz",
"integrity": "sha512-qBs4sfmnLlPOyo2oSdvHbIFHe2CPgU54/1UGfSNceb7LARpIEVxUaeRX0Doje6oKpuySS2stqy90R3YrynR8Kg=="
},
"node_modules/typedarray-to-buffer": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
@@ -32,6 +32,7 @@
"react-scrollbars-custom": "^4.1.1",
"react-signature-canvas": "^1.0.6",
"reactour": "^1.19.1",
"select-dom": "^9.0.0",
"web-vitals": "^2.1.4"
},
"scripts": {
@@ -1,7 +1,15 @@
import React, { useEffect, useState } from "react";
import "./certificate.css";
import opensignLogo from "../../assests/open-sign-logo.png";
import { Page, Text, View, Document, StyleSheet } from "@react-pdf/renderer";
import {
Page,
Text,
View,
Document,
StyleSheet,
Image
} from "@react-pdf/renderer";
function Certificate({ pdfData }) {
const [isMultiSigners, setIsMultiSigners] = useState();
@@ -49,70 +57,34 @@ function Certificate({ pdfData }) {
fontSize: "11px",
marginBottom: "10px",
color: "gray"
},
image: {
width: "71px",
height: "17px"
}
});
const generatedDate = () => {
const newDate = new Date();
const localExpireDate = newDate.toLocaleDateString("en-US", {
day: "numeric",
month: "long",
year: "numeric"
});
var currentOffset = newDate.getTimezoneOffset();
var ISTOffset = 330; // IST offset UTC +5:30
var ISTTime = new Date(
newDate.getTime() + (ISTOffset + currentOffset) * 60000
);
// ISTTime now represents the time in IST coordinates
var hoursIST = ISTTime.getHours();
var minutesIST = ISTTime.getMinutes();
const utcTime = newDate.toUTCString();
return (
<Text
style={{
textAlign: "right",
color: "gray",
fontSize: "10px",
marginBottom: "30px"
fontSize: "10px"
}}
>
Generated On {localExpireDate} {hoursIST}:{minutesIST} IST
Generated On {utcTime}
</Text>
);
};
const changeCompletedDate = () => {
const completedOn = pdfData[0].updatedAt;
const newDate = new Date(completedOn);
const localExpireDate = newDate.toLocaleDateString("en-US", {
day: "numeric",
month: "long",
year: "numeric"
});
const utcTime = newDate.toUTCString();
var currentOffset = newDate.getTimezoneOffset();
var ISTOffset = 330; // IST offset UTC +5:30
var ISTTime = new Date(
newDate.getTime() + (ISTOffset + currentOffset) * 60000
);
// ISTTime now represents the time in IST coordinates
var hoursIST = ISTTime.getHours();
var minutesIST = ISTTime.getMinutes();
return (
<Text style={styles.textStyle2}>
{localExpireDate} {hoursIST}:{minutesIST} IST
</Text>
);
return <Text style={styles.textStyle2}>{utcTime}</Text>;
};
const signerName = (data) => {
@@ -143,7 +115,19 @@ function Certificate({ pdfData }) {
{/** Page defines a single page of content. */}
<Page size="A4" style={styles.page}>
<View style={styles.section1}>
{generatedDate()}
<View
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
marginBottom: "30px"
}}
>
<Image src={opensignLogo} style={styles.image} />
{generatedDate()}
</View>
<View style={{ justifyContent: "center" }}>
<Text
style={{
@@ -182,7 +166,9 @@ function Certificate({ pdfData }) {
</Text>
<Text style={styles.textStyle}>
Organization : &nbsp;
<Text style={styles.textStyle2}>__</Text>
<Text style={styles.textStyle2}>
{pdfData[0].ExtUserPtr.Company}
</Text>
</Text>
<Text style={styles.textStyle}>
Completed on : &nbsp;{changeCompletedDate()}
@@ -260,6 +246,12 @@ function Certificate({ pdfData }) {
{pdfData[0].ExtUserPtr.Name}
</Text>
</Text>
<Text style={styles.textStyle}>
Email : &nbsp;
<Text style={styles.textStyle2}>
{pdfData[0].ExtUserPtr.Email}
</Text>
</Text>
<Text style={styles.textStyle}>
Accessed from : &nbsp;
<Text style={styles.textStyle2}>
@@ -1,61 +1,47 @@
import React, { useEffect, useState } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import Loader from "./component/loader";
import { getHostUrl } from "../utils/Utils";
import { contractDocument, getHostUrl } from "../utils/Utils";
function DraftDocument() {
const navigate = useNavigate();
const [pdfDetails, setPdfDetails] = useState([]);
const [isLoading, setIsLoading] = useState({
isLoad: true,
message: "This might take some time",
message: "This might take some time"
});
const rowLevel =
localStorage.getItem("rowlevel") &&
JSON.parse(localStorage.getItem("rowlevel"));
const signObjId =
const docId =
rowLevel && rowLevel?.id
? rowLevel.id
: rowLevel?.objectId && rowLevel.objectId;
useEffect(() => {
if (signObjId) {
if (docId) {
getDocumentDetails();
}
}, []);
//get document details
const getDocumentDetails = async () => {
await axios
.get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
"_appName"
)}_Document?where={"objectId":"${signObjId}"}&include=ExtUserPtr,Signers`,
{
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) {
setPdfDetails(res);
const loadObj = {
isLoad: false,
};
setIsLoading(loadObj);
} else {
alert("No data found!");
}
})
.catch((err) => {
console.log("axois err ", err);
});
//getting document details
const documentData = await contractDocument(docId);
if (documentData && documentData.length > 0) {
setPdfDetails(documentData);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
} else if (
documentData === "Error: Something went wrong!" ||
(documentData.result && documentData.result.error)
) {
alert("Error: Something went wrong!");
} else {
alert("No data found!");
}
};
//check document type and render on signyour self and placeholder route
@@ -63,24 +49,25 @@ function DraftDocument() {
const data = pdfDetails[0];
const checkSignerExist =
pdfDetails[0] && pdfDetails[0].Signers && pdfDetails[0].Signers;
const isPlaceholder =
const isPlaceholder =
pdfDetails[0].Placeholders && pdfDetails[0].Placeholders;
const isDecline = data.IsDeclined && data.IsDeclined;
const signUrl = data.SignedUrl && data.SignedUrl;
const expireDate = pdfDetails[0] && pdfDetails[0].ExpiryDate.iso && pdfDetails[0].ExpiryDate.iso;
const expireDate =
pdfDetails[0] &&
pdfDetails[0].ExpiryDate.iso &&
pdfDetails[0].ExpiryDate.iso;
const expireUpdateDate = new Date(expireDate).getTime();
const currDate = new Date().getTime();
const hostUrl = getHostUrl();
//checking document is completed and signer exist then navigate to pdfRequestFiles file
if (data.IsCompleted && checkSignerExist) {
navigate(`${hostUrl}pdfRequestFiles`);
navigate(`${hostUrl}pdfRequestFiles`);
}
//checking document is completed and signer does not exist then navigate to recipientSignPdf file
else if (data.IsCompleted && !checkSignerExist) {
navigate(
`${hostUrl}signaturePdf`
);
navigate(`${hostUrl}signaturePdf`);
}
//checking document is declined by someone then navigate to pdfRequestFiles file
else if (isDecline) {
@@ -6,6 +6,7 @@ import PdfFileComponent from "./FolderDrive/legaDriveComponent";
import Modal from "react-bootstrap/Modal";
import ModalHeader from "react-bootstrap/esm/ModalHeader";
import { themeColor, iconColor } from "../../utils/ThemeColor/backColor";
import { getDrive } from "../../utils/Utils";
function PdfFile() {
const scrollRef = useRef(null);
@@ -15,29 +16,18 @@ function PdfFile() {
const [pdfData, setPdfData] = useState([]);
const [isFolder, setIsFolder] = useState(false);
const [newFolderName, setNewFolderName] = useState();
// const [parentFolderName, setParentFolderName] = useState();
// const [parentFolder, setParentFolder] = useState([]);
const [error, setError] = useState();
const [folderLoader, setIsFolderLoader] = useState(false);
const [isShowSort, setIsShowSort] = useState(false);
const [isLoading, setIsLoading] = useState({
isLoad: true,
message: "This might take some time",
message: "This might take some time"
});
const [docId, setDocId] = useState();
const [handleError, setHandleError] = useState();
const [folderName, setFolderName] = useState([]);
const senderUser =
localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
) &&
localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
);
const jsonSender = JSON.parse(senderUser);
useEffect(() => {
if (docId) {
getPdfFolderDocumentList();
@@ -50,104 +40,59 @@ function PdfFile() {
const getPdfDocumentList = async () => {
const load = {
isLoad: true,
message: "This might take some time",
message: "This might take some time"
};
setIsLoading(load);
//?where={"Type":"Folder" }&include=ExtUserPtr,Signers
//?where={"$or":[{"Type":{"$exists":true}},{"Folder":{"$exists":false}}]}&include=ExtUserPtr,Signers
// "CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${jsonSender.objectId}"}
// where={"Folder":{"$exists":false} }&include=ExtUserPtr,Signers`,
await axios
.get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
"_appName"
)}_Document?where={"Folder":{"$exists":false},"$or":[{"CreatedBy":{"$exists":false}},{"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${
jsonSender.objectId
}"}}]}&include=ExtUserPtr,Signers`,
{
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;
// console.log("result", res);
if (res[0] && res.length > 0) {
setPdfData(res);
}
const driveDetails = await getDrive();
const data = [
{
name: "OpenSignDrive™",
objectId: "",
},
];
setFolderName(data);
const loadObj = {
isLoad: false,
};
setIsLoading(loadObj);
})
.catch((err) => {
const loadObj = {
isLoad: false,
};
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
});
if (driveDetails) {
if (driveDetails.length > 0) {
setPdfData(driveDetails);
}
const data = [
{
name: "OpenSignDrive™",
objectId: ""
}
];
setFolderName(data);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
} else if (driveDetails === "Error: Something went wrong!") {
const loadObj = {
isLoad: false
};
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
}
};
//function for get parent folder document list
const getPdfFolderDocumentList = async () => {
const load = {
isLoad: true,
message: "This might take some time",
message: "This might take some time"
};
setIsLoading(load);
//{"$inQuery":{"where":{"objectId":"${docId}"},"className":"${appName}_Document"}}
//"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${jsonSender.objectId}"}
await axios
.get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
"_appName"
)}_Document?where={"Folder":{"__type":"Pointer","className":"${localStorage.getItem(
"_appName"
)}_Document","objectId":"${docId}"},"$or":[{"CreatedBy":{"$exists":false}},{"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${
jsonSender.objectId
}"}}]}&include=ExtUserPtr,Signers,Folder`,
{
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) {
setPdfData(res);
} else {
setPdfData([]);
}
const loadObj = {
isLoad: false,
};
setIsLoading(loadObj);
})
.catch((err) => {
const loadObj = {
isLoad: false,
};
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
});
const driveDetails = await getDrive(docId);
if (driveDetails) {
if (driveDetails.length > 0) {
setPdfData(driveDetails);
} else {
setPdfData([]);
}
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
} else if (driveDetails === "Error: Something went wrong!") {
const loadObj = {
isLoad: false
};
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
}
};
//function for get all pdf document list
@@ -158,7 +103,7 @@ function PdfFile() {
const handleRoute = (data) => {
let loadObj = {
isLoad: true,
message: "This might take some time",
message: "This might take some time"
};
if (data.name === "LegaDrive™") {
setIsLoading(loadObj);
@@ -167,7 +112,7 @@ function PdfFile() {
} else {
setTimeout(() => {
const loadObj = {
isLoad: false,
isLoad: false
};
setIsLoading(loadObj);
}, 1000);
@@ -176,12 +121,11 @@ function PdfFile() {
setIsLoading(loadObj);
setTimeout(() => {
const loadObj = {
isLoad: false,
isLoad: false
};
setIsLoading(loadObj);
}, 1000);
} else {
// console.log("go here1",data.objectId)
const findIndex = folderName.findIndex(
(fold) => fold.objectId === data.objectId
);
@@ -216,13 +160,13 @@ function PdfFile() {
Folder: {
__type: "Pointer",
className: `${localStorage.getItem("_appName")}_Document`,
objectId: isParentId,
},
objectId: isParentId
}
};
} else {
data = {
Name: newFolderName,
Type: "Folder",
Type: "Folder"
};
}
@@ -237,8 +181,8 @@ function PdfFile() {
headers: {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
"X-Parse-Session-Token": localStorage.getItem("accesstoken"),
},
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
}
}
)
@@ -388,7 +332,7 @@ function PdfFile() {
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
alignItems: "center"
}}
>
<img
@@ -406,7 +350,7 @@ function PdfFile() {
style={{
margin: "10px 0px 10px 0px",
fontSize: "15px",
fontWeight: "400",
fontWeight: "400"
}}
>
Name*
@@ -428,7 +372,7 @@ function PdfFile() {
display: "flex",
alignItems: "flex-end",
justifyContent: "flex-end",
alignContent: "flex-end",
alignContent: "flex-end"
}}
>
<button
@@ -437,7 +381,7 @@ function PdfFile() {
borderRadius: "0px",
border: "1.5px solid #e3e2e1",
fontWeight: "600",
color: "black",
color: "black"
}}
className="finishBtn"
onClick={() => setIsFolder(false)}
@@ -448,7 +392,7 @@ function PdfFile() {
<button
onClick={() => handleAddFolder()}
style={{
background: themeColor(),
background: themeColor()
}}
type="button"
className="finishBtn"
@@ -469,7 +413,7 @@ function PdfFile() {
alignItems: "center",
height: "100vh",
width: "100%",
flexDirection: "column",
flexDirection: "column"
}}
>
<img
@@ -488,7 +432,7 @@ function PdfFile() {
justifyContent: "center",
alignItems: "center",
height: "100vh",
width: "100%",
width: "100%"
}}
>
<span style={{ fontSize: "20px", color: "gray" }}>
@@ -502,7 +446,7 @@ function PdfFile() {
onMouseEnter={(e) => handleMouseEnter(e)}
ref={scrollRef}
style={{
width: "100%",
width: "100%"
}}
className="folderPath"
>
@@ -514,7 +458,7 @@ function PdfFile() {
style={{
color: "#a64b4e",
fontWeight: "400",
cursor: "pointer",
cursor: "pointer"
}}
>
{data.name}
@@ -523,7 +467,7 @@ function PdfFile() {
color: "#a64b4e",
fontWeight: "200",
cursor: "pointer",
margin: "0 4px",
margin: "0 4px"
}}
>
&gt;
@@ -545,13 +489,13 @@ function PdfFile() {
style={{
marginRight: "5px",
fontSize: "14px",
color: `${iconColor()}`,
color: `${iconColor()}`
}}
></i>
<span
style={{
fontSize: "15px",
color: `${iconColor()}`,
color: `${iconColor()}`
}}
>
{selectedSort}
@@ -694,7 +638,7 @@ function PdfFile() {
justifyContent: "center",
alignItems: "center",
height: "50vh",
width: "100%",
width: "100%"
}}
>
<span style={{ fontWeight: "bold" }}>No Data Found!</span>
@@ -11,7 +11,13 @@ import { HTML5Backend } from "react-dnd-html5-backend";
import { useParams } from "react-router-dom";
import SignPad from "./component/signPad";
import RenderAllPdfPage from "./component/renderAllPdfPage";
import { getBase64FromIMG, getBase64FromUrl } from "../utils/Utils";
import {
convertPNGtoJPEG,
contractDocument,
getBase64FromIMG,
getBase64FromUrl,
urlValidator
} from "../utils/Utils";
import Loader from "./component/loader";
import HandleError from "./component/HandleError";
import Nodata from "./component/Nodata";
@@ -106,153 +112,135 @@ function PdfRequestFiles() {
//function for get document details for perticular signer with signer'object id
const getDocumentDetails = async () => {
await axios
.get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
"_appName"
)}_Document?where={"objectId":"${documentId}"}&include=ExtUserPtr,Signers,UserPtr`,
{
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;
//getting document details
const documentData = await contractDocument(documentId);
if (documentData && documentData.length > 0) {
const isCompleted =
documentData[0].IsCompleted && documentData[0].IsCompleted;
const expireDate = documentData[0].ExpiryDate.iso;
const declined = documentData[0].IsDeclined && documentData[0].IsDeclined;
const expireUpdateDate = new Date(expireDate).getTime();
const currDate = new Date().getTime();
const getSigners = documentData[0].Signers;
const getCurrentSigner =
getSigners &&
getSigners.filter(
(data) => data.UserId.objectId === jsonSender.objectId
);
if (res[0] && res.length > 0) {
const isCompleted = res[0].IsCompleted && res[0].IsCompleted;
const expireDate = res[0].ExpiryDate.iso;
const declined = res[0].IsDeclined && res[0].IsDeclined;
const expireUpdateDate = new Date(expireDate).getTime();
const currDate = new Date().getTime();
const getSigners = res[0].Signers;
const getCurrentSigner =
getSigners &&
getSigners.filter(
(data) => data.UserId.objectId === jsonSender.objectId
);
const currUserId = getCurrentSigner[0]
? getCurrentSigner[0].objectId
: "";
setSignerObjectId(currUserId);
if (res[0].SignedUrl) {
setPdfUrl(res[0].SignedUrl);
} else {
setPdfUrl(res[0].URL);
}
if (isCompleted) {
setIsSigned(true);
const data = {
isCertificate: true,
isModal: true
};
setAlreadySign(true);
setIsCompleted(data);
} else if (declined) {
const currentDecline = {
currnt: "another",
isDeclined: true
};
setIsDecline(currentDecline);
} else if (currDate > expireUpdateDate) {
setIsExpired(true);
}
if (res.length > 0) {
const checkDocIdExist =
json.results[0].AuditTrail &&
json.results[0].AuditTrail.length > 0 &&
json.results[0].AuditTrail.filter(
(data) => data.Activity === "Signed"
);
const checkAlreadySign =
json.results[0].AuditTrail &&
json.results[0].AuditTrail.length > 0 &&
json.results[0].AuditTrail.filter(
(data) =>
data.UserPtr.objectId === currUserId &&
data.Activity === "Signed"
);
if (
checkAlreadySign &&
checkAlreadySign[0] &&
checkAlreadySign.length > 0
) {
setAlreadySign(true);
}
let signers = [];
let unSignedSigner = [];
//check document is signed or not
if (checkDocIdExist && checkDocIdExist.length > 0) {
setAlreadySign(true);
setIsDocId(true);
const signerRes = res[0].Signers;
//comparison auditTrail user details with signers user details
for (let i = 0; i < signerRes.length; i++) {
const signerId = signerRes[i].objectId;
let isSigned = false;
for (let j = 0; j < checkDocIdExist.length; j++) {
const signedExist =
checkDocIdExist[j] && checkDocIdExist[j].UserPtr.objectId;
//checking signerObjId and auditTrail User objId
// if match then add signed data in signer array and break loop
if (signerId === signedExist) {
signers.push({ ...signerRes[i], ...signerRes[i] });
isSigned = true;
break;
}
// if does not match then add unsigned data in unSignedSigner array
}
if (!isSigned) {
unSignedSigner.push({ ...signerRes[i], ...signerRes[i] });
}
}
setSignedSigners(signers);
setUnSignedSigners(unSignedSigner);
setSignerPos(res[0].Placeholders);
} else {
let unsigned = [];
for (let i = 0; i < res.length; i++) {
unsigned.push(res[i].Signers);
}
setUnSignedSigners(unsigned[0]);
setSignerPos(res[0].Placeholders);
}
setPdfDetails(res);
setIsUiLoading(false);
} else {
alert("No data found!");
}
} else {
setNoData(true);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
setIsUiLoading(false);
}
})
.catch((err) => {
console.log("err", err);
const loadObj = {
isLoad: false
const currUserId = getCurrentSigner[0]
? getCurrentSigner[0].objectId
: "";
setSignerObjectId(currUserId);
if (documentData[0].SignedUrl) {
setPdfUrl(documentData[0].SignedUrl);
} else {
setPdfUrl(documentData[0].URL);
}
if (isCompleted) {
setIsSigned(true);
const data = {
isCertificate: true,
isModal: true
};
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
});
setAlreadySign(true);
setIsCompleted(data);
} else if (declined) {
const currentDecline = {
currnt: "another",
isDeclined: true
};
setIsDecline(currentDecline);
} else if (currDate > expireUpdateDate) {
setIsExpired(true);
}
if (documentData.length > 0) {
const checkDocIdExist =
documentData[0].AuditTrail &&
documentData[0].AuditTrail.length > 0 &&
documentData[0].AuditTrail.filter(
(data) => data.Activity === "Signed"
);
const checkAlreadySign =
documentData[0].AuditTrail &&
documentData[0].AuditTrail.length > 0 &&
documentData[0].AuditTrail.filter(
(data) =>
data.UserPtr.objectId === currUserId && data.Activity === "Signed"
);
if (
checkAlreadySign &&
checkAlreadySign[0] &&
checkAlreadySign.length > 0
) {
setAlreadySign(true);
}
let signers = [];
let unSignedSigner = [];
//check document is signed or not
if (checkDocIdExist && checkDocIdExist.length > 0) {
setIsDocId(true);
const signerRes = documentData[0].Signers;
//comparison auditTrail user details with signers user details
for (let i = 0; i < signerRes.length; i++) {
const signerId = signerRes[i].objectId;
let isSigned = false;
for (let j = 0; j < checkDocIdExist.length; j++) {
const signedExist =
checkDocIdExist[j] && checkDocIdExist[j].UserPtr.objectId;
//checking signerObjId and auditTrail User objId
// if match then add signed data in signer array and break loop
if (signerId === signedExist) {
signers.push({ ...signerRes[i], ...signerRes[i] });
isSigned = true;
break;
}
// if does not match then add unsigned data in unSignedSigner array
}
if (!isSigned) {
unSignedSigner.push({ ...signerRes[i], ...signerRes[i] });
}
}
setSignedSigners(signers);
setUnSignedSigners(unSignedSigner);
setSignerPos(documentData[0].Placeholders);
} else {
let unsigned = [];
for (let i = 0; i < documentData.length; i++) {
unsigned.push(documentData[i].Signers);
}
setUnSignedSigners(unsigned[0]);
setSignerPos(documentData[0].Placeholders);
}
setPdfDetails(documentData);
setIsUiLoading(false);
} else {
alert("No data found!");
}
} else if (
documentData === "Error: Something went wrong!" ||
(documentData.result && documentData.result.error)
) {
const loadObj = {
isLoad: false
};
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
} else {
setNoData(true);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
setIsUiLoading(false);
}
await axios
.get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
@@ -294,7 +282,6 @@ function PdfRequestFiles() {
const checkUser = signerPos.filter(
(data) => data.signerObjId === signerObjectId
);
if (checkUser && checkUser.length > 0) {
let checkSignUrl = [];
const checkSign = checkUser[0].placeHolder.filter(
@@ -361,38 +348,13 @@ function PdfRequestFiles() {
imgUrlList.map(async (data) => {
//cheking signUrl is defau;t signature url of custom url
let ImgUrl = data.SignUrl;
const checkUrl = ImgUrl.includes("https:");
const checkUrl = urlValidator(ImgUrl);
//if default signature url then convert it in base 64
if (checkUrl) {
ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
}
//function for called convert png signatre to jpeg in base 64
const convertPNGtoJPEG = (base64Data) => {
return new Promise((resolve, reject) => {
const canvas = document.createElement("canvas");
const img = new Image();
img.src = base64Data;
img.onload = () => {
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
// Convert to JPEG by using the canvas.toDataURL() method
const jpegBase64Data = canvas.toDataURL("image/jpeg");
resolve(jpegBase64Data);
};
img.onerror = (error) => {
reject(error);
};
});
};
convertPNGtoJPEG(ImgUrl)
.then((jpegBase64Data) => {
const removeBase64Fromjpeg = "data:image/jpeg;base64,";
@@ -448,32 +410,21 @@ function PdfRequestFiles() {
const images = await Promise.all(
imgUrlList.map(async (url) => {
let signUrl = url.SignUrl;
const checkUrl = url.SignUrl.includes("https:");
if (url.ImageType === "image/png") {
//function for convert signature png base64 url to jpeg base64
const newUrl = await convertPNGtoJPEG(signUrl);
signUrl = newUrl;
}
const checkUrl = urlValidator(signUrl);
if (checkUrl) {
signUrl = signUrl + "?get";
}
const res = await fetch(signUrl);
return res.arrayBuffer();
})
);
images.forEach(async (imgData, id) => {
let img;
if (
imgUrlList[id].ImageType &&
imgUrlList[id].ImageType === "image/jpeg"
) {
img = await pdfDoc.embedJpg(imgData);
} else if (
imgUrlList[id].ImageType &&
imgUrlList[id].ImageType === "image/png"
) {
img = await pdfDoc.embedPng(imgData);
} else {
img = await pdfDoc.embedPng(imgData);
}
let img = await pdfDoc.embedJpg(imgData);
const imgHeight = imgUrlList[id].Height
? imgUrlList[id].Height
: 60;
@@ -597,12 +548,12 @@ function PdfRequestFiles() {
if (isMobile) {
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
if (pos.isMobile) {
const y = pos.yPosition * (pos.scale / scale);
const y = pos.yBottom * (pos.scale / scale);
yPosition = pos.isDrag
? y * scale - height
: pos.firstYPos
? y * scale - height + pos.firstYPos
: y * scale - height;
? y * scale - height + pos.firstYPos
: y * scale - height;
return yPosition;
} else {
const y = pos.yBottom / scale;
@@ -610,8 +561,8 @@ function PdfRequestFiles() {
yPosition = pos.isDrag
? y * scale - height
: pos.firstYPos
? y * scale - height + pos.firstYPos
: y * scale - height;
? y * scale - height + pos.firstYPos
: y * scale - height;
return yPosition;
}
} else {
@@ -622,15 +573,15 @@ function PdfRequestFiles() {
yPosition = pos.isDrag
? y - height
: pos.firstYPos
? y - height + pos.firstYPos
: y - height;
? y - height + pos.firstYPos
: y - height;
return yPosition;
} else {
yPosition = pos.isDrag
? pos.yBottom - height
: pos.firstYPos
? pos.yBottom - height + pos.firstYPos
: pos.yBottom - height;
? pos.yBottom - height + pos.firstYPos
: pos.yBottom - height;
return yPosition;
}
}
@@ -1048,7 +999,7 @@ function PdfRequestFiles() {
<Modal.Body>
<p className="pTagBody">
This document has been signed by all Sigers.
This document has been signed by all Signers.
</p>
</Modal.Body>
@@ -15,7 +15,11 @@ import EmailComponent from "./component/emailComponent";
import FieldsComponent from "./component/fieldsComponent";
import Modal from "react-bootstrap/Modal";
import ModalHeader from "react-bootstrap/esm/ModalHeader";
import { getBase64FromIMG } from "../utils/Utils";
import {
convertPNGtoJPEG,
contractDocument,
getBase64FromIMG
} from "../utils/Utils";
import { useParams } from "react-router-dom";
import Tour from "reactour";
import { onSaveImage, onSaveSign } from "../utils/Utils";
@@ -24,7 +28,9 @@ import HandleError from "./component/HandleError";
import Nodata from "./component/Nodata";
import Header from "./component/header";
import RenderPdf from "./component/renderPdf";
import { contractUsers, contactBook } from "../utils/Utils";
import { contractUsers, contactBook, urlValidator } from "../utils/Utils";
import { modalAlign } from "../utils/Utils";
import { $ } from "select-dom";
//For signYourself inProgress section signer can add sign and complete doc sign.
function SignYourSelf() {
const [pdfDetails, setPdfDetails] = useState([]);
@@ -167,61 +173,48 @@ function SignYourSelf() {
//pdf from left and right component
setPdfNewWidth(pdfWidth);
if (documentId) {
getDocumentDetails();
getDocumentDetails(true);
}
}, []);
//function for get document details for perticular signer with signer'object id
const getDocumentDetails = async () => {
await axios
.get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
"_appName"
)}_Document?where={"objectId":"${documentId}"}&include=ExtUserPtr,Signers`,
{
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;
const getDocumentDetails = async (showComplete) => {
//getting document details
const documentData = await contractDocument(documentId);
if (res[0] && res.length > 0) {
setPdfDetails(res);
const isCompleted = res[0].IsCompleted && res[0].IsCompleted;
if (isCompleted) {
const docStatus = {
isCompleted: isCompleted
};
setDocumentStatus(docStatus);
const alreadySign = {
status: true,
mssg: "You have successfully signed the document!"
};
setShowAlreadySignDoc(alreadySign);
setPdfUrl(res[0].SignedUrl);
}
} else {
setNoData(true);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
}
})
.catch((err) => {
const loadObj = {
isLoad: false
if (documentData && documentData.length > 0) {
setPdfDetails(documentData);
const isCompleted =
documentData[0].IsCompleted && documentData[0].IsCompleted;
if (isCompleted && showComplete) {
const docStatus = {
isCompleted: isCompleted
};
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
});
setDocumentStatus(docStatus);
const alreadySign = {
status: true,
mssg: "You have successfully signed the document!"
};
setShowAlreadySignDoc(alreadySign);
setPdfUrl(documentData[0].SignedUrl);
}
} else if (
documentData === "Error: Something went wrong!" ||
(documentData.result && documentData.result.error)
) {
const loadObj = {
isLoad: false
};
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
} else {
setNoData(true);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
}
await axios
.get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
@@ -252,13 +245,10 @@ function SignYourSelf() {
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
});
const contractUsersRes = await contractUsers(jsonSender.objectId);
if (
contractUsersRes !== "Error: Something went wrong!" &&
contractUsersRes &&
contractUsersRes[0]
) {
const contractUsersRes = await contractUsers(jsonSender.email);
if (contractUsersRes[0] && contractUsersRes.length > 0) {
setContractName("_Users");
setSignerUserId(contractUsersRes[0].objectId);
const tourstatuss =
@@ -285,14 +275,12 @@ function SignYourSelf() {
setIsLoading(loadObj);
} else if (contractUsersRes.length === 0) {
const contractContactBook = await contactBook(jsonSender.objectId);
if (contractContactBook && contractContactBook[0]) {
if (contractContactBook && contractContactBook.length > 0) {
setContractName("_Contactbook");
setSignerUserId(contractContactBook[0].objectId);
const tourstatuss =
contractContactBook[0].TourStatus &&
contractContactBook[0].TourStatus;
if (tourstatuss && tourstatuss.length > 0) {
setTourStatus(tourstatuss);
const checkTourRecipients = tourstatuss.filter(
@@ -302,6 +290,8 @@ function SignYourSelf() {
setCheckTourStatus(checkTourRecipients[0].signyourself);
}
}
} else {
setNoData(true);
}
const loadObj = {
isLoad: false
@@ -460,39 +450,13 @@ function SignYourSelf() {
imgUrlList.map(async (data) => {
let ImgUrl = data.SignUrl;
//cheking signUrl is defau;t signature url of custom url
const checkUrl = ImgUrl.includes("https:");
const checkUrl = urlValidator(ImgUrl);
//if default signature url then convert it in base 64
if (checkUrl) {
ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
}
//function for convert signature png base64 url to jpeg base64
const convertPNGtoJPEG = (base64Data) => {
return new Promise((resolve, reject) => {
const canvas = document.createElement("canvas");
const img = new Image();
img.src = base64Data;
img.onload = () => {
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
// Convert to JPEG by using the canvas.toDataURL() method
const jpegBase64Data = canvas.toDataURL("image/jpeg");
resolve(jpegBase64Data);
};
img.onerror = (error) => {
reject(error);
};
});
};
convertPNGtoJPEG(ImgUrl)
.then((jpegBase64Data) => {
const removeBase64Fromjpeg = "data:image/jpeg;base64,";
@@ -540,7 +504,12 @@ function SignYourSelf() {
imgUrlList.map(async (url) => {
let signUrl = url.SignUrl;
const checkUrl = url.SignUrl.includes("https:");
if (url.ImageType === "image/png") {
//function for convert signature png base64 url to jpeg base64
const newUrl = await convertPNGtoJPEG(signUrl);
signUrl = newUrl;
}
const checkUrl = urlValidator(signUrl);
if (checkUrl) {
signUrl = signUrl + "?get";
}
@@ -550,21 +519,7 @@ function SignYourSelf() {
})
);
images.forEach(async (imgData, id) => {
let img;
if (
imgUrlList[id].ImageType &&
imgUrlList[id].ImageType === "image/jpeg"
) {
img = await pdfDoc.embedJpg(imgData);
} else if (
imgUrlList[id].ImageType &&
imgUrlList[id].ImageType === "image/png"
) {
img = await pdfDoc.embedPng(imgData);
} else {
img = await pdfDoc.embedPng(imgData);
}
let img = await pdfDoc.embedJpg(imgData);
const imgHeight = imgUrlList[id].Height
? imgUrlList[id].Height
: 60;
@@ -627,8 +582,8 @@ function SignYourSelf() {
const bottomY = xyPosData.isDrag
? xyPosData.yBottom * scale - height
: xyPosData.firstYPos
? xyPosData.yBottom * scale - height + xyPosData.firstYPos
: xyPosData.yBottom * scale - height;
? xyPosData.yBottom * scale - height + xyPosData.firstYPos
: xyPosData.yBottom * scale - height;
singleSign = {
pdfFile: pdfBase64Url,
@@ -664,15 +619,7 @@ function SignYourSelf() {
// console.log("json ", json);
setPdfUrl(json.result.data);
if (json.result.data) {
const docStatus = {
isCompleted: true
};
setDocumentStatus(docStatus);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
getDocumentDetails(false);
}
})
.catch((err) => {
@@ -1044,7 +991,11 @@ function SignYourSelf() {
>
{/* this modal is used show this document is already sign */}
<Modal show={showAlreadySignDoc.status}>
<Modal
show={showAlreadySignDoc.status}
onShow={() => modalAlign()}
backdropClassName="signature-backdrop"
>
<ModalHeader style={{ background: themeColor() }}>
<span style={{ color: "white" }}> Sign Documents</span>
</ModalHeader>
@@ -28,9 +28,7 @@ function EmailComponent({
setIsLoading(true);
let sendMail;
for (let i = 0; i < emailCount.length; i++) {
try {
const imgPng =
"https://qikinnovation.ams3.digitaloceanspaces.com/logo.png";
// "https://qikinnovation.ams3.digitaloceanspaces.com/mailLogo_2023-08-18T12%3A51%3A31.573Z.png";
@@ -111,16 +109,22 @@ function EmailComponent({
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
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 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');
window.open(blobUrl, "_blank");
} else {
printModule({ printable: pdf, type: "pdf", base64: true });
}
};
//handle download signed pdf
@@ -130,12 +134,11 @@ function EmailComponent({
const sanitizeFileName = (pdfName) => {
// Replace spaces with underscore
return pdfName.replace(/ /g, '_');
}
return pdfName.replace(/ /g, "_");
};
const isAndroid = /Android/i.test(navigator.userAgent);
return (
<div>
{/* isEmail */}
@@ -167,7 +170,7 @@ function EmailComponent({
)}
<ModalHeader style={{ background: themeColor() }}>
<span style={{ color: "white" }}>Email Documents</span>
<span style={{ color: "white" }}>Successfully signed!</span>
<div style={{ display: "flex", flexDirection: "row" }}>
<div></div>
@@ -259,14 +262,20 @@ function EmailComponent({
>
{emailCount.map((data, ind) => {
return (
<div className="emailChip"
style={{display:"flex", flexDirection:"row", alignItems:"center"}}
key={ind}>
<div
className="emailChip"
style={{
display: "flex",
flexDirection: "row",
alignItems: "center"
}}
key={ind}
>
<span
style={{
color: "white",
fontSize: "13px",
marginRight: "20px"
marginTop: "2px"
}}
>
{data}
@@ -278,7 +287,7 @@ function EmailComponent({
src={close}
width={10}
height={10}
style={{ fontWeight: "600" }}
style={{ fontWeight: "600", margin: "0 0 10px 2px" }}
/>
</div>
);
@@ -27,13 +27,13 @@ function Header({
signersdata,
isMailSend,
alertSendEmail,
isSigned,
isCompleted,
isShowHeader,
decline,
currentSigner,
dataTut4,
alreadySign
alreadySign,
isSignYourself
}) {
const isMobile = window.innerWidth < 767;
const navigate = useNavigate();
@@ -61,12 +61,19 @@ function Header({
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
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 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');
window.open(blobUrl, "_blank");
} else {
printModule({ printable: pdf, type: "pdf", base64: true });
}
@@ -75,19 +82,148 @@ function Header({
//handle download signed pdf
const handleDownloadPdf = () => {
const pdfName = pdfDetails[0] && pdfDetails[0].Name;
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
};
const sanitizeFileName = (pdfName) => {
// Replace spaces with underscore
return pdfName.replace(/ /g, '_');
}
return pdfName.replace(/ /g, "_");
};
//certificate generate and download component in mobile view
const CertificateDropDown = () => {
//after generate download certifcate pdf
const handleDownload = (pdfBlob, fileName) => {
if (pdfBlob) {
const url = window.URL.createObjectURL(pdfBlob);
// Create a temporary anchor element
const link = document.createElement("a");
link.href = url;
link.download = fileName;
// Append the anchor to the body
document.body.appendChild(link);
// Programmatically click the anchor to trigger the download
link.click();
// Remove the anchor from the body
document.body.removeChild(link);
// Release the object URL to free up resources
window.URL.revokeObjectURL(url);
}
};
return (
<PDFDownloadLink
onClick={(e) => e.preventDefault()}
style={{ textDecoration: "none", zIndex: "35" }}
document={<Certificate pdfData={pdfDetails} />}
>
{({ blob, url, loading, error }) => (
<>
{loading ? (
<div
style={{
border: "none",
backgroundColor: "#fff"
}}
>
<i
className="fa fa-certificate"
style={{
marginRight: "2px"
}}
aria-hidden="true"
></i>
Certificate
</div>
) : (
<div
style={{
border: "none",
backgroundColor: "#fff"
}}
onClick={() =>
handleDownload(
blob,
`completion certificate-${
pdfDetails[0] && pdfDetails[0].Name
}.pdf`
)
}
>
<i
className="fa fa-certificate"
style={{
marginRight: "2px"
}}
aria-hidden="true"
></i>
Certificate
</div>
)}
</>
)}
</PDFDownloadLink>
);
};
const CertificateComponent = () => {
return (
<PDFDownloadLink
style={{ textDecoration: "none" }}
document={<Certificate pdfData={pdfDetails} />}
fileName={`completion certificate-${
pdfDetails[0] && pdfDetails[0].Name
}.pdf`}
>
{({ blob, url, loading, error }) =>
loading ? (
<button
type="button"
className="defaultBtn certificateBtn"
style={{
display: "flex",
flexDirection: "row",
alignItems: "center"
}}
>
<i
className="fa fa-certificate"
style={{
color: "white",
fontSize: "15px",
marginRight: "3px"
}}
aria-hidden="true"
></i>
Certificate
</button>
) : (
<button
type="button"
className="defaultBtn certificateBtn"
style={{
display: "flex",
flexDirection: "row",
alignItems: "center"
}}
>
<i
className="fa fa-certificate"
style={{
color: "white",
fontSize: "15px",
marginRight: "3px"
}}
aria-hidden="true"
></i>
Certificate
</button>
)
}
</PDFDownloadLink>
);
};
return (
<div
style={{ padding: !isGuestSigner && "5px 0px 5px 0px" }}
style={{ padding: !isGuestSigner && "5px 0px 5px 0px" }}
className="mobileHead"
>
{isMobile && isShowHeader ? (
@@ -95,7 +231,9 @@ function Header({
id="navbar"
className={isGuestSigner ? "stickySignerHead" : "stickyHead"}
style={{
width: isGuestSigner ? window.innerWidth : window.innerWidth - 30 + "px"
width: isGuestSigner
? window.innerWidth
: window.innerWidth - 30 + "px"
}}
>
<div className="preBtn2">
@@ -140,16 +278,16 @@ function Header({
style={{ color: "gray", cursor: "pointer" }}
></i>
</div>
{pdfUrl ? (
{pdfUrl && alreadySign ? (
<DropdownMenu.Root>
<DropdownMenu.Trigger asChild>
<div
// onClick={() => handleDownloadPdf()}
style={{
color: themeColor(),
border: "none",
fontWeight: "650",
fontSize: "16px"
fontSize: "16px",
padding: "0px 3px 0px 5px"
}}
>
<i className="fa fa-ellipsis-v" aria-hidden="true"></i>
@@ -179,51 +317,48 @@ function Header({
Download
</div>
</DropdownMenu.Item>
<DropdownMenu.Item className="DropdownMenuItem">
<PDFDownloadLink
style={{ textDecoration: "none" }}
document={<Certificate pdfData={pdfDetails} />}
fileName={`completion certificate-${
pdfDetails[0] && pdfDetails[0].Name
}.pdf`}
{recipient && pdfDetails[0] && pdfDetails.length > 0 ? (
<DropdownMenu.Item className="DropdownMenuItem">
<CertificateDropDown />
</DropdownMenu.Item>
) : isPdfRequestFiles &&
alreadySign &&
isCompleted.isCertificate ? (
<DropdownMenu.Item className="DropdownMenuItem">
<CertificateDropDown />
</DropdownMenu.Item>
) : (
isSignYourself && (
<DropdownMenu.Item className="DropdownMenuItem">
<CertificateDropDown />
</DropdownMenu.Item>
)
)}
<DropdownMenu.Item
className="DropdownMenuItem"
onClick={handleToPrint}
>
<div
style={{
display: "flex",
flexDirection: "row"
}}
>
{({ blob, url, loading, error }) => (
<>
{console.log("error", error)}
{loading ? (
"Loading document..."
) : (
<button
type="button"
className="defaultBtn certificateBtn"
style={{
display: "flex",
flexDirection: "row",
alignItems: "center"
}}
>
<i
className="fa fa-certificate"
style={{
color: "white",
fontSize: "15px",
marginRight: "3px"
}}
aria-hidden="true"
></i>
Certificate
</button>
)}
</>
)}
</PDFDownloadLink>
{" "}
<i
className="fa fa-print"
aria-hidden="true"
style={{ marginRight: "2px" }}
></i>
Print
</div>
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Portal>
</DropdownMenu.Root>
) : (
<div style={{ display: "flex", justifyContent: "space-around" }}>
{/* current signer is checking user send request and check status of pdf sign than if current
{/* current signer is checking user send request and check status of pdf sign than if current
user exist than show finish button else no
*/}
{currentSigner && (
@@ -267,6 +402,8 @@ function Header({
onClick={() => {
if (!pdfUrl) {
embedImages();
} else if (isPdfRequestFiles) {
embedImages();
}
}}
style={{
@@ -297,40 +434,7 @@ function Header({
pdfUrl || isAlreadySign.mssg ? (
<div style={{ display: "flex", flexDirection: "row" }}>
{pdfDetails[0] && pdfDetails.length > 0 && (
<PDFDownloadLink
style={{ textDecoration: "none" }}
document={<Certificate pdfData={pdfDetails} />}
fileName={`completion certificate-${
pdfDetails[0] && pdfDetails[0].Name
}.pdf`}
>
{({ blob, url, loading, error }) =>
loading ? (
"Loading document..."
) : (
<button
type="button"
className="defaultBtn certificateBtn"
style={{
display: "flex",
flexDirection: "row",
alignItems: "center"
}}
>
<i
className="fa fa-certificate"
style={{
color: "white",
fontSize: "15px",
marginRight: "3px"
}}
aria-hidden="true"
></i>
Certificate
</button>
)
}
</PDFDownloadLink>
<CertificateComponent />
)}
<button
onClick={handleToPrint}
@@ -455,42 +559,7 @@ function Header({
) : isPdfRequestFiles ? (
alreadySign ? (
<div style={{ display: "flex", flexDirection: "row" }}>
{isCompleted.isCertificate && (
<PDFDownloadLink
style={{ textDecoration: "none" }}
document={<Certificate pdfData={pdfDetails} />}
fileName={`completion certificate-${
pdfDetails[0] && pdfDetails[0].Name
}.pdf`}
>
{({ blob, url, loading, error }) =>
loading ? (
"Loading document..."
) : (
<button
type="button"
className="defaultBtn certificateBtn"
style={{
display: "flex",
flexDirection: "row",
alignItems: "center"
}}
>
<i
className="fa fa-certificate"
style={{
color: "white",
fontSize: "15px",
marginRight: "3px"
}}
aria-hidden="true"
></i>
Certificate
</button>
)
}
</PDFDownloadLink>
)}
{isCompleted.isCertificate && <CertificateComponent />}
<button
onClick={handleToPrint}
type="button"
@@ -577,40 +646,7 @@ function Header({
)
) : pdfUrl || (documentStatus && documentStatus.isCompleted) ? (
<div style={{ display: "flex", flexDirection: "row" }}>
<PDFDownloadLink
style={{ textDecoration: "none" }}
document={<Certificate pdfData={pdfDetails} />}
fileName={`completion certificate-${
pdfDetails[0] && pdfDetails[0].Name
}.pdf`}
>
{({ blob, url, loading, error }) =>
loading ? (
"Loading document..."
) : (
<button
type="button"
style={{
display: "flex",
flexDirection: "row",
alignItems: "center"
}}
className="defaultBtn certificateBtn"
>
<i
className="fa fa-certificate"
style={{
color: "white",
fontSize: "15px",
marginRight: "3px"
}}
aria-hidden="true"
></i>
Certificate
</button>
)
}
</PDFDownloadLink>
<CertificateComponent />
<button
onClick={handleToPrint}
type="button"
@@ -42,7 +42,8 @@ function RenderPdf({
const isMobile = window.innerWidth < 767;
const newWidth = window.innerWidth;
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
//check isGuestSigner is present in local if yes than handle login flow header in mobile view
const isGuestSigner = localStorage.getItem("isGuestSigner");
// handle signature block width and height according to screen
const posWidth = (pos) => {
let width;
@@ -74,8 +75,7 @@ function RenderPdf({
return width;
}
};
//check isGuestSigner is present in local if yes than handle login flow header in mobile view
const isGuestSigner = localStorage.getItem("isGuestSigner");
//function for render placeholder block over pdf document
const checkSignedSignes = (data) => {
@@ -606,7 +606,7 @@ function RenderPdf({
>
{" "}
<div
onTouchStart={(e) => {
onTouchEnd ={(e) => {
if (!isDragging) {
setTimeout(() => {
e.stopPropagation();
@@ -640,6 +640,7 @@ function RenderPdf({
alt="signimg"
onClick={(e) => {
setSignKey(pos.key);
console.log("Drag 2");
setIsSignPad(true);
setIsStamp(pos.isStamp);
}}
@@ -692,11 +693,10 @@ function RenderPdf({
}}
>
<div
onTouchStart={(e) => {
onTouchEnd ={(e) => {
if (!isDragging) {
setTimeout(() => {
setIsSignPad(true);
setSignKey(pos.key);
setIsStamp(pos.isStamp);
}, 500);
@@ -777,7 +777,13 @@ function RenderPdf({
}}
onLoadSuccess={pageDetails}
ref={pdfRef}
file={pdfUrl ? pdfUrl : pdfDetails[0] && pdfDetails[0].URL}
file={
pdfUrl
? pdfUrl
: pdfDetails[0] && pdfDetails[0].SignedUrl
? pdfDetails[0].SignedUrl
: pdfDetails[0].URL
}
>
{Array.from(new Array(numPages), (el, index) => (
<Page
@@ -1293,7 +1299,13 @@ function RenderPdf({
}}
onLoadSuccess={pageDetails}
ref={pdfRef}
file={pdfUrl ? pdfUrl : pdfDetails[0] && pdfDetails[0].URL}
file={
pdfUrl
? pdfUrl
: pdfDetails[0] && pdfDetails[0].SignedUrl
? pdfDetails[0].SignedUrl
: pdfDetails[0].URL
}
>
{Array.from(new Array(numPages), (el, index) => (
<Page
@@ -17,7 +17,12 @@ import HandleError from "./component/HandleError";
import Nodata from "./component/Nodata";
import SignerListPlace from "./component/signerListPlace";
import Header from "./component/header";
import { contactBook, contractUsers, getHostUrl } from "../utils/Utils";
import {
contactBook,
contractDocument,
contractUsers,
getHostUrl
} from "../utils/Utils";
import RenderPdf from "./component/renderPdf";
import ModalComponent from "./component/modalComponent";
import { useNavigate } from "react-router-dom";
@@ -169,56 +174,40 @@ function PlaceHolderSign() {
//function for get document details
const getDocumentDetails = async () => {
await axios
.get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
"_appName"
)}_Document?where={"objectId":"${documentId}"}&include=ExtUserPtr,Signers`,
{
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;
//getting document details
const documentData = await contractDocument(documentId);
if (documentData && documentData.length > 0) {
setPdfDetails(documentData);
if (res[0] && res.length > 0) {
setPdfDetails(res);
const currEmail = documentData[0].ExtUserPtr.Email;
const filterCurrEmail = documentData[0].Signers.filter(
(data) => data.Email === currEmail
);
const currEmail = res[0].ExtUserPtr.Email;
const filterCurrEmail = res[0].Signers.filter(
(data) => data.Email === currEmail
);
setCurrentEmail(filterCurrEmail);
setSignersData(documentData[0]);
setCurrentEmail(filterCurrEmail);
setSignersData(res[0]);
setSignerObjId(res[0].Signers[0].objectId);
setContractName(res[0].Signers[0].className);
setIsSelectId(0);
} else {
setNoData(true);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
}
})
.catch((err) => {
console.log("axois err ", err);
const loadObj = {
isLoad: false
};
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
});
const res = await contractUsers(jsonSender.objectId);
setSignerObjId(documentData[0].Signers[0].objectId);
setContractName(documentData[0].Signers[0].className);
setIsSelectId(0);
} else if (
documentData === "Error: Something went wrong!" ||
(documentData.result && documentData.result.error)
) {
const loadObj = {
isLoad: false
};
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
} else {
setNoData(true);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
}
const res = await contractUsers(jsonSender.email);
if (res[0] && res.length) {
setSignerUserId(res[0].objectId);
const tourstatus = res[0].TourStatus && res[0].TourStatus;
@@ -242,24 +231,12 @@ function PlaceHolderSign() {
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
} else if (res.length === 0) {
const res = await contactBook(jsonSender.objectId);
if (res[0] && res.length) {
setSignerUserId(res[0].objectId);
const tourstatus = res[0].TourStatus && res[0].TourStatus;
if (tourstatus && tourstatus.length > 0) {
setTourStatus(tourstatus);
const checkTourRecipients = tourstatus.filter(
(data) => data.placeholder
);
if (checkTourRecipients && checkTourRecipients.length > 0) {
setCheckTourStatus(checkTourRecipients[0].placeholder);
}
}
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
}
setNoData(true);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
}
};
@@ -14,7 +14,12 @@ import DefaultSignature from "./component/defaultSignature";
import {
getBase64FromUrl,
getBase64FromIMG,
contactBookName
contactBookName,
convertPNGtoJPEG,
contractUsers,
contactBook,
contractDocument,
urlValidator
} from "../utils/Utils";
import Tour from "reactour";
import Signedby from "./component/signedby";
@@ -25,6 +30,7 @@ import Nodata from "./component/Nodata";
import Header from "./component/header";
import RenderPdf from "./component/renderPdf";
import CustomModal from "./component/CustomModal";
import { modalAlign } from "../utils/Utils";
function EmbedPdfImage() {
const { id, contactBookId } = useParams();
const [isSignPad, setIsSignPad] = useState(false);
@@ -74,6 +80,15 @@ function EmbedPdfImage() {
return object.pageNumber === pageNumber;
});
const divRef = useRef(null);
const senderUser = localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
)
? localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
)
: `${localStorage.getItem("UserInformation")}` &&
`${localStorage.getItem("UserInformation")}`;
const jsonSender = JSON.parse(senderUser);
//check isGuestSigner is present in local if yes than handle login flow header in mobile view
const isGuestSigner = localStorage.getItem("isGuestSigner");
useEffect(() => {
@@ -96,33 +111,26 @@ function EmbedPdfImage() {
//function for get document details for perticular signer with signer'object id
const getDocumentDetails = async () => {
let currUserId, userObjectId;
const json = await contactBookName(contactBookId, "_Contactbook");
if (json !== "Error: Something went wrong!" && json && json.results[0]) {
//getting contracts_contactBook details
const json = await contactBook(contactBookId);
if (json && json.length > 0) {
setContractName("_Contactbook");
if (json.results[0]) {
userObjectId = json.results[0].UserId.objectId;
setUserObjectID(userObjectId);
currUserId = json.results[0].objectId;
setSignerUserId(currUserId);
const tourstatus =
json.results[0].TourStatus && json.results[0].TourStatus;
userObjectId = json[0].UserId.objectId;
setUserObjectID(userObjectId);
currUserId = json[0].objectId;
if (tourstatus && tourstatus.length > 0) {
setTourStatus(tourstatus);
const checkTourRecipients = tourstatus.filter(
(data) => data.recipientssign
);
if (checkTourRecipients && checkTourRecipients.length > 0) {
setCheckTourStatus(checkTourRecipients[0].recipientssign);
}
setSignerUserId(currUserId);
const tourstatus = json[0].TourStatus && json[0].TourStatus;
if (tourstatus && tourstatus.length > 0) {
setTourStatus(tourstatus);
const checkTourRecipients = tourstatus.filter(
(data) => data.recipientssign
);
if (checkTourRecipients && checkTourRecipients.length > 0) {
setCheckTourStatus(checkTourRecipients[0].recipientssign);
}
} else {
setNoData(true);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
}
} else if (json === "Error: Something went wrong!") {
const loadObj = {
@@ -131,18 +139,16 @@ function EmbedPdfImage() {
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
} else {
const json = await contactBookName(contactBookId, "_Users");
if (json !== "Error: Something went wrong!" && json && json.results[0]) {
const json = await contractUsers(jsonSender.email);
if (json && json.length > 0) {
setContractName("_Users");
if (json.results[0]) {
userObjectId = json.results[0].UserId.objectId;
if (json[0]) {
userObjectId = json[0].UserId.objectId;
setUserObjectID(userObjectId);
currUserId = json.results[0].objectId;
currUserId = json[0].objectId;
setSignerUserId(currUserId);
const tourstatus =
json.results[0].TourStatus && json.results[0].TourStatus;
const tourstatus = json[0].TourStatus && json[0].TourStatus;
if (tourstatus && tourstatus.length > 0) {
setTourStatus(tourstatus);
@@ -166,171 +172,170 @@ function EmbedPdfImage() {
};
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
}
}
} else {
setNoData(true);
await axios
.get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
"_appName"
)}_Document?where={"objectId":"${docId}"}&include=ExtUserPtr,Signers,AuditTrail
,`,
{
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) {
const declined = res[0].IsDeclined && res[0].IsDeclined;
const isCompleted = res[0].IsCompleted && res[0].IsCompleted;
const expireDate = res[0].ExpiryDate.iso;
const expireUpdateDate = new Date(expireDate).getTime();
const currDate = new Date().getTime();
if (isCompleted) {
//checking document is completed (signed by all requested signers) than isCompleted true
//then show alert with completed message
const alreadySign = {
status: true,
mssg: "This document has been successfully signed!"
};
setIsAlreadySign(alreadySign);
setPdfUrl(res[0].SignedUrl);
setSignedPdfData(json.results);
setCompletePdfData(res);
} else if (declined) {
const currentDecline = {
currnt: "another",
isDeclined: true
};
setIsDecline(currentDecline);
setSignedPdfData(json.results);
} else if (currDate > expireUpdateDate) {
setIsExpired(true);
const checkDocIdExist =
json.results[0].AuditTrail &&
json.results[0].AuditTrail.length > 0 &&
json.results[0].AuditTrail.filter(
(data) => data.Activity === "Signed"
);
//if signed by someone than go to in if condition
// and second signer could not be add documentId
//for that setIsDocId true
if (checkDocIdExist && checkDocIdExist.length > 0) {
setIsDocId(true);
const currUser =
json.results[0].Placeholders &&
json.results[0].Placeholders.filter(
(data) => data.signerObjId === currUserId
);
setSignedPdfData(json.results);
setXyPostion(currUser[0].placeHolder);
const key = currUser[0].placeHolder[0].pos[0].key;
setSignKey(key);
}
//for show current requested signer's placeholder
else {
const currUser =
json.results[0].Placeholders &&
json.results[0].Placeholders.filter(
(data) => data.signerObjId === currUserId
);
setSignedPdfData(json.results);
setXyPostion(currUser[0].placeHolder);
const key = currUser[0].placeHolder[0].pos[0].key;
setSignKey(key);
}
} else {
//checking document has signed by someone or not
const checkDocIdExist =
json.results[0].AuditTrail &&
json.results[0].AuditTrail.length > 0 &&
json.results[0].AuditTrail.filter(
(data) => data.Activity === "Signed"
);
//if signed by someone than go to in if condition
// and second signer could not be add documentId
//for that setIsDocId true
if (checkDocIdExist && checkDocIdExist.length > 0) {
setIsDocId(true);
//condition for checking document signed by current requested user or not
const checkAlreadyBySigner = json.results[0].AuditTrail.filter(
(data) =>
data.UserPtr.objectId === currUserId &&
data.Activity === "Signed"
);
// if checkAlreadyBySigner has some data that current user already sign this document
// then show alert with message
if (checkAlreadyBySigner && checkAlreadyBySigner.length > 0) {
const alreadySign = {
status: true,
mssg: "You have successfully signed the document!"
};
setIsAlreadySign(alreadySign);
setPdfUrl(res[0].SignedUrl);
setSignedPdfData(json.results);
}
//else show placeholder of current requested signer
else {
const currUser =
json.results[0].Placeholders &&
json.results[0].Placeholders.filter(
(data) => data.signerObjId === currUserId
);
setSignedPdfData(json.results);
setXyPostion(currUser[0].placeHolder);
const key = currUser[0].placeHolder[0].pos[0].key;
setSignKey(key);
}
}
//for show current requested signer's placeholder
else {
const currUser =
json.results[0].Placeholders &&
json.results[0].Placeholders.filter(
(data) => data.signerObjId === currUserId
);
setSignedPdfData(json.results);
setXyPostion(currUser[0].placeHolder);
const key = currUser[0].placeHolder[0].pos[0].key;
setSignKey(key);
}
}
}
})
.catch((err) => {
const loadObj = {
isLoad: false
};
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
console.log("err", err);
});
}
}
//getting document details
const documentData = await contractDocument(docId);
if (documentData && documentData.length > 0) {
const declined = documentData[0].IsDeclined && documentData[0].IsDeclined;
const isCompleted =
documentData[0].IsCompleted && documentData[0].IsCompleted;
const expireDate = documentData[0].ExpiryDate.iso;
const expireUpdateDate = new Date(expireDate).getTime();
const currDate = new Date().getTime();
if (isCompleted) {
//checking document is completed (signed by all requested signers) than isCompleted true
//then show alert with completed message
const alreadySign = {
status: true,
mssg: "This document has been successfully signed!"
};
setIsAlreadySign(alreadySign);
setPdfUrl(documentData[0].SignedUrl);
setSignedPdfData(documentData);
setCompletePdfData(documentData);
} else if (declined) {
const currentDecline = {
currnt: "another",
isDeclined: true
};
setIsDecline(currentDecline);
setSignedPdfData(documentData);
} else if (currDate > expireUpdateDate) {
setIsExpired(true);
const checkDocIdExist =
documentData[0].AuditTrail &&
documentData[0].AuditTrail.length > 0 &&
documentData[0].AuditTrail.filter(
(data) => data.Activity === "Signed"
);
//if signed by someone than go to in if condition
// and second signer could not be add documentId
//for that setIsDocId true
if (checkDocIdExist && checkDocIdExist.length > 0) {
setIsDocId(true);
const currUser =
documentData.Placeholders &&
documentData.Placeholders.filter(
(data) => data.signerObjId === currUserId
);
setSignedPdfData(documentData);
setXyPostion(currUser[0].placeHolder);
const key = currUser[0].placeHolder[0].pos[0].key;
setSignKey(key);
}
//for show current requested signer's placeholder
else {
const currUser =
documentData[0].Placeholders &&
documentData[0].Placeholders.filter(
(data) => data.signerObjId === currUserId
);
setSignedPdfData(documentData);
setXyPostion(currUser[0].placeHolder);
const key = currUser[0].placeHolder[0].pos[0].key;
setSignKey(key);
}
} else {
//checking document has signed by someone or not
const checkDocIdExist =
documentData[0].AuditTrail &&
documentData[0].AuditTrail.length > 0 &&
documentData[0].AuditTrail.filter(
(data) => data.Activity === "Signed"
);
//if signed by someone than go to in if condition
// and second signer could not be add documentId
//for that setIsDocId true
if (checkDocIdExist && checkDocIdExist.length > 0) {
setIsDocId(true);
//condition for checking document signed by current requested user or not
const checkAlreadyBySigner = documentData[0].AuditTrail.filter(
(data) =>
data.UserPtr.objectId === currUserId && data.Activity === "Signed"
);
// if checkAlreadyBySigner has some data that current user already sign this document
// then show alert with message
if (checkAlreadyBySigner && checkAlreadyBySigner.length > 0) {
const alreadySign = {
status: true,
mssg: "You have successfully signed the document!"
};
setIsAlreadySign(alreadySign);
setPdfUrl(documentData[0].SignedUrl);
setSignedPdfData(documentData);
}
//else show placeholder of current requested signer
else {
const currUser =
documentData[0].Placeholders &&
documentData[0].Placeholders.filter(
(data) => data.signerObjId === currUserId
);
setSignedPdfData(documentData);
setXyPostion(currUser[0].placeHolder);
const key = currUser[0].placeHolder[0].pos[0].key;
setSignKey(key);
}
}
//for show current requested signer's placeholder
else {
const currUser =
documentData[0].Placeholders &&
documentData[0].Placeholders.filter(
(data) => data.signerObjId === currUserId
);
setSignedPdfData(documentData);
setXyPostion(currUser[0].placeHolder);
const key = currUser[0].placeHolder[0].pos[0].key;
setSignKey(key);
}
}
} else if (
documentData === "Error: Something went wrong!" ||
(documentData.result && documentData.result.error)
) {
const loadObj = {
isLoad: false
};
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
} else {
setNoData(true);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
}
await axios
.get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
@@ -444,38 +449,13 @@ function EmbedPdfImage() {
imgUrlList.map(async (data) => {
//cheking signUrl is defau;t signature url of custom url
let ImgUrl = data.SignUrl;
const checkUrl = ImgUrl.includes("https:");
const checkUrl = urlValidator(ImgUrl);
//if default signature url then convert it in base 64
if (checkUrl) {
ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
}
//function for called convert png signatre to jpeg in base 64
const convertPNGtoJPEG = (base64Data) => {
return new Promise((resolve, reject) => {
const canvas = document.createElement("canvas");
const img = new Image();
img.src = base64Data;
img.onload = () => {
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
// Convert to JPEG by using the canvas.toDataURL() method
const jpegBase64Data = canvas.toDataURL("image/jpeg");
resolve(jpegBase64Data);
};
img.onerror = (error) => {
reject(error);
};
});
};
//function for convert signature png base64 url to jpeg base64
convertPNGtoJPEG(ImgUrl)
.then((jpegBase64Data) => {
const removeBase64Fromjpeg = "data:image/jpeg;base64,";
@@ -522,7 +502,12 @@ function EmbedPdfImage() {
const images = await Promise.all(
imgUrlList.map(async (url) => {
let signUrl = url.SignUrl;
const checkUrl = url.SignUrl.includes("https:");
if (url.ImageType === "image/png") {
//function for convert signature png base64 url to jpeg base64
const newUrl = await convertPNGtoJPEG(signUrl);
signUrl = newUrl;
}
const checkUrl = urlValidator(signUrl);
if (checkUrl) {
signUrl = signUrl + "?get";
}
@@ -532,20 +517,7 @@ function EmbedPdfImage() {
})
);
images.forEach(async (imgData, id) => {
let img;
if (
imgUrlList[id].ImageType &&
imgUrlList[id].ImageType === "image/jpeg"
) {
img = await pdfDoc.embedJpg(imgData);
} else if (
imgUrlList[id].ImageType &&
imgUrlList[id].ImageType === "image/png"
) {
img = await pdfDoc.embedPng(imgData);
} else {
img = await pdfDoc.embedPng(imgData);
}
let img = await pdfDoc.embedJpg(imgData);
const imgHeight = imgUrlList[id].Height
? imgUrlList[id].Height
@@ -662,8 +634,8 @@ function EmbedPdfImage() {
yPosition = pos.isDrag
? y * scale - height
: pos.firstYPos
? y * scale - height + pos.firstYPos
: y * scale - height;
? y * scale - height + pos.firstYPos
: y * scale - height;
return yPosition;
} else {
const y = pos.yBottom / scale;
@@ -671,8 +643,8 @@ function EmbedPdfImage() {
yPosition = pos.isDrag
? y * scale - height
: pos.firstYPos
? y * scale - height + pos.firstYPos
: y * scale - height;
? y * scale - height + pos.firstYPos
: y * scale - height;
return yPosition;
}
} else {
@@ -683,15 +655,15 @@ function EmbedPdfImage() {
yPosition = pos.isDrag
? y - height
: pos.firstYPos
? y - height + pos.firstYPos
: y - height;
? y - height + pos.firstYPos
: y - height;
return yPosition;
} else {
yPosition = pos.isDrag
? pos.yBottom - height
: pos.firstYPos
? pos.yBottom - height + pos.firstYPos
: pos.yBottom - height;
? pos.yBottom - height + pos.firstYPos
: pos.yBottom - height;
return yPosition;
}
}
@@ -1016,7 +988,11 @@ function EmbedPdfImage() {
}}
>
{/* this modal is used show this document is already sign */}
<Modal show={isAlreadySign.status}>
<Modal
show={isAlreadySign.status}
onShow={() => modalAlign()}
backdropClassName="signature-backdrop"
>
<ModalHeader style={{ background: themeColor() }}>
<span style={{ color: "white" }}> Sign Documents</span>
</ModalHeader>
@@ -1083,6 +1059,7 @@ function EmbedPdfImage() {
isShowHeader={true}
currentSigner={true}
decline={true}
alreadySign={pdfUrl ? true : false}
/>
<RenderPdf
@@ -1127,9 +1104,8 @@ function EmbedPdfImage() {
)}
</div>
)}
</DndProvider>
);
}
export default EmbedPdfImage;
export default EmbedPdfImage;
Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

@@ -374,15 +374,13 @@
font-size: 50px;
}
.DropdownMenuContent,
.DropdownMenuSubContent {
min-width: 130px;
background-color: #887abf;
border: none;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, .15);
border-radius: 0.25rem;
padding: 5px;
animation-duration: 400ms;
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
will-change: transform, opacity;
@@ -413,13 +411,13 @@
font-size: 13px;
line-height: 1;
color: black;
background-color: #887abf;
background-color: #fff;
display: flex;
align-items: center;
height: 25px;
padding: 0 5px;
position: relative;
padding-left: 25px;
padding-left: 20px;
user-select: none;
outline: none;
border: none;
@@ -565,13 +563,13 @@ option {
color: var(--violet-11);
cursor: default;
}
.fontOptionContainer{
border: 1px solid #d6d3d3;
margin: 10px 5px 5px 5px;
.fontOptionContainer {
border: 1px solid #d6d3d3;
margin: 10px 5px 5px 5px;
}
@media screen and (max-width:766px) {
.showPages {
@@ -628,25 +626,26 @@ option {
padding: 16px;
}
/* The sticky class is added to the navbar
/* The sticky class is added to the navbar
with JS when it reaches its scroll position */
.stickyHead {
position: fixed;
top: 50px;
left: 0.9rem;
}
.stickySignerHead{
position: fixed;
}
.stickyfooter {
}
.stickySignerHead {
position: fixed;
}
.stickyfooter {
position: fixed;
bottom: 0px;
right: 0rem;
}
/* Add some top padding to the page content
to prevent sudden quick movement (as the
navigation bar gets a new position at the top of the
/* Add some top padding to the page content
to prevent sudden quick movement (as the
navigation bar gets a new position at the top of the
page (position:fixed and top:0) */
.stickyHead+.content {
padding-top: 60px;
@@ -776,4 +775,14 @@ option {
.mobileHead {
display: flex;
}
}
.signature-backdrop {
position: fixed;
top: 0; bottom: 0; left: 0; right: 0;
background-color: #000;
}
.signature-backdrop.fade.in {
opacity: 0.5;
}
+130 -48
View File
@@ -1,4 +1,5 @@
import axios from "axios";
import { $ } from 'select-dom';
export async function getBase64FromUrl(url) {
const data = await fetch(url);
@@ -28,13 +29,35 @@ export async function getBase64FromIMG(url) {
};
});
}
//function for convert signature png base64 url to jpeg base64
export const convertPNGtoJPEG = (base64Data) => {
return new Promise((resolve, reject) => {
const canvas = document.createElement("canvas");
const img = new Image();
img.src = base64Data;
img.onload = () => {
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext("2d");
ctx.fillStyle = "#ffffff"; // white color
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0);
// Convert to JPEG by using the canvas.toDataURL() method
const jpegBase64Data = canvas.toDataURL("image/jpeg");
resolve(jpegBase64Data);
};
img.onerror = (error) => {
reject(error);
};
});
};
export function getHostUrl() {
const hostUrl = window.location.href;
/// const hostUrl = "https://contracts-defaultssty.qik.ai/#/mf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive";
// const hostUrl = "https://contracts-defaultssty.qik.ai/#/"
// const hostUrl = "https://lionfish-app-75ly7.ondigitalocean.app/mf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive"
//const hostUrl = "https://app.opensignlabs.com/rpmf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument";
if (hostUrl) {
const urlSplit = hostUrl.split("/");
@@ -57,7 +80,6 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
(data, ind) =>
data.key === signKey && data.Width && data.Height && data.SignUrl
);
if (updateFilter.length > 0) {
let newWidth, newHeight;
@@ -139,7 +161,7 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
...url,
Width: getPosData[0].Width ? getPosData[0].Width : newWidth,
Height: getPosData[0].Height ? getPosData[0].Height : newHeight,
SignUrl: image.src,
SignUrl: image.src,
ImageType: image.imgType
};
}
@@ -153,7 +175,6 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
return obj;
});
return newUpdateUrl;
// setXyPostion(newUpdateUrl);
}
}
@@ -183,40 +204,105 @@ export function onSaveSign(xyPostion, index, signKey, signatureImg) {
return newUpdateUrl;
}
//function for getting contract_User details
export const contractUsers = async (objectId) => {
const result = await axios
.get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
"_appName"
)}_Users?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")
}
//function for getting document details from contract_Documents class
export const contractDocument = async (documentId) => {
const data = {
docId: documentId
};
const documentDeatils = await axios
.post(`${localStorage.getItem("baseUrl")}functions/getDocument`, data, {
headers: {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
sessionToken: localStorage.getItem("accesstoken")
}
)
})
.then((Listdata) => {
const json = Listdata.data;
const res = json.results;
return res;
let data = [];
if (json && json.result.error) {
return json;
} else if (json && json.result) {
data.push(json.result);
return data;
} else {
return [];
}
})
.catch((err) => {
return "Error: Something went wrong!";
});
return result;
return documentDeatils;
};
//function for getting contrscts_contactbook details
//function for getting document details for getDrive
export const getDrive = async (documentId) => {
const data = {
docId: documentId && documentId
};
const driveDeatils = await axios
.post(`${localStorage.getItem("baseUrl")}functions/getDrive`, data, {
headers: {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
sessiontoken: localStorage.getItem("accesstoken")
}
})
.then((Listdata) => {
const json = Listdata.data;
if (json && json.result.error) {
return json;
} else if (json && json.result) {
const data = json.result;
return data;
} else {
return [];
}
})
.catch((err) => {
return "Error: Something went wrong!";
});
return driveDeatils;
};
//function for getting contract_User details
export const contractUsers = async (email) => {
const data = {
email: email
};
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 = [];
if (json && json.result) {
data.push(json.result);
return data;
}
})
.catch((err) => {
return "Error: Something went wrong!";
});
return userDetails;
};
//function for getting contracts_contactbook details
export const contactBook = async (objectId) => {
const result = await axios
.get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
"_appName"
)}_Contactbook?where={"UserId": {"__type": "Pointer","className": "_User", "objectId":"${objectId}"}}`,
)}_Contactbook?where={"objectId":"${objectId}"}`,
{
headers: {
"Content-Type": "application/json",
@@ -237,26 +323,22 @@ export const contactBook = async (objectId) => {
return result;
};
export const contactBookName = async (objectId, className) => {
const result = await axios
.get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
"_appName"
)}${className}?where={"objectId":"${objectId}"}`,
{
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;
return json;
})
.catch((err) => {
return "Error: Something went wrong!";
});
return result;
// function for validating URLs
export function urlValidator(url) {
try {
const newUrl = new URL(url);
return newUrl.protocol === 'http:' || newUrl.protocol === 'https:';
} catch (err) {
return false;
}
}
export function modalAlign() {
let modalDialog = $('.modal-dialog').getBoundingClientRect();
let mobileHead = $('.mobileHead').getBoundingClientRect()
let modal = $('.modal-dialog');
if (modalDialog.left < mobileHead.left) {
let leftOffset = mobileHead.left - modalDialog.left;
modal.style.left = leftOffset + 'px';
modal.style.top = (window.innerHeight/3) + 'px';
}
};
+704
View File
@@ -0,0 +1,704 @@
{
"name": "opensign",
"version": "1.0.6",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "opensign",
"version": "1.0.6",
"license": "AGPL-3.0",
"devDependencies": {
"husky": "^8.0.0",
"lint-staged": "^15.1.0",
"prettier": "3.1.0"
}
},
"node_modules/ansi-escapes": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz",
"integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==",
"dev": true,
"dependencies": {
"type-fest": "^1.0.2"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/ansi-regex": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/ansi-styles": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"dependencies": {
"fill-range": "^7.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/chalk": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
"integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
"dev": true,
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/cli-cursor": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
"integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==",
"dev": true,
"dependencies": {
"restore-cursor": "^4.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/cli-truncate": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz",
"integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==",
"dev": true,
"dependencies": {
"slice-ansi": "^5.0.0",
"string-width": "^5.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/colorette": {
"version": "2.0.20",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
"dev": true
},
"node_modules/commander": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
"dev": true,
"engines": {
"node": ">=16"
}
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dev": true,
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dev": true,
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"dev": true
},
"node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true
},
"node_modules/eventemitter3": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
"dev": true
},
"node_modules/execa": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
"integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
"dev": true,
"dependencies": {
"cross-spawn": "^7.0.3",
"get-stream": "^8.0.1",
"human-signals": "^5.0.0",
"is-stream": "^3.0.0",
"merge-stream": "^2.0.0",
"npm-run-path": "^5.1.0",
"onetime": "^6.0.0",
"signal-exit": "^4.1.0",
"strip-final-newline": "^3.0.0"
},
"engines": {
"node": ">=16.17"
},
"funding": {
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/get-stream": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
"integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
"dev": true,
"engines": {
"node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/human-signals": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
"integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
"dev": true,
"engines": {
"node": ">=16.17.0"
}
},
"node_modules/husky": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz",
"integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==",
"dev": true,
"bin": {
"husky": "lib/bin.js"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/typicode"
}
},
"node_modules/is-fullwidth-code-point": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
"integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/is-stream": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
"integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
"dev": true,
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
},
"node_modules/lilconfig": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
"integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
"dev": true,
"engines": {
"node": ">=10"
}
},
"node_modules/lint-staged": {
"version": "15.1.0",
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.1.0.tgz",
"integrity": "sha512-ZPKXWHVlL7uwVpy8OZ7YQjYDAuO5X4kMh0XgZvPNxLcCCngd0PO5jKQyy3+s4TL2EnHoIXIzP1422f/l3nZKMw==",
"dev": true,
"dependencies": {
"chalk": "5.3.0",
"commander": "11.1.0",
"debug": "4.3.4",
"execa": "8.0.1",
"lilconfig": "2.1.0",
"listr2": "7.0.2",
"micromatch": "4.0.5",
"pidtree": "0.6.0",
"string-argv": "0.3.2",
"yaml": "2.3.4"
},
"bin": {
"lint-staged": "bin/lint-staged.js"
},
"engines": {
"node": ">=18.12.0"
},
"funding": {
"url": "https://opencollective.com/lint-staged"
}
},
"node_modules/listr2": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/listr2/-/listr2-7.0.2.tgz",
"integrity": "sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==",
"dev": true,
"dependencies": {
"cli-truncate": "^3.1.0",
"colorette": "^2.0.20",
"eventemitter3": "^5.0.1",
"log-update": "^5.0.1",
"rfdc": "^1.3.0",
"wrap-ansi": "^8.1.0"
},
"engines": {
"node": ">=16.0.0"
}
},
"node_modules/log-update": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz",
"integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==",
"dev": true,
"dependencies": {
"ansi-escapes": "^5.0.0",
"cli-cursor": "^4.0.0",
"slice-ansi": "^5.0.0",
"strip-ansi": "^7.0.1",
"wrap-ansi": "^8.0.1"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"dev": true
},
"node_modules/micromatch": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
"dev": true,
"dependencies": {
"braces": "^3.0.2",
"picomatch": "^2.3.1"
},
"engines": {
"node": ">=8.6"
}
},
"node_modules/mimic-fn": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
"integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"node_modules/npm-run-path": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz",
"integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==",
"dev": true,
"dependencies": {
"path-key": "^4.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/npm-run-path/node_modules/path-key": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
"integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/onetime": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
"integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
"dev": true,
"dependencies": {
"mimic-fn": "^4.0.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/pidtree": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
"integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
"dev": true,
"bin": {
"pidtree": "bin/pidtree.js"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/prettier": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz",
"integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/restore-cursor": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz",
"integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==",
"dev": true,
"dependencies": {
"onetime": "^5.1.0",
"signal-exit": "^3.0.2"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/restore-cursor/node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/restore-cursor/node_modules/onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dev": true,
"dependencies": {
"mimic-fn": "^2.1.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/restore-cursor/node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true
},
"node_modules/rfdc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
"dev": true
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"dependencies": {
"shebang-regex": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/signal-exit": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"dev": true,
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/slice-ansi": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
"integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
"dev": true,
"dependencies": {
"ansi-styles": "^6.0.0",
"is-fullwidth-code-point": "^4.0.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
}
},
"node_modules/string-argv": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
"integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
"dev": true,
"engines": {
"node": ">=0.6.19"
}
},
"node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dev": true,
"dependencies": {
"eastasianwidth": "^0.2.0",
"emoji-regex": "^9.2.2",
"strip-ansi": "^7.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/strip-ansi": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dev": true,
"dependencies": {
"ansi-regex": "^6.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/strip-final-newline": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
"integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"dependencies": {
"is-number": "^7.0.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/type-fest": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
"integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"node-which": "bin/node-which"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/wrap-ansi": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"dev": true,
"dependencies": {
"ansi-styles": "^6.1.0",
"string-width": "^5.0.1",
"strip-ansi": "^7.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/yaml": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz",
"integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==",
"dev": true,
"engines": {
"node": ">= 14"
}
}
}
}
+30
View File
@@ -0,0 +1,30 @@
{
"name": "opensign",
"version": "1.0.6",
"description": "Free and open source alternative to DocuSign",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"prepare": "husky install",
"lint-staged-changes": "lint-staged"
},
"repository": {
"type": "git",
"url": "github.com/opensignlabs/opensign"
},
"keywords": [
"digital",
"signature",
"e-signature",
"docusign",
"electronic",
"signature"
],
"author": "OpenSignLabs",
"license": "AGPL-3.0",
"devDependencies": {
"husky": "^8.0.0",
"lint-staged": "^15.1.0",
"prettier": "3.1.0"
}
}