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
69 changed files with 3488 additions and 2641 deletions
+56 -57
View File
@@ -42,7 +42,7 @@ DO_SECRET_ACCESS_KEY=
# Digital ocean spaces region or AWS s3 region # Digital ocean spaces region or AWS s3 region
DO_REGION=us-west DO_REGION=us-west
# local storage # local storage
USE_LOCAL=FALSE USE_LOCAL=TRUE
# Email mailgun config (The app will not initialize if any of these 3 variables are not set) ********************************************************************************************************************* # Email mailgun config (The app will not initialize if any of these 3 variables are not set) *********************************************************************************************************************
MAILGUN_API_KEY=XXXXX MAILGUN_API_KEY=XXXXX
@@ -50,61 +50,60 @@ MAILGUN_DOMAIN=mail.yourdomain.com
MAILGUN_SENDER=postmaster@mail.yourdomain.com MAILGUN_SENDER=postmaster@mail.yourdomain.com
# Base64 encoded PFX or p12 document signing certificate file ********************************************************************************************************************* # Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
PFX_BASE64='MIIKLwIBAzCCCeUGCSqGSIb3DQEHAaCCCdYEggnSMIIJzjCCBEIGCSqGSIb3DQEH PFX_BASE64='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 3pXAXxZuvVvv9tsb4bdrBAhyb+KCIjp/gAICCAA='
c6yryFgECIld0S5kDk7JAgIIAA=='
# Provide Pass pharse of above PFX or p12 document # Provide Pass pharse of above PFX or p12 document
PASS_PHRASE= PASS_PHRASE=opensign
+3 -4
View File
@@ -1,5 +1,4 @@
#!/bin/sh #!/usr/bin/env sh
. "$(dirname "$0")/_/husky.sh" . "$(dirname -- "$0")/_/husky.sh"
npx eslint '**/*.{js,jsx}' npm run lint-staged-changes
npx pretty-quick --staged '**/*.{js,jsx}'
+3
View File
@@ -0,0 +1,3 @@
{
"*.js": "prettier --write"
}
+1 -1
View File
@@ -2,7 +2,7 @@ build:
cp .env.local_dev .env cp .env.local_dev .env
rm -rf apps/OpenSign/public/mfbuild rm -rf apps/OpenSign/public/mfbuild
cd microfrontends/SignDocuments && npm install && npm run build cd microfrontends/SignDocuments && npm install && npm run build
docker compose up -d docker compose up --build --force-recreate
run: run:
cp .env.local_dev .env cp .env.local_dev .env
+16 -13
View File
@@ -1,8 +1,7 @@
<h1 align="center"><a href='https://www.opensignlabs.com'>OpenSign™</a></h1> <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">
<div align="center"> [The free and open source alternative to DocuSign](https://www.opensignlabs.com)
The free and open source alternative to DocuSign
[![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") [![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) [![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> <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> </div>
@@ -48,14 +47,18 @@ Welcome to OpenSign, an open-source document e-signing solution designed to prov
### Features ### Features
- **Secure Signing**: Utilizes state-of-the-art cryptographic algorithms to ensure the security & integrity of your documents. - **Secure PDF E-Signing:** With the help of Robust encryption algorithms, OpenSign™ ensures maximum security, privacy & compatibility.
- **User-Friendly Interface**: Designed with usability in mind, making it easy for both technical and non-technical users. - **Annotate Documents:** OpenSign™ allows you to annotate PDF documents with an advanced signing pad that comes with hand drawn signatures support as well as uploaded images & saved signatures for the simplest signing experience.
- **Multi-Platform Support**: Compatible with various browsers and devices. - **User-Friendly Interface:** OpenSign™ was built while keeping Intuitive design in mind for ease of use. Features like "Sign yourself", "One click signatures" and "OpenSign Drive" makes it stand out of the crowd and even makes it better than a lot of so-called industry leaders.
- **Invite & collaborate users**: Bring multiple people from your team into the signing process, all within your own infrastructure. - **Multi-signer Support:** OpenSign's ability to invite multiple signers for signing along with the ability to invite witnesses & being able to enforce signing in a sequence makes it the only open source solution that is fully loaded and allows it to compete head-to-head with established players.
- **Secure**: Allows for the easy, secure and seamless organization of your documents using 'OpenSigDrive'. - **Email Unique Code(OTP) verification support for guest signers:** With OpenSign™, your documents are fully secure even when being signed by guest users. Guest signers can only sign the document after entering a unique code sent to their email address. 
- **Audit Trails**: Keeps a detailed log of all activities related to the document signing process including IP addresses and access timings. - **"Expiring Docs" & "Rejection":** You can set documents to expire after certain number of days after which nobody will be able to sign it. Not just this, OpenSign also allows signers to reject signing a document.
- **Completion Certificate**: Generate secure completion certificate as soon as a document is signed by all participants. - **Beautiful email templates:** All document signing invitations, completion notifications & reminders are formatted using great looking email templates.
- **API Support**: Provides a robust API for integration into other software and services. - **PDF Template Creation(coming soon):** OpenSign™ allows you to create and store PDF document templates for repeated use thereby saving you a lot of time.
- **OpenSign™ Drive:** It is a centralised secure vault for your signed documents that makes storing, signing, organizing, sharing & achieving your docs a breeze.
- **Audit Trails & completion certificate:** Being a security focused solution, OpenSign™ makes it a top priority to save detailed logs for tracking document activities along with time-stamps, IP addresses, email IDs & phone numbers. A completion certificate is generated as soon as document is completed which contains all the document related logs for added safety.
- **API Support(coming soon):** OpenSign™ API allows seamless integration into existing systems and software. APIs will soon be available as a cloud hosted solution.
- **Integrations:** Seamless integrations with various Cloud storage systems, CRMs & enterprise platforms is coming soon.
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/b37ff443-7099-4273-9aeb-21c46d7154cf height='200'> <img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/b37ff443-7099-4273-9aeb-21c46d7154cf height='200'>
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/86db91b7-6c2f-4885-a33c-58f4fd35ec89 height='200'> <img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/86db91b7-6c2f-4885-a33c-58f4fd35ec89 height='200'>
+1
View File
@@ -10,6 +10,7 @@
# production # production
/build /build
/mfbuild
# misc # misc
.env .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" className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
/> />
</div> </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"> <div className="mb-3">
<label <label
htmlFor="email" 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" className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
/> />
</div> </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"> <div className="mt-4 flex justify-start">
<button <button
+15 -12
View File
@@ -27,14 +27,14 @@ const LoginFacebook = ({
setThirdpartyLoader(true); setThirdpartyLoader(true);
const details = { const details = {
Email: response.email, Email: response.email,
Name: response.name, Name: response.name
}; };
setUserDetails({ ...userDetails, ...details }); setUserDetails({ ...userDetails, ...details });
const fDetails = { const fDetails = {
Id: response.userID, Id: response.userID,
AccessToken: response.accessToken, AccessToken: response.accessToken,
Name: response.name, Name: response.name,
Email: response.email, Email: response.email
}; };
setFBDetails({ ...fBDetails, ...fDetails }); setFBDetails({ ...fBDetails, ...fDetails });
const res = await checkExtUser(fDetails); const res = await checkExtUser(fDetails);
@@ -42,9 +42,11 @@ const LoginFacebook = ({
}; };
const checkExtUser = async (details) => { const checkExtUser = async (details) => {
const extUser = new Parse.Query("contracts_Users"); // const extUser = new Parse.Query("contracts_Users");
extUser.equalTo("Email", details.Email); // extUser.equalTo("Email", details.Email);
const extRes = await extUser.first(); // const extRes = await extUser.first();
const params = { email: details.Email };
const extRes = await Parse.Cloud.run("getUserDetails", params);
// console.log("extRes ", extRes); // console.log("extRes ", extRes);
if (extRes) { if (extRes) {
const params = { ...details, Phone: extRes.get("Phone") }; const params = { ...details, Phone: extRes.get("Phone") };
@@ -209,18 +211,19 @@ const LoginFacebook = ({
<div> <div>
<button <button
type="button" type="button"
className="btn btn-secondary" onClick={() => handleSubmitbtn()}
onClick={() => setIsModal(false)} className="btn btn-info"
style={{ marginRight: 10, width: 90 }} style={{ marginRight: 10 }}
> >
Cancel Sign up
</button> </button>
<button <button
type="button" type="button"
onClick={() => handleSubmitbtn()} className="btn btn-secondary"
className="btn btn-info" onClick={() => setIsModal(false)}
style={{ width: 90 }}
> >
Sign up Cancel
</button> </button>
</div> </div>
</form> </form>
+51 -13
View File
@@ -42,7 +42,42 @@ const GoogleSignInBtn = ({
width: "187px" 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) => { const responseGoogle = async (response) => {
clearStorage();
setThirdpartyLoader(true); setThirdpartyLoader(true);
// console.log("response ", response); // console.log("response ", response);
if (response.credential) { if (response.credential) {
@@ -66,9 +101,11 @@ const GoogleSignInBtn = ({
} }
}; };
const checkExtUser = async (details) => { const checkExtUser = async (details) => {
const extUser = new Parse.Query("contracts_Users"); // const extUser = new Parse.Query("contracts_Users");
extUser.equalTo("Email", details.Gmail); // extUser.equalTo("Email", details.Gmail);
const extRes = await extUser.first(); // const extRes = await extUser.first();
const params = { email: details.Gmail };
const extRes = await Parse.Cloud.run("getUserDetails", params);
// console.log("extRes ", extRes); // console.log("extRes ", extRes);
if (extRes) { if (extRes) {
const params = { ...details, Phone: extRes.get("Phone") }; const params = { ...details, Phone: extRes.get("Phone") };
@@ -261,17 +298,17 @@ const GoogleSignInBtn = ({
</div> </div>
<div className="form-group"> <div className="form-group">
<label <label
htmlFor="Destination" htmlFor="JobTitle"
style={{ display: "flex" }} style={{ display: "flex" }}
className="col-form-label" className="col-form-label"
> >
Destination{" "} Job Title{" "}
<span style={{ fontSize: 13, color: "red" }}>*</span> <span style={{ fontSize: 13, color: "red" }}>*</span>
</label> </label>
<input <input
type="text" type="text"
className="form-control" className="form-control"
id="Destination" id="JobTitle"
value={userDetails.Destination} value={userDetails.Destination}
onChange={(e) => onChange={(e) =>
setUserDetails({ setUserDetails({
@@ -285,18 +322,19 @@ const GoogleSignInBtn = ({
<div> <div>
<button <button
type="button" type="button"
className="bg-[#6c757d] p-2 text-white rounded" className="bg-[#17a2b8] p-2 text-white rounded"
onClick={handleCloseModal} onClick={() => handleSubmitbtn()}
style={{ marginRight: 10, width: 90 }} style={{ marginRight: 10 }}
> >
Cancel Sign up
</button> </button>
<button <button
type="button" type="button"
className="bg-[#17a2b8] p-2 text-white rounded" className="bg-[#6c757d] p-2 text-white rounded"
onClick={() => handleSubmitbtn()} onClick={handleCloseModal}
style={{ width: 90 }}
> >
Sign up Cancel
</button> </button>
</div> </div>
</form> </form>
+16 -17
View File
@@ -49,12 +49,9 @@ const TreeWidget = (props) => {
let data = JSON.parse(localStorage.getItem("Extand_Class")); let data = JSON.parse(localStorage.getItem("Extand_Class"));
res = data[0]; res = data[0];
} else { } else {
var emp = Parse.Object.extend( res = await Parse.Cloud.run("getUserDetails", {
localStorage.getItem("extended_class") email: currentUser.get("email")
); });
var q = new Parse.Query(emp);
q.equalTo("UserId", currentUser);
res = await q.first();
if (res) res = res.toJSON(); if (res) res = res.toJSON();
} }
if (res) { if (res) {
@@ -79,12 +76,9 @@ const TreeWidget = (props) => {
let data = JSON.parse(localStorage.getItem("Extand_Class")); let data = JSON.parse(localStorage.getItem("Extand_Class"));
res = data[0]; res = data[0];
} else { } else {
emp = Parse.Object.extend( res = await Parse.Cloud.run("getUserDetails", {
localStorage.getItem("extended_class") email: currentUser.get("email")
); });
q = new Parse.Query(emp);
q.equalTo("UserId", currentUser);
res = await q.first();
if (res) res = res.toJSON(); if (res) res = res.toJSON();
} }
@@ -121,10 +115,15 @@ const TreeWidget = (props) => {
let data = JSON.parse(localStorage.getItem("Extand_Class")); let data = JSON.parse(localStorage.getItem("Extand_Class"));
res = data[0]; res = data[0];
} else { } else {
emp = Parse.Object.extend(localStorage.getItem("extended_class")); // emp = Parse.Object.extend(localStorage.getItem("extended_class"));
q = new Parse.Query(emp); // q = new Parse.Query(emp);
q.equalTo("UserId", currentUser); // q.equalTo("UserId", currentUser);
res = await q.first(); // 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(); if (res) res = res.toJSON();
} }
@@ -532,7 +531,7 @@ const TreeWidget = (props) => {
padding: 0 padding: 0
}, },
overlay: { overlay: {
width:"100%", width: "100%",
backgroundColor: "rgba(0, 0, 0, 0.75)", backgroundColor: "rgba(0, 0, 0, 0.75)",
zIndex: 50 zIndex: 50
} }
@@ -1,7 +1,6 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import axios from "axios"; import axios from "axios";
import Parse from "parse"; import Parse from "parse";
import onSearchFilter from "../../constant/searchQuery";
import getReplacedHashQuery from "../../constant/getReplacedHashQuery"; import getReplacedHashQuery from "../../constant/getReplacedHashQuery";
import "../../styles/loader.css"; import "../../styles/loader.css";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
@@ -35,14 +34,9 @@ const DashboardCard = (props) => {
let data = JSON.parse(localStorage.getItem("Extand_Class")); let data = JSON.parse(localStorage.getItem("Extand_Class"));
res = data[0]; res = data[0];
} else { } else {
var emp = Parse.Object.extend(localStorage.getItem("extended_class")); res = await Parse.Cloud.run("getUserDetails", {
var q = new Parse.Query(emp); email: currentUser.get("email")
q.equalTo("UserId", {
__type: "Pointer",
className: "_User",
objectId: currentUser
}); });
res = await q.first();
if (res) res = res.toJSON(); if (res) res = res.toJSON();
} }
if (res) { if (res) {
@@ -50,12 +44,7 @@ const DashboardCard = (props) => {
var reg = /(\#.*?\#)/gi; // eslint-disable-line var reg = /(\#.*?\#)/gi; // eslint-disable-line
var str = props.Data.query; var str = props.Data.query;
var test = ""; var test = "";
if (str.includes("#filterCondition#")) {
str = str.replace(
"#filterCondition#",
onSearchFilter(props.DefaultQuery)
);
}
if (props.Data.extendkey) { if (props.Data.extendkey) {
let a = props.Data.extendkey.split("."); let a = props.Data.extendkey.split(".");
if (a.length > 0) { if (a.length > 0) {
@@ -110,13 +99,10 @@ const DashboardCard = (props) => {
let data = JSON.parse(localStorage.getItem("Extand_Class")); let data = JSON.parse(localStorage.getItem("Extand_Class"));
resr = data[0]; resr = data[0];
} else { } else {
let emp = Parse.Object.extend( resr = await Parse.Cloud.run("getUserDetails", {
localStorage.getItem("extended_class") email: currentUser.get("email")
); });
let q = new Parse.Query(emp); if (resr) resr = resr.toJSON();
q.equalTo("UserId", currentUser);
let t = await q.first();
resr = t.toJSON();
} }
let json = resr; let json = resr;
@@ -150,47 +136,65 @@ const DashboardCard = (props) => {
"X-Parse-Application-Id": parseAppId, "X-Parse-Application-Id": parseAppId,
"X-Parse-Session-Token": localStorage.getItem("accesstoken") "X-Parse-Session-Token": localStorage.getItem("accesstoken")
}; };
await axios.get(url, { headers: headers }).then((res) => { // handle need your sign report count
if (res.data.results.length > 0) { if (props.Data.Redirect_id === "4Hhwbp482K") {
setLoading(false); const params = {
if (props.Data.key !== "count") { reportId: props.Data.Redirect_id,
setresponse(res.data.results[0][props.Data.key]); skip: 0,
} else { limit: 200
if (props.Label === "Need your Signature") { };
const listData = res.data?.results.filter( const url = `${parseBaseUrl}/functions/getReport`;
(x) => x.Signers.length > 0 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 = []; if (isSigner) {
for (const obj of listData) { let isRecord;
const isSigner = obj.Signers.some( if (obj?.AuditTrail && obj?.AuditTrail.length > 0) {
(item) => item.UserId.objectId === currentUser.id isRecord = obj?.AuditTrail.some(
); (item) =>
if (isSigner) { item?.UserPtr?.UserId?.objectId === currentUser.id &&
let isRecord; item.Activity === "Signed"
if (obj?.AuditTrail && obj?.AuditTrail.length > 0) { );
isRecord = obj?.AuditTrail.some( } else {
(item) => isRecord = false;
item?.UserPtr?.UserId?.objectId === currentUser.id && }
item.Activity === "Signed" if (isRecord === false) {
); arr.push(obj);
} 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 { } else {
setresponse(res.data[props.Data.key]); setresponse(res.data[props.Data.key]);
} }
} else {
setresponse(0);
setLoading(false);
} }
} else { });
setresponse(0); }
setLoading(false);
}
});
} catch (e) { } catch (e) {
console.error("Problem", e); console.error("Problem", e);
setLoading(false); setLoading(false);
@@ -227,13 +231,10 @@ const DashboardCard = (props) => {
let data = JSON.parse(localStorage.getItem("Extand_Class")); let data = JSON.parse(localStorage.getItem("Extand_Class"));
res = data[0]; res = data[0];
} else { } else {
var emp = Parse.Object.extend( let resr = await Parse.Cloud.run("getUserDetails", {
localStorage.getItem("extended_class") email: currentUser.get("email")
); });
var q = new Parse.Query(emp); if (res) res = resr.toJSON();
q.equalTo("UserId", currentUser);
let resr = await q.first();
res = resr.toJSON();
} }
let json = res; let json = res;
@@ -9,39 +9,58 @@ function DashboardReport(props) {
const [isLoader, setIsLoader] = useState(true); const [isLoader, setIsLoader] = useState(true);
const [reportName, setReportName] = useState(""); const [reportName, setReportName] = useState("");
const [actions, setActions] = useState([]); const [actions, setActions] = useState([]);
const [isNextRecord, setIsNextRecord] = useState(false);
const [isMoreDocs, setIsMoreDocs] = useState(true);
const abortController = new AbortController();
const docPerPage = 5;
useEffect(() => { useEffect(() => {
setReportName(""); setReportName("");
getReportData(props.Record.reportId); 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]); }, [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); setIsLoader(true);
const json = reportJson(id); const json = reportJson(id);
if (json) { if (json) {
setActions(json.actions); setActions(json.actions);
setReportName(json.reportName); setReportName(json.reportName);
const { className, params, keys, orderBy } = json;
Parse.serverURL = localStorage.getItem("BaseUrl12"); Parse.serverURL = localStorage.getItem("BaseUrl12");
Parse.initialize(localStorage.getItem("AppID12")); Parse.initialize(localStorage.getItem("AppID12"));
const serverURL = const currentUser = Parse.User.current().id;
localStorage.getItem("BaseUrl12") + "classes/" + className;
const strParams = JSON.stringify(params);
const strKeys = keys.join();
const headers = { const headers = {
"Content-Type": "application/json", "Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("AppID12"), "X-Parse-Application-Id": localStorage.getItem("AppID12"),
"X-Parse-Session-Token": localStorage.getItem("accesstoken") sessiontoken: localStorage.getItem("accesstoken")
}; };
try { try {
const url = `${serverURL}?where=${strParams}&keys=${strKeys}&order=${orderBy}&include=AuditTrail.UserPtr`; const params = { reportId: id, skip: skipUserRecord, limit: limit };
const res = await axios.get(url, { headers: headers }); const url = `${localStorage.getItem("BaseUrl12")}/functions/getReport`;
// console.log("res ", res.data?.results); const res = await axios.post(url, params, {
headers: headers,
signal: abortController.signal // is used to cancel fetch query
});
if (id === "5Go51Q7T8r") { if (id === "5Go51Q7T8r") {
const currentUser = Parse.User.current().id; const listData = res.data?.result.filter((x) => x.Signers.length > 0);
const listData = res.data?.results.filter(
(x) => x.Signers.length > 0
);
let arr = []; let arr = [];
for (const obj of listData) { for (const obj of listData) {
const isSigner = obj.Signers.some( 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 { } 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); setIsLoader(false);
} catch (err) { } catch (err) {
console.log("err ", err); const isCancel = axios.isCancel(err);
setIsLoader(false); if (!isCancel) {
console.log("err ", err);
setIsLoader(false);
}
} }
} else { } else {
setIsLoader(false); setIsLoader(false);
@@ -101,8 +140,10 @@ function DashboardReport(props) {
<ReportTable <ReportTable
ReportName={reportName} ReportName={reportName}
List={List} List={List}
act={"Sign"}
actions={actions} actions={actions}
setIsNextRecord={setIsNextRecord}
isMoreDocs={isMoreDocs}
docPerPage={docPerPage}
/> />
) : ( ) : (
<div className="flex items-center justify-center h-[100px] w-full bg-white rounded"> <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 React, { Suspense, lazy } from "react";
import moment from "moment";
import ErrorBoundary from "../ErrorBoundary"; import ErrorBoundary from "../ErrorBoundary";
const DashboardCard = lazy(() => import("./DashboardCard")); const DashboardCard = lazy(() => import("./DashboardCard"));
@@ -7,258 +6,6 @@ const DashboardCard = lazy(() => import("./DashboardCard"));
const DashboardReport = lazy(() => import("./DashboardReport")); const DashboardReport = lazy(() => import("./DashboardReport"));
const GetDashboard = (props) => { 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) => { const renderSwitchWithTour = (col) => {
switch (col.widget.type) { switch (col.widget.type) {
case "Card": case "Card":
@@ -272,7 +19,6 @@ const GetDashboard = (props) => {
<DashboardCard <DashboardCard
Icon={col.widget.icon} Icon={col.widget.icon}
Label={col.widget.label} Label={col.widget.label}
Filter={filter}
Format={col.widget.format && col.widget.format} Format={col.widget.format && col.widget.format}
Data={col.widget.data} Data={col.widget.data}
FilterData={col.widget.filter} FilterData={col.widget.filter}
@@ -281,50 +27,12 @@ const GetDashboard = (props) => {
</Suspense> </Suspense>
</div> </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": { case "report": {
let _filter = `${col.widget.filterKey}:${filter}`;
return ( return (
<div data-tut={col.widget.data.tourSection}> <div data-tut={col.widget.data.tourSection}>
<Suspense fallback={<div>please wait</div>}> <Suspense fallback={<div>please wait</div>}>
<div className="mb-4 md:mb-0"> <div className="mb-4 md:mb-0">
<DashboardReport Filter={_filter} Record={col.widget} /> <DashboardReport Record={col.widget} />
</div> </div>
</Suspense> </Suspense>
</div> </div>
@@ -346,7 +54,6 @@ const GetDashboard = (props) => {
<DashboardCard <DashboardCard
Icon={col.widget.icon} Icon={col.widget.icon}
Label={col.widget.label} Label={col.widget.label}
Filter={filter}
Format={col.widget.format && col.widget.format} Format={col.widget.format && col.widget.format}
Data={col.widget.data} Data={col.widget.data}
FilterData={col.widget.filter} FilterData={col.widget.filter}
@@ -355,48 +62,11 @@ const GetDashboard = (props) => {
</Suspense> </Suspense>
</div> </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": { case "report": {
let _filter = `${col.widget.filterKey}:${filter}`;
return ( return (
<Suspense fallback={<div>please wait</div>}> <Suspense fallback={<div>please wait</div>}>
<div className="mb-4 md:mb-0"> <div className="mb-4 md:mb-0">
<DashboardReport Filter={_filter} Record={col.widget} /> <DashboardReport Record={col.widget} />
</div> </div>
</Suspense> </Suspense>
); );
@@ -1,6 +1,6 @@
import React, { Component } from "react"; import React, { Component } from "react";
import Parse from "parse"; import Parse from "parse";
import axios from "axios"; // import axios from "axios";
export class HiddenField extends Component { export class HiddenField extends Component {
state = { state = {
@@ -37,31 +37,46 @@ export class HiddenField extends Component {
this.setState({ _fields: custome_Filed }); this.setState({ _fields: custome_Filed });
} else { } else {
if (currentUser) { if (currentUser) {
let url = `${this.state.baseUrl}classes/${localStorage.getItem( // let url = `${this.state.baseUrl}classes/${localStorage.getItem(
"extended_class" // "extended_class"
)}?where={"UserId":{"__type":"Pointer","className":"_User","objectId":"${ // )}?where={"UserId":{"__type":"Pointer","className":"_User","objectId":"${
currentUser.id // currentUser.id
}"}}&keys=${this.props.schema.data.valueKey}`; // }"}}&keys=${this.props.schema.data.valueKey}`;
const headers = { // const headers = {
"Content-Type": "application/json", // "Content-Type": "application/json",
"X-Parse-Application-Id": this.state.parseAppId // "X-Parse-Application-Id": this.state.parseAppId
}; // };
await axios.get(url, { headers: headers }).then((res) => { // await axios.get(url, { headers: headers }).then((res) => {
let custome_Filed = ""; // let custome_Filed = "";
let _rdata = res.data.results; // let _rdata = res.data.results;
let splitArray = this.props.schema.data.valueKey.split("."); // let splitArray = this.props.schema.data.valueKey.split(".");
if (splitArray.length > 1) { // if (splitArray.length > 1) {
custome_Filed = _rdata[0][splitArray[0]][splitArray[1]]; // custome_Filed = _rdata[0][splitArray[0]][splitArray[1]];
} else { // } else {
console.log(_rdata[0][splitArray[0]]); // console.log(_rdata[0][splitArray[0]]);
custome_Filed = _rdata[0][splitArray[0]]; // custome_Filed = _rdata[0][splitArray[0]];
} // }
this.setState({ _fields: custome_Filed }); // 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) { } 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")); let data = JSON.parse(localStorage.getItem("Extand_Class"));
res = data[0]; res = data[0];
} else { } else {
var emp = Parse.Object.extend( const currentUser = Parse.User.current();
localStorage.getItem("extended_class") res = await Parse.Cloud.run("getUserDetails", {
); email: currentUser.get("email")
var q = new Parse.Query(emp); });
q.equalTo("UserId", currentUser);
res = await q.first();
if (res) res = res.toJSON(); if (res) res = res.toJSON();
} }
@@ -339,7 +337,7 @@ const Level1Dropdown = (props) => {
x.className = x.className.replace("show", ""); x.className = x.className.replace("show", "");
}, 5000); }, 5000);
} catch (error) { } 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) { export default function reportJson(id) {
const currentUserId = Parse.User.current().id;
// console.log("json ", json); // console.log("json ", json);
switch (id) { switch (id) {
@@ -8,28 +6,6 @@ export default function reportJson(id) {
case "ByHuevtCFY": case "ByHuevtCFY":
return { return {
reportName: "Draft Documents", 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: [ actions: [
{ {
btnLabel: "sign", btnLabel: "sign",
@@ -45,27 +21,6 @@ export default function reportJson(id) {
case "4Hhwbp482K": case "4Hhwbp482K":
return { return {
reportName: "Need your sign", 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: [ actions: [
{ {
btnLabel: "sign", btnLabel: "sign",
@@ -81,31 +36,6 @@ export default function reportJson(id) {
case "1MwEuxLEkF": case "1MwEuxLEkF":
return { return {
reportName: "In-progress documents", 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: [ actions: [
{ {
btnLabel: "View", btnLabel: "View",
@@ -121,27 +51,6 @@ export default function reportJson(id) {
case "kQUoW4hUXz": case "kQUoW4hUXz":
return { return {
reportName: "Completed Documents", 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: [ actions: [
{ {
btnLabel: "View", 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 // declined documents report
case "UPr2Fm5WY3": case "UPr2Fm5WY3":
return { return {
reportName: "Declined Documents", 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: [ actions: [
{ {
btnLabel: "View", btnLabel: "View",
@@ -225,39 +81,6 @@ export default function reportJson(id) {
case "zNqBHXHsYH": case "zNqBHXHsYH":
return { return {
reportName: "Expired Documents", 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: [ actions: [
{ {
btnLabel: "View", btnLabel: "View",
@@ -273,31 +96,6 @@ export default function reportJson(id) {
case "d9k3UfYHBc": case "d9k3UfYHBc":
return { return {
reportName: "Recently sent for signatures", 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: [ actions: [
{ {
btnLabel: "View", btnLabel: "View",
@@ -313,27 +111,6 @@ export default function reportJson(id) {
case "5Go51Q7T8r": case "5Go51Q7T8r":
return { return {
reportName: "Recent signature requests", 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: [ actions: [
{ {
btnLabel: "Sign", btnLabel: "Sign",
@@ -349,28 +126,6 @@ export default function reportJson(id) {
case "kC5mfynCi4": case "kC5mfynCi4":
return { return {
reportName: "Drafts", 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: [ actions: [
{ {
btnLabel: "sign", btnLabel: "sign",
+4 -1
View File
@@ -6,6 +6,7 @@
"subtitle": "Free for life One click install.", "subtitle": "Free for life One click install.",
"btnText": "Visit github", "btnText": "Visit github",
"url": "https://github.com/opensignlabs/opensign", "url": "https://github.com/opensignlabs/opensign",
"target": "_blank",
"benefits": [ "benefits": [
"Sign Unlimited Documents", "Sign Unlimited Documents",
"S3 Doc Storage", "S3 Doc Storage",
@@ -26,9 +27,10 @@
"planName": "THANKS PLAN", "planName": "THANKS PLAN",
"currency": "$", "currency": "$",
"price": "29.99", "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", "btnText": "Subscribe",
"url": "https://subscriptions.zoho.in/subscribe/ef798486e6a0a11ea65f2bae8f2af901dbadf3175d495584fd25b9af5d2f2b9e/thanks", "url": "https://subscriptions.zoho.in/subscribe/ef798486e6a0a11ea65f2bae8f2af901dbadf3175d495584fd25b9af5d2f2b9e/thanks",
"target": "_self",
"benefits": [ "benefits": [
"Sign Unlimited Documents", "Sign Unlimited Documents",
"Unlimited Secure Doc Storage with OpenSignDrive", "Unlimited Secure Doc Storage with OpenSignDrive",
@@ -50,6 +52,7 @@
"subtitle": "Customization available Priority support.", "subtitle": "Customization available Priority support.",
"btnText": "Contact us", "btnText": "Contact us",
"url": "https://www.opensignlabs.com/contact-us", "url": "https://www.opensignlabs.com/contact-us",
"target": "_self",
"benefits": [ "benefits": [
"All features", "All features",
"Custom domain", "Custom domain",
+6 -15
View File
@@ -6,7 +6,7 @@ import { useWindowSize } from "../hook/useWindowSize";
import Tour from "reactour"; import Tour from "reactour";
import axios from "axios"; import axios from "axios";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import Parse from "parse";
const HomeLayout = ({ children }) => { const HomeLayout = ({ children }) => {
const { width } = useWindowSize(); const { width } = useWindowSize();
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
@@ -124,20 +124,11 @@ const HomeLayout = ({ children }) => {
}; };
async function checkTourStatus() { async function checkTourStatus() {
const serverUrl = localStorage.getItem("baseUrl"); const currentUser = Parse.User.current();
const appId = localStorage.getItem("AppID12"); const cloudRes = await Parse.Cloud.run("getUserDetails", {
const extUserClass = localStorage.getItem("extended_class"); email: currentUser.get("email")
const json = JSON.parse(localStorage.getItem("Extand_Class")); });
const extUserId = json && json.length > 0 && json[0].objectId; const res = { data: cloudRes.toJSON() };
// console.log("extUserId ", extUserId);
const res = await axios.get(
serverUrl + "classes/" + extUserClass + "/" + extUserId,
{
headers: {
"X-Parse-Application-Id": appId
}
}
);
if (res.data && res.data.TourStatus && res.data.TourStatus.length > 0) { if (res.data && res.data.TourStatus && res.data.TourStatus.length > 0) {
const tourStatus = res.data.TourStatus; const tourStatus = res.data.TourStatus;
// console.log("res ", res.data.TourStatus); // console.log("res ", res.data.TourStatus);
@@ -7,11 +7,11 @@ const ReportTable = ({
List, List,
actions, actions,
setIsNextRecord, setIsNextRecord,
isMoreDocs isMoreDocs,
docPerPage
}) => { }) => {
const navigate = useNavigate(); const navigate = useNavigate();
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const docPerPage = 10;
// const pageNumbers = []; // const pageNumbers = [];
// For loop is used to calculate page numbers visible below table // For loop is used to calculate page numbers visible below table
@@ -22,7 +22,7 @@ const ReportTable = ({
calculatedPageNumbers.push(i); calculatedPageNumbers.push(i);
} }
return calculatedPageNumbers; return calculatedPageNumbers;
}, [List]); }, [List, docPerPage]);
// below useEffect reset currenpage to 1 if user change route // below useEffect reset currenpage to 1 if user change route
useEffect(() => { useEffect(() => {
return () => setCurrentPage(1); return () => setCurrentPage(1);
@@ -154,7 +154,7 @@ const ReportTable = ({
</tbody> </tbody>
</table> </table>
<div className="flex flex-wrap items-center gap-2 p-2 "> <div className="flex flex-wrap items-center gap-2 p-2 ">
{List.length > 10 && ( {List.length > docPerPage && (
<> <>
{currentPage > 1 && ( {currentPage > 1 && (
<button <button
@@ -178,7 +178,7 @@ const ReportTable = ({
{isMoreDocs && ( {isMoreDocs && (
<button className="text-black rounded px-1 py-2">...</button> <button className="text-black rounded px-1 py-2">...</button>
)} )}
{List.length > 10 && ( {List.length > docPerPage && (
<> <>
{pageNumbers.includes(currentPage + 1) && ( {pageNumbers.includes(currentPage + 1) && (
<button <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 let _base = ""; // Define _base here and initialize it to an empty string
if (response && response.baseurl) { if (response && response.baseurl) {
_base = response.baseurl.charAt(response.baseurl.length - 1); _base = response.baseurl.charAt(response.baseurl.length - 1);
} localStorage.removeItem("baseUrl"); }
localStorage.removeItem("baseUrl");
localStorage.setItem("_appName", response.appname); localStorage.setItem("_appName", response.appname);
localStorage.setItem("_app_objectId", response.objectId); localStorage.setItem("_app_objectId", response.objectId);
if (_base === "/") { if (_base === "/") {
@@ -120,16 +121,11 @@ export const login = (username, password) => async (dispatch) => {
localStorage.setItem("_user_role", _role); localStorage.setItem("_user_role", _role);
} }
try { try {
const tour = Parse.Object.extend( const currentUser = Parse.User.current();
localStorage.getItem("extended_class") await Parse.Cloud.run("getUserDetails", {
); email: currentUser.get("email")
let _tour = new Parse.Query(tour); })
_tour.equalTo("UserId", { .then(
__type: "Pointer",
className: "_User",
objectId: resultjson.objectId
});
await _tour.first().then(
(results) => { (results) => {
let userinfo = results.toJSON(); let userinfo = results.toJSON();
if (userinfo.TenantId) { if (userinfo.TenantId) {
@@ -142,7 +138,7 @@ export const login = (username, password) => async (dispatch) => {
} }
); );
} catch (error) { } catch (error) {
console.log("err ", error) console.log("err ", error);
} }
} }
}); });
+74 -93
View File
@@ -10,9 +10,11 @@ import GoogleSignInBtn from "../components/LoginGoogle";
// import LoginFacebook from "../components/LoginFacebook"; // import LoginFacebook from "../components/LoginFacebook";
import { NavLink, useNavigate } from "react-router-dom"; import { NavLink, useNavigate } from "react-router-dom";
import login_img from "../assets/images/login_img.svg"; import login_img from "../assets/images/login_img.svg";
import { useWindowSize } from "../hook/useWindowSize";
function Login(props) { function Login(props) {
const navigate = useNavigate(); const navigate = useNavigate();
const { width } = useWindowSize();
const [state, setState] = useState({ const [state, setState] = useState({
email: "", email: "",
toastColor: "#5cb85c", toastColor: "#5cb85c",
@@ -21,7 +23,6 @@ function Login(props) {
passwordVisible: false, passwordVisible: false,
mobile: "", mobile: "",
phone: "", phone: "",
hideNav: "",
scanResult: "", scanResult: "",
baseUrl: localStorage.getItem("baseUrl"), baseUrl: localStorage.getItem("baseUrl"),
parseAppId: localStorage.getItem("parseAppId"), parseAppId: localStorage.getItem("parseAppId"),
@@ -47,26 +48,11 @@ function Login(props) {
); );
// eslint-disable-next-line // eslint-disable-next-line
}, []); }, []);
useEffect(() => {
resize();
window.addEventListener("resize", resize());
return () => {
window.removeEventListener("resize", resize());
};
// eslint-disable-next-line
}, []);
const handleChange = (event) => { const handleChange = (event) => {
const { name, value } = event.target; const { name, value } = event.target;
setState({ ...state, [name]: value }); setState({ ...state, [name]: value });
}; };
const resize = () => {
let currentHideNav = window.innerWidth <= 760;
if (currentHideNav !== state.hideNav) {
setState({ ...state, hideNav: currentHideNav });
}
};
const handleSubmit = async (event) => { const handleSubmit = async (event) => {
localStorage.removeItem("accesstoken"); localStorage.removeItem("accesstoken");
event.preventDefault(); event.preventDefault();
@@ -162,15 +148,13 @@ function Login(props) {
element.userpointer element.userpointer
); );
const extendedClass = Parse.Object.extend( const currentUser = Parse.User.current();
element.extended_class await Parse.Cloud.run("getUserDetails", {
); email: currentUser.get("email")
let query = new Parse.Query(extendedClass); }).then(
query.equalTo("UserId", Parse.User.current()); (result) => {
query.include("TenantId");
await query.find().then(
(results) => {
let tenentInfo = []; let tenentInfo = [];
const results = [result];
if (results) { if (results) {
let extendedInfo_stringify = let extendedInfo_stringify =
JSON.stringify(results); JSON.stringify(results);
@@ -280,10 +264,14 @@ function Login(props) {
`/${element.pageType}/${element.pageId}` `/${element.pageType}/${element.pageId}`
); );
} else { } else {
navigate(`/subscription`); navigate(`/subscription`, {
replace: true
});
} }
} else { } else {
navigate(`/subscription`); navigate(`/subscription`, {
replace: true
});
} }
} else { } else {
navigate( navigate(
@@ -320,7 +308,9 @@ function Login(props) {
); );
const billingDate = ""; const billingDate = "";
if (billingDate) { if (billingDate) {
navigate(`/subscription`); navigate(`/subscription`, {
replace: true
});
} }
} else { } else {
navigate( navigate(
@@ -334,23 +324,6 @@ function Login(props) {
sessionToken: user.getSessionToken() sessionToken: user.getSessionToken()
}; };
handleSubmitbtn(payload); 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( console.error(
"Error while fetching Follow", "Error while fetching Follow",
error error
@@ -502,16 +475,13 @@ function Login(props) {
element.extended_class element.extended_class
); );
localStorage.setItem("userpointer", element.userpointer); localStorage.setItem("userpointer", element.userpointer);
const currentUser = Parse.User.current();
const extendedClass = Parse.Object.extend( await Parse.Cloud.run("getUserDetails", {
element.extended_class email: currentUser.get("email")
); }).then(
let query = new Parse.Query(extendedClass); (result) => {
query.equalTo("UserId", Parse.User.current());
query.include("TenantId");
await query.find().then(
(results) => {
let tenentInfo = []; let tenentInfo = [];
const results = [result];
if (results) { if (results) {
let extendedInfo_stringify = let extendedInfo_stringify =
JSON.stringify(results); JSON.stringify(results);
@@ -596,20 +566,26 @@ function Login(props) {
setThirdpartyLoader(false); setThirdpartyLoader(false);
setState({ ...state, loading: false }); setState({ ...state, loading: false });
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) { if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
if (billingDate) { if (billingDate) {
if (billingDate > new Date()) { if (billingDate > new Date()) {
localStorage.removeItem("userDetails"); localStorage.removeItem("userDetails");
navigate( navigate(
`/${element.pageType}/${element.pageId}` `/${element.pageType}/${element.pageId}`
); );
} else {
navigate(`/subscription`, {
replace: true
});
}
} else { } else {
navigate(`/subscription`); navigate(`/subscription`, { replace: true });
} }
} else { } else {
navigate(`/subscription`); navigate(
`/${element.pageType}/${element.pageId}`
);
} }
} }
}
} else { } else {
localStorage.setItem("PageLanding", element.pageId); localStorage.setItem("PageLanding", element.pageId);
localStorage.setItem( localStorage.setItem(
@@ -620,21 +596,25 @@ function Login(props) {
setState({ ...state, loading: false }); setState({ ...state, loading: false });
setThirdpartyLoader(false); setThirdpartyLoader(false);
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) { if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
if (billingDate) { if (billingDate) {
if (billingDate > new Date()) { if (billingDate > new Date()) {
localStorage.removeItem("userDetails"); localStorage.removeItem("userDetails");
navigate( navigate(
`/${element.pageType}/${element.pageId}` `/${element.pageType}/${element.pageId}`
); );
} else {
navigate(`/subscription`, { replace: true });
}
} else { } else {
navigate(`/subscription`); navigate(`/subscription`, { replace: true });
} }
} else { } else {
navigate(`/subscription`); navigate(
`/${element.pageType}/${element.pageId}`
);
} }
} }
} },
},
(error) => { (error) => {
const payload = { const payload = {
sessionToken: sessionToken sessionToken: sessionToken
@@ -655,7 +635,6 @@ function Login(props) {
} else { } else {
setThirdpartyLoader(false); setThirdpartyLoader(false);
setState({ ...state, loading: false }); setState({ ...state, loading: false });
} }
}) })
.catch((err) => { .catch((err) => {
@@ -717,9 +696,10 @@ function Login(props) {
await axios await axios
.post(url, JSON.stringify(body), { headers: headers1 }) .post(url, JSON.stringify(body), { headers: headers1 })
.then((roles) => { .then((axiosres) => {
const roles = axiosres.data.result;
if (roles) { if (roles) {
userRoles = roles.data.result; userRoles = roles;
let _currentRole = ""; let _currentRole = "";
if (userRoles.length > 1) { if (userRoles.length > 1) {
if ( if (
@@ -767,15 +747,13 @@ function Login(props) {
element.extended_class element.extended_class
); );
const extendedClass = Parse.Object.extend( const currentUser = Parse.User.current();
element.extended_class await Parse.Cloud.run("getUserDetails", {
); email: currentUser.get("email")
let query = new Parse.Query(extendedClass); }).then(
query.equalTo("UserId", Parse.User.current()); (result) => {
query.include("TenantId");
await query.find().then(
(results) => {
let tenentInfo = []; let tenentInfo = [];
const results = [result];
if (results) { if (results) {
let extendedInfo_stringify = JSON.stringify(results); let extendedInfo_stringify = JSON.stringify(results);
let extendedInfo = JSON.parse(extendedInfo_stringify); let extendedInfo = JSON.parse(extendedInfo_stringify);
@@ -1066,7 +1044,7 @@ function Login(props) {
<NavLink <NavLink
className="rounded-sm cursor-pointer bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] w-full py-3 shadow uppercase" className="rounded-sm cursor-pointer bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] w-full py-3 shadow uppercase"
to="/signup" to="/signup"
style={state.hideNav ? { textAlign: "center" } : {}} style={width < 768 ? { textAlign: "center" } : {}}
> >
Create Account Create Account
</NavLink> </NavLink>
@@ -1134,7 +1112,7 @@ function Login(props) {
</div> </div>
</div> </div>
</div> </div>
{!state.hideNav && ( {width >= 768 && (
<div className="self-center"> <div className="self-center">
<div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]"> <div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]">
<img <img
@@ -1171,7 +1149,9 @@ function Login(props) {
<div className="modal-dialog" role="document"> <div className="modal-dialog" role="document">
<div className="modal-content"> <div className="modal-content">
<div className="modal-header"> <div className="modal-header">
<h5 className="modal-title">Login form</h5> <h5 className="modal-title font-semibold">
Additional Info
</h5>
<span> <span>
<span></span> <span></span>
</span> </span>
@@ -1227,18 +1207,19 @@ function Login(props) {
<div className="mt-4"> <div className="mt-4">
<button <button
type="button" type="button"
className="bg-[#6c757d] text-sm p-2 text-white rounded uppercase" className="bg-[#17a2b8] text-sm p-2 text-white rounded uppercase"
onClick={handleCloseModal} onClick={(e) => handleSubmitbtn(e)}
style={{ marginRight: 10, width: 90 }} style={{ marginRight: 10 }}
> >
Cancel Login
</button> </button>
<button <button
type="button" type="button"
className="bg-[#17a2b8] text-sm p-2 text-white rounded uppercase" className="bg-[#6c757d] text-sm p-2 text-white rounded uppercase"
onClick={(e) => handleSubmitbtn(e)} onClick={handleCloseModal}
style={{ width: 90 }}
> >
Login Cancel
</button> </button>
</div> </div>
</form> </form>
+13 -22
View File
@@ -67,9 +67,8 @@ const PgSignUp = (props) => {
const userSettings = JSON.parse(localStorage.getItem("userSettings")); const userSettings = JSON.parse(localStorage.getItem("userSettings"));
const extClass = userSettings[0].extended_class; const extClass = userSettings[0].extended_class;
// console.log("extClass ", extClass); // console.log("extClass ", extClass);
const checkUser = new Parse.Query(extClass); const params = { email: userDetails.email };
checkUser.equalTo("Email", userDetails.email); const res = await Parse.Cloud.run("getUserDetails", params);
const res = await checkUser.first();
// console.log("res", res); // console.log("res", res);
if (res) { if (res) {
const checkUser = new Parse.Query(extClass); const checkUser = new Parse.Query(extClass);
@@ -152,6 +151,7 @@ const PgSignUp = (props) => {
if (res) { if (res) {
const params = { const params = {
userDetails: { userDetails: {
jobTitle: zohoRes.data.result.jobTitle,
company: zohoRes.data.result.company, company: zohoRes.data.result.company,
name: zohoRes.data.result.name, name: zohoRes.data.result.name,
email: zohoRes.data.result.email, email: zohoRes.data.result.email,
@@ -279,13 +279,6 @@ const PgSignUp = (props) => {
"" ""
); );
localStorage.setItem("_user_role", _role); 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 // Get TenentID from Extendend Class
localStorage.setItem( localStorage.setItem(
"extended_class", "extended_class",
@@ -293,14 +286,12 @@ const PgSignUp = (props) => {
); );
localStorage.setItem("userpointer", element.userpointer); localStorage.setItem("userpointer", element.userpointer);
const extendedClass = Parse.Object.extend( const currentUser = Parse.User.current();
element.extended_class await Parse.Cloud.run("getUserDetails", {
); email: currentUser.get("email")
let query = new Parse.Query(extendedClass); }).then(
query.equalTo("UserId", Parse.User.current()); (result) => {
query.include("TenantId"); const results = [result];
await query.find().then(
(results) => {
let tenentInfo = []; let tenentInfo = [];
if (results) { if (results) {
let extendedInfo_stringify = let extendedInfo_stringify =
@@ -415,7 +406,7 @@ const PgSignUp = (props) => {
} }
}) })
.catch((err) => { .catch((err) => {
console.log('err', err) console.log("err", err);
setIsLoader(false); setIsLoader(false);
}); });
} }
@@ -448,10 +439,10 @@ const PgSignUp = (props) => {
) : ( ) : (
<form id="signup" className="pgsignup-content" onSubmit={handleSubmit}> <form id="signup" className="pgsignup-content" onSubmit={handleSubmit}>
<div className="pgsignup-container"> <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" /> <hr className="hrt" />
<label htmlFor="password"> <label htmlFor="password">
<b>Password</b> <b className="text-[13px]">Password</b>
</label> </label>
<input <input
type="password" type="password"
@@ -464,7 +455,7 @@ const PgSignUp = (props) => {
/> />
<label htmlFor="confirmPassword"> <label htmlFor="confirmPassword">
<b>Confirm Password</b> <b className="text-[13px]">Confirm Password</b>
</label> </label>
<input <input
type="password" type="password"
+19 -16
View File
@@ -2,14 +2,14 @@ import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router"; import { useNavigate } from "react-router";
import { NavLink } from "react-router-dom"; import { NavLink } from "react-router-dom";
import checkmark from "../assets/images/checkmark.png"; import checkmark from "../assets/images/checkmark.png";
import plansArr from '../json/plansArr.json' import plansArr from "../json/plansArr.json";
import Title from "../components/Title"; import Title from "../components/Title";
const listItemStyle = { 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 backgroundImage: `url(${checkmark})`, // Set your image as the list style image
backgroundPosition: 'left', backgroundPosition: "left",
backgroundRepeat: 'no-repeat', backgroundRepeat: "no-repeat",
backgroundSize: '16px 16px', // Adjust the size of the image backgroundSize: "16px 16px" // Adjust the size of the image
}; };
const PlanSubscriptions = () => { const PlanSubscriptions = () => {
@@ -28,7 +28,12 @@ const PlanSubscriptions = () => {
: ""; : "";
const phone = const phone =
userDetails && userDetails.phone ? "&mobile=" + userDetails.phone : ""; userDetails && userDetails.phone ? "&mobile=" + userDetails.phone : "";
const details = "?" + name + email + company + phone; const details =
"?shipping_country_code=US&billing_country_code=US&billing_state_code=CA&" +
name +
email +
company +
phone;
useEffect(() => { useEffect(() => {
if (localStorage.getItem("accesstoken")) { if (localStorage.getItem("accesstoken")) {
setIsLoader(false); setIsLoader(false);
@@ -41,7 +46,7 @@ const PlanSubscriptions = () => {
return ( return (
<> <>
<Title title={"Subscriptions"} /> <Title title={"Subscriptions"} />
{isLoader ? ( {isLoader ? (
<div <div
style={{ style={{
@@ -131,15 +136,13 @@ const PlanSubscriptions = () => {
<p>{item.subtitle}</p> <p>{item.subtitle}</p>
</div> </div>
</div> </div>
<div className="bg-[#002862] w-full text-white py-2 rounded"> <NavLink
<NavLink to={item.url + details}
to={item.url + details} className="bg-[#002862] w-full text-white py-2 rounded uppercase hover:no-underline hover:text-white"
className="rounded uppercase hover:no-underline hover:text-white" target={item.target}
target="_self" >
> {item.btnText}
{item.btnText} </NavLink>
</NavLink>
</div>
</div> </div>
<hr className="w-full bg-gray-300 p-[.5px]" /> <hr className="w-full bg-gray-300 p-[.5px]" />
<ul className="mx-1 p-3 text-left break-words text-sm list-none"> <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 [isNextRecord, setIsNextRecord] = useState(false);
const [isMoreDocs, setIsMoreDocs] = useState(true); const [isMoreDocs, setIsMoreDocs] = useState(true);
const abortController = new AbortController(); const abortController = new AbortController();
const docPerPage = 10;
// below useEffect is call when id param change // below useEffect is call when id param change
useEffect(() => { useEffect(() => {
@@ -47,30 +48,24 @@ const Report = () => {
if (json) { if (json) {
setActions(json.actions); setActions(json.actions);
setReportName(json.reportName); setReportName(json.reportName);
const { className, params, keys, orderBy } = json;
Parse.serverURL = localStorage.getItem("BaseUrl12"); Parse.serverURL = localStorage.getItem("BaseUrl12");
Parse.initialize(localStorage.getItem("AppID12")); Parse.initialize(localStorage.getItem("AppID12"));
const currentUser = Parse.User.current().id; const currentUser = Parse.User.current().id;
const serverURL =
localStorage.getItem("BaseUrl12") + "classes/" + className;
const strParams = JSON.stringify(params);
const strKeys = keys.join();
const headers = { const headers = {
"Content-Type": "application/json", "Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("AppID12"), "X-Parse-Application-Id": localStorage.getItem("AppID12"),
"X-Parse-Session-Token": localStorage.getItem("accesstoken") sessiontoken: localStorage.getItem("accesstoken")
}; };
try { try {
const url = `${serverURL}?where=${strParams}&keys=${strKeys}&order=${orderBy}&skip=${skipUserRecord}&limit=${limit}&include=AuditTrail.UserPtr`; const params = { reportId: id, skip: skipUserRecord, limit: limit };
const res = await axios.get(url, { const url = `${localStorage.getItem("BaseUrl12")}/functions/getReport`;
const res = await axios.post(url, params, {
headers: headers, headers: headers,
signal: abortController.signal // is used to cancel fetch query signal: abortController.signal // is used to cancel fetch query
}); });
if (id === "4Hhwbp482K") { if (id === "4Hhwbp482K") {
const listData = res.data?.results.filter( const listData = res.data?.result.filter((x) => x.Signers.length > 0);
(x) => x.Signers.length > 0
);
let arr = []; let arr = [];
for (const obj of listData) { for (const obj of listData) {
const isSigner = obj.Signers.some( const isSigner = obj.Signers.some(
@@ -92,7 +87,7 @@ const Report = () => {
} }
} }
} }
if (arr.length === 10) { if (arr.length === docPerPage) {
setIsMoreDocs(true); setIsMoreDocs(true);
} else { } else {
setIsMoreDocs(false); setIsMoreDocs(false);
@@ -101,17 +96,16 @@ const Report = () => {
prevRecord.length > 0 ? [...prevRecord, ...arr] : arr prevRecord.length > 0 ? [...prevRecord, ...arr] : arr
); );
} else { } else {
if (res.data.results.length === 10) { if (res.data.result.length === docPerPage) {
setIsMoreDocs(true); setIsMoreDocs(true);
console.log("here");
} else { } else {
setIsMoreDocs(false); setIsMoreDocs(false);
} }
setIsNextRecord(false); setIsNextRecord(false);
setList((prevRecord) => setList((prevRecord) =>
prevRecord.length > 0 prevRecord.length > 0
? [...prevRecord, ...res.data.results] ? [...prevRecord, ...res.data.result]
: res.data.results : res.data.result
); );
} }
setIsLoader(false); setIsLoader(false);
@@ -155,6 +149,7 @@ const Report = () => {
actions={actions} actions={actions}
setIsNextRecord={setIsNextRecord} setIsNextRecord={setIsNextRecord}
isMoreDocs={isMoreDocs} isMoreDocs={isMoreDocs}
docPerPage={docPerPage}
/> />
) : ( ) : (
<div className="flex items-center justify-center h-screen w-full bg-white rounded"> <div className="flex items-center justify-center h-screen w-full bg-white rounded">
+33 -80
View File
@@ -6,8 +6,10 @@ import Title from "../components/Title";
import { fetchAppInfo, showTenantName } from "../redux/actions"; import { fetchAppInfo, showTenantName } from "../redux/actions";
import { useNavigate, NavLink } from "react-router-dom"; import { useNavigate, NavLink } from "react-router-dom";
import login_img from "../assets/images/login_img.svg"; import login_img from "../assets/images/login_img.svg";
import { useWindowSize } from "../hook/useWindowSize";
const Signup = (props) => { const Signup = (props) => {
const { width } = useWindowSize();
const navigate = useNavigate(); const navigate = useNavigate();
const [name, setName] = useState(""); const [name, setName] = useState("");
const [phone, setPhone] = useState(""); const [phone, setPhone] = useState("");
@@ -18,7 +20,6 @@ const Signup = (props) => {
const [company, setCompany] = useState(""); const [company, setCompany] = useState("");
const [jobTitle, setJobTitle] = useState(""); const [jobTitle, setJobTitle] = useState("");
const [state, setState] = useState({ const [state, setState] = useState({
hideNav: "",
loading: false, loading: false,
toastColor: "#5cb85c", toastColor: "#5cb85c",
toastDescription: "" toastDescription: ""
@@ -52,58 +53,34 @@ const Signup = (props) => {
res res
.then(async (r) => { .then(async (r) => {
if (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; let roleData = props.appInfo.settings;
if (roleData && roleData.length > 0) { if (roleData && roleData.length > 0) {
roleData.forEach((rld) => { const params = {
if (rld.role === props.appInfo.defaultRole) { userDetails: {
const extCls = Parse.Object.extend(rld.extended_class); jobTitle: jobTitle,
const newObj = new extCls(); company: company,
newObj.set("UserId", { name: name,
__type: "Pointer", email: email,
className: "_User", phone: phone,
objectId: r.id role: props.appInfo.defaultRole
});
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 });
});
} }
}); };
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) => { .catch(async (err) => {
if (err.code === 202) { if (err.code === 202) {
const userQuery = new Parse.Query("contracts_Users"); const params = { email: email };
userQuery.equalTo("Email", email); const res = await Parse.Cloud.run("getUserDetails", params);
const res = await userQuery.first();
// console.log("Res ", res); // console.log("Res ", res);
if (res) { if (res) {
alert("User already exists with this username!"); alert("User already exists with this username!");
@@ -118,7 +95,7 @@ const Signup = (props) => {
await Parse.User.requestPasswordReset(email).then( await Parse.User.requestPasswordReset(email).then(
async function (res1) { async function (res1) {
if (res1.data === undefined) { if (res1.data === undefined) {
alert("Email has been sent to your mail!"); alert("Verification mail has been sent to your E-mail!");
} }
} }
); );
@@ -208,13 +185,6 @@ const Signup = (props) => {
"" ""
); );
localStorage.setItem("_user_role", _role); 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 // Get TenentID from Extendend Class
localStorage.setItem( localStorage.setItem(
"extended_class", "extended_class",
@@ -222,15 +192,12 @@ const Signup = (props) => {
); );
localStorage.setItem("userpointer", element.userpointer); localStorage.setItem("userpointer", element.userpointer);
const extendedClass = Parse.Object.extend( await Parse.Cloud.run("getUserDetails", {
element.extended_class email: email
); }).then(
let query = new Parse.Query(extendedClass); (result) => {
query.equalTo("UserId", Parse.User.current());
query.include("TenantId");
await query.find().then(
(results) => {
let tenentInfo = []; let tenentInfo = [];
const results = [result];
if (results) { if (results) {
let extendedInfo_stringify = let extendedInfo_stringify =
JSON.stringify(results); JSON.stringify(results);
@@ -318,7 +285,7 @@ const Signup = (props) => {
); );
setState({ loading: false }); setState({ loading: false });
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) { if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
navigate("/subscription"); navigate(`/subscription`, { replace: true });
} else { } else {
alert("Registered user successfully"); alert("Registered user successfully");
navigate( navigate(
@@ -336,7 +303,7 @@ const Signup = (props) => {
localStorage.setItem("pageType", element.pageType); localStorage.setItem("pageType", element.pageType);
setState({ loading: false }); setState({ loading: false });
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) { if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
navigate("/subscription"); navigate(`/subscription`, { replace: true });
} else { } else {
navigate( navigate(
`/${element.pageType}/${element.pageId}` `/${element.pageType}/${element.pageId}`
@@ -421,24 +388,14 @@ const Signup = (props) => {
} }
}; };
useEffect(() => { useEffect(() => {
window.addEventListener("resize", resize);
props.fetchAppInfo( props.fetchAppInfo(
localStorage.getItem("domain"), localStorage.getItem("domain"),
localStorage.getItem("BaseUrl12"), localStorage.getItem("BaseUrl12"),
localStorage.getItem("AppID12") localStorage.getItem("AppID12")
); );
return () => {
window.removeEventListener("resize", resize);
};
// eslint-disable-next-line // eslint-disable-next-line
}, []); }, []);
const resize = () => {
let currentHideNav = window.innerWidth <= 760;
if (currentHideNav !== state.hideNav) {
setState({ hideNav: currentHideNav });
}
};
return ( return (
<div className="bg-white"> <div className="bg-white">
{state.loading && ( {state.loading && (
@@ -472,11 +429,7 @@ const Signup = (props) => {
<div> <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="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"> <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>
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2"> <div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
<div className=""> <div className="">
@@ -584,14 +537,14 @@ const Signup = (props) => {
<NavLink <NavLink
className="rounded-sm cursor-pointer bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] w-full py-3 shadow uppercase" className="rounded-sm cursor-pointer bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] w-full py-3 shadow uppercase"
to="/" to="/"
style={state.hideNav ? { textAlign: "center" } : {}} style={width < 768 ? { textAlign: "center" } : {}}
> >
Login Login
</NavLink> </NavLink>
</div> </div>
</form> </form>
</div> </div>
{!state.hideNav && ( {width >= 768 && (
<div className="self-center"> <div className="self-center">
<div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]"> <div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]">
<img src={login_img} alt="bisec" width="100%" /> <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 dp from "../assets/images/dp.png";
import Title from "../components/Title"; import Title from "../components/Title";
import sanitizeFileName from "../primitives/sanitizeFileName"; import sanitizeFileName from "../primitives/sanitizeFileName";
import axios from "axios";
function UserProfile() { function UserProfile() {
const navigate = useNavigate(); const navigate = useNavigate();
let UserProfile = JSON.parse(localStorage.getItem("UserInformation")); let UserProfile = JSON.parse(localStorage.getItem("UserInformation"));
@@ -16,6 +16,8 @@ function UserProfile() {
const [Phone, SetPhone] = useState(UserProfile && UserProfile.phone); const [Phone, SetPhone] = useState(UserProfile && UserProfile.phone);
const [Image, setImage] = useState(localStorage.getItem("profileImg")); const [Image, setImage] = useState(localStorage.getItem("profileImg"));
const [isLoader, setIsLoader] = useState(false); const [isLoader, setIsLoader] = useState(false);
const [percentage, setpercentage] = useState(0);
Parse.serverURL = parseBaseUrl; Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId); Parse.initialize(parseAppId);
const handleSubmit = async (e) => { const handleSubmit = async (e) => {
@@ -44,7 +46,7 @@ function UserProfile() {
await updateExtUser({ Name: res.name, Phone: res.phone }); await updateExtUser({ Name: res.name, Phone: res.phone });
alert("Profile updated successfully."); alert("Profile updated successfully.");
setEditMode(false); setEditMode(false);
navigate("/"); navigate("/dashboard/35KBoSgoAK");
} }
}, },
(error) => { (error) => {
@@ -64,18 +66,24 @@ function UserProfile() {
const extClass = localStorage.getItem("extended_class"); const extClass = localStorage.getItem("extended_class");
const extData = JSON.parse(localStorage.getItem("Extand_Class")); const extData = JSON.parse(localStorage.getItem("Extand_Class"));
const ExtUserId = extData[0].objectId; const ExtUserId = extData[0].objectId;
// console.log("extData ", extData);
// console.log("UserId ", ExtUserId); // 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 json = JSON.parse(JSON.stringify([res]));
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 extRes = JSON.stringify(json); const extRes = JSON.stringify(json);
localStorage.setItem("Extand_Class", extRes); localStorage.setItem("Extand_Class", extRes);
@@ -96,7 +104,15 @@ function UserProfile() {
const parseFile = new Parse.File(name, pdfFile); const parseFile = new Parse.File(name, pdfFile);
try { 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 // // The response object will contain information about the uploaded file
// console.log("File uploaded:", response); // console.log("File uploaded:", response);
@@ -105,6 +121,7 @@ function UserProfile() {
if (response.url()) { if (response.url()) {
setImage(response.url()); setImage(response.url());
localStorage.setItem("profileImg", response.url()); localStorage.setItem("profileImg", response.url());
setpercentage(0);
SaveFileSize(size, response.url()); SaveFileSize(size, response.url());
return response.url(); return response.url();
} }
@@ -154,14 +171,25 @@ function UserProfile() {
<input <input
type="file" type="file"
className="max-w-[270px] text-sm py-1 px-2 mt-4 border-[1px] border-[#15b4e9] text-black rounded" 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) => { onChange={(e) => {
let files = e.target.files; let files = e.target.files;
fileUpload(files[0]); 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"> <div className="text-base font-semibold pt-4">
{" "}
{localStorage.getItem("_user_role")} {localStorage.getItem("_user_role")}
</div> </div>
</div> </div>
@@ -214,26 +242,11 @@ function UserProfile() {
</li> </li>
</ul> </ul>
<div className="flex justify-center pb-4"> <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 ? ( {editmode ? (
<button <button
type="button" type="button"
onClick={handleSubmit} 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 Save
</button> </button>
@@ -243,11 +256,26 @@ function UserProfile() {
onClick={() => { onClick={() => {
setEditMode(true); 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 Edit
</button> </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>
</div> </div>
)} )}
+28 -8
View File
@@ -1,12 +1,14 @@
/* Full-width input fields */ /* Full-width input fields */
.inputt { .inputt {
width: 100%; width: 100%;
padding: 15px; padding: 8px;
margin: 5px 0 22px 0; margin-bottom: 10px;
/* margin: 5px 0 14px 0; */
display: inline-block; display: inline-block;
border: none; border: none;
background: #f1f1f1; background: #f1f1f1;
color: black; color: black;
font-size: 12px;
} }
/* Add a background color when the inputs get focus */ /* Add a background color when the inputs get focus */
@@ -18,11 +20,12 @@
.confirmInputt { .confirmInputt {
width: 100%; width: 100%;
padding: 15px; padding: 8px;
margin: 5px 0 1px 0; /* margin: 5px 0 14px 0; */
display: inline-block; display: inline-block;
background: #f1f1f1; background: #f1f1f1;
color: black; color: black;
font-size: 12px;
} }
.inputt::placeholder, .inputt::placeholder,
@@ -42,11 +45,10 @@
.signupbtn { .signupbtn {
background-color: #15b4e9; background-color: #15b4e9;
color: white; color: white;
padding: 14px 20px; padding: 12px 12px;
margin: 8px 0; margin: 8px 0;
border: none; border: none;
cursor: pointer; cursor: pointer;
width: 100%;
opacity: 0.9; opacity: 0.9;
float: left; float: left;
width: 50%; width: 50%;
@@ -87,7 +89,7 @@
margin: 5% auto 15% auto; margin: 5% auto 15% auto;
/* 5% from the top, 15% from the bottom and centered */ /* 5% from the top, 15% from the bottom and centered */
border: 1px solid #888; border: 1px solid #888;
width: 80%; width: 50%;
/* Could be more or less, depending on screen size */ /* 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 */ /* 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 { .signupbtn {
width: 100%; 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 SendMailv1 from './parsefunction/SendMailv1.js';
import AuthLoginAsMail from './parsefunction/AuthLoginAsMail.js'; import AuthLoginAsMail from './parsefunction/AuthLoginAsMail.js';
import getUserId from './parsefunction/getUserId.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('AddUserToRole', addUserToGroups);
Parse.Cloud.define('UserGroups', getUserGroups); Parse.Cloud.define('UserGroups', getUserGroups);
@@ -29,3 +33,7 @@ Parse.Cloud.define('SendOTPMailV1', sendMailOTPv1);
Parse.Cloud.define('sendmail', SendMailv1); Parse.Cloud.define('sendmail', SendMailv1);
Parse.Cloud.define('AuthLoginAsMail', AuthLoginAsMail); Parse.Cloud.define('AuthLoginAsMail', AuthLoginAsMail);
Parse.Cloud.define('getUserId', getUserId); 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 recipient = request.params.email;
const otp = request.params.otp; const otp = request.params.otp;
const res = await Parse.Cloud.sendEmail({ 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, recipient: recipient,
subject: 'Your OpenSign™ OTP', subject: 'Your OpenSign™ OTP',
text: 'This email is a test.', 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 &&
userData.data.data.subscription.customer.company_name) || userData.data.data.subscription.customer.company_name) ||
''; '';
const jobTitle =
(userData.data.data.subscription.customer &&
userData.data.data.subscription.customer.cd_job_title) ||
'';
const resData = { const resData = {
phone: userData.data.data.subscription.contactpersons[0].mobile, phone: userData.data.data.subscription.contactpersons[0].mobile,
name: first_name + ' ' + last_name, name: first_name + ' ' + last_name,
email: userData.data.data.subscription.contactpersons[0].email, email: userData.data.data.subscription.contactpersons[0].email,
nextBillingDate: userData.data.expiring_time, nextBillingDate: userData.data.data.subscription.next_billing_at,
company: company_name, company: company_name,
plan: userData.data.data.subscription.plan, plan: userData.data.data.subscription.plan,
customer_id: userData.data.data.subscription.customer_id, customer_id: userData.data.data.subscription.customer_id,
subscription_id: userData.data.data.subscription.subscription_id, subscription_id: userData.data.data.subscription.subscription_id,
jobTitle: jobTitle,
}; };
return resData; 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, url: a,
from: 'OpenSign™', from: 'OpenSign™',
recipient: e.receiver, recipient: e.receiver,
subject: `Document ${s} has beeen signed by all parties`, subject: `Document ${s} has been signed by all parties`,
pdfName: s, pdfName: s,
html: 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" + "<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: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-Parse-Application-Id': APPID, 'X-Parse-Application-Id': APPID,
'X-Parse-Session-Token': s.headers.sessiontoken, 'X-Parse-Master-Key': masterKEY,
}, },
}), }),
d = await axios.get(serverUrl + '/users/me', { 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, { : ((a = await axios.get(serverUrl + '/classes/contracts_Users?where=' + m, {
headers: { headers: {
'X-Parse-Application-Id': APPID, 'X-Parse-Application-Id': APPID,
'X-Parse-Session-Token': s.headers.sessiontoken, 'X-Parse-Master-Key': masterKEY,
}, },
})), })),
'contracts_Users') 'contracts_Users')
@@ -142,7 +142,7 @@ async function PDF(s, r) {
(c = await axios.get(serverUrl + '/classes/contracts_Users?where=' + p, { (c = await axios.get(serverUrl + '/classes/contracts_Users?where=' + p, {
headers: { headers: {
'X-Parse-Application-Id': APPID, 'X-Parse-Application-Id': APPID,
'X-Parse-Session-Token': s.headers.sessiontoken, 'X-Parse-Master-Key': masterKEY,
}, },
})).data && 0 < c.data.results.length })).data && 0 < c.data.results.length
? ((a = c), 'contracts_Users') ? ((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 /Img${t.index} ${t.index} 0 R
>> >>
/Font << /Font <<
/f1 ${n.index} 0 R /f1 ${n.index} 0 R
>> >>
>>`,MediaBox:[0,0,197,70],Subtype:"Form"},null,getStream(t.index))}const getStream=e=>getConvertedText(` >>`,MediaBox:[0,10,200,60],Subtype:"Form"},null,getStream(t.index))}const getStream=e=>getConvertedText(`
1.0 1.0 1.0 rg 1.0 1.0 1.0 rg
0.0 0.0 0.0 RG 0.0 0.0 0.0 RG
q q
q q
200 0 0 50 0 10 cm 200 0 0 50 0 10 cm
/Img${e} Do /Img${e} Do
Q Q
0 0 0 rg 0 0 0 rg
BT BT
0 Tr 0 Tr
/f1 10.0 Tf /f1 10.0 Tf
1.4 0 0 1 20 45.97412 Tm 1.4 0 0 1 20 45.97412 Tm
ET ET
BT BT
0 Tr 0 Tr
/f1 10.0 Tf /f1 10.0 Tf
1.4 0 0 1 20 33.56006 Tm 1.4 0 0 1 20 33.56006 Tm
ET 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 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>> <</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 fs from 'node:fs';
import https from 'https';
import formData from 'form-data'; import formData from 'form-data';
import Mailgun from 'mailgun.js'; import Mailgun from 'mailgun.js';
import https from 'https'; import { createTransport } from 'nodemailer';
const mailgun = new Mailgun(formData); let transporterSMTP;
const mailgunClient = mailgun.client({ let mailgunClient;
username: 'api', let mailgunDomain;
key: process.env.MAILGUN_API_KEY, if (process.env.SMTP_ENABLE) {
}); transporterSMTP = createTransport({
const mailgunDomain = process.env.MAILGUN_DOMAIN; 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) { async function sendmail(req) {
try { try {
@@ -38,22 +54,67 @@ async function sendmail(req) {
const pdfName = req.params.pdfName && `${req.params.pdfName}.pdf`; const pdfName = req.params.pdfName && `${req.params.pdfName}.pdf`;
const file = { const file = {
filename: pdfName || 'exported.pdf', 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 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 from = req.params.from || '';
const mailsender = process.env.SMTP_ENABLE
? process.env.SMTP_USER_EMAIL
: process.env.MAILGUN_SENDER;
const messageParams = { const messageParams = {
from: from + ' <' + process.env.MAILGUN_SENDER + '>', from: from + ' <' + mailsender + '>',
to: req.params.recipient, to: req.params.recipient,
subject: req.params.subject, subject: req.params.subject,
text: req.params.text || 'mail', text: req.params.text || 'mail',
html: req.params.html || '', 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); const res = await mailgunClient.messages.create(mailgunDomain, messageParams);
console.log('Res ', res); console.log('Res ', res);
if (res.status === 200) { 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) { } catch (err) {
console.log('err ', 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 /> <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> <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 /> <br />
<p>ExampleApp</p> <p><a href="https://www.opensignlabs.com">OpenSign™</a></p>
</body> </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 FSFilesAdapter from 'parse-server-fs-adapter';
import AWS from 'aws-sdk'; import AWS from 'aws-sdk';
import { app as customRoute } from './cloud/customRoute/customApp.js'; import { app as customRoute } from './cloud/customRoute/customApp.js';
import { exec } from 'child_process';
const spacesEndpoint = new AWS.Endpoint(process.env.DO_ENDPOINT); const spacesEndpoint = new AWS.Endpoint(process.env.DO_ENDPOINT);
// console.log("configuration ", configuration); // console.log("configuration ", configuration);
if (process.env.USE_LOCAL !== "TRUE") { if (process.env.USE_LOCAL !== 'TRUE') {
const s3Options = { const s3Options = {
bucket: process.env.DO_SPACE, // globalConfig.S3FilesAdapter.bucket, bucket: process.env.DO_SPACE, // globalConfig.S3FilesAdapter.bucket,
baseUrl: process.env.DO_BASEURL, baseUrl: process.env.DO_BASEURL,
@@ -36,18 +37,31 @@ if (process.env.USE_LOCAL !== "TRUE") {
var fsAdapter = new S3Adapter(s3Options); var fsAdapter = new S3Adapter(s3Options);
} else { } else {
var fsAdapter = new FSFilesAdapter({ var fsAdapter = new FSFilesAdapter({
"filesSubDirectory": "files" // optional, defaults to ./files filesSubDirectory: 'files', // optional, defaults to ./files
}); });
} }
let transporterMail;
let mailgunClient; let mailgunClient;
let mailgunDomain; 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); const mailgun = new Mailgun(formData);
mailgunClient = mailgun.client({ mailgunClient = mailgun.client({
username: 'api', username: 'api',
key: process.env.MAILGUN_API_KEY, key: process.env.MAILGUN_API_KEY,
}); });
mailgunDomain = process.env.MAILGUN_DOMAIN; 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! masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it secret!
masterKeyIps: ['0.0.0.0/0', '::1'], // '::1' 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 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', 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. // Your apps name. This will appear in the subject and body of the emails that are sent.
appName: 'Open Sign', appName: 'Open Sign',
allowClientClassCreation: false, allowClientClassCreation: false,
emailAdapter: process.env.MAILGUN_API_KEY emailAdapter:
? { process.env.SMTP_ENABLE || process.env.MAILGUN_API_KEY
module: 'parse-server-api-mail-adapter', ? {
options: { module: 'parse-server-api-mail-adapter',
// The email address from which emails are sent. options: {
sender: process.env.MAILGUN_SENDER, // The email address from which emails are sent.
// The email templates. sender: process.env.SMTP_ENABLE
templates: { ? process.env.SMTP_USER_EMAIL
// The template used by Parse Server to send an email for password : process.env.MAILGUN_SENDER,
// reset; this is a reserved template name. // The email templates.
passwordResetEmail: { templates: {
subjectPath: './files/password_reset_email_subject.txt', // The template used by Parse Server to send an email for password
textPath: './files/password_reset_email.txt', // reset; this is a reserved template name.
htmlPath: './files/password_reset_email.html', 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 apiCallback: async ({ payload, locale }) => {
// address verification; this is a reserved template name. if (mailgunClient) {
verificationEmail: { const mailgunPayload = ApiPayloadConverter.mailgun(payload);
subjectPath: './files/verification_email_subject.txt', await mailgunClient.messages.create(mailgunDomain, mailgunPayload);
textPath: './files/verification_email.txt', } else if (transporterMail) await transporterMail.sendMail(payload);
htmlPath: './files/verification_email.html',
}, },
}, },
apiCallback: async ({ payload, locale }) => { }
const mailgunPayload = ApiPayloadConverter.mailgun(payload); : null,
await mailgunClient.messages.create(mailgunDomain, mailgunPayload);
},
},
}
: null,
filesAdapter: fsAdapter, filesAdapter: fsAdapter,
auth: { auth: {
google: { google: {
@@ -164,6 +183,20 @@ if (!process.env.TESTING) {
httpServer.headersTimeout = 100000; // in milliseconds httpServer.headersTimeout = 100000; // in milliseconds
httpServer.listen(port, function () { httpServer.listen(port, function () {
console.log('parse-server-example running on port ' + port + '.'); 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 // This will enable the Live Query real-time server
await ParseServer.createLiveQueryServer(httpServer); await ParseServer.createLiveQueryServer(httpServer);
+334 -11
View File
@@ -18,16 +18,19 @@
"express-sse": "^0.5.3", "express-sse": "^0.5.3",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"jsonschema": "^1.4.1", "jsonschema": "^1.4.1",
"mailgun.js": "^9.0.1", "mailgun.js": "^9.3.0",
"mongoose": "^7.2.1", "mongoose": "^7.2.1",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"multer-s3": "^2.10.0", "multer-s3": "^2.10.0",
"node-forge": "^1.3.1", "node-forge": "^1.3.1",
"node-signpdf": "^1.5.1", "node-signpdf": "^1.5.1",
"nodemailer": "^6.9.7",
"openai": "^4.8.0", "openai": "^4.8.0",
"parse": "4.1.0", "parse": "4.1.0",
"parse-dbtool": "^1.2.0",
"parse-server": "6.3.1", "parse-server": "6.3.1",
"parse-server-api-mail-adapter": "^3.0.0", "parse-server-api-mail-adapter": "^3.0.0",
"parse-server-fs-adapter": "1.0.1",
"parse-server-s3-adapter": "^1.2.0", "parse-server-s3-adapter": "^1.2.0",
"pdf-lib": "^1.16.0", "pdf-lib": "^1.16.0",
"pdfkit": "^0.13.0", "pdfkit": "^0.13.0",
@@ -2145,7 +2148,6 @@
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"dependencies": { "dependencies": {
"fill-range": "^7.0.1" "fill-range": "^7.0.1"
}, },
@@ -2794,6 +2796,37 @@
"node": ">=0.10" "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": { "node_modules/debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "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", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" "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": { "node_modules/fast-json-stable-stringify": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "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", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"dependencies": { "dependencies": {
"to-regex-range": "^5.0.1" "to-regex-range": "^5.0.1"
}, },
@@ -4335,7 +4393,6 @@
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true,
"engines": { "engines": {
"node": "6.* || 8.* || >= 10.*" "node": "6.* || 8.* || >= 10.*"
} }
@@ -5091,7 +5148,6 @@
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"engines": { "engines": {
"node": ">=0.12.0" "node": ">=0.12.0"
} }
@@ -6016,9 +6072,9 @@
} }
}, },
"node_modules/mailgun.js": { "node_modules/mailgun.js": {
"version": "9.0.1", "version": "9.3.0",
"resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-9.0.1.tgz", "resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-9.3.0.tgz",
"integrity": "sha512-bVZ1zGh5UfQcChqIwIAil99hzoTeB3aHqAUbqmIBLMLcKfx+FF2qvhbc00WtwrFhe5dBQqQw6zPj0QBlqV4nXg==", "integrity": "sha512-iRqCglCdi+Q5anFpeRKHiytT/i34E14p/WtTE57VSeq5bATK+zQ8UnpFgPRaqGGTJqyGjqcO9m5YDRRB4/qirw==",
"dependencies": { "dependencies": {
"axios": "^1.3.3", "axios": "^1.3.3",
"base-64": "^1.0.0", "base-64": "^1.0.0",
@@ -6087,6 +6143,14 @@
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" "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": { "node_modules/methods": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@@ -6095,6 +6159,18 @@
"node": ">= 0.6" "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": { "node_modules/mime": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
@@ -6799,6 +6875,14 @@
"node-forge": "^1.2.1" "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": { "node_modules/nodemon": {
"version": "2.0.22", "version": "2.0.22",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
@@ -7328,6 +7412,234 @@
"crypto-js": "4.1.1" "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": { "node_modules/parse-server": {
"version": "6.3.1", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/parse-server/-/parse-server-6.3.1.tgz", "resolved": "https://registry.npmjs.org/parse-server/-/parse-server-6.3.1.tgz",
@@ -7403,6 +7715,12 @@
"node": ">=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": { "node_modules/parse-server-s3-adapter": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/parse-server-s3-adapter/-/parse-server-s3-adapter-1.2.0.tgz", "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", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"engines": { "engines": {
"node": ">=8.6" "node": ">=8.6"
}, },
@@ -8455,7 +8772,6 @@
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"dev": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@@ -9221,7 +9537,6 @@
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"dependencies": { "dependencies": {
"is-number": "^7.0.0" "is-number": "^7.0.0"
}, },
@@ -9283,6 +9598,14 @@
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" "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": { "node_modules/tslib": {
"version": "2.5.2", "version": "2.5.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz",
+4 -2
View File
@@ -27,18 +27,20 @@
"express-sse": "^0.5.3", "express-sse": "^0.5.3",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"jsonschema": "^1.4.1", "jsonschema": "^1.4.1",
"mailgun.js": "^9.0.1", "mailgun.js": "^9.3.0",
"mongoose": "^7.2.1", "mongoose": "^7.2.1",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"multer-s3": "^2.10.0", "multer-s3": "^2.10.0",
"node-forge": "^1.3.1", "node-forge": "^1.3.1",
"node-signpdf": "^1.5.1", "node-signpdf": "^1.5.1",
"nodemailer": "^6.9.7",
"openai": "^4.8.0", "openai": "^4.8.0",
"parse": "4.1.0", "parse": "4.1.0",
"parse-dbtool": "^1.2.0",
"parse-server": "6.3.1", "parse-server": "6.3.1",
"parse-server-api-mail-adapter": "^3.0.0", "parse-server-api-mail-adapter": "^3.0.0",
"parse-server-s3-adapter": "^1.2.0",
"parse-server-fs-adapter": "1.0.1", "parse-server-fs-adapter": "1.0.1",
"parse-server-s3-adapter": "^1.2.0",
"pdf-lib": "^1.16.0", "pdf-lib": "^1.16.0",
"pdfkit": "^0.13.0", "pdfkit": "^0.13.0",
"razorpay": "^2.8.6", "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}`);
// });
@@ -40,7 +40,7 @@
"id": "c1935cc0-28d4-3d73-b72a-8c1e3d18a17f", "id": "c1935cc0-28d4-3d73-b72a-8c1e3d18a17f",
"queryType": "", "queryType": "",
"class": "contracts_Document", "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", "key": "count",
"Redirect_type": "Report", "Redirect_type": "Report",
"Redirect_id": "1MwEuxLEkF", "Redirect_id": "1MwEuxLEkF",
+54 -55
View File
@@ -1,55 +1,54 @@
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 3pXAXxZuvVvv9tsb4bdrBAhyb+KCIjp/gAICCAA=
c6yryFgECIld0S5kDk7JAgIIAA==
+21 -19
View File
@@ -1,21 +1,23 @@
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
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
Jg== Z8hExWGEMaMWiA9rxTMX6iu/parGH/pWU/55Os3WlcHPhlvqchBkQFJ+f8b+NYz0
vIHQgwn4K5WMsZVLxoiUcU7cSqE/qhnP+pzBf8lRaYwd+zUznDvzpKKz6nFgeHok
s8BK7JAKkIsl
-----END CERTIFICATE----- -----END CERTIFICATE-----
+30 -30
View File
@@ -1,30 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY----- -----BEGIN RSA PRIVATE KEY-----
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIJvntFBuTIWACAggA Proc-Type: 4,ENCRYPTED
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECEE+1CDDu5XvBIIEyEwR/61HhjJ0 DEK-Info: DES-EDE3-CBC,5932FA9F02938D1B
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
mFXB4iaMX0hGcgzpK4iNcg== oszD2BQvXgkWdrJtHuHjJCdDl03Y+daS5yP8IKTDucHvRv4ZSMghZ34SJTw5MaBP
-----END ENCRYPTED PRIVATE KEY----- -----END RSA PRIVATE KEY-----
Binary file not shown.
+20
View File
@@ -36,6 +36,7 @@
"react-scrollbars-custom": "^4.1.1", "react-scrollbars-custom": "^4.1.1",
"react-signature-canvas": "^1.0.6", "react-signature-canvas": "^1.0.6",
"reactour": "^1.19.1", "reactour": "^1.19.1",
"select-dom": "^9.0.0",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
} }
}, },
@@ -18702,6 +18703,20 @@
"resolved": "https://registry.npmjs.org/scrollparent/-/scrollparent-2.0.1.tgz", "resolved": "https://registry.npmjs.org/scrollparent/-/scrollparent-2.0.1.tgz",
"integrity": "sha512-HSdN78VMvFCSGCkh0oYX/tY4R3P1DW61f8+TeZZ4j2VLgfwvw0bpRSOv4PCVKisktIwbzHCfZsx+rLbbDBqIBA==" "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": { "node_modules/select-hose": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@@ -20203,6 +20218,11 @@
"url": "https://github.com/sponsors/ljharb" "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": { "node_modules/typedarray-to-buffer": {
"version": "3.1.5", "version": "3.1.5",
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "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-scrollbars-custom": "^4.1.1",
"react-signature-canvas": "^1.0.6", "react-signature-canvas": "^1.0.6",
"reactour": "^1.19.1", "reactour": "^1.19.1",
"select-dom": "^9.0.0",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"scripts": { "scripts": {
@@ -1,7 +1,15 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import "./certificate.css"; 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 }) { function Certificate({ pdfData }) {
const [isMultiSigners, setIsMultiSigners] = useState(); const [isMultiSigners, setIsMultiSigners] = useState();
@@ -49,70 +57,34 @@ function Certificate({ pdfData }) {
fontSize: "11px", fontSize: "11px",
marginBottom: "10px", marginBottom: "10px",
color: "gray" color: "gray"
},
image: {
width: "71px",
height: "17px"
} }
}); });
const generatedDate = () => { const generatedDate = () => {
const newDate = new Date(); const newDate = new Date();
const localExpireDate = newDate.toLocaleDateString("en-US", { const utcTime = newDate.toUTCString();
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();
return ( return (
<Text <Text
style={{ style={{
textAlign: "right",
color: "gray", color: "gray",
fontSize: "10px", fontSize: "10px"
marginBottom: "30px"
}} }}
> >
Generated On {localExpireDate} {hoursIST}:{minutesIST} IST Generated On {utcTime}
</Text> </Text>
); );
}; };
const changeCompletedDate = () => { const changeCompletedDate = () => {
const completedOn = pdfData[0].updatedAt; const completedOn = pdfData[0].updatedAt;
const newDate = new Date(completedOn); const newDate = new Date(completedOn);
const localExpireDate = newDate.toLocaleDateString("en-US", { const utcTime = newDate.toUTCString();
day: "numeric",
month: "long",
year: "numeric"
});
var currentOffset = newDate.getTimezoneOffset(); return <Text style={styles.textStyle2}>{utcTime}</Text>;
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>
);
}; };
const signerName = (data) => { const signerName = (data) => {
@@ -143,7 +115,19 @@ function Certificate({ pdfData }) {
{/** Page defines a single page of content. */} {/** Page defines a single page of content. */}
<Page size="A4" style={styles.page}> <Page size="A4" style={styles.page}>
<View style={styles.section1}> <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" }}> <View style={{ justifyContent: "center" }}>
<Text <Text
style={{ style={{
@@ -182,7 +166,9 @@ function Certificate({ pdfData }) {
</Text> </Text>
<Text style={styles.textStyle}> <Text style={styles.textStyle}>
Organization : &nbsp; Organization : &nbsp;
<Text style={styles.textStyle2}>__</Text> <Text style={styles.textStyle2}>
{pdfData[0].ExtUserPtr.Company}
</Text>
</Text> </Text>
<Text style={styles.textStyle}> <Text style={styles.textStyle}>
Completed on : &nbsp;{changeCompletedDate()} Completed on : &nbsp;{changeCompletedDate()}
@@ -260,6 +246,12 @@ function Certificate({ pdfData }) {
{pdfData[0].ExtUserPtr.Name} {pdfData[0].ExtUserPtr.Name}
</Text> </Text>
</Text> </Text>
<Text style={styles.textStyle}>
Email : &nbsp;
<Text style={styles.textStyle2}>
{pdfData[0].ExtUserPtr.Email}
</Text>
</Text>
<Text style={styles.textStyle}> <Text style={styles.textStyle}>
Accessed from : &nbsp; Accessed from : &nbsp;
<Text style={styles.textStyle2}> <Text style={styles.textStyle2}>
@@ -1,61 +1,47 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import Loader from "./component/loader"; import Loader from "./component/loader";
import { getHostUrl } from "../utils/Utils"; import { contractDocument, getHostUrl } from "../utils/Utils";
function DraftDocument() { function DraftDocument() {
const navigate = useNavigate(); const navigate = useNavigate();
const [pdfDetails, setPdfDetails] = useState([]); const [pdfDetails, setPdfDetails] = useState([]);
const [isLoading, setIsLoading] = useState({ const [isLoading, setIsLoading] = useState({
isLoad: true, isLoad: true,
message: "This might take some time", message: "This might take some time"
}); });
const rowLevel = const rowLevel =
localStorage.getItem("rowlevel") && localStorage.getItem("rowlevel") &&
JSON.parse(localStorage.getItem("rowlevel")); JSON.parse(localStorage.getItem("rowlevel"));
const signObjId = const docId =
rowLevel && rowLevel?.id rowLevel && rowLevel?.id
? rowLevel.id ? rowLevel.id
: rowLevel?.objectId && rowLevel.objectId; : rowLevel?.objectId && rowLevel.objectId;
useEffect(() => { useEffect(() => {
if (signObjId) { if (docId) {
getDocumentDetails(); getDocumentDetails();
} }
}, []); }, []);
//get document details //get document details
const getDocumentDetails = async () => { const getDocumentDetails = async () => {
await axios //getting document details
.get( const documentData = await contractDocument(docId);
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( if (documentData && documentData.length > 0) {
"_appName" setPdfDetails(documentData);
)}_Document?where={"objectId":"${signObjId}"}&include=ExtUserPtr,Signers`, const loadObj = {
{ isLoad: false
headers: { };
"Content-Type": "application/json", setIsLoading(loadObj);
"X-Parse-Application-Id": localStorage.getItem("parseAppId"), } else if (
"X-Parse-Session-Token": localStorage.getItem("accesstoken"), documentData === "Error: Something went wrong!" ||
}, (documentData.result && documentData.result.error)
} ) {
) alert("Error: Something went wrong!");
.then((Listdata) => { } else {
const json = Listdata.data; alert("No data found!");
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);
});
}; };
//check document type and render on signyour self and placeholder route //check document type and render on signyour self and placeholder route
@@ -63,24 +49,25 @@ function DraftDocument() {
const data = pdfDetails[0]; const data = pdfDetails[0];
const checkSignerExist = const checkSignerExist =
pdfDetails[0] && pdfDetails[0].Signers && pdfDetails[0].Signers; pdfDetails[0] && pdfDetails[0].Signers && pdfDetails[0].Signers;
const isPlaceholder = const isPlaceholder =
pdfDetails[0].Placeholders && pdfDetails[0].Placeholders; pdfDetails[0].Placeholders && pdfDetails[0].Placeholders;
const isDecline = data.IsDeclined && data.IsDeclined; const isDecline = data.IsDeclined && data.IsDeclined;
const signUrl = data.SignedUrl && data.SignedUrl; 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 expireUpdateDate = new Date(expireDate).getTime();
const currDate = new Date().getTime(); const currDate = new Date().getTime();
const hostUrl = getHostUrl(); const hostUrl = getHostUrl();
//checking document is completed and signer exist then navigate to pdfRequestFiles file //checking document is completed and signer exist then navigate to pdfRequestFiles file
if (data.IsCompleted && checkSignerExist) { if (data.IsCompleted && checkSignerExist) {
navigate(`${hostUrl}pdfRequestFiles`); navigate(`${hostUrl}pdfRequestFiles`);
} }
//checking document is completed and signer does not exist then navigate to recipientSignPdf file //checking document is completed and signer does not exist then navigate to recipientSignPdf file
else if (data.IsCompleted && !checkSignerExist) { else if (data.IsCompleted && !checkSignerExist) {
navigate( navigate(`${hostUrl}signaturePdf`);
`${hostUrl}signaturePdf`
);
} }
//checking document is declined by someone then navigate to pdfRequestFiles file //checking document is declined by someone then navigate to pdfRequestFiles file
else if (isDecline) { else if (isDecline) {
@@ -221,13 +221,19 @@ function PdfFileComponent({
// console.log("download") // console.log("download")
const pdfName = data && data.Name; const pdfName = data && data.Name;
const pdfUrl = data && data.SignedUrl ? data.SignedUrl : data.URL; const pdfUrl = data && data.SignedUrl ? data.SignedUrl : data.URL;
saveAs(pdfUrl, `${pdfName}_signed_by_OpenSign™.pdf`); saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
} else if (selectType === "Rename") { } else if (selectType === "Rename") {
// console.log("rename") // console.log("rename")
setRenameValue(data.Name); setRenameValue(data.Name);
setRename(data.objectId); setRename(data.objectId);
} }
}; };
const sanitizeFileName = (pdfName) => {
// Replace spaces with underscore
return pdfName.replace(/ /g, '_');
}
const handleEnterPress = (e, data) => { const handleEnterPress = (e, data) => {
if (e.key === "Enter") { if (e.key === "Enter") {
handledRenameDoc(data); handledRenameDoc(data);
@@ -6,6 +6,7 @@ import PdfFileComponent from "./FolderDrive/legaDriveComponent";
import Modal from "react-bootstrap/Modal"; import Modal from "react-bootstrap/Modal";
import ModalHeader from "react-bootstrap/esm/ModalHeader"; import ModalHeader from "react-bootstrap/esm/ModalHeader";
import { themeColor, iconColor } from "../../utils/ThemeColor/backColor"; import { themeColor, iconColor } from "../../utils/ThemeColor/backColor";
import { getDrive } from "../../utils/Utils";
function PdfFile() { function PdfFile() {
const scrollRef = useRef(null); const scrollRef = useRef(null);
@@ -15,29 +16,18 @@ function PdfFile() {
const [pdfData, setPdfData] = useState([]); const [pdfData, setPdfData] = useState([]);
const [isFolder, setIsFolder] = useState(false); const [isFolder, setIsFolder] = useState(false);
const [newFolderName, setNewFolderName] = useState(); const [newFolderName, setNewFolderName] = useState();
// const [parentFolderName, setParentFolderName] = useState();
// const [parentFolder, setParentFolder] = useState([]);
const [error, setError] = useState(); const [error, setError] = useState();
const [folderLoader, setIsFolderLoader] = useState(false); const [folderLoader, setIsFolderLoader] = useState(false);
const [isShowSort, setIsShowSort] = useState(false); const [isShowSort, setIsShowSort] = useState(false);
const [isLoading, setIsLoading] = useState({ const [isLoading, setIsLoading] = useState({
isLoad: true, isLoad: true,
message: "This might take some time", message: "This might take some time"
}); });
const [docId, setDocId] = useState(); const [docId, setDocId] = useState();
const [handleError, setHandleError] = useState(); const [handleError, setHandleError] = useState();
const [folderName, setFolderName] = 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(() => { useEffect(() => {
if (docId) { if (docId) {
getPdfFolderDocumentList(); getPdfFolderDocumentList();
@@ -50,104 +40,59 @@ function PdfFile() {
const getPdfDocumentList = async () => { const getPdfDocumentList = async () => {
const load = { const load = {
isLoad: true, isLoad: true,
message: "This might take some time", message: "This might take some time"
}; };
setIsLoading(load); setIsLoading(load);
//?where={"Type":"Folder" }&include=ExtUserPtr,Signers const driveDetails = await getDrive();
//?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 data = [ if (driveDetails) {
{ if (driveDetails.length > 0) {
name: "OpenSignDrive™", setPdfData(driveDetails);
objectId: "", }
}, const data = [
]; {
setFolderName(data); name: "OpenSignDrive™",
const loadObj = { objectId: ""
isLoad: false, }
}; ];
setIsLoading(loadObj); setFolderName(data);
}) const loadObj = {
.catch((err) => { isLoad: false
const loadObj = { };
isLoad: false, setIsLoading(loadObj);
}; } else if (driveDetails === "Error: Something went wrong!") {
setHandleError("Error: Something went wrong!"); const loadObj = {
setIsLoading(loadObj); isLoad: false
}); };
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
}
}; };
//function for get parent folder document list //function for get parent folder document list
const getPdfFolderDocumentList = async () => { const getPdfFolderDocumentList = async () => {
const load = { const load = {
isLoad: true, isLoad: true,
message: "This might take some time", message: "This might take some time"
}; };
setIsLoading(load); setIsLoading(load);
//{"$inQuery":{"where":{"objectId":"${docId}"},"className":"${appName}_Document"}} const driveDetails = await getDrive(docId);
//"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${jsonSender.objectId}"} if (driveDetails) {
await axios if (driveDetails.length > 0) {
.get( setPdfData(driveDetails);
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( } else {
"_appName" setPdfData([]);
)}_Document?where={"Folder":{"__type":"Pointer","className":"${localStorage.getItem( }
"_appName" const loadObj = {
)}_Document","objectId":"${docId}"},"$or":[{"CreatedBy":{"$exists":false}},{"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${ isLoad: false
jsonSender.objectId };
}"}}]}&include=ExtUserPtr,Signers,Folder`, setIsLoading(loadObj);
{ } else if (driveDetails === "Error: Something went wrong!") {
headers: { const loadObj = {
"Content-Type": "application/json", isLoad: false
"X-Parse-Application-Id": localStorage.getItem("parseAppId"), };
"X-Parse-Session-Token": localStorage.getItem("accesstoken"), setHandleError("Error: Something went wrong!");
}, setIsLoading(loadObj);
} }
)
.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);
});
}; };
//function for get all pdf document list //function for get all pdf document list
@@ -158,7 +103,7 @@ function PdfFile() {
const handleRoute = (data) => { const handleRoute = (data) => {
let loadObj = { let loadObj = {
isLoad: true, isLoad: true,
message: "This might take some time", message: "This might take some time"
}; };
if (data.name === "LegaDrive™") { if (data.name === "LegaDrive™") {
setIsLoading(loadObj); setIsLoading(loadObj);
@@ -167,7 +112,7 @@ function PdfFile() {
} else { } else {
setTimeout(() => { setTimeout(() => {
const loadObj = { const loadObj = {
isLoad: false, isLoad: false
}; };
setIsLoading(loadObj); setIsLoading(loadObj);
}, 1000); }, 1000);
@@ -176,12 +121,11 @@ function PdfFile() {
setIsLoading(loadObj); setIsLoading(loadObj);
setTimeout(() => { setTimeout(() => {
const loadObj = { const loadObj = {
isLoad: false, isLoad: false
}; };
setIsLoading(loadObj); setIsLoading(loadObj);
}, 1000); }, 1000);
} else { } else {
// console.log("go here1",data.objectId)
const findIndex = folderName.findIndex( const findIndex = folderName.findIndex(
(fold) => fold.objectId === data.objectId (fold) => fold.objectId === data.objectId
); );
@@ -216,13 +160,13 @@ function PdfFile() {
Folder: { Folder: {
__type: "Pointer", __type: "Pointer",
className: `${localStorage.getItem("_appName")}_Document`, className: `${localStorage.getItem("_appName")}_Document`,
objectId: isParentId, objectId: isParentId
}, }
}; };
} else { } else {
data = { data = {
Name: newFolderName, Name: newFolderName,
Type: "Folder", Type: "Folder"
}; };
} }
@@ -237,8 +181,8 @@ function PdfFile() {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"), "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", display: "flex",
flexDirection: "column", flexDirection: "column",
justifyContent: "center", justifyContent: "center",
alignItems: "center", alignItems: "center"
}} }}
> >
<img <img
@@ -406,7 +350,7 @@ function PdfFile() {
style={{ style={{
margin: "10px 0px 10px 0px", margin: "10px 0px 10px 0px",
fontSize: "15px", fontSize: "15px",
fontWeight: "400", fontWeight: "400"
}} }}
> >
Name* Name*
@@ -428,7 +372,7 @@ function PdfFile() {
display: "flex", display: "flex",
alignItems: "flex-end", alignItems: "flex-end",
justifyContent: "flex-end", justifyContent: "flex-end",
alignContent: "flex-end", alignContent: "flex-end"
}} }}
> >
<button <button
@@ -437,7 +381,7 @@ function PdfFile() {
borderRadius: "0px", borderRadius: "0px",
border: "1.5px solid #e3e2e1", border: "1.5px solid #e3e2e1",
fontWeight: "600", fontWeight: "600",
color: "black", color: "black"
}} }}
className="finishBtn" className="finishBtn"
onClick={() => setIsFolder(false)} onClick={() => setIsFolder(false)}
@@ -448,7 +392,7 @@ function PdfFile() {
<button <button
onClick={() => handleAddFolder()} onClick={() => handleAddFolder()}
style={{ style={{
background: themeColor(), background: themeColor()
}} }}
type="button" type="button"
className="finishBtn" className="finishBtn"
@@ -469,7 +413,7 @@ function PdfFile() {
alignItems: "center", alignItems: "center",
height: "100vh", height: "100vh",
width: "100%", width: "100%",
flexDirection: "column", flexDirection: "column"
}} }}
> >
<img <img
@@ -488,7 +432,7 @@ function PdfFile() {
justifyContent: "center", justifyContent: "center",
alignItems: "center", alignItems: "center",
height: "100vh", height: "100vh",
width: "100%", width: "100%"
}} }}
> >
<span style={{ fontSize: "20px", color: "gray" }}> <span style={{ fontSize: "20px", color: "gray" }}>
@@ -502,7 +446,7 @@ function PdfFile() {
onMouseEnter={(e) => handleMouseEnter(e)} onMouseEnter={(e) => handleMouseEnter(e)}
ref={scrollRef} ref={scrollRef}
style={{ style={{
width: "100%", width: "100%"
}} }}
className="folderPath" className="folderPath"
> >
@@ -514,7 +458,7 @@ function PdfFile() {
style={{ style={{
color: "#a64b4e", color: "#a64b4e",
fontWeight: "400", fontWeight: "400",
cursor: "pointer", cursor: "pointer"
}} }}
> >
{data.name} {data.name}
@@ -523,7 +467,7 @@ function PdfFile() {
color: "#a64b4e", color: "#a64b4e",
fontWeight: "200", fontWeight: "200",
cursor: "pointer", cursor: "pointer",
margin: "0 4px", margin: "0 4px"
}} }}
> >
&gt; &gt;
@@ -545,13 +489,13 @@ function PdfFile() {
style={{ style={{
marginRight: "5px", marginRight: "5px",
fontSize: "14px", fontSize: "14px",
color: `${iconColor()}`, color: `${iconColor()}`
}} }}
></i> ></i>
<span <span
style={{ style={{
fontSize: "15px", fontSize: "15px",
color: `${iconColor()}`, color: `${iconColor()}`
}} }}
> >
{selectedSort} {selectedSort}
@@ -694,7 +638,7 @@ function PdfFile() {
justifyContent: "center", justifyContent: "center",
alignItems: "center", alignItems: "center",
height: "50vh", height: "50vh",
width: "100%", width: "100%"
}} }}
> >
<span style={{ fontWeight: "bold" }}>No Data Found!</span> <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 { useParams } from "react-router-dom";
import SignPad from "./component/signPad"; import SignPad from "./component/signPad";
import RenderAllPdfPage from "./component/renderAllPdfPage"; 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 Loader from "./component/loader";
import HandleError from "./component/HandleError"; import HandleError from "./component/HandleError";
import Nodata from "./component/Nodata"; import Nodata from "./component/Nodata";
@@ -106,153 +112,135 @@ function PdfRequestFiles() {
//function for get document details for perticular signer with signer'object id //function for get document details for perticular signer with signer'object id
const getDocumentDetails = async () => { const getDocumentDetails = async () => {
await axios //getting document details
.get( const documentData = await contractDocument(documentId);
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( if (documentData && documentData.length > 0) {
"_appName" const isCompleted =
)}_Document?where={"objectId":"${documentId}"}&include=ExtUserPtr,Signers,UserPtr`, documentData[0].IsCompleted && documentData[0].IsCompleted;
{ const expireDate = documentData[0].ExpiryDate.iso;
headers: { const declined = documentData[0].IsDeclined && documentData[0].IsDeclined;
"Content-Type": "application/json", const expireUpdateDate = new Date(expireDate).getTime();
"X-Parse-Application-Id": localStorage.getItem("parseAppId"), const currDate = new Date().getTime();
"X-Parse-Session-Token": localStorage.getItem("accesstoken") const getSigners = documentData[0].Signers;
} const getCurrentSigner =
} getSigners &&
) getSigners.filter(
.then((Listdata) => { (data) => data.UserId.objectId === jsonSender.objectId
const json = Listdata.data; );
const res = json.results;
if (res[0] && res.length > 0) { const currUserId = getCurrentSigner[0]
const isCompleted = res[0].IsCompleted && res[0].IsCompleted; ? getCurrentSigner[0].objectId
const expireDate = res[0].ExpiryDate.iso; : "";
const declined = res[0].IsDeclined && res[0].IsDeclined; setSignerObjectId(currUserId);
const expireUpdateDate = new Date(expireDate).getTime(); if (documentData[0].SignedUrl) {
const currDate = new Date().getTime(); setPdfUrl(documentData[0].SignedUrl);
const getSigners = res[0].Signers; } else {
const getCurrentSigner = setPdfUrl(documentData[0].URL);
getSigners && }
getSigners.filter( if (isCompleted) {
(data) => data.UserId.objectId === jsonSender.objectId setIsSigned(true);
); const data = {
isCertificate: true,
const currUserId = getCurrentSigner[0] isModal: true
? 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
}; };
setHandleError("Error: Something went wrong!"); setAlreadySign(true);
setIsLoading(loadObj); 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 await axios
.get( .get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( `${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
@@ -294,7 +282,6 @@ function PdfRequestFiles() {
const checkUser = signerPos.filter( const checkUser = signerPos.filter(
(data) => data.signerObjId === signerObjectId (data) => data.signerObjId === signerObjectId
); );
if (checkUser && checkUser.length > 0) { if (checkUser && checkUser.length > 0) {
let checkSignUrl = []; let checkSignUrl = [];
const checkSign = checkUser[0].placeHolder.filter( const checkSign = checkUser[0].placeHolder.filter(
@@ -361,38 +348,13 @@ function PdfRequestFiles() {
imgUrlList.map(async (data) => { imgUrlList.map(async (data) => {
//cheking signUrl is defau;t signature url of custom url //cheking signUrl is defau;t signature url of custom url
let ImgUrl = data.SignUrl; let ImgUrl = data.SignUrl;
const checkUrl = ImgUrl.includes("https:"); const checkUrl = urlValidator(ImgUrl);
//if default signature url then convert it in base 64 //if default signature url then convert it in base 64
if (checkUrl) { if (checkUrl) {
ImgUrl = await getBase64FromIMG(ImgUrl + "?get"); ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
} }
//function for called convert png signatre to jpeg in base 64 //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) convertPNGtoJPEG(ImgUrl)
.then((jpegBase64Data) => { .then((jpegBase64Data) => {
const removeBase64Fromjpeg = "data:image/jpeg;base64,"; const removeBase64Fromjpeg = "data:image/jpeg;base64,";
@@ -448,32 +410,21 @@ function PdfRequestFiles() {
const images = await Promise.all( const images = await Promise.all(
imgUrlList.map(async (url) => { imgUrlList.map(async (url) => {
let signUrl = url.SignUrl; let signUrl = url.SignUrl;
if (url.ImageType === "image/png") {
const checkUrl = url.SignUrl.includes("https:"); //function for convert signature png base64 url to jpeg base64
const newUrl = await convertPNGtoJPEG(signUrl);
signUrl = newUrl;
}
const checkUrl = urlValidator(signUrl);
if (checkUrl) { if (checkUrl) {
signUrl = signUrl + "?get"; signUrl = signUrl + "?get";
} }
const res = await fetch(signUrl); const res = await fetch(signUrl);
return res.arrayBuffer(); return res.arrayBuffer();
}) })
); );
images.forEach(async (imgData, id) => { images.forEach(async (imgData, id) => {
let img; let img = await pdfDoc.embedJpg(imgData);
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);
}
const imgHeight = imgUrlList[id].Height const imgHeight = imgUrlList[id].Height
? imgUrlList[id].Height ? imgUrlList[id].Height
: 60; : 60;
@@ -597,12 +548,12 @@ function PdfRequestFiles() {
if (isMobile) { if (isMobile) {
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale //if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
if (pos.isMobile) { if (pos.isMobile) {
const y = pos.yPosition * (pos.scale / scale); const y = pos.yBottom * (pos.scale / scale);
yPosition = pos.isDrag yPosition = pos.isDrag
? y * scale - height ? y * scale - height
: pos.firstYPos : pos.firstYPos
? y * scale - height + pos.firstYPos ? y * scale - height + pos.firstYPos
: y * scale - height; : y * scale - height;
return yPosition; return yPosition;
} else { } else {
const y = pos.yBottom / scale; const y = pos.yBottom / scale;
@@ -610,8 +561,8 @@ function PdfRequestFiles() {
yPosition = pos.isDrag yPosition = pos.isDrag
? y * scale - height ? y * scale - height
: pos.firstYPos : pos.firstYPos
? y * scale - height + pos.firstYPos ? y * scale - height + pos.firstYPos
: y * scale - height; : y * scale - height;
return yPosition; return yPosition;
} }
} else { } else {
@@ -622,15 +573,15 @@ function PdfRequestFiles() {
yPosition = pos.isDrag yPosition = pos.isDrag
? y - height ? y - height
: pos.firstYPos : pos.firstYPos
? y - height + pos.firstYPos ? y - height + pos.firstYPos
: y - height; : y - height;
return yPosition; return yPosition;
} else { } else {
yPosition = pos.isDrag yPosition = pos.isDrag
? pos.yBottom - height ? pos.yBottom - height
: pos.firstYPos : pos.firstYPos
? pos.yBottom - height + pos.firstYPos ? pos.yBottom - height + pos.firstYPos
: pos.yBottom - height; : pos.yBottom - height;
return yPosition; return yPosition;
} }
} }
@@ -1048,7 +999,7 @@ function PdfRequestFiles() {
<Modal.Body> <Modal.Body>
<p className="pTagBody"> <p className="pTagBody">
This document has been signed by all Sigers. This document has been signed by all Signers.
</p> </p>
</Modal.Body> </Modal.Body>
@@ -15,7 +15,11 @@ import EmailComponent from "./component/emailComponent";
import FieldsComponent from "./component/fieldsComponent"; import FieldsComponent from "./component/fieldsComponent";
import Modal from "react-bootstrap/Modal"; import Modal from "react-bootstrap/Modal";
import ModalHeader from "react-bootstrap/esm/ModalHeader"; 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 { useParams } from "react-router-dom";
import Tour from "reactour"; import Tour from "reactour";
import { onSaveImage, onSaveSign } from "../utils/Utils"; import { onSaveImage, onSaveSign } from "../utils/Utils";
@@ -24,7 +28,9 @@ import HandleError from "./component/HandleError";
import Nodata from "./component/Nodata"; import Nodata from "./component/Nodata";
import Header from "./component/header"; import Header from "./component/header";
import RenderPdf from "./component/renderPdf"; 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. //For signYourself inProgress section signer can add sign and complete doc sign.
function SignYourSelf() { function SignYourSelf() {
const [pdfDetails, setPdfDetails] = useState([]); const [pdfDetails, setPdfDetails] = useState([]);
@@ -167,61 +173,48 @@ function SignYourSelf() {
//pdf from left and right component //pdf from left and right component
setPdfNewWidth(pdfWidth); setPdfNewWidth(pdfWidth);
if (documentId) { if (documentId) {
getDocumentDetails(); getDocumentDetails(true);
} }
}, []); }, []);
//function for get document details for perticular signer with signer'object id //function for get document details for perticular signer with signer'object id
const getDocumentDetails = async () => { const getDocumentDetails = async (showComplete) => {
await axios //getting document details
.get( const documentData = await contractDocument(documentId);
`${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;
if (res[0] && res.length > 0) { if (documentData && documentData.length > 0) {
setPdfDetails(res); setPdfDetails(documentData);
const isCompleted = res[0].IsCompleted && res[0].IsCompleted; const isCompleted =
if (isCompleted) { documentData[0].IsCompleted && documentData[0].IsCompleted;
const docStatus = { if (isCompleted && showComplete) {
isCompleted: 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
}; };
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 await axios
.get( .get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( `${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
@@ -252,13 +245,10 @@ function SignYourSelf() {
setHandleError("Error: Something went wrong!"); setHandleError("Error: Something went wrong!");
setIsLoading(loadObj); setIsLoading(loadObj);
}); });
const contractUsersRes = await contractUsers(jsonSender.objectId);
if ( const contractUsersRes = await contractUsers(jsonSender.email);
contractUsersRes !== "Error: Something went wrong!" &&
contractUsersRes && if (contractUsersRes[0] && contractUsersRes.length > 0) {
contractUsersRes[0]
) {
setContractName("_Users"); setContractName("_Users");
setSignerUserId(contractUsersRes[0].objectId); setSignerUserId(contractUsersRes[0].objectId);
const tourstatuss = const tourstatuss =
@@ -285,14 +275,12 @@ function SignYourSelf() {
setIsLoading(loadObj); setIsLoading(loadObj);
} else if (contractUsersRes.length === 0) { } else if (contractUsersRes.length === 0) {
const contractContactBook = await contactBook(jsonSender.objectId); const contractContactBook = await contactBook(jsonSender.objectId);
if (contractContactBook && contractContactBook[0]) { if (contractContactBook && contractContactBook.length > 0) {
setContractName("_Contactbook"); setContractName("_Contactbook");
setSignerUserId(contractContactBook[0].objectId); setSignerUserId(contractContactBook[0].objectId);
const tourstatuss = const tourstatuss =
contractContactBook[0].TourStatus && contractContactBook[0].TourStatus &&
contractContactBook[0].TourStatus; contractContactBook[0].TourStatus;
if (tourstatuss && tourstatuss.length > 0) { if (tourstatuss && tourstatuss.length > 0) {
setTourStatus(tourstatuss); setTourStatus(tourstatuss);
const checkTourRecipients = tourstatuss.filter( const checkTourRecipients = tourstatuss.filter(
@@ -302,6 +290,8 @@ function SignYourSelf() {
setCheckTourStatus(checkTourRecipients[0].signyourself); setCheckTourStatus(checkTourRecipients[0].signyourself);
} }
} }
} else {
setNoData(true);
} }
const loadObj = { const loadObj = {
isLoad: false isLoad: false
@@ -460,39 +450,13 @@ function SignYourSelf() {
imgUrlList.map(async (data) => { imgUrlList.map(async (data) => {
let ImgUrl = data.SignUrl; let ImgUrl = data.SignUrl;
//cheking signUrl is defau;t signature url of custom url //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 default signature url then convert it in base 64
if (checkUrl) { if (checkUrl) {
ImgUrl = await getBase64FromIMG(ImgUrl + "?get"); ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
} }
//function for convert signature png base64 url to jpeg base64 //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) convertPNGtoJPEG(ImgUrl)
.then((jpegBase64Data) => { .then((jpegBase64Data) => {
const removeBase64Fromjpeg = "data:image/jpeg;base64,"; const removeBase64Fromjpeg = "data:image/jpeg;base64,";
@@ -500,7 +464,6 @@ function SignYourSelf() {
removeBase64Fromjpeg, removeBase64Fromjpeg,
"" ""
); );
//function for call to embed signature in pdf and get digital signature pdf //function for call to embed signature in pdf and get digital signature pdf
signPdfFun(newImgUrl, documentId, data, pdfBase64, pageNo); signPdfFun(newImgUrl, documentId, data, pdfBase64, pageNo);
}) })
@@ -541,7 +504,12 @@ function SignYourSelf() {
imgUrlList.map(async (url) => { imgUrlList.map(async (url) => {
let signUrl = url.SignUrl; 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) { if (checkUrl) {
signUrl = signUrl + "?get"; signUrl = signUrl + "?get";
} }
@@ -551,21 +519,7 @@ function SignYourSelf() {
}) })
); );
images.forEach(async (imgData, id) => { images.forEach(async (imgData, id) => {
let img; let img = await pdfDoc.embedJpg(imgData);
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);
}
const imgHeight = imgUrlList[id].Height const imgHeight = imgUrlList[id].Height
? imgUrlList[id].Height ? imgUrlList[id].Height
: 60; : 60;
@@ -575,14 +529,18 @@ function SignYourSelf() {
const scale = isMobile ? pdfOriginalWidth / newWidth : 1; const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
const posY = () => { const posY = () => {
if (id === 0) { if (isMobile) {
return ( if (id === 0) {
page.getHeight() - return (
imgUrlList[id].yPosition * scale - page.getHeight() -
imgHeight imgUrlList[id].yPosition * scale -
); imgHeight
} else if (id > 0) { );
return page.getHeight() - imgUrlList[id].yPosition * scale; } else if (id > 0) {
return page.getHeight() - imgUrlList[id].yPosition * scale;
}
} else {
return page.getHeight() - imgUrlList[id].yPosition - imgHeight;
} }
}; };
page.drawImage(img, { page.drawImage(img, {
@@ -596,7 +554,6 @@ function SignYourSelf() {
}); });
} }
const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false }); const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false });
signPdfFun(pdfBytes, documentId); signPdfFun(pdfBytes, documentId);
} }
setIsSignPad(false); setIsSignPad(false);
@@ -615,17 +572,18 @@ function SignYourSelf() {
pageNo pageNo
) => { ) => {
let singleSign; let singleSign;
const isMobile = window.innerWidth < 767; const isMobile = window.innerWidth < 767;
const newWidth = window.innerWidth; const newWidth = window.innerWidth;
const scale = isMobile ? pdfOriginalWidth / newWidth : 1; const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
const imgWidth = xyPosData.Width.Width ? xyPosData.Width.Width : 150; const imgWidth = xyPosData ? xyPosData.Width : 150;
if (xyPostion.length === 1 && xyPostion[0].pos.length === 1) { if (xyPostion.length === 1 && xyPostion[0].pos.length === 1) {
const height = xyPosData.Height ? xyPosData.Height : 60; const height = xyPosData.Height ? xyPosData.Height : 60;
const bottomY = xyPosData.isDrag const bottomY = xyPosData.isDrag
? xyPosData.yBottom * scale - height ? xyPosData.yBottom * scale - height
: xyPosData.firstYPos : xyPosData.firstYPos
? xyPosData.yBottom * scale - height + xyPosData.firstYPos ? xyPosData.yBottom * scale - height + xyPosData.firstYPos
: xyPosData.yBottom * scale - height; : xyPosData.yBottom * scale - height;
singleSign = { singleSign = {
pdfFile: pdfBase64Url, pdfFile: pdfBase64Url,
@@ -661,15 +619,7 @@ function SignYourSelf() {
// console.log("json ", json); // console.log("json ", json);
setPdfUrl(json.result.data); setPdfUrl(json.result.data);
if (json.result.data) { if (json.result.data) {
const docStatus = { getDocumentDetails(false);
isCompleted: true
};
setDocumentStatus(docStatus);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
} }
}) })
.catch((err) => { .catch((err) => {
@@ -1041,7 +991,11 @@ function SignYourSelf() {
> >
{/* this modal is used show this document is already sign */} {/* 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() }}> <ModalHeader style={{ background: themeColor() }}>
<span style={{ color: "white" }}> Sign Documents</span> <span style={{ color: "white" }}> Sign Documents</span>
</ModalHeader> </ModalHeader>
@@ -1115,6 +1069,8 @@ function SignYourSelf() {
pdfDetails={pdfDetails} pdfDetails={pdfDetails}
isShowHeader={true} isShowHeader={true}
currentSigner={true} currentSigner={true}
alreadySign={pdfUrl ? true : false}
isSignYourself={true}
/> />
{/* className="hidePdf" */} {/* className="hidePdf" */}
@@ -28,9 +28,7 @@ function EmailComponent({
setIsLoading(true); setIsLoading(true);
let sendMail; let sendMail;
for (let i = 0; i < emailCount.length; i++) { for (let i = 0; i < emailCount.length; i++) {
try { try {
const imgPng = const imgPng =
"https://qikinnovation.ams3.digitaloceanspaces.com/logo.png"; "https://qikinnovation.ams3.digitaloceanspaces.com/logo.png";
// "https://qikinnovation.ams3.digitaloceanspaces.com/mailLogo_2023-08-18T12%3A51%3A31.573Z.png"; // "https://qikinnovation.ams3.digitaloceanspaces.com/mailLogo_2023-08-18T12%3A51%3A31.573Z.png";
@@ -111,26 +109,36 @@ function EmailComponent({
const pdf = await getBase64FromUrl(pdfUrl); const pdf = await getBase64FromUrl(pdfUrl);
const isAndroidDevice = navigator.userAgent.match(/Android/i); 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) { if (isAndroidDevice || isAppleDevice) {
const byteArray = Uint8Array.from(atob(pdf).split('').map(char => char.charCodeAt(0))); const byteArray = Uint8Array.from(
const blob = new Blob([byteArray], { type: 'application/pdf' }); atob(pdf)
.split("")
.map((char) => char.charCodeAt(0))
);
const blob = new Blob([byteArray], { type: "application/pdf" });
const blobUrl = URL.createObjectURL(blob); const blobUrl = URL.createObjectURL(blob);
window.open(blobUrl, '_blank'); window.open(blobUrl, "_blank");
} else { } else {
printModule({ printable: pdf, type: "pdf", base64: true }); printModule({ printable: pdf, type: "pdf", base64: true });
} }
}; };
//handle download signed pdf //handle download signed pdf
const handleDownloadPdf = () => { const handleDownloadPdf = () => {
saveAs(pdfUrl, `${pdfName}_signed_by_OpenSign™.pdf`); saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
};
const sanitizeFileName = (pdfName) => {
// Replace spaces with underscore
return pdfName.replace(/ /g, "_");
}; };
const isAndroid = /Android/i.test(navigator.userAgent); const isAndroid = /Android/i.test(navigator.userAgent);
return ( return (
<div> <div>
{/* isEmail */} {/* isEmail */}
@@ -162,7 +170,7 @@ function EmailComponent({
)} )}
<ModalHeader style={{ background: themeColor() }}> <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 style={{ display: "flex", flexDirection: "row" }}>
<div></div> <div></div>
@@ -254,14 +262,20 @@ function EmailComponent({
> >
{emailCount.map((data, ind) => { {emailCount.map((data, ind) => {
return ( return (
<div className="emailChip" <div
style={{display:"flex", flexDirection:"row", alignItems:"center"}} className="emailChip"
key={ind}> style={{
display: "flex",
flexDirection: "row",
alignItems: "center"
}}
key={ind}
>
<span <span
style={{ style={{
color: "white", color: "white",
fontSize: "13px", fontSize: "13px",
marginRight: "20px" marginTop: "2px"
}} }}
> >
{data} {data}
@@ -273,7 +287,7 @@ function EmailComponent({
src={close} src={close}
width={10} width={10}
height={10} height={10}
style={{ fontWeight: "600" }} style={{ fontWeight: "600", margin: "0 0 10px 2px" }}
/> />
</div> </div>
); );
@@ -27,13 +27,13 @@ function Header({
signersdata, signersdata,
isMailSend, isMailSend,
alertSendEmail, alertSendEmail,
isSigned,
isCompleted, isCompleted,
isShowHeader, isShowHeader,
decline, decline,
currentSigner, currentSigner,
dataTut4, dataTut4,
alreadySign alreadySign,
isSignYourself
}) { }) {
const isMobile = window.innerWidth < 767; const isMobile = window.innerWidth < 767;
const navigate = useNavigate(); const navigate = useNavigate();
@@ -61,12 +61,19 @@ function Header({
const pdf = await getBase64FromUrl(pdfUrl); const pdf = await getBase64FromUrl(pdfUrl);
const isAndroidDevice = navigator.userAgent.match(/Android/i); 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) { if (isAndroidDevice || isAppleDevice) {
const byteArray = Uint8Array.from(atob(pdf).split('').map(char => char.charCodeAt(0))); const byteArray = Uint8Array.from(
const blob = new Blob([byteArray], { type: 'application/pdf' }); atob(pdf)
.split("")
.map((char) => char.charCodeAt(0))
);
const blob = new Blob([byteArray], { type: "application/pdf" });
const blobUrl = URL.createObjectURL(blob); const blobUrl = URL.createObjectURL(blob);
window.open(blobUrl, '_blank'); window.open(blobUrl, "_blank");
} else { } else {
printModule({ printable: pdf, type: "pdf", base64: true }); printModule({ printable: pdf, type: "pdf", base64: true });
} }
@@ -75,13 +82,148 @@ function Header({
//handle download signed pdf //handle download signed pdf
const handleDownloadPdf = () => { const handleDownloadPdf = () => {
const pdfName = pdfDetails[0] && pdfDetails[0].Name; const pdfName = pdfDetails[0] && pdfDetails[0].Name;
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
saveAs(pdfUrl, `${pdfName}_signed_by_OpenSign™.pdf`);
}; };
const sanitizeFileName = (pdfName) => {
// Replace spaces with underscore
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 ( return (
<div <div
style={{ padding: !isGuestSigner && "5px 0px 5px 0px" }} style={{ padding: !isGuestSigner && "5px 0px 5px 0px" }}
className="mobileHead" className="mobileHead"
> >
{isMobile && isShowHeader ? ( {isMobile && isShowHeader ? (
@@ -89,7 +231,9 @@ function Header({
id="navbar" id="navbar"
className={isGuestSigner ? "stickySignerHead" : "stickyHead"} className={isGuestSigner ? "stickySignerHead" : "stickyHead"}
style={{ style={{
width: isGuestSigner ? window.innerWidth : window.innerWidth - 30 + "px" width: isGuestSigner
? window.innerWidth
: window.innerWidth - 30 + "px"
}} }}
> >
<div className="preBtn2"> <div className="preBtn2">
@@ -134,16 +278,16 @@ function Header({
style={{ color: "gray", cursor: "pointer" }} style={{ color: "gray", cursor: "pointer" }}
></i> ></i>
</div> </div>
{pdfUrl ? ( {pdfUrl && alreadySign ? (
<DropdownMenu.Root> <DropdownMenu.Root>
<DropdownMenu.Trigger asChild> <DropdownMenu.Trigger asChild>
<div <div
// onClick={() => handleDownloadPdf()}
style={{ style={{
color: themeColor(), color: themeColor(),
border: "none", border: "none",
fontWeight: "650", fontWeight: "650",
fontSize: "16px" fontSize: "16px",
padding: "0px 3px 0px 5px"
}} }}
> >
<i className="fa fa-ellipsis-v" aria-hidden="true"></i> <i className="fa fa-ellipsis-v" aria-hidden="true"></i>
@@ -173,44 +317,41 @@ function Header({
Download Download
</div> </div>
</DropdownMenu.Item> </DropdownMenu.Item>
<DropdownMenu.Item className="DropdownMenuItem"> {recipient && pdfDetails[0] && pdfDetails.length > 0 ? (
<PDFDownloadLink <DropdownMenu.Item className="DropdownMenuItem">
style={{ textDecoration: "none" }} <CertificateDropDown />
document={<Certificate pdfData={pdfDetails} />} </DropdownMenu.Item>
fileName={`completion certificate-${ ) : isPdfRequestFiles &&
pdfDetails[0] && pdfDetails[0].Name alreadySign &&
}.pdf`} 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 }) => ( {" "}
<> <i
{console.log("error", error)} className="fa fa-print"
{loading ? ( aria-hidden="true"
"Loading document..." style={{ marginRight: "2px" }}
) : ( ></i>
<button Print
type="button" </div>
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>
</DropdownMenu.Item> </DropdownMenu.Item>
</DropdownMenu.Content> </DropdownMenu.Content>
</DropdownMenu.Portal> </DropdownMenu.Portal>
@@ -261,6 +402,8 @@ function Header({
onClick={() => { onClick={() => {
if (!pdfUrl) { if (!pdfUrl) {
embedImages(); embedImages();
} else if (isPdfRequestFiles) {
embedImages();
} }
}} }}
style={{ style={{
@@ -291,40 +434,7 @@ function Header({
pdfUrl || isAlreadySign.mssg ? ( pdfUrl || isAlreadySign.mssg ? (
<div style={{ display: "flex", flexDirection: "row" }}> <div style={{ display: "flex", flexDirection: "row" }}>
{pdfDetails[0] && pdfDetails.length > 0 && ( {pdfDetails[0] && pdfDetails.length > 0 && (
<PDFDownloadLink <CertificateComponent />
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>
)} )}
<button <button
onClick={handleToPrint} onClick={handleToPrint}
@@ -449,42 +559,7 @@ function Header({
) : isPdfRequestFiles ? ( ) : isPdfRequestFiles ? (
alreadySign ? ( alreadySign ? (
<div style={{ display: "flex", flexDirection: "row" }}> <div style={{ display: "flex", flexDirection: "row" }}>
{isCompleted.isCertificate && ( {isCompleted.isCertificate && <CertificateComponent />}
<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>
)}
<button <button
onClick={handleToPrint} onClick={handleToPrint}
type="button" type="button"
@@ -571,40 +646,7 @@ function Header({
) )
) : pdfUrl || (documentStatus && documentStatus.isCompleted) ? ( ) : pdfUrl || (documentStatus && documentStatus.isCompleted) ? (
<div style={{ display: "flex", flexDirection: "row" }}> <div style={{ display: "flex", flexDirection: "row" }}>
<PDFDownloadLink <CertificateComponent />
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>
<button <button
onClick={handleToPrint} onClick={handleToPrint}
type="button" type="button"
@@ -42,7 +42,8 @@ function RenderPdf({
const isMobile = window.innerWidth < 767; const isMobile = window.innerWidth < 767;
const newWidth = window.innerWidth; const newWidth = window.innerWidth;
const scale = isMobile ? pdfOriginalWidth / newWidth : 1; 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 // handle signature block width and height according to screen
const posWidth = (pos) => { const posWidth = (pos) => {
let width; let width;
@@ -74,8 +75,7 @@ function RenderPdf({
return width; 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 //function for render placeholder block over pdf document
const checkSignedSignes = (data) => { const checkSignedSignes = (data) => {
@@ -606,7 +606,7 @@ function RenderPdf({
> >
{" "} {" "}
<div <div
onTouchStart={(e) => { onTouchEnd ={(e) => {
if (!isDragging) { if (!isDragging) {
setTimeout(() => { setTimeout(() => {
e.stopPropagation(); e.stopPropagation();
@@ -640,6 +640,7 @@ function RenderPdf({
alt="signimg" alt="signimg"
onClick={(e) => { onClick={(e) => {
setSignKey(pos.key); setSignKey(pos.key);
console.log("Drag 2");
setIsSignPad(true); setIsSignPad(true);
setIsStamp(pos.isStamp); setIsStamp(pos.isStamp);
}} }}
@@ -692,11 +693,10 @@ function RenderPdf({
}} }}
> >
<div <div
onTouchStart={(e) => { onTouchEnd ={(e) => {
if (!isDragging) { if (!isDragging) {
setTimeout(() => { setTimeout(() => {
setIsSignPad(true); setIsSignPad(true);
setSignKey(pos.key); setSignKey(pos.key);
setIsStamp(pos.isStamp); setIsStamp(pos.isStamp);
}, 500); }, 500);
@@ -777,7 +777,13 @@ function RenderPdf({
}} }}
onLoadSuccess={pageDetails} onLoadSuccess={pageDetails}
ref={pdfRef} 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) => ( {Array.from(new Array(numPages), (el, index) => (
<Page <Page
@@ -1293,7 +1299,13 @@ function RenderPdf({
}} }}
onLoadSuccess={pageDetails} onLoadSuccess={pageDetails}
ref={pdfRef} 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) => ( {Array.from(new Array(numPages), (el, index) => (
<Page <Page
@@ -17,7 +17,12 @@ import HandleError from "./component/HandleError";
import Nodata from "./component/Nodata"; import Nodata from "./component/Nodata";
import SignerListPlace from "./component/signerListPlace"; import SignerListPlace from "./component/signerListPlace";
import Header from "./component/header"; 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 RenderPdf from "./component/renderPdf";
import ModalComponent from "./component/modalComponent"; import ModalComponent from "./component/modalComponent";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
@@ -169,56 +174,40 @@ function PlaceHolderSign() {
//function for get document details //function for get document details
const getDocumentDetails = async () => { const getDocumentDetails = async () => {
await axios //getting document details
.get( const documentData = await contractDocument(documentId);
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( if (documentData && documentData.length > 0) {
"_appName" setPdfDetails(documentData);
)}_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;
if (res[0] && res.length > 0) { const currEmail = documentData[0].ExtUserPtr.Email;
setPdfDetails(res); const filterCurrEmail = documentData[0].Signers.filter(
(data) => data.Email === currEmail
);
const currEmail = res[0].ExtUserPtr.Email; setCurrentEmail(filterCurrEmail);
const filterCurrEmail = res[0].Signers.filter( setSignersData(documentData[0]);
(data) => data.Email === currEmail
);
setCurrentEmail(filterCurrEmail); setSignerObjId(documentData[0].Signers[0].objectId);
setSignersData(res[0]); setContractName(documentData[0].Signers[0].className);
setIsSelectId(0);
setSignerObjId(res[0].Signers[0].objectId); } else if (
setContractName(res[0].Signers[0].className); documentData === "Error: Something went wrong!" ||
setIsSelectId(0); (documentData.result && documentData.result.error)
} else { ) {
setNoData(true); const loadObj = {
const loadObj = { isLoad: false
isLoad: false };
}; setHandleError("Error: Something went wrong!");
setIsLoading(loadObj); setIsLoading(loadObj);
} } else {
}) setNoData(true);
.catch((err) => {
console.log("axois err ", err);
const loadObj = {
isLoad: false
};
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
});
const res = await contractUsers(jsonSender.objectId);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
}
const res = await contractUsers(jsonSender.email);
if (res[0] && res.length) { if (res[0] && res.length) {
setSignerUserId(res[0].objectId); setSignerUserId(res[0].objectId);
const tourstatus = res[0].TourStatus && res[0].TourStatus; const tourstatus = res[0].TourStatus && res[0].TourStatus;
@@ -242,24 +231,12 @@ function PlaceHolderSign() {
setHandleError("Error: Something went wrong!"); setHandleError("Error: Something went wrong!");
setIsLoading(loadObj); setIsLoading(loadObj);
} else if (res.length === 0) { } else if (res.length === 0) {
const res = await contactBook(jsonSender.objectId); setNoData(true);
if (res[0] && res.length) {
setSignerUserId(res[0].objectId); const loadObj = {
const tourstatus = res[0].TourStatus && res[0].TourStatus; isLoad: false
if (tourstatus && tourstatus.length > 0) { };
setTourStatus(tourstatus); setIsLoading(loadObj);
const checkTourRecipients = tourstatus.filter(
(data) => data.placeholder
);
if (checkTourRecipients && checkTourRecipients.length > 0) {
setCheckTourStatus(checkTourRecipients[0].placeholder);
}
}
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
}
} }
}; };
@@ -14,7 +14,12 @@ import DefaultSignature from "./component/defaultSignature";
import { import {
getBase64FromUrl, getBase64FromUrl,
getBase64FromIMG, getBase64FromIMG,
contactBookName contactBookName,
convertPNGtoJPEG,
contractUsers,
contactBook,
contractDocument,
urlValidator
} from "../utils/Utils"; } from "../utils/Utils";
import Tour from "reactour"; import Tour from "reactour";
import Signedby from "./component/signedby"; import Signedby from "./component/signedby";
@@ -25,6 +30,7 @@ import Nodata from "./component/Nodata";
import Header from "./component/header"; import Header from "./component/header";
import RenderPdf from "./component/renderPdf"; import RenderPdf from "./component/renderPdf";
import CustomModal from "./component/CustomModal"; import CustomModal from "./component/CustomModal";
import { modalAlign } from "../utils/Utils";
function EmbedPdfImage() { function EmbedPdfImage() {
const { id, contactBookId } = useParams(); const { id, contactBookId } = useParams();
const [isSignPad, setIsSignPad] = useState(false); const [isSignPad, setIsSignPad] = useState(false);
@@ -74,6 +80,15 @@ function EmbedPdfImage() {
return object.pageNumber === pageNumber; return object.pageNumber === pageNumber;
}); });
const divRef = useRef(null); 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 //check isGuestSigner is present in local if yes than handle login flow header in mobile view
const isGuestSigner = localStorage.getItem("isGuestSigner"); const isGuestSigner = localStorage.getItem("isGuestSigner");
useEffect(() => { useEffect(() => {
@@ -96,33 +111,26 @@ function EmbedPdfImage() {
//function for get document details for perticular signer with signer'object id //function for get document details for perticular signer with signer'object id
const getDocumentDetails = async () => { const getDocumentDetails = async () => {
let currUserId, userObjectId; let currUserId, userObjectId;
const json = await contactBookName(contactBookId, "_Contactbook"); //getting contracts_contactBook details
if (json !== "Error: Something went wrong!" && json && json.results[0]) { const json = await contactBook(contactBookId);
if (json && json.length > 0) {
setContractName("_Contactbook"); setContractName("_Contactbook");
if (json.results[0]) {
userObjectId = json.results[0].UserId.objectId;
setUserObjectID(userObjectId);
currUserId = json.results[0].objectId;
setSignerUserId(currUserId); userObjectId = json[0].UserId.objectId;
const tourstatus = setUserObjectID(userObjectId);
json.results[0].TourStatus && json.results[0].TourStatus; currUserId = json[0].objectId;
if (tourstatus && tourstatus.length > 0) { setSignerUserId(currUserId);
setTourStatus(tourstatus); const tourstatus = json[0].TourStatus && json[0].TourStatus;
const checkTourRecipients = tourstatus.filter(
(data) => data.recipientssign if (tourstatus && tourstatus.length > 0) {
); setTourStatus(tourstatus);
if (checkTourRecipients && checkTourRecipients.length > 0) { const checkTourRecipients = tourstatus.filter(
setCheckTourStatus(checkTourRecipients[0].recipientssign); (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!") { } else if (json === "Error: Something went wrong!") {
const loadObj = { const loadObj = {
@@ -131,18 +139,16 @@ function EmbedPdfImage() {
setHandleError("Error: Something went wrong!"); setHandleError("Error: Something went wrong!");
setIsLoading(loadObj); setIsLoading(loadObj);
} else { } else {
const json = await contactBookName(contactBookId, "_Users"); const json = await contractUsers(jsonSender.email);
if (json && json.length > 0) {
if (json !== "Error: Something went wrong!" && json && json.results[0]) {
setContractName("_Users"); setContractName("_Users");
if (json.results[0]) { if (json[0]) {
userObjectId = json.results[0].UserId.objectId; userObjectId = json[0].UserId.objectId;
setUserObjectID(userObjectId); setUserObjectID(userObjectId);
currUserId = json.results[0].objectId; currUserId = json[0].objectId;
setSignerUserId(currUserId); setSignerUserId(currUserId);
const tourstatus = const tourstatus = json[0].TourStatus && json[0].TourStatus;
json.results[0].TourStatus && json.results[0].TourStatus;
if (tourstatus && tourstatus.length > 0) { if (tourstatus && tourstatus.length > 0) {
setTourStatus(tourstatus); setTourStatus(tourstatus);
@@ -166,171 +172,170 @@ function EmbedPdfImage() {
}; };
setHandleError("Error: Something went wrong!"); setHandleError("Error: Something went wrong!");
setIsLoading(loadObj); 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 = { const loadObj = {
isLoad: false isLoad: false
}; };
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj); 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 await axios
.get( .get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( `${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
@@ -444,38 +449,13 @@ function EmbedPdfImage() {
imgUrlList.map(async (data) => { imgUrlList.map(async (data) => {
//cheking signUrl is defau;t signature url of custom url //cheking signUrl is defau;t signature url of custom url
let ImgUrl = data.SignUrl; let ImgUrl = data.SignUrl;
const checkUrl = ImgUrl.includes("https:"); const checkUrl = urlValidator(ImgUrl);
//if default signature url then convert it in base 64 //if default signature url then convert it in base 64
if (checkUrl) { if (checkUrl) {
ImgUrl = await getBase64FromIMG(ImgUrl + "?get"); ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
} }
//function for called convert png signatre to jpeg in base 64 //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) convertPNGtoJPEG(ImgUrl)
.then((jpegBase64Data) => { .then((jpegBase64Data) => {
const removeBase64Fromjpeg = "data:image/jpeg;base64,"; const removeBase64Fromjpeg = "data:image/jpeg;base64,";
@@ -522,7 +502,12 @@ function EmbedPdfImage() {
const images = await Promise.all( const images = await Promise.all(
imgUrlList.map(async (url) => { imgUrlList.map(async (url) => {
let signUrl = url.SignUrl; 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) { if (checkUrl) {
signUrl = signUrl + "?get"; signUrl = signUrl + "?get";
} }
@@ -532,20 +517,7 @@ function EmbedPdfImage() {
}) })
); );
images.forEach(async (imgData, id) => { images.forEach(async (imgData, id) => {
let img; let img = await pdfDoc.embedJpg(imgData);
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);
}
const imgHeight = imgUrlList[id].Height const imgHeight = imgUrlList[id].Height
? imgUrlList[id].Height ? imgUrlList[id].Height
@@ -662,8 +634,8 @@ function EmbedPdfImage() {
yPosition = pos.isDrag yPosition = pos.isDrag
? y * scale - height ? y * scale - height
: pos.firstYPos : pos.firstYPos
? y * scale - height + pos.firstYPos ? y * scale - height + pos.firstYPos
: y * scale - height; : y * scale - height;
return yPosition; return yPosition;
} else { } else {
const y = pos.yBottom / scale; const y = pos.yBottom / scale;
@@ -671,8 +643,8 @@ function EmbedPdfImage() {
yPosition = pos.isDrag yPosition = pos.isDrag
? y * scale - height ? y * scale - height
: pos.firstYPos : pos.firstYPos
? y * scale - height + pos.firstYPos ? y * scale - height + pos.firstYPos
: y * scale - height; : y * scale - height;
return yPosition; return yPosition;
} }
} else { } else {
@@ -683,15 +655,15 @@ function EmbedPdfImage() {
yPosition = pos.isDrag yPosition = pos.isDrag
? y - height ? y - height
: pos.firstYPos : pos.firstYPos
? y - height + pos.firstYPos ? y - height + pos.firstYPos
: y - height; : y - height;
return yPosition; return yPosition;
} else { } else {
yPosition = pos.isDrag yPosition = pos.isDrag
? pos.yBottom - height ? pos.yBottom - height
: pos.firstYPos : pos.firstYPos
? pos.yBottom - height + pos.firstYPos ? pos.yBottom - height + pos.firstYPos
: pos.yBottom - height; : pos.yBottom - height;
return yPosition; return yPosition;
} }
} }
@@ -1016,7 +988,11 @@ function EmbedPdfImage() {
}} }}
> >
{/* this modal is used show this document is already sign */} {/* 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() }}> <ModalHeader style={{ background: themeColor() }}>
<span style={{ color: "white" }}> Sign Documents</span> <span style={{ color: "white" }}> Sign Documents</span>
</ModalHeader> </ModalHeader>
@@ -1083,6 +1059,7 @@ function EmbedPdfImage() {
isShowHeader={true} isShowHeader={true}
currentSigner={true} currentSigner={true}
decline={true} decline={true}
alreadySign={pdfUrl ? true : false}
/> />
<RenderPdf <RenderPdf
@@ -1127,7 +1104,6 @@ function EmbedPdfImage() {
)} )}
</div> </div>
)} )}
</DndProvider> </DndProvider>
); );
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

@@ -374,15 +374,13 @@
font-size: 50px; font-size: 50px;
} }
.DropdownMenuContent, .DropdownMenuContent,
.DropdownMenuSubContent { .DropdownMenuSubContent {
min-width: 130px; min-width: 130px;
background-color: #887abf; background-color: #fff;
border: none; border: 1px solid rgba(0, 0, 0, .15);
border-radius: 0.25rem;
padding: 5px; padding: 5px;
animation-duration: 400ms; animation-duration: 400ms;
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1); animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
will-change: transform, opacity; will-change: transform, opacity;
@@ -413,13 +411,13 @@
font-size: 13px; font-size: 13px;
line-height: 1; line-height: 1;
color: black; color: black;
background-color: #887abf; background-color: #fff;
display: flex; display: flex;
align-items: center; align-items: center;
height: 25px; height: 25px;
padding: 0 5px; padding: 0 5px;
position: relative; position: relative;
padding-left: 25px; padding-left: 20px;
user-select: none; user-select: none;
outline: none; outline: none;
border: none; border: none;
@@ -565,13 +563,13 @@ option {
color: var(--violet-11); color: var(--violet-11);
cursor: default; cursor: default;
} }
.fontOptionContainer{
border: 1px solid #d6d3d3; .fontOptionContainer {
margin: 10px 5px 5px 5px; border: 1px solid #d6d3d3;
margin: 10px 5px 5px 5px;
} }
@media screen and (max-width:766px) { @media screen and (max-width:766px) {
.showPages { .showPages {
@@ -631,14 +629,15 @@ option {
/* The sticky class is added to the navbar /* The sticky class is added to the navbar
with JS when it reaches its scroll position */ with JS when it reaches its scroll position */
.stickyHead { .stickyHead {
position: fixed;
top: 50px; top: 50px;
left: 0.9rem; left: 0.9rem;
} }
.stickySignerHead{
position: fixed; .stickySignerHead {
} position: fixed;
.stickyfooter { }
.stickyfooter {
position: fixed; position: fixed;
bottom: 0px; bottom: 0px;
right: 0rem; right: 0rem;
@@ -777,3 +776,13 @@ option {
display: flex; 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 axios from "axios";
import { $ } from 'select-dom';
export async function getBase64FromUrl(url) { export async function getBase64FromUrl(url) {
const data = await fetch(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() { export function getHostUrl() {
const hostUrl = window.location.href; 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) { if (hostUrl) {
const urlSplit = hostUrl.split("/"); const urlSplit = hostUrl.split("/");
@@ -58,7 +81,6 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
data.key === signKey && data.Width && data.Height && data.SignUrl data.key === signKey && data.Width && data.Height && data.SignUrl
); );
if (updateFilter.length > 0) { if (updateFilter.length > 0) {
let newWidth, newHeight; let newWidth, newHeight;
const aspectRatio = imgWH.width / imgWH.height; const aspectRatio = imgWH.width / imgWH.height;
@@ -139,7 +161,7 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
...url, ...url,
Width: getPosData[0].Width ? getPosData[0].Width : newWidth, Width: getPosData[0].Width ? getPosData[0].Width : newWidth,
Height: getPosData[0].Height ? getPosData[0].Height : newHeight, Height: getPosData[0].Height ? getPosData[0].Height : newHeight,
SignUrl: image.src, SignUrl: image.src,
ImageType: image.imgType ImageType: image.imgType
}; };
} }
@@ -153,7 +175,6 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
return obj; return obj;
}); });
return newUpdateUrl; return newUpdateUrl;
// setXyPostion(newUpdateUrl);
} }
} }
@@ -183,40 +204,105 @@ export function onSaveSign(xyPostion, index, signKey, signatureImg) {
return newUpdateUrl; return newUpdateUrl;
} }
//function for getting contract_User details //function for getting document details from contract_Documents class
export const contractUsers = async (objectId) => { export const contractDocument = async (documentId) => {
const result = await axios const data = {
.get( docId: documentId
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( };
"_appName" const documentDeatils = await axios
)}_Users?where={"UserId": {"__type": "Pointer","className": "_User", "objectId":"${objectId}"}}`, .post(`${localStorage.getItem("baseUrl")}functions/getDocument`, data, {
{ headers: {
headers: { "Content-Type": "application/json",
"Content-Type": "application/json", "X-Parse-Application-Id": localStorage.getItem("parseAppId"),
"X-Parse-Application-Id": localStorage.getItem("parseAppId"), sessionToken: localStorage.getItem("accesstoken")
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
}
} }
) })
.then((Listdata) => { .then((Listdata) => {
const json = Listdata.data; const json = Listdata.data;
const res = json.results; let data = [];
return res; if (json && json.result.error) {
return json;
} else if (json && json.result) {
data.push(json.result);
return data;
} else {
return [];
}
}) })
.catch((err) => { .catch((err) => {
return "Error: Something went wrong!"; 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) => { export const contactBook = async (objectId) => {
const result = await axios const result = await axios
.get( .get(
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( `${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
"_appName" "_appName"
)}_Contactbook?where={"UserId": {"__type": "Pointer","className": "_User", "objectId":"${objectId}"}}`, )}_Contactbook?where={"objectId":"${objectId}"}`,
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@@ -237,26 +323,22 @@ export const contactBook = async (objectId) => {
return result; return result;
}; };
export const contactBookName = async (objectId, className) => { // function for validating URLs
const result = await axios export function urlValidator(url) {
.get( try {
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( const newUrl = new URL(url);
"_appName" return newUrl.protocol === 'http:' || newUrl.protocol === 'https:';
)}${className}?where={"objectId":"${objectId}"}`, } catch (err) {
{ return false;
headers: { }
"Content-Type": "application/json", }
"X-Parse-Application-Id": localStorage.getItem("parseAppId"), export function modalAlign() {
"X-Parse-Session-Token": localStorage.getItem("accesstoken") let modalDialog = $('.modal-dialog').getBoundingClientRect();
} let mobileHead = $('.mobileHead').getBoundingClientRect()
} let modal = $('.modal-dialog');
) if (modalDialog.left < mobileHead.left) {
.then((Listdata) => { let leftOffset = mobileHead.left - modalDialog.left;
const json = Listdata.data; modal.style.left = leftOffset + 'px';
return json; modal.style.top = (window.innerHeight/3) + 'px';
}) }
.catch((err) => {
return "Error: Something went wrong!";
});
return result;
}; };
+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"
}
}