Compare commits

..
Author SHA1 Message Date
RaktimaNXG e71924a264 Merge branch 'staging' of https://github.com/OpenSignLabs/OpenSign into raktima-patch-2 2024-09-25 16:29:26 +05:30
RaktimaNXG 4ae9748004 feat: add agreement for signing document 2024-09-25 16:28:53 +05:30
prafull-opensignlabsandGitHub eda6113792 Merge pull request #1261 from OpenSignLabs/raktima-patch-2
fix: update npm package name of public sign
2024-09-25 12:04:21 +05:30
RaktimaNXG 4f1509c836 fix: handle condition of embed options 2024-09-25 11:53:15 +05:30
prafull-opensignlabsandGitHub dfcf32ef3e Merge pull request #1260 from OpenSignLabs/validation
build(deps): update dependencies
2024-09-25 11:14:53 +05:30
prafull-opensignlabs 4a95257ee2 build(deps): update googleapis package 2024-09-25 11:13:18 +05:30
prafull-opensignlabs ee1e13ef61 build(deps): update dependencies 2024-09-25 11:00:57 +05:30
prafull-opensignlabsandGitHub c9c099ffc5 Merge pull request #1259 from OpenSignLabs/raktima-patch-4
fix: document download & document redirect on wrong route issue in opensign-drive
2024-09-25 10:23:30 +05:30
RaktimaNXG a80f4fb3c9 fix: document download & document redirect on wrong route issue in opensign-drive 2024-09-25 10:21:16 +05:30
prafull-opensignlabsandGitHub 941f3ac47f Merge pull request #1258 from OpenSignLabs/validation
fix: valid file is not attached to mail in signyourself flow
2024-09-25 10:12:11 +05:30
prafull-opensignlabs 80d3200d57 fix: valid file is not attached to mail in signyourself flow 2024-09-25 10:11:01 +05:30
ZathielandGitHub 55926e25d2 Merge pull request #1206 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSign/eslint-plugin-react-7.36.1
build(deps-dev): bump eslint-plugin-react from 7.35.0 to 7.36.1 in /apps/OpenSign
2024-09-24 19:46:14 +02:00
ZathielandGitHub a31f3ebad7 Merge pull request #1251 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSignServer/eslint-9.11.1
build(deps-dev): bump eslint from 9.9.1 to 9.11.1 in /apps/OpenSignServer
2024-09-24 19:44:11 +02:00
RaktimaNXG dc9c32c6ee fix: update npm package name of public sign 2024-09-24 20:19:16 +05:30
dependabot[bot]andGitHub dac3aac2a1 build(deps-dev): bump eslint in /apps/OpenSignServer
Bumps [eslint](https://github.com/eslint/eslint) from 9.9.1 to 9.11.1.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.9.1...v9.11.1)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-24 14:06:57 +00:00
AndrewandGitHub 40196e823c Merge pull request #1252 from OpenSignLabs/validation
build(deps): bump parse-server from 7.2.0 to 7.3.0-alpha.7 in /apps/OpenSignServer
2024-09-24 19:35:40 +05:30
prafull-opensignlabs 7708b7e938 build(deps): bump googleapis from 7.2.0 to 7.3.0-alpha.7 in /apps/OpenSignServer 2024-09-24 19:34:38 +05:30
prafull-opensignlabsandGitHub 8bbc5a9bc6 Merge pull request #1149 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSign/babel/runtime-corejs2-7.25.6
build(deps-dev): bump @babel/runtime-corejs2 from 7.25.4 to 7.25.6 in /apps/OpenSign
2024-09-24 19:13:56 +05:30
prafull-opensignlabsandGitHub 4dbdfb1b77 Merge pull request #1238 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSignServer/nodemon-3.1.7
build(deps-dev): bump nodemon from 3.1.4 to 3.1.7 in /apps/OpenSignServer
2024-09-24 19:10:12 +05:30
prafull-opensignlabsandGitHub 05c51edce3 Merge pull request #1209 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSignServer/aws-sdk-2.1691.0
build(deps): bump aws-sdk from 2.1687.0 to 2.1691.0 in /apps/OpenSignServer
2024-09-24 19:09:24 +05:30
prafull-opensignlabsandGitHub 379e8cd95e Merge pull request #1208 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSign/react-router-dom-6.26.2
build(deps): bump react-router-dom from 6.26.1 to 6.26.2 in /apps/OpenSign
2024-09-24 19:08:57 +05:30
prafull-opensignlabsandGitHub 9fd00d4427 Merge pull request #1250 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSign/tailwindcss-3.4.13
build(deps-dev): bump tailwindcss from 3.4.12 to 3.4.13 in /apps/OpenSign
2024-09-24 19:08:27 +05:30
dependabot[bot]andGitHub ca114cf124 build(deps-dev): bump eslint-plugin-react in /apps/OpenSign
Bumps [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) from 7.35.0 to 7.36.1.
- [Release notes](https://github.com/jsx-eslint/eslint-plugin-react/releases)
- [Changelog](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.35.0...v7.36.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-react
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-24 13:37:44 +00:00
prafull-opensignlabsandGitHub 75128784db Merge pull request #1240 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSignServer/mongoose-8.6.3
build(deps): bump mongoose from 8.6.1 to 8.6.3 in /apps/OpenSignServer
2024-09-24 19:07:23 +05:30
dependabot[bot]andGitHub 722f0e277e build(deps-dev): bump tailwindcss in /apps/OpenSign
Bumps [tailwindcss](https://github.com/tailwindlabs/tailwindcss) from 3.4.12 to 3.4.13.
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/v3.4.13/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/compare/v3.4.12...v3.4.13)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-24 13:36:58 +00:00
prafull-opensignlabsandGitHub 7089998966 Merge pull request #1241 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSign/tailwindcss-3.4.12
build(deps-dev): bump tailwindcss from 3.4.10 to 3.4.12 in /apps/OpenSign
2024-09-24 19:06:28 +05:30
prafull-opensignlabsandGitHub 52211ddfa4 Merge pull request #1242 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSign/postcss-8.4.47
build(deps-dev): bump postcss from 8.4.45 to 8.4.47 in /apps/OpenSign
2024-09-24 19:05:24 +05:30
AndrewandGitHub 2b8b762d35 Merge pull request #1225 from OpenSignLabs/raktima-patch-2
feat: introduce embedding feature for template
2024-09-24 19:03:11 +05:30
RaktimaNXG a9c08c8a9f fix: update angular package name 2024-09-24 16:11:58 +05:30
RaktimaNXG 9406c4f718 Merge branch 'raktima-patch-2' of https://github.com/OpenSignLabs/OpenSign into raktima-patch-2 2024-09-24 15:01:23 +05:30
dependabot[bot]andGitHub 531ef4d0b2 build(deps-dev): bump postcss from 8.4.45 to 8.4.47 in /apps/OpenSign
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.45 to 8.4.47.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.45...8.4.47)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-23 00:38:18 +00:00
dependabot[bot]andGitHub 4c6dbb6690 build(deps-dev): bump tailwindcss in /apps/OpenSign
Bumps [tailwindcss](https://github.com/tailwindlabs/tailwindcss) from 3.4.10 to 3.4.12.
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/v3.4.12/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/compare/v3.4.10...v3.4.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-23 00:35:44 +00:00
dependabot[bot]andGitHub 0beb60d1b5 build(deps): bump mongoose from 8.6.1 to 8.6.3 in /apps/OpenSignServer
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.6.1 to 8.6.3.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.6.1...8.6.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-23 00:20:14 +00:00
dependabot[bot]andGitHub 893c9d7c42 build(deps-dev): bump nodemon in /apps/OpenSignServer
Bumps [nodemon](https://github.com/remy/nodemon) from 3.1.4 to 3.1.7.
- [Release notes](https://github.com/remy/nodemon/releases)
- [Commits](https://github.com/remy/nodemon/compare/v3.1.4...v3.1.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-23 00:19:44 +00:00
RaktimaNXG c442689573 fix: remove console 2024-09-19 18:38:32 +05:30
RaktimaNXG 88919f2634 refactor code 2024-09-19 17:47:50 +05:30
RaktimaNXG 50557d8bc5 Merge branch 'staging' of https://github.com/OpenSignLabs/OpenSign into raktima-patch-2 2024-09-19 17:34:28 +05:30
RaktimaNXG 0f1ef0406e refactor code 2024-09-19 17:19:45 +05:30
RaktimaNXG 9852c87be7 fix: design in mobile view 2024-09-18 18:19:08 +05:30
RaktimaNXG 1268f65516 fix: update angular text 2024-09-18 16:58:04 +05:30
RaktimaNXG 6551b2537a feat: implement angular npm package use case in public template 2024-09-18 16:48:20 +05:30
dependabot[bot]andGitHub b138ccf625 build(deps): bump aws-sdk in /apps/OpenSignServer
Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1687.0 to 2.1691.0.
- [Release notes](https://github.com/aws/aws-sdk-js/releases)
- [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1687.0...v2.1691.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-16 00:51:57 +00:00
dependabot[bot]andGitHub 27ff7baa6d build(deps): bump react-router-dom in /apps/OpenSign
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.26.1 to 6.26.2.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.26.2/packages/react-router-dom)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-16 00:12:46 +00:00
RaktimaNXG 3fc41f4255 feat : implement credit deduction in the public signature process 2024-09-09 09:59:33 +05:30
RaktimaNXG b20aa33a04 Merge branch 'staging' of https://github.com/OpenSignLabs/OpenSign into raktima-patch-2 2024-09-06 15:23:31 +05:30
RaktimaNXG a64da4cd85 Merge branch 'staging' of https://github.com/OpenSignLabs/OpenSign into raktima-patch-2 2024-09-06 09:59:41 +05:30
RaktimaNXG e80bcfc586 refactor code 2024-09-05 18:41:09 +05:30
RaktimaNXG de5b8160a2 fix: add embedding functionality for all template & add CopyTemplateId button in template report list options 2024-09-05 16:40:15 +05:30
RaktimaNXG 83df969751 feat: introduce embedding feature after make template public 2024-09-05 12:56:38 +05:30
dependabot[bot]andGitHub f04fd16c9e build(deps-dev): bump @babel/runtime-corejs2 in /apps/OpenSign
Bumps [@babel/runtime-corejs2](https://github.com/babel/babel/tree/HEAD/packages/babel-runtime-corejs2) from 7.25.4 to 7.25.6.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.6/packages/babel-runtime-corejs2)

---
updated-dependencies:
- dependency-name: "@babel/runtime-corejs2"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-02 00:32:16 +00:00
22 changed files with 2311 additions and 1909 deletions
+1241 -835
View File
File diff suppressed because it is too large Load Diff
+20 -19
View File
@@ -4,14 +4,14 @@
"private": true, "private": true,
"dependencies": { "dependencies": {
"@formkit/auto-animate": "^0.8.2", "@formkit/auto-animate": "^0.8.2",
"@lottiefiles/dotlottie-react": "^0.8.9", "@lottiefiles/dotlottie-react": "^0.9.0",
"@pdf-lib/fontkit": "^1.1.1", "@pdf-lib/fontkit": "^1.1.1",
"@radix-ui/themes": "^3.1.3", "@radix-ui/themes": "^3.1.3",
"@react-pdf/renderer": "^3.4.4", "@react-pdf/renderer": "^4.0.0",
"@reduxjs/toolkit": "^2.2.7", "@reduxjs/toolkit": "^2.2.7",
"axios": "^1.7.5", "axios": "^1.7.7",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"i18next": "^23.14.0", "i18next": "^23.15.1",
"i18next-browser-languagedetector": "^8.0.0", "i18next-browser-languagedetector": "^8.0.0",
"i18next-http-backend": "^2.6.1", "i18next-http-backend": "^2.6.1",
"jszip": "^3.10.1", "jszip": "^3.10.1",
@@ -26,7 +26,7 @@
"react-bootstrap": "^2.10.4", "react-bootstrap": "^2.10.4",
"react-confetti": "^6.1.0", "react-confetti": "^6.1.0",
"react-cookie": "^7.2.0", "react-cookie": "^7.2.0",
"react-datepicker": "^7.3.0", "react-datepicker": "^7.4.0",
"react-dnd": "^16.0.1", "react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1", "react-dnd-html5-backend": "^16.0.1",
"react-dnd-multi-backend": "^8.0.3", "react-dnd-multi-backend": "^8.0.3",
@@ -34,17 +34,18 @@
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-gtm-module": "^2.0.11", "react-gtm-module": "^2.0.11",
"react-helmet": "^6.1.0", "react-helmet": "^6.1.0",
"react-i18next": "^15.0.1", "react-i18next": "^15.0.2",
"react-konva": "^18.2.10", "react-konva": "^18.2.10",
"react-pdf": "^9.1.0", "react-pdf": "^9.1.1",
"react-quill-new": "^3.3.0", "react-quill-new": "^3.3.2",
"react-redux": "^9.1.2", "react-redux": "^9.1.2",
"react-rnd": "^10.4.11", "react-rnd": "^10.4.13",
"react-router-dom": "^6.26.1", "react-router-dom": "^6.26.2",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"react-scrollbars-custom": "^4.1.1", "react-scrollbars-custom": "^4.1.1",
"react-select": "^5.8.0", "react-select": "^5.8.1",
"react-signature-canvas": "^1.0.6", "react-signature-canvas": "^1.0.6",
"react-syntax-highlighter": "^15.5.0",
"react-tooltip": "^5.28.0", "react-tooltip": "^5.28.0",
"react-web-share": "^2.0.2", "react-web-share": "^2.0.2",
"reactour": "^1.19.4", "reactour": "^1.19.4",
@@ -60,7 +61,7 @@
"build-webpack": "webpack --config webpack.config.js", "build-webpack": "webpack --config webpack.config.js",
"build": "npm run version && npm run build-webpack && react-scripts build", "build": "npm run version && npm run build-webpack && react-scripts build",
"build-watch": "webpack --config webpack.config.js --watch", "build-watch": "webpack --config webpack.config.js --watch",
"start-dev": "concurrently \"npm run build-watch\" \"react-scripts start\"", "start-dev": "react-scripts start",
"start": "serve -s build", "start": "serve -s build",
"version": "curl -s https://api.github.com/repos/opensignlabs/opensign/releases/latest | grep '\"tag_name\":' | awk -F '\"' '{print $4}' > ./public/version.txt", "version": "curl -s https://api.github.com/repos/opensignlabs/opensign/releases/latest | grep '\"tag_name\":' | awk -F '\"' '{print $4}' > ./public/version.txt",
"version-win": "powershell -Command \"Invoke-RestMethod -Uri 'https://api.github.com/repos/opensignlabs/opensign/releases/latest' | Select-Object -ExpandProperty tag_name | Out-File -FilePath ./public/version.txt\"", "version-win": "powershell -Command \"Invoke-RestMethod -Uri 'https://api.github.com/repos/opensignlabs/opensign/releases/latest' | Select-Object -ExpandProperty tag_name | Out-File -FilePath ./public/version.txt\"",
@@ -97,25 +98,25 @@
"@babel/core": "^7.25.2", "@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.4", "@babel/preset-env": "^7.25.4",
"@babel/preset-react": "^7.24.7", "@babel/preset-react": "^7.24.7",
"@babel/runtime-corejs2": "^7.25.4", "@babel/runtime-corejs2": "^7.25.6",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"babel-loader": "^9.1.3", "babel-loader": "^9.2.1",
"clean-webpack-plugin": "^4.0.0", "clean-webpack-plugin": "^4.0.0",
"commitizen": "^4.3.0", "commitizen": "^4.3.0",
"concurrently": "^8.2.2", "concurrently": "^9.0.1",
"css-loader": "^7.1.2", "css-loader": "^7.1.2",
"daisyui": "^4.12.10", "daisyui": "^4.12.10",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"dotenv-webpack": "^8.1.0", "dotenv-webpack": "^8.1.0",
"eslint": "^8.57.0", "eslint": "^9.11.1",
"eslint-plugin-prettier": "^5.2.1", "eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.34.3", "eslint-plugin-react": "^7.36.1",
"lint-staged": "^15.2.10", "lint-staged": "^15.2.10",
"mini-css-extract-plugin": "^2.9.1", "mini-css-extract-plugin": "^2.9.1",
"postcss": "^8.4.45", "postcss": "^8.4.47",
"prettier": "^3.3.3", "prettier": "^3.3.3",
"pretty-quick": "^4.0.0", "pretty-quick": "^4.0.0",
"tailwindcss": "^3.4.10", "tailwindcss": "^3.4.13",
"terser-webpack-plugin": "^5.3.10", "terser-webpack-plugin": "^5.3.10",
"webpack-cli": "^5.1.4" "webpack-cli": "^5.1.4"
}, },
@@ -131,7 +131,8 @@
"Share": "Share", "Share": "Share",
"View": "View", "View": "View",
"option": "Option", "option": "Option",
"Embed": "Embed" "Embed": "Embed",
"Copy TemplateId":"Copy TemplateId"
}, },
"report-heading": { "report-heading": {
"Sr.No": "Sr.No", "Sr.No": "Sr.No",
@@ -264,7 +265,8 @@
"make-template-private-alert": "Are you sure you want to make this template private? This will remove it from your public profile.", "make-template-private-alert": "Are you sure you want to make this template private? This will remove it from your public profile.",
"public-role": "Public role", "public-role": "Public role",
"public-url": "Public URL", "public-url": "Public URL",
"public-url-copy-mssg": " Heres your public URL: Copy it or share it with the signer, and you will be able to see all your publicly set templates.", "public-url-copy": "Heres your public URL: ",
"public-url-copy-mssg":"Copy it or share it with the signer, and you will be able to see all your publicly set templates.",
"add-public-url-alert": "Please add your public URL, and you will be able to make a public template.", "add-public-url-alert": "Please add your public URL, and you will be able to make a public template.",
"share-with-alert": "You cannot share a template if any roles already have contacts assigned. Please remove all contact assignments from the roles before sharing the template.", "share-with-alert": "You cannot share a template if any roles already have contacts assigned. Please remove all contact assignments from the roles before sharing the template.",
"share-with": "Share with", "share-with": "Share with",
@@ -632,6 +634,19 @@
"reason":"Reason", "reason":"Reason",
"decline-by":"Declined/revoked by", "decline-by":"Declined/revoked by",
"document-declined": "Document declined", "document-declined": "Document declined",
"public-template-mssg-1":"To integrate OpenSign into your React or Next.js project, simply run the following command:",
"public-template-mssg-2" :"Ensure you have npm or yarn set up in your project. If youre using Yarn, you can replace npm install with yarn add @opensign/react.",
"public-template-mssg-3" :"Need more details or examples?",
"public-template-mssg-4": "Visit the",
"public-template-mssg-5": " npm for the latest updates, detailed documentation, and version history.",
"public-template-mssg-6" :"You need to set this template as public before you can utilize this code snippet.",
"copy-code":"COPY",
"copied-code":"COPIED",
"Installation":"Installation",
"Usage" :"Usage",
"insufficient-credits":"Insufficient Signing Credits",
"insufficient-credits-mssg":"The owner of this document currently lacks the necessary OpenSign credits for you to sign. Please reach out to the owner if you require further details.",
"angular-npm-mssg-1": "To integrate OpenSign into your Angular project, simply run the following command:",
"quota-mail-info-head":"Monthly request signatures email limit", "quota-mail-info-head":"Monthly request signatures email limit",
"quota-mail-info": "You can send upto 15 signature request emails every month. Upgrade now to send unlimited signing requests directly.", "quota-mail-info": "You can send upto 15 signature request emails every month. Upgrade now to send unlimited signing requests directly.",
"quota-mail": "You've reached your limit of 15 signature request emails for this month. Upgrade now to continue sending emails directly.", "quota-mail": "You've reached your limit of 15 signature request emails for this month. Upgrade now to continue sending emails directly.",
@@ -151,7 +151,8 @@
"Share": "Partager", "Share": "Partager",
"View": "Voir", "View": "Voir",
"option": "Option", "option": "Option",
"Embed": "Intégrer" "Embed": "Intégrer",
"Copy TemplateId": "Copier l'ID du modèle"
}, },
"report-help": { "report-help": {
"Draft Documents": "Il s'agit de documents que vous avez commencés mais que vous n'avez pas finalisés pour envoi.", "Draft Documents": "Il s'agit de documents que vous avez commencés mais que vous n'avez pas finalisés pour envoi.",
@@ -263,7 +264,8 @@
"make-template-private-alert": "Êtes-vous sûr de vouloir rendre ce modèle privé ? Cela le supprimera de votre profil public.", "make-template-private-alert": "Êtes-vous sûr de vouloir rendre ce modèle privé ? Cela le supprimera de votre profil public.",
"public-role": "Rôle public", "public-role": "Rôle public",
"public-url": "URL publique", "public-url": "URL publique",
"public-url-copy-mssg": "Voici votre URL publique : copiez-la ou partagez-le avec le signataire et vous pouvoir voir tous vos paramètres publics modèles.", "public-url-copy": "Voici votre URL publique : ",
"public-url-copy-mssg": "copiez-la ou partagez-le avec le signataire et vous pouvoir voir tous vos paramètres publics modèles.",
"add-public-url-alert": "Veuillez ajouter votre URL publique et vous pourra rendre public modèle.", "add-public-url-alert": "Veuillez ajouter votre URL publique et vous pourra rendre public modèle.",
"share-with-alert": "Vous ne pouvez pas partager un modèle si des contacts sont déjà attribués à des rôles. Veuillez supprimer toutes les attributions de contacts des rôles avant de partager le modèle.", "share-with-alert": "Vous ne pouvez pas partager un modèle si des contacts sont déjà attribués à des rôles. Veuillez supprimer toutes les attributions de contacts des rôles avant de partager le modèle.",
"share-with": "Partager avec", "share-with": "Partager avec",
@@ -631,6 +633,19 @@
"reason" :"Raison", "reason" :"Raison",
"decline-by" :"Refusé/révoqué par", "decline-by" :"Refusé/révoqué par",
"document-declined":"document refusé", "document-declined":"document refusé",
"public-template-mssg-1" :"Pour intégrer OpenSign dans votre projet React ou Next.js, exécutez simplement la commande suivante :",
"public-template-mssg-2" :"Assurez-vous que npm ou Yarn est configuré dans votre projet. Si vous utilisez Yarn, vous pouvez remplacer npm install par Yarn Add @opensign/react.",
"public-template-mssg-3" :"Besoin de plus de détails ou d'exemples ?",
"public-template-mssg-4": "Visitez le",
"public-template-mssg-5": "npm pour les dernières mises à jour, une documentation détaillée et l'historique des versions.",
"public-template-mssg-6":"Vous devez définir ce modèle comme public avant de pouvoir utiliser cet extrait de code.",
"copy-code":"COPIE",
"copied-code":"COPIÉ",
"Installation":"Installation",
"Usage" :"Usage",
"insufficient-credits":"Crédits de signature insuffisants",
"insufficient-credits-mssg" :"Le propriétaire de ce document ne dispose actuellement pas des crédits OpenSign nécessaires pour que vous puissiez le signer. Veuillez contacter le propriétaire si vous avez besoin de plus de détails.",
"angular-npm-mssg-1" :"Pour intégrer OpenSign dans votre projet Angular, exécutez simplement la commande suivante :",
"quota-mail-info-head":"Limite mensuelle d'e-mails de signatures de demandes", "quota-mail-info-head":"Limite mensuelle d'e-mails de signatures de demandes",
"quota-mail-info": "Vous pouvez envoyer jusqu'à 15 e-mails de demande de signature chaque mois. Mettez à niveau maintenant pour envoyer directement des demandes de signature illimitées.", "quota-mail-info": "Vous pouvez envoyer jusqu'à 15 e-mails de demande de signature chaque mois. Mettez à niveau maintenant pour envoyer directement des demandes de signature illimitées.",
"quota-mail": "Vous avez atteint votre limite de 15 e-mails de demande de signature pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.", "quota-mail": "Vous avez atteint votre limite de 15 e-mails de demande de signature pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.",
@@ -9,6 +9,7 @@ import * as HoverCard from "@radix-ui/react-hover-card";
import ModalUi from "../../primitives/ModalUi"; import ModalUi from "../../primitives/ModalUi";
import FolderModal from "../shared/fields/FolderModal"; import FolderModal from "../shared/fields/FolderModal";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { handleDownloadPdf } from "../../constant/Utils";
function DriveBody(props) { function DriveBody(props) {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -100,16 +101,17 @@ function DriveBody(props) {
//function for navigate user to microapp-signature component //function for navigate user to microapp-signature component
const checkPdfStatus = async (data) => { const checkPdfStatus = async (data) => {
const signerExist = data.Signers && data.Signers; const signerExist = data?.Signers;
const isDecline = data.IsDeclined && data.IsDeclined; const isDecline = data?.IsDeclined;
const isPlaceholder = data.Placeholders && data.Placeholders; const isPlaceholder = data?.Placeholders;
const signedUrl = data.SignedUrl; const signedUrl = data?.SignedUrl;
const isSignYourself = data?.IsSignyourself;
//checking if document has completed and request signature flow //checking if document has completed and request signature flow
if (data?.IsCompleted && signerExist?.length > 0) { if (data?.IsCompleted && signerExist?.length > 0) {
navigate(`/recipientSignPdf/${data.objectId}`); navigate(`/recipientSignPdf/${data.objectId}`);
} }
//checking if document has completed and signyour-self flow //checking if document has completed and signyour-self flow
else if (!signerExist && !isPlaceholder) { else if ((!signerExist && !isPlaceholder) || isSignYourself) {
navigate(`/signaturePdf/${data.objectId}`); navigate(`/signaturePdf/${data.objectId}`);
} }
//checking if document has declined by someone //checking if document has declined by someone
@@ -136,12 +138,10 @@ function DriveBody(props) {
} }
}; };
const handleMenuItemClick = (selectType, data) => { const handleMenuItemClick = async (selectType, data) => {
switch (selectType) { switch (selectType) {
case "Download": { case "Download": {
const pdfName = data && data.Name; await handleDownloadPdf([data]);
const pdfUrl = data && data.SignedUrl ? data.SignedUrl : data.URL;
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
break; break;
} }
case "Rename": { case "Rename": {
@@ -30,6 +30,28 @@ function EmailComponent({
const pdfName = pdfDetails[0]?.Name; const pdfName = pdfDetails[0]?.Name;
setIsLoading(true); setIsLoading(true);
let sendMail; let sendMail;
const docId = !pdfDetails?.[0]?.IsEnableOTP
? pdfDetails?.[0]?.objectId
: "";
let presignedUrl = pdfUrl;
try {
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
const axiosRes = await axios.post(
`${localStorage.getItem("baseUrl")}/functions/getsignedurl`,
{ url: pdfUrl, docId: docId },
{
headers: {
"content-type": "Application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
}
}
);
presignedUrl = axiosRes.data.result;
} catch (err) {
console.log("err in getsignedurl", err);
}
for (let i = 0; i < emailList.length; i++) { for (let i = 0; i < emailList.length; i++) {
try { try {
const imgPng = const imgPng =
@@ -47,7 +69,7 @@ function EmailComponent({
mailProvider: activeMailAdapter, mailProvider: activeMailAdapter,
extUserId: extUserId, extUserId: extUserId,
pdfName: pdfName, pdfName: pdfName,
url: pdfUrl, url: presignedUrl,
recipient: emailList[i], recipient: emailList[i],
subject: `${sender.name} has signed the doc - ${pdfName}`, subject: `${sender.name} has signed the doc - ${pdfName}`,
from: sender.email, from: sender.email,
@@ -0,0 +1,267 @@
import React, { useState } from "react";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { tomorrow } from "react-syntax-highlighter/dist/esm/styles/prism";
import { copytoData } from "../../constant/Utils";
import { useTranslation } from "react-i18next";
function EmbedTab(props) {
const { t } = useTranslation();
const tabName = [
{ title: "React/Next.js", icon: "fa-brands fa-react", color: "#61dafb" },
{ title: "JavaScript", icon: "fa-brands fa-js", color: "#ffd43b" },
{ title: "Angular", icon: "fa-brands fa-angular", color: "#ff5733" }
];
const [activeTab, setActiveTab] = useState(0);
// State to track if the code has been copied
const [isCopied, setIsCopied] = useState(false);
const reactCode = [
{
id: 0,
title: "Installation",
codeString: `
npm install @opensign/react`
},
{
id: 1,
title: "Usage",
codeString: `
import React from "react";
import Opensign from "@opensign/react";
export function App() {
return (
<div className="app">
<Opensign
onLoad={() => console.log("success")}
onLoadError={(error) => console.log(error)}
templateId= {"${props.templateId}"}
/>
</div>
);
}
`
}
];
const angularCode = [
{
id: 0,
title: "Installation",
codeString: `
npm install @opensign/angular`
},
{
id: 1,
title: "Usage",
codeString: `
import { Component } from '@angular/core';
import {OpensignComponent} from "@opensign/angular"
@Component({
selector:'app-root',
standalone: true,
imports: [OpensignComponent],
template: '<opensign templateId={"${props.templateId}"}
(onLoad)="handleLoad()"
(onLoadError)="handleError($event)"
></opensign>',
})
export class AppComponent{
handleLoad() {
console.log("success");
}
handleError(error: string) {
console.log(error);
}
}
`
}
];
const jsCodeString = `
<script
src= "https://app.opensignlabs.com/static/js/public-template.bundle.js"
id="opensign-script"
templateId=${props.templateId}
></script>
`;
const handleCopy = (code, ind) => {
copytoData(code);
setIsCopied({ ...isCopied, [ind]: true });
setTimeout(() => setIsCopied(false), 3000);
};
return (
<div className="mt-4 border-t-[1px]">
<div className="flex justify-center items-center mt-2">
<div role="tablist" className="op-tabs op-tabs-bordered">
{tabName.map((tabData, ind) => (
<div
onClick={() => setActiveTab(ind)}
key={ind}
role="tab"
className={`${
activeTab === ind ? "op-tab-active" : ""
} op-tab flex items-center`}
>
<i
className={`${tabData.icon}`}
style={{ color: tabData.color }}
></i>
<span className="ml-1 text-[10px] font-medium md:font-normal md:text-[15px]">
{tabData.title}
</span>
</div>
))}
</div>
</div>
<div>
{activeTab === 0 ? (
<div className="mt-4">
{reactCode.map((data, ind) => {
return (
<div key={ind}>
<p className="font-medium text-[18px]">
{t(`${data.title}`)}
</p>
<p className="text-[13px] mt-2">
{t("public-template-mssg-1")}
</p>
<div className="relative p-1">
<div
onClick={() => handleCopy(data.codeString, ind)}
className="absolute top-[20px] right-[20px] cursor-pointer"
>
<i className="fa-light fa-copy text-white mr-[2px]" />
<span className=" text-white">
{isCopied[ind] ? t("copied-code") : t("copy-code")}
</span>
</div>
<SyntaxHighlighter
customStyle={{
borderRadius: "15px"
}}
language="javascript"
style={tomorrow}
>
{data.codeString}
</SyntaxHighlighter>
</div>
</div>
);
})}
<p className="font-medium text-[15px]">
{t("public-template-mssg-3")}
</p>
<p className="my-[6px]">
{" "}
{t("public-template-mssg-4")}
<a
href="https://www.npmjs.com/package/@opensign/react"
target="_blank"
rel="noreferrer"
className="cursor-pointer text-blue-700 "
>
{" "}
OpenSign React package{" "}
</a>
{t("public-template-mssg-5")}
</p>
</div>
) : activeTab === 1 ? (
<div className="mt-4">
<div>
{/* <p className="font-medium text-[18px]">{t(`${data.title}`)}</p> */}
<div className="relative p-1">
<div
onClick={() => handleCopy(jsCodeString, 0)}
className="absolute top-[20px] right-[20px] cursor-pointer"
>
<i className="fa-light fa-copy text-white mr-[2px]" />
<span className=" text-white">
{isCopied[0] ? t("copied-code") : t("copy-code")}
</span>
</div>
<SyntaxHighlighter
customStyle={{
borderRadius: "15px"
}}
language="javascript"
style={tomorrow}
>
{jsCodeString}
</SyntaxHighlighter>
</div>
</div>
</div>
) : (
activeTab === 2 && (
<div className="mt-4">
{angularCode.map((data, ind) => {
return (
<div key={ind}>
<p className="font-medium text-[18px]">
{t(`${data.title}`)}
</p>
<p className="text-[13px] mt-2">
{t("angular-npm-mssg-1")}
</p>
<div className="relative p-1">
<div
onClick={() => handleCopy(data.codeString, ind)}
className="absolute top-[20px] right-[20px] cursor-pointer"
>
<i className="fa-light fa-copy text-white mr-[2px]" />
<span className=" text-white">
{isCopied[ind] ? t("copied-code") : t("copy-code")}
</span>
</div>
<SyntaxHighlighter
customStyle={{
borderRadius: "15px"
}}
language="javascript"
style={tomorrow}
>
{data.codeString}
</SyntaxHighlighter>
</div>
</div>
);
})}
<p className="font-medium text-[15px]">
{t("public-template-mssg-3")}
</p>
<p className="my-[6px]">
{" "}
{t("public-template-mssg-4")}
<a
href="https://www.npmjs.com/package/@opensign/angular"
target="_blank"
rel="noreferrer"
className="cursor-pointer text-blue-700 "
>
{" "}
OpenSign Angular package{" "}
</a>
{t("public-template-mssg-5")}
</p>
</div>
)
)}
</div>
</div>
);
}
export default EmbedTab;
+6 -5
View File
@@ -33,14 +33,15 @@ export const openInNewTab = (url, target) => {
export async function fetchSubscription( export async function fetchSubscription(
extUserId, extUserId,
contactObjId, contactObjId,
isGuestSign = false isGuestSign = false,
isPublic = false
) { ) {
try { try {
const Extand_Class = localStorage.getItem("Extand_Class"); const Extand_Class = localStorage.getItem("Extand_Class");
const extClass = Extand_Class && JSON.parse(Extand_Class); const extClass = Extand_Class && JSON.parse(Extand_Class);
// console.log("extClass ", extClass); // console.log("extClass ", extClass);
let extUser; let extUser;
if (extClass && extClass.length > 0) { if (extClass && extClass.length > 0 && !isPublic) {
extUser = extClass[0].objectId; extUser = extClass[0].objectId;
} else { } else {
extUser = extUserId; extUser = extUserId;
@@ -54,7 +55,7 @@ export async function fetchSubscription(
}; };
const params = isGuestSign const params = isGuestSign
? { contactId: contactObjId } ? { contactId: contactObjId }
: { extUserId: extUser }; : { extUserId: extUser, ispublic: isPublic };
const tenatRes = await axios.post(url, params, { headers: headers }); const tenatRes = await axios.post(url, params, { headers: headers });
let plan, status, billingDate, adminId; let plan, status, billingDate, adminId;
if (isGuestSign) { if (isGuestSign) {
@@ -2058,12 +2059,12 @@ export const getSignedUrl = async (pdfUrl, docId) => {
export const handleDownloadPdf = async (pdfDetails, setIsDownloading) => { export const handleDownloadPdf = async (pdfDetails, setIsDownloading) => {
const pdfName = pdfDetails[0] && pdfDetails[0]?.Name; const pdfName = pdfDetails[0] && pdfDetails[0]?.Name;
const pdfUrl = pdfDetails?.[0]?.SignedUrl || pdfDetails?.[0]?.URL; const pdfUrl = pdfDetails?.[0]?.SignedUrl || pdfDetails?.[0]?.URL;
setIsDownloading("pdf"); setIsDownloading && setIsDownloading("pdf");
const docId = !pdfDetails?.[0]?.IsEnableOTP ? pdfDetails?.[0]?.objectId : ""; const docId = !pdfDetails?.[0]?.IsEnableOTP ? pdfDetails?.[0]?.objectId : "";
try { try {
const url = await getSignedUrl(pdfUrl, docId); const url = await getSignedUrl(pdfUrl, docId);
await fetchUrl(url, pdfName); await fetchUrl(url, pdfName);
setIsDownloading(""); setIsDownloading && setIsDownloading("");
} catch (err) { } catch (err) {
console.log("err in getsignedurl", err); console.log("err in getsignedurl", err);
setIsDownloading(""); setIsDownloading("");
+21 -7
View File
@@ -1,3 +1,5 @@
import { isEnableSubscription } from "../constant/const";
export default function reportJson(id) { export default function reportJson(id) {
// console.log("json ", json); // console.log("json ", json);
const head = ["Sr.No", "Title", "Note", "Folder", "File", "Owner", "Signers"]; const head = ["Sr.No", "Title", "Note", "Folder", "File", "Owner", "Signers"];
@@ -22,6 +24,24 @@ export default function reportJson(id) {
const contactbook = ["Sr.No", "Name", "Email", "Phone"]; const contactbook = ["Sr.No", "Name", "Email", "Phone"];
const dashboardReportHead = ["Title", "File", "Owner", "Signers"]; const dashboardReportHead = ["Title", "File", "Owner", "Signers"];
const templateReport = ["Sr.No", "Title", "File", "Owner", "Signers"]; const templateReport = ["Sr.No", "Title", "File", "Owner", "Signers"];
const templateSubAction = isEnableSubscription
? [
{
btnId: "2434",
btnLabel: "Embed",
hoverLabel: "Embed",
btnIcon: "fa-light fa-code",
action: "Embed"
},
{
btnId: "2434",
btnLabel: "Copy TemplateId",
hoverLabel: "Copy TemplateId",
btnIcon: "fa-light fa-copy",
action: "CopyTemplateId"
}
]
: [];
switch (id) { switch (id) {
// draft documents report // draft documents report
case "ByHuevtCFY": case "ByHuevtCFY":
@@ -363,13 +383,7 @@ export default function reportJson(id) {
redirectUrl: "template", redirectUrl: "template",
action: "redirect" action: "redirect"
}, },
{ ...templateSubAction,
btnId: "2434",
btnLabel: "Embed",
hoverLabel: "Embed",
btnIcon: "fa-light fa-code",
action: "Embed"
},
{ {
btnId: "1834", btnId: "1834",
btnLabel: "Delete", btnLabel: "Delete",
+119 -44
View File
@@ -51,6 +51,7 @@ import LoaderWithMsg from "../primitives/LoaderWithMsg";
import DownloadPdfZip from "../primitives/DownloadPdfZip"; import DownloadPdfZip from "../primitives/DownloadPdfZip";
import Loader from "../primitives/Loader"; import Loader from "../primitives/Loader";
import PdfDeclineModal from "../primitives/PdfDeclineModal"; import PdfDeclineModal from "../primitives/PdfDeclineModal";
import Agreement from "../primitives/Agreement";
function PdfRequestFiles(props) { function PdfRequestFiles(props) {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -137,6 +138,8 @@ function PdfRequestFiles(props) {
const isHeader = useSelector((state) => state.showHeader); const isHeader = useSelector((state) => state.showHeader);
const divRef = useRef(null); const divRef = useRef(null);
const [isDownloadModal, setIsDownloadModal] = useState(false); const [isDownloadModal, setIsDownloadModal] = useState(false);
const [isAgree, setIsAgree] = useState(false);
const [isAgreeTour, setIsAgreeTour] = useState(false);
const isMobile = window.innerWidth < 767; const isMobile = window.innerWidth < 767;
@@ -244,7 +247,13 @@ function PdfRequestFiles(props) {
}; };
async function checkIsSubscribed(extUserId, contactId) { async function checkIsSubscribed(extUserId, contactId) {
const isGuestSign = isGuestSignFlow || false; const isGuestSign = isGuestSignFlow || false;
const res = await fetchSubscription(extUserId, contactId, isGuestSign); const isPublic = props.templateId ? true : false;
const res = await fetchSubscription(
extUserId,
contactId,
isGuestSign,
isPublic
);
const plan = res.plan; const plan = res.plan;
const billingDate = res?.billingDate; const billingDate = res?.billingDate;
const status = res?.status; const status = res?.status;
@@ -292,19 +301,21 @@ function PdfRequestFiles(props) {
} }
} }
); );
const documentData = const documentData = templateDeatils?.data?.result
templateDeatils.data && templateDeatils.data.result ? [templateDeatils?.data?.result]
? [templateDeatils.data.result] : [];
: [];
if (documentData && documentData[0]?.error) { if (documentData && documentData[0]?.error) {
props?.setTemplateStatus({ props?.setTemplateStatus &&
status: "Invalid" props?.setTemplateStatus({
}); status: "Invalid"
});
throw new Error("error: Invalid TemplateId");
} else if (documentData && documentData.length > 0) { } else if (documentData && documentData.length > 0) {
if (documentData[0]?.IsPublic) { if (documentData[0]?.IsPublic) {
props?.setTemplateStatus({ props?.setTemplateStatus &&
status: "Success" props?.setTemplateStatus({
}); status: "Success"
});
const url = const url =
documentData[0] && documentData[0] &&
(documentData[0]?.SignedUrl || documentData[0]?.URL); (documentData[0]?.SignedUrl || documentData[0]?.URL);
@@ -348,22 +359,34 @@ function PdfRequestFiles(props) {
isLoad: false isLoad: false
}); });
} else { } else {
props?.setTemplateStatus({ props?.setTemplateStatus &&
status: "Private" props?.setTemplateStatus({
}); status: "Private"
});
setIsLoading(false);
setHandleError(t("something-went-wrong-mssg"));
console.error("error: TemplateId is not public");
return;
} }
} else { } else {
props?.setTemplateStatus({ props?.setTemplateStatus &&
status: "Invalid" props?.setTemplateStatus({
}); status: "Invalid"
});
setIsLoading(false);
setHandleError(t("something-went-wrong-mssg"));
console.error("error: Invalid TemplateId");
return;
} }
} catch (err) { } catch (err) {
console.log("err in get template details ", err); setIsLoading(false);
if (err?.response?.data?.code === 101) { if (err?.response?.data?.code === 101) {
setHandleError(t("error-template")); setHandleError(t("error-template"));
} else { } else {
setHandleError(t("something-went-wrong-mssg")); setHandleError(t("something-went-wrong-mssg"));
} }
console.error("error: Invalid TemplateId");
return;
} }
}; };
//function for get document details for perticular signer with signer'object id //function for get document details for perticular signer with signer'object id
@@ -1287,7 +1310,11 @@ function PdfRequestFiles(props) {
.catch((err) => { .catch((err) => {
console.log("error updating field is decline ", err); console.log("error updating field is decline ", err);
setIsUiLoading(false); setIsUiLoading(false);
alert(t("something-went-wrong-mssg")); setIsAlert({
title: "Error",
isShow: true,
alertMessage: t("something-went-wrong-mssg")
});
}); });
}; };
//function to add default signature for all requested placeholder of sign //function to add default signature for all requested placeholder of sign
@@ -1488,11 +1515,32 @@ function PdfRequestFiles(props) {
await SendOtp(); await SendOtp();
} else { } else {
console.log("error in public-sign to create user details"); console.log("error in public-sign to create user details");
alert(t("something-went-wrong-mssg")); setIsAlert({
title: "Error",
isShow: true,
alertMessage: t("something-went-wrong-mssg")
});
} }
} catch (e) { } catch (e) {
console.log("e", e); console.log("e", e);
// setIsLoader(false); if (
e?.response?.data?.error === "Insufficient Credit" ||
e?.response?.data?.error === "Plan expired"
) {
handleCloseOtp();
setIsAlert({
title: t("insufficient-credits"),
isShow: true,
alertMessage: t("insufficient-credits-mssg")
});
} else {
handleCloseOtp();
setIsAlert({
title: "Error",
isShow: true,
alertMessage: t("something-went-wrong-mssg")
});
}
} }
}; };
@@ -1524,7 +1572,11 @@ function PdfRequestFiles(props) {
} }
} catch (error) { } catch (error) {
console.log("error in verify otp in public-sign", error); console.log("error in verify otp in public-sign", error);
alert(t("something-went-wrong-mssg")); setIsAlert({
title: "Error",
isShow: true,
alertMessage: t("something-went-wrong-mssg")
});
} }
}; };
@@ -1623,6 +1675,17 @@ function PdfRequestFiles(props) {
</div> </div>
); );
}; };
const AgreementTour = [
{
selector: '[data-tut="IsAgree"]',
content: "Please agree & continue to start signing",
position: "top",
style: { fontSize: "13px" }
}
];
const handleCloseAgreeTour = () => {
setIsAgreeTour(false);
};
return ( return (
<DndProvider backend={HTML5Backend}> <DndProvider backend={HTML5Backend}>
<Title title={props.templateId ? "Public Sign" : "Request Sign"} /> <Title title={props.templateId ? "Public Sign" : "Request Sign"} />
@@ -1645,7 +1708,23 @@ function PdfRequestFiles(props) {
) : handleError ? ( ) : handleError ? (
<HandleError handleError={handleError} /> <HandleError handleError={handleError} />
) : ( ) : (
<div> <div onClick={() => !isAgree && setIsAgreeTour(true)}>
{!isAgree && (
<Agreement
setIsAgree={setIsAgree}
setIsAgreeTour={setIsAgreeTour}
/>
)}
<Tour
showNumber={false}
showNavigation={false}
showNavigationNumber={false}
onRequestClose={handleCloseAgreeTour}
steps={AgreementTour}
isOpen={isAgreeTour}
rounded={5}
closeWithMask={false}
/>
{isUiLoading && ( {isUiLoading && (
<div className="absolute h-[100vh] w-full flex flex-col justify-center items-center z-[999] bg-[#e6f2f2] bg-opacity-80"> <div className="absolute h-[100vh] w-full flex flex-col justify-center items-center z-[999] bg-[#e6f2f2] bg-opacity-80">
<Loader /> <Loader />
@@ -1664,6 +1743,7 @@ function PdfRequestFiles(props) {
/> />
</div> </div>
)} )}
<div <div
style={{ style={{
pointerEvents: pointerEvents:
@@ -1680,27 +1760,6 @@ function PdfRequestFiles(props) {
{!requestSignTour && {!requestSignTour &&
signerObjectId && signerObjectId &&
requestSignTourFunction()} requestSignTourFunction()}
<ModalUi
isOpen={isAlert.isShow}
title={t("alert-message")}
handleClose={() =>
setIsAlert({ isShow: false, alertMessage: "" })
}
>
<div className="h-full p-[20px]">
<p>{isAlert.alertMessage}</p>
<button
onClick={() =>
setIsAlert({ isShow: false, alertMessage: "" })
}
type="button"
className="op-btn op-btn-primary mt-3 px-4"
>
{t("ok")}
</button>
</div>
</ModalUi>
<Tour <Tour
showNumber={false} showNumber={false}
showNavigation={false} showNavigation={false}
@@ -2216,6 +2275,22 @@ function PdfRequestFiles(props) {
pdfDetails={pdfDetails} pdfDetails={pdfDetails}
isDocId={true} isDocId={true}
/> />
<ModalUi
isOpen={isAlert.isShow}
title={isAlert?.title || t("alert-message")}
handleClose={() => setIsAlert({ isShow: false, alertMessage: "" })}
>
<div className="h-full p-[20px]">
<p>{isAlert.alertMessage}</p>
<button
onClick={() => setIsAlert({ isShow: false, alertMessage: "" })}
type="button"
className="op-btn op-btn-primary mt-3 px-4"
>
{t("close")}
</button>
</div>
</ModalUi>
</> </>
)} )}
</DndProvider> </DndProvider>
+1 -1
View File
@@ -1047,7 +1047,7 @@ function PlaceHolderSign() {
type="button" type="button"
className="flex flex-row items-center op-link op-link-primary" className="flex flex-row items-center op-link op-link-primary"
> >
<i className="fa-light fa-link" aria-hidden="true"></i> <i className="fa-light fa-copy" />
<span className=" hidden md:block ml-1 ">{t("copy-link")}</span> <span className=" hidden md:block ml-1 ">{t("copy-link")}</span>
</button> </button>
<RWebShare data={{ url: data.url, title: t("sign-url") }}> <RWebShare data={{ url: data.url, title: t("sign-url") }}>
+1 -1
View File
@@ -596,7 +596,7 @@ function UserProfile() {
className="op-btn op-btn-primary op-btn-outline op-btn-xs md:op-btn-sm" className="op-btn op-btn-primary op-btn-outline op-btn-xs md:op-btn-sm"
onClick={() => copytoclipboard()} onClick={() => copytoclipboard()}
> >
<i className="fa-light fa-link"></i>{" "} <i className="fa-light fa-copy" />
</button> </button>
</div> </div>
</div> </div>
+43
View File
@@ -0,0 +1,43 @@
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
function Agreement(props) {
const { t } = useTranslation();
const [isChecked, setIsChecked] = useState(false);
return (
<div className="flex justify-between mx-2 mb-2 pt-1" data-tut="IsAgree">
<div className="flex items-center">
<input
className="mr-3 op-checkbox op-checkbox-m"
type="checkbox"
value={isChecked}
onChange={(e) => {
setIsChecked(e.target.checked);
if (e.target.checked) {
props.setIsAgreeTour(false);
}
}}
/>
I confirm that I have read and understood the &apos;Electronic Record
and Signature Disclosure&apos; and consent to use electronic records and
signatures.
</div>
<div className="flex">
<button
onClick={() => {
if (isChecked) {
props.setIsAgreeTour(false);
props.setIsAgree(true);
}
}}
className="op-btn op-btn-primary op-btn-sm"
>
Agree & Continue
</button>
</div>
</div>
);
}
export default Agreement;
+2 -2
View File
@@ -25,8 +25,8 @@ const Alert = ({ children, type, className }) => {
: "z-[1000] fixed top-20 left-1/2 transform -translate-x-1/2 text-sm" : "z-[1000] fixed top-20 left-1/2 transform -translate-x-1/2 text-sm"
} `} } `}
> >
<div className={`op-alert ${textcolor}`}> <div className={`op-alert ${textcolor} flex justify-center`}>
<span className="ml-3">{children}</span> <span className="px-1">{children}</span>
</div> </div>
</div> </div>
) )
@@ -32,6 +32,7 @@ import { validplan } from "../json/plansArr";
import { serverUrl_fn } from "../constant/appinfo"; import { serverUrl_fn } from "../constant/appinfo";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import DownloadPdfZip from "./DownloadPdfZip"; import DownloadPdfZip from "./DownloadPdfZip";
import EmbedTab from "../components/pdf/EmbedTab";
const ReportTable = (props) => { const ReportTable = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -74,6 +75,7 @@ const ReportTable = (props) => {
const [isModal, setIsModal] = useState({}); const [isModal, setIsModal] = useState({});
const [reason, setReason] = useState(""); const [reason, setReason] = useState("");
const [isDownloadModal, setIsDownloadModal] = useState(false); const [isDownloadModal, setIsDownloadModal] = useState(false);
const [isEmbed, setIsEmbed] = useState(false);
const Extand_Class = localStorage.getItem("Extand_Class"); const Extand_Class = localStorage.getItem("Extand_Class");
const extClass = Extand_Class && JSON.parse(Extand_Class); const extClass = Extand_Class && JSON.parse(Extand_Class);
const startIndex = (currentPage - 1) * props.docPerPage; const startIndex = (currentPage - 1) * props.docPerPage;
@@ -369,6 +371,8 @@ const ReportTable = (props) => {
setIsShareWith({ [item.objectId]: true }); setIsShareWith({ [item.objectId]: true });
} else if (act.action === "Embed") { } else if (act.action === "Embed") {
handleEmbedFunction(item); handleEmbedFunction(item);
} else if (act.action === "CopyTemplateId") {
copyTemplateId(item.objectId);
} }
}; };
// Get current list // Get current list
@@ -1121,12 +1125,14 @@ const ReportTable = (props) => {
} }
}; };
const handleEmbedFunction = async (item) => { const handleEmbedFunction = async (item) => {
setIsEmbed(true);
setIsPublicProfile({ setIsPublicProfile({
[item.objectId]: props.isPublic[item.objectId] [item.objectId]: true
}); });
let extendUser = JSON.parse(localStorage.getItem("Extand_Class")); let extendUser = JSON.parse(localStorage.getItem("Extand_Class"));
setIsPublicUserName(extendUser[0]?.UserName || ""); setIsPublicUserName(extendUser[0]?.UserName || "");
}; };
return ( return (
<div className="relative"> <div className="relative">
{Object.keys(actLoader)?.length > 0 && ( {Object.keys(actLoader)?.length > 0 && (
@@ -1446,22 +1452,27 @@ const ReportTable = (props) => {
<ModalUi <ModalUi
isOpen isOpen
title={t("public-url")} title={t("public-url")}
handleClose={() => setIsPublicProfile({})} handleClose={() => {
setIsPublicProfile({});
setIsEmbed(false);
}}
> >
<div className="m-[20px]"> <div className="m-[20px]">
{publicUserName ? ( {isEmbed && !item?.IsPublic ? (
<>
<p>{t("public-template-mssg-6")}</p>
<EmbedTab templateId={item.objectId} />
</>
) : publicUserName ? (
<div className="font-normal text-black"> <div className="font-normal text-black">
<p>{t("public-url-copy-mssg")}</p> <span>{t("public-url-copy")}</span>
<div className=" flex items-center justify-between gap-3 mt-2 p-[2px] "> <div className=" flex items-center justify-between gap-3 p-[2px] ">
<div className="w-[280px] whitespace-nowrap overflow-hidden text-ellipsis"> <div className="w-[280px] whitespace-nowrap overflow-hidden text-ellipsis">
<span className="font-bold">
{t("public-url")} :
</span>
<span <span
onClick={() => onClick={() =>
copytoProfileLink() copytoProfileLink()
} }
className="ml-[2px] underline underline-offset-2 cursor-pointer" className="ml-[2px] underline underline-offset-2 cursor-pointer text-blue-800"
> >
{publicUrl()} {publicUrl()}
</span> </span>
@@ -1486,7 +1497,7 @@ const ReportTable = (props) => {
copytoProfileLink() copytoProfileLink()
} }
> >
<i className="fa-light fa-link"></i>{" "} <i className="fa-light fa-copy" />
<span className="hidden md:inline-block"> <span className="hidden md:inline-block">
{copied["publicprofile"] {copied["publicprofile"]
? t("copied") ? t("copied")
@@ -1495,36 +1506,10 @@ const ReportTable = (props) => {
</button> </button>
</div> </div>
</div> </div>
<div className=" flex items-center justify-between gap-3 mt-2 p-[2px] "> <p className="text-[13px] mt-[5px]">
<div> {t("public-url-copy-mssg")}
<span className="font-bold"> </p>
{t("templateid")} : <EmbedTab templateId={item.objectId} />
</span>
<span
onClick={() =>
copyTemplateId(item.objectId)
}
className="underline ml-[2px] underline-offset-2 w-[150px] md:w-[350px] whitespace-nowrap overflow-hidden text-ellipsis cursor-pointer"
>
{item.objectId}
</span>
</div>
<div className="flex items-center gap-2">
<button
className="op-btn op-btn-primary op-btn-outline op-btn-xs md:op-btn-sm"
onClick={() =>
copyTemplateId(item.objectId)
}
>
<i className="fa-light fa-link"></i>{" "}
<span className="hidden md:inline-block">
{copied["templateid"]
? t("copied")
: t("copy")}
</span>
</button>
</div>
</div>
</div> </div>
) : ( ) : (
<div className="font-normal text-black"> <div className="font-normal text-black">
@@ -1584,65 +1569,33 @@ const ReportTable = (props) => {
{isOption[item.objectId] && {isOption[item.objectId] &&
act.action === "option" && ( act.action === "option" && (
<ul className="absolute -right-1 top-auto z-[70] w-max op-dropdown-content op-menu shadow bg-base-100 text-base-content rounded-box"> <ul className="absolute -right-1 top-auto z-[70] w-max op-dropdown-content op-menu shadow bg-base-100 text-base-content rounded-box">
{act.subaction?.map((subact) => {act.subaction?.map((subact) => (
props.isPublic[ <li
item.objectId key={subact.btnId}
] ? ( onClick={() =>
<li handleActionBtn(
key={subact.btnId} subact,
onClick={() => item
handleActionBtn( )
subact, }
item title={t(
) `btnLabel.${subact.btnLabel}`
} )}
title={t( >
`btnLabel.${subact.btnLabel}` <span>
)} <i
> className={`${subact.btnIcon} mr-1.5`}
<span> ></i>
<i {subact.btnLabel && (
className={`${subact.btnIcon} mr-1.5`} <span className="text-[13px] capitalize font-medium">
></i> {t(
{subact.btnLabel && ( `btnLabel.${subact.btnLabel}`
<span className="text-[13px] capitalize font-medium">
{t(
`btnLabel.${subact.btnLabel}`
)}
</span>
)}
</span>
</li>
) : (
subact.action !== "Embed" && (
<li
key={subact.btnId}
onClick={() =>
handleActionBtn(
subact,
item
)
}
title={t(
`btnLabel.${subact.btnLabel}`
)}
>
<span>
<i
className={`${subact.btnIcon} mr-1.5`}
></i>
{subact.btnLabel && (
<span className="text-[13px] capitalize font-medium">
{t(
`btnLabel.${subact.btnLabel}`
)}
</span>
)} )}
</span> </span>
</li> )}
) </span>
) </li>
)} ))}
</ul> </ul>
)} )}
</div> </div>
@@ -1963,7 +1916,7 @@ const ReportTable = (props) => {
className="op-btn op-btn-primary op-btn-outline op-btn-xs md:op-btn-sm" className="op-btn op-btn-primary op-btn-outline op-btn-xs md:op-btn-sm"
onClick={() => copytoclipboard(share)} onClick={() => copytoclipboard(share)}
> >
<i className="fa-light fa-link"></i>{" "} <i className="fa-light fa-copy" />
{copied[share.email] {copied[share.email]
? t("copied") ? t("copied")
: t("copy")} : t("copy")}
+18 -9
View File
@@ -11,28 +11,37 @@ import { isPublicStaging } from "../constant/const";
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.mjs`; pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.mjs`;
// Wrapper component to manage props // Wrapper component to manage props
const PublicScriptFileWrapper = ({ initialProps }) => { const PublicScriptFileWrapper = () => {
const [props, setProps] = useState(initialProps); const [props, setProps] = useState("");
// Make the setProps function globally accessible
useEffect(() => { useEffect(() => {
// Assigns the function 'setProps' to the global 'window' object as 'updatePublicTemplateProps'.
// This allows 'setProps' to be accessed and called globally across different scripts or components,
// enabling dynamic updates to the public template's properties.
window.updatePublicTemplateProps = setProps; window.updatePublicTemplateProps = setProps;
const publicScript = document.getElementById("opensign-script");
// condition for using plan js load opensign-script then get templateId
if (publicScript) {
// Get the custom templateId attribute
const templateId = publicScript.getAttribute("templateId");
if (templateId) {
setProps({ templateId: templateId });
} else {
const error = "error: TemplateId is missing";
throw new Error(error);
}
}
return () => { return () => {
window.updatePublicTemplateProps = undefined; window.updatePublicTemplateProps = undefined;
}; };
}, []); }, []);
return <PdfRequestFiles {...props} />; return <PdfRequestFiles {...props} />;
}; };
const appId = isPublicStaging ? "opensign" : "legadranaxn"; const appId = isPublicStaging ? "opensign" : "legadranaxn";
//"opensign"
const serverUrl = isPublicStaging const serverUrl = isPublicStaging
? "https://staging-app.opensignlabs.com/api/app" ? "https://staging-app.opensignlabs.com/api/app"
: "https://app.opensignlabs.com/api/app"; : "https://app.opensignlabs.com/api/app";
// "https://staging-app.opensignlabs.com/api/app"
localStorage.setItem("baseUrl", `${serverUrl}/`); localStorage.setItem("baseUrl", `${serverUrl}/`);
localStorage.setItem("parseAppId", appId); localStorage.setItem("parseAppId", appId);
@@ -58,7 +67,7 @@ const root = ReactDOM.createRoot(document.getElementById("script-component"));
root.render( root.render(
<div data-theme="opensigncss"> <div data-theme="opensigncss">
<Provider store={store}> <Provider store={store}>
<PublicScriptFileWrapper initialProps={{ text: "templateId" }} /> <PublicScriptFileWrapper />
</Provider> </Provider>
</div> </div>
); );
@@ -41,7 +41,7 @@
"upgrade-now": "Upgrade now", "upgrade-now": "Upgrade now",
"upgrade-to": "Upgrade to", "upgrade-to": "Upgrade to",
"plan": "Plan", "plan": "Plan",
"subscribe-card-teamplan": "Unlock the full power of collaboration! Create unlimited organizations, teams, and hierarchies. Share templates seamlessly across teams and assign custom user roles. Elevate your workflow today!", "subscribe-card-teamplan":"Unlock the full power of collaboration! Create unlimited organizations, teams, and hierarchies. Share templates seamlessly across teams and assign custom user roles. Elevate your workflow today!",
"subscribe-card-plan": "Unlock premium features starting at just {{premiumPrice}}/month. Enjoy enhanced performance and only {{addonPrice}} per additional credit after your included premium credits.", "subscribe-card-plan": "Unlock premium features starting at just {{premiumPrice}}/month. Enjoy enhanced performance and only {{addonPrice}} per additional credit after your included premium credits.",
"user-name-limit-char": "To have a username less than 8 character please subscribe", "user-name-limit-char": "To have a username less than 8 character please subscribe",
"tour-content": "Don't show this again", "tour-content": "Don't show this again",
@@ -131,7 +131,8 @@
"Share": "Share", "Share": "Share",
"View": "View", "View": "View",
"option": "Option", "option": "Option",
"Embed": "Embed" "Embed": "Embed",
"Copy TemplateId":"Copy TemplateId"
}, },
"report-heading": { "report-heading": {
"Sr.No": "Sr.No", "Sr.No": "Sr.No",
@@ -264,7 +265,8 @@
"make-template-private-alert": "Are you sure you want to make this template private? This will remove it from your public profile.", "make-template-private-alert": "Are you sure you want to make this template private? This will remove it from your public profile.",
"public-role": "Public role", "public-role": "Public role",
"public-url": "Public URL", "public-url": "Public URL",
"public-url-copy-mssg": " Heres your public URL: Copy it or share it with the signer, and you will be able to see all your publicly set templates.", "public-url-copy": "Heres your public URL: ",
"public-url-copy-mssg":"Copy it or share it with the signer, and you will be able to see all your publicly set templates.",
"add-public-url-alert": "Please add your public URL, and you will be able to make a public template.", "add-public-url-alert": "Please add your public URL, and you will be able to make a public template.",
"share-with-alert": "You cannot share a template if any roles already have contacts assigned. Please remove all contact assignments from the roles before sharing the template.", "share-with-alert": "You cannot share a template if any roles already have contacts assigned. Please remove all contact assignments from the roles before sharing the template.",
"share-with": "Share with", "share-with": "Share with",
@@ -595,7 +597,7 @@
"Recently sent for signatures": "This is a list of documents you've sent to other parties for signature.", "Recently sent for signatures": "This is a list of documents you've sent to other parties for signature.",
"Drafts": "This are documents you have started but have not finalized for sending.", "Drafts": "This are documents you have started but have not finalized for sending.",
"public-template": "This video demonstrates how to set up your personalized public profile, such as https://opensign.me/your-username. Youll also learn how to customize your tagline and make your templates available for public signing." "public-template": "This video demonstrates how to set up your personalized public profile, such as https://opensign.me/your-username. Youll also learn how to customize your tagline and make your templates available for public signing."
}, },
"enter-email-plaholder": "Add an email address and hit enter", "enter-email-plaholder": "Add an email address and hit enter",
"success-email-alert": "Email sent successfully!", "success-email-alert": "Email sent successfully!",
"expired-doc-title": "Expired Document", "expired-doc-title": "Expired Document",
@@ -616,31 +618,44 @@
"select-date-format": "Select a date format", "select-date-format": "Select a date format",
"quantity-of-credits": "Quantity of premium credits", "quantity-of-credits": "Quantity of premium credits",
"remaining-credits": "Premium credits available:", "remaining-credits": "Premium credits available:",
"remaining-credits-help": "Use premium credits for API document signing, bulk sending, or embedding OpenSign integration on your website. You have {{allowedcredits}} included credits and {{addoncredits}} additional purchased credits remaining.", "remaining-credits-help":"Use premium credits for API document signing, bulk sending, or embedding OpenSign integration on your website. You have {{allowedcredits}} included credits and {{addoncredits}} additional purchased credits remaining.",
"additional-credits": "Please purchase premium credits", "additional-credits": "Please purchase premium credits",
"quota-err-quicksend": "Quota Reached, You don't have enough credits.", "quota-err-quicksend": "Quota Reached, You don't have enough credits.",
"buy-credits": "Buy Premium Credits", "buy-credits": "Buy Premium Credits",
"rotate-right": "Rotate right", "rotate-right":"Rotate right",
"rotate-left": "Rotate left", "rotate-left":"Rotate left",
"rotate-alert-mssg": "All widgets on this page will be lost. Are you sure you want to proceed?", "rotate-alert-mssg":"All widgets on this page will be lost. Are you sure you want to proceed?",
"templateid": "Template-Id", "templateid":"Template-Id",
"bulk-send-subcription-alert": "Please upgrade to Professional or Team plan to use bulk send.", "bulk-send-subcription-alert":"Please upgrade to Professional or Team plan to use bulk send.",
"generate-test-token": "Generate Test Token", "generate-test-token":"Generate Test Token",
"regenerate-test-token": "Regenerate Test Token", "regenerate-test-token":"Regenerate Test Token",
"help-test-token": "This token can be used to test the APIs at the https://sandbox.opensignlabs.com/api/v1 endpoint, allowing you to conduct unlimited document signatures. Please note that the sandbox API will sign your documents with self-signed certificates, which may not be recognized as valid by Adobe. Once youve completed your testing, you can upgrade to one of our paid plans to generate a production token.", "help-test-token":"This token can be used to test the APIs at the https://sandbox.opensignlabs.com/api/v1 endpoint, allowing you to conduct unlimited document signatures. Please note that the sandbox API will sign your documents with self-signed certificates, which may not be recognized as valid by Adobe. Once youve completed your testing, you can upgrade to one of our paid plans to generate a production token.",
"help-api-token": "This token can be used to access the production APIs at the {{origin}}/api/v1 endpoint. It can only be generated on one of our paid plans.", "help-api-token":"This token can be used to access the production APIs at the {{origin}}/api/v1 endpoint. It can only be generated on one of our paid plans.",
"reason": "Reason", "reason":"Reason",
"decline-by": "Declined/revoked by", "decline-by":"Declined/revoked by",
"document-declined": "Document declined", "document-declined": "Document declined",
"quota-mail-info-head": "Monthly request signatures email limit", "public-template-mssg-1":"To integrate OpenSign into your React or Next.js project, simply run the following command:",
"public-template-mssg-2" :"Ensure you have npm or yarn set up in your project. If youre using Yarn, you can replace npm install with yarn add @opensign/react.",
"public-template-mssg-3" :"Need more details or examples?",
"public-template-mssg-4": "Visit the",
"public-template-mssg-5": " npm for the latest updates, detailed documentation, and version history.",
"public-template-mssg-6" :"You need to set this template as public before you can utilize this code snippet.",
"copy-code":"COPY",
"copied-code":"COPIED",
"Installation":"Installation",
"Usage" :"Usage",
"insufficient-credits":"Insufficient Signing Credits",
"insufficient-credits-mssg":"The owner of this document currently lacks the necessary OpenSign credits for you to sign. Please reach out to the owner if you require further details.",
"angular-npm-mssg-1": "To integrate OpenSign into your Angular project, simply run the following command:",
"quota-mail-info-head":"Monthly request signatures email limit",
"quota-mail-info": "You can send upto 15 signature request emails every month. Upgrade now to send unlimited signing requests directly.", "quota-mail-info": "You can send upto 15 signature request emails every month. Upgrade now to send unlimited signing requests directly.",
"quota-mail": "You've reached your limit of 15 signature request emails for this month. Upgrade now to continue sending emails directly.", "quota-mail": "You've reached your limit of 15 signature request emails for this month. Upgrade now to continue sending emails directly.",
"quota-mail-tip": "Tip: You can still sign <1>unlimited documents</1> by manually sharing the signing request links.", "quota-mail-tip":"Tip: You can still sign <1>unlimited documents</1> by manually sharing the signing request links.",
"quota-mail-head": "Quota Reached", "quota-mail-head":"Quota Reached",
"unauthorized-modal": "You don't have permission to perform this action, please contact {{adminEmail}}.", "unauthorized-modal":"You don't have permission to perform this action, please contact {{adminEmail}}.",
"sent-this-month": "Sent this month", "sent-this-month":"Sent this month",
"available-seats": "Available seats", "available-seats":"Available seats",
"buy-users": "Buy more users", "buy-users":"Buy more users",
"isenable-otp": "Enable OTP verification", "isenable-otp": "Enable OTP verification",
"isenable-otp-help": { "isenable-otp-help": {
"p1": "Would you like to enable the verification process using a one-time password (OTP)?", "p1": "Would you like to enable the verification process using a one-time password (OTP)?",
@@ -648,10 +663,10 @@
"p3": "Selecting this option will disable OTP verification, allowing users to sign the document directly without additional steps.", "p3": "Selecting this option will disable OTP verification, allowing users to sign the document directly without additional steps.",
"p4": "Please choose the option that best suits your document signing requirements." "p4": "Please choose the option that best suits your document signing requirements."
}, },
"advanced-options": "Advanced options", "advanced-options":"Advanced options",
"hide-advanced-options": "Hide Advanced options", "hide-advanced-options":"Hide Advanced options",
"download-files": "Download files", "download-files":"Download files",
"download-pdf": "Download Pdf", "download-pdf":"Download Pdf",
"pdf-certificate": "Download Pdf + Certificate", "pdf-certificate":"Download Pdf + Certificate",
"document-logs": "Document logs" "document-logs":"Document logs"
} }
@@ -42,7 +42,7 @@
"upgrade-to": "Mettre à niveau vers", "upgrade-to": "Mettre à niveau vers",
"pro": "PRO", "pro": "PRO",
"plan": "Offre", "plan": "Offre",
"subscribe-card-teamplan": "Libérez toute la puissance de la collaboration ! Créez un nombre illimité d'organisations, d'équipes et de hiérarchies. Partagez des modèles de manière transparente entre les équipes et attribuez des rôles d'utilisateur personnalisés. Améliorez votre flux de travail dès aujourd'hui !", "subscribe-card-teamplan":"Libérez toute la puissance de la collaboration ! Créez un nombre illimité d'organisations, d'équipes et de hiérarchies. Partagez des modèles de manière transparente entre les équipes et attribuez des rôles d'utilisateur personnalisés. Améliorez votre flux de travail dès aujourd'hui !",
"subscribe-card-plan": "Débloquez des fonctionnalités premium à partir de seulement {{premiumPrice}}/mois. Bénéficiez de performances améliorées et de seulement {{addonPrice}} par crédit supplémentaire après vos crédits premium inclus.", "subscribe-card-plan": "Débloquez des fonctionnalités premium à partir de seulement {{premiumPrice}}/mois. Bénéficiez de performances améliorées et de seulement {{addonPrice}} par crédit supplémentaire après vos crédits premium inclus.",
"user-name-limit-char": "Pour avoir un nom d'utilisateur de moins de 8 caractères s'il vous plaît s'abonner", "user-name-limit-char": "Pour avoir un nom d'utilisateur de moins de 8 caractères s'il vous plaît s'abonner",
"tour-content": "Ne plus afficher", "tour-content": "Ne plus afficher",
@@ -151,7 +151,8 @@
"Share": "Partager", "Share": "Partager",
"View": "Voir", "View": "Voir",
"option": "Option", "option": "Option",
"Embed": "Intégrer" "Embed": "Intégrer",
"Copy TemplateId": "Copier l'ID du modèle"
}, },
"report-help": { "report-help": {
"Draft Documents": "Il s'agit de documents que vous avez commencés mais que vous n'avez pas finalisés pour envoi.", "Draft Documents": "Il s'agit de documents que vous avez commencés mais que vous n'avez pas finalisés pour envoi.",
@@ -263,7 +264,8 @@
"make-template-private-alert": "Êtes-vous sûr de vouloir rendre ce modèle privé ? Cela le supprimera de votre profil public.", "make-template-private-alert": "Êtes-vous sûr de vouloir rendre ce modèle privé ? Cela le supprimera de votre profil public.",
"public-role": "Rôle public", "public-role": "Rôle public",
"public-url": "URL publique", "public-url": "URL publique",
"public-url-copy-mssg": "Voici votre URL publique : copiez-la ou partagez-le avec le signataire et vous pouvoir voir tous vos paramètres publics modèles.", "public-url-copy": "Voici votre URL publique : ",
"public-url-copy-mssg": "copiez-la ou partagez-le avec le signataire et vous pouvoir voir tous vos paramètres publics modèles.",
"add-public-url-alert": "Veuillez ajouter votre URL publique et vous pourra rendre public modèle.", "add-public-url-alert": "Veuillez ajouter votre URL publique et vous pourra rendre public modèle.",
"share-with-alert": "Vous ne pouvez pas partager un modèle si des contacts sont déjà attribués à des rôles. Veuillez supprimer toutes les attributions de contacts des rôles avant de partager le modèle.", "share-with-alert": "Vous ne pouvez pas partager un modèle si des contacts sont déjà attribués à des rôles. Veuillez supprimer toutes les attributions de contacts des rôles avant de partager le modèle.",
"share-with": "Partager avec", "share-with": "Partager avec",
@@ -613,33 +615,46 @@
"Add-seats": "Ajouter des sièges", "Add-seats": "Ajouter des sièges",
"format": "format", "format": "format",
"select-date-format": "Sélectionnez un format de date", "select-date-format": "Sélectionnez un format de date",
"quantity-of-credits": "Quantité de crédits de prime", "quantity-of-credits":"Quantité de crédits de prime",
"remaining-credits": "Crédits premium disponibles :", "remaining-credits":"Crédits premium disponibles :",
"additional-credits": "Veuillez acheter des crédits premium", "additional-credits":"Veuillez acheter des crédits premium",
"remaining-credits-help": "Utilisez des crédits premium pour la signature de documents API, l'envoi groupé ou l'intégration d'OpenSign sur votre site Web. Il vous reste {{allowedcredits}} crédits inclus et {{addoncredits}} crédits achetés supplémentaires.", "remaining-credits-help":"Utilisez des crédits premium pour la signature de documents API, l'envoi groupé ou l'intégration d'OpenSign sur votre site Web. Il vous reste {{allowedcredits}} crédits inclus et {{addoncredits}} crédits achetés supplémentaires.",
"quota-err-quicksend": "Quota atteint, vous n'avez pas assez de crédits.", "quota-err-quicksend": "Quota atteint, vous n'avez pas assez de crédits.",
"buy-credits": "Acheter des crédits premium", "buy-credits": "Acheter des crédits premium",
"rotate-right": "Faire pivoter à droite", "rotate-right" :"Faire pivoter à droite",
"rotate-left": "Faire pivoter à gauche", "rotate-left" :"Faire pivoter à gauche",
"rotate-alert-mssg": "Tous les widgets de cette page seront perdus. Êtes-vous sûr de vouloir continuer ?", "rotate-alert-mssg" :"Tous les widgets de cette page seront perdus. Êtes-vous sûr de vouloir continuer ?",
"templateid": "ID de modèle", "templateid":"ID de modèle",
"bulk-send-subcription-alert": "Veuillez passer au forfait Professionnel ou Équipe pour utiliser Quicksend.", "bulk-send-subcription-alert":"Veuillez passer au forfait Professionnel ou Équipe pour utiliser Quicksend.",
"generate-test-token": "Générer jeton de test", "generate-test-token": "Générer jeton de test",
"regenerate-test-token": "Régénérer le jeton de test", "regenerate-test-token":"Régénérer le jeton de test",
"help-test-token": "Ce jeton peut être utilisé pour tester les API au niveau du point de terminaison https://sandbox.opensignlabs.com/api/v1, vous permettant ainsi d'effectuer un nombre illimité de signatures de documents. Veuillez noter que l'API sandbox signera vos documents avec des certificats auto-signés, qui peuvent ne pas être reconnus comme valides par Adobe. Une fois vos tests terminés, vous pouvez passer à lun de nos forfaits payants pour générer un jeton de production.", "help-test-token":"Ce jeton peut être utilisé pour tester les API au niveau du point de terminaison https://sandbox.opensignlabs.com/api/v1, vous permettant ainsi d'effectuer un nombre illimité de signatures de documents. Veuillez noter que l'API sandbox signera vos documents avec des certificats auto-signés, qui peuvent ne pas être reconnus comme valides par Adobe. Une fois vos tests terminés, vous pouvez passer à lun de nos forfaits payants pour générer un jeton de production.",
"help-api-token": "Ce jeton peut être utilisé pour accéder aux API de production au point de terminaison {{origin}}/api/v1. Il ne peut être généré que sur l'un de nos forfaits payants.", "help-api-token":"Ce jeton peut être utilisé pour accéder aux API de production au point de terminaison {{origin}}/api/v1. Il ne peut être généré que sur l'un de nos forfaits payants.",
"reason": "Raison", "reason" :"Raison",
"decline-by": "Refusé/révoqué par", "decline-by" :"Refusé/révoqué par",
"document-declined": "document refusé", "document-declined":"document refusé",
"quota-mail-info-head": "Limite mensuelle d'e-mails de signatures de demandes", "public-template-mssg-1" :"Pour intégrer OpenSign dans votre projet React ou Next.js, exécutez simplement la commande suivante :",
"public-template-mssg-2" :"Assurez-vous que npm ou Yarn est configuré dans votre projet. Si vous utilisez Yarn, vous pouvez remplacer npm install par Yarn Add @opensign/react.",
"public-template-mssg-3" :"Besoin de plus de détails ou d'exemples ?",
"public-template-mssg-4": "Visitez le",
"public-template-mssg-5": "npm pour les dernières mises à jour, une documentation détaillée et l'historique des versions.",
"public-template-mssg-6":"Vous devez définir ce modèle comme public avant de pouvoir utiliser cet extrait de code.",
"copy-code":"COPIE",
"copied-code":"COPIÉ",
"Installation":"Installation",
"Usage" :"Usage",
"insufficient-credits":"Crédits de signature insuffisants",
"insufficient-credits-mssg" :"Le propriétaire de ce document ne dispose actuellement pas des crédits OpenSign nécessaires pour que vous puissiez le signer. Veuillez contacter le propriétaire si vous avez besoin de plus de détails.",
"angular-npm-mssg-1" :"Pour intégrer OpenSign dans votre projet Angular, exécutez simplement la commande suivante :",
"quota-mail-info-head":"Limite mensuelle d'e-mails de signatures de demandes",
"quota-mail-info": "Vous pouvez envoyer jusqu'à 15 e-mails de demande de signature chaque mois. Mettez à niveau maintenant pour envoyer directement des demandes de signature illimitées.", "quota-mail-info": "Vous pouvez envoyer jusqu'à 15 e-mails de demande de signature chaque mois. Mettez à niveau maintenant pour envoyer directement des demandes de signature illimitées.",
"quota-mail": "Vous avez atteint votre limite de 15 e-mails de demande de signature pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.", "quota-mail": "Vous avez atteint votre limite de 15 e-mails de demande de signature pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.",
"quota-mail-tip-tip": "Astuce : Vous pouvez toujours signer un nombre <1>illimité de documents</1> en partageant manuellement les liens de demande de signature.", "quota-mail-tip-tip":"Astuce : Vous pouvez toujours signer un nombre <1>illimité de documents</1> en partageant manuellement les liens de demande de signature.",
"quota-mail-head": "Quota atteint", "quota-mail-head":"Quota atteint",
"unauthorized-modal": "Vous n'êtes pas autorisé à effectuer cette action, veuillez contacter {{adminEmail}}.", "unauthorized-modal":"Vous n'êtes pas autorisé à effectuer cette action, veuillez contacter {{adminEmail}}.",
"sent-this-month": "envoyé ce mois-ci", "sent-this-month":"envoyé ce mois-ci",
"available-seats": "Disponible sièges", "available-seats":"Disponible sièges",
"buy-users": "Acheter plus d'utilisateurs", "buy-users":"Acheter plus d'utilisateurs",
"isenable-otp": "Activer la vérification OTP", "isenable-otp": "Activer la vérification OTP",
"isenable-otp-help": { "isenable-otp-help": {
"p1": "Souhaitez-vous activer le processus de vérification à l'aide d'un mot de passe à usage unique (OTP)?", "p1": "Souhaitez-vous activer le processus de vérification à l'aide d'un mot de passe à usage unique (OTP)?",
@@ -647,10 +662,11 @@
"p3": "La sélection de cette option désactivera la vérification OTP, permettant aux utilisateurs de signer le document directement sans étapes supplémentaires.", "p3": "La sélection de cette option désactivera la vérification OTP, permettant aux utilisateurs de signer le document directement sans étapes supplémentaires.",
"p4": "Veuillez choisir l'option qui correspond le mieux à vos exigences en matière de signature de documents." "p4": "Veuillez choisir l'option qui correspond le mieux à vos exigences en matière de signature de documents."
}, },
"advanced-options": "Options avancées", "advanced-options":"Options avancées",
"hide-advanced-options": "Masquer les options avancées", "hide-advanced-options": "Masquer les options avancées",
"download-files": "Télécharger des fichiers", "download-files" :"Télécharger des fichiers",
"download-pdf": "Télécharger le PDF", "download-pdf" :"Télécharger le PDF",
"pdf-certificate": "Télécharger Pdf + Certificat", "pdf-certificate" :"Télécharger Pdf + Certificat",
"document-logs": "Journaux de documents" "document-logs":"Journaux de documents"
} }
@@ -222,6 +222,25 @@ const sendMailToAllSigners = async docId => {
} }
}; };
const deductcount = async _resSub => {
try {
const subscriptionCls = new Parse.Object('contracts_Subscriptions');
subscriptionCls.id = _resSub.objectId;
const allowedCredits = _resSub?.AllowedCredits || 0;
const addonCredits = _resSub?.AddonCredits || 0;
if (allowedCredits > 0) {
const updateAllowedcredits = allowedCredits - 1 || 0;
subscriptionCls.set('AllowedCredits', updateAllowedcredits);
} else {
const updateAddonCredits = addonCredits > 0 ? addonCredits - 1 : 0;
subscriptionCls.set('AddonCredits', updateAddonCredits);
}
await subscriptionCls.save(null, { useMasterKey: true });
} catch (err) {
console.log('Err in deductcount in PublicUserLinkContacttoDoc cloud function', err);
}
};
// `PublicUserLinkContactToDoc` cloud function is used to create contact, add this contact in contracts_Guest role and // `PublicUserLinkContactToDoc` cloud function is used to create contact, add this contact in contracts_Guest role and
// create new document from template and save contact pointer in placeholder, signers and ACL of Document // create new document from template and save contact pointer in placeholder, signers and ACL of Document
export default async function PublicUserLinkContactToDoc(req) { export default async function PublicUserLinkContactToDoc(req) {
@@ -241,126 +260,163 @@ export default async function PublicUserLinkContactToDoc(req) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Template not found.'); throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Template not found.');
} }
const _tempRes = JSON.parse(JSON.stringify(tempRes)); const _tempRes = JSON.parse(JSON.stringify(tempRes));
const Placeholders = _tempRes?.Placeholders || []; const subscription = new Parse.Query('contracts_Subscriptions');
let index; subscription.equalTo('TenantId', {
if (role) { __type: 'Pointer',
index = Placeholders?.findIndex(x => x.Role && x.Role === role); className: 'partners_Tenant',
} else { objectId: _tempRes?.ExtUserPtr?.TenantId?.objectId,
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, ''); });
} subscription.include('ExtUserPtr');
if (index !== -1) { const date = new Date();
// Execute the query to check if a contact already exists in the 'contracts_Contactbook' class subscription.greaterThanOrEqualTo('Next_billing_date', date);
const contactCls = new Parse.Query('contracts_Contactbook'); const resSub = await subscription.first({ useMasterKey: true });
contactCls.equalTo('Email', email); if (resSub) {
contactCls.equalTo('CreatedBy', _tempRes.CreatedBy); const _resSub = JSON.parse(JSON.stringify(resSub));
contactCls.notEqualTo('IsDeleted', true); const allowedCredits = _resSub?.AllowedCredits || 0;
const existContact = await contactCls.first({ useMasterKey: true }); const addonCredits = _resSub?.AddonCredits || 0;
if (existContact) { const totalcredits = allowedCredits + addonCredits;
const template_json = JSON.parse(JSON.stringify(tempRes)); if (totalcredits > 0) {
//update contact in placeholder, signers and update ACl in provide document const Placeholders = _tempRes?.Placeholders || [];
const docRes = await createDocumentFromTemplate(template_json, existContact, index); let index;
if (docRes) { if (role) {
//condition will execute only if sendInOrder will be false for send email to all signers at a time. index = Placeholders?.findIndex(x => x.Role && x.Role === role);
if (!template_json?.SendinOrder) { } else {
await sendMailToAllSigners(docRes.id); throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, '');
}
return { contactId: existContact.id, docId: docRes.id };
} }
} else { if (index !== -1) {
// Execute the query to check if a user already exists in the 'contracts_Users' class // Execute the query to check if a contact already exists in the 'contracts_Contactbook' class
const extUserQuery = new Parse.Query('contracts_Users'); const contactCls = new Parse.Query('contracts_Contactbook');
extUserQuery.equalTo('Email', email); contactCls.equalTo('Email', email);
const extUser = await extUserQuery.first({ useMasterKey: true }); contactCls.equalTo('CreatedBy', _tempRes.CreatedBy);
if (extUser) { contactCls.notEqualTo('IsDeleted', true);
const _extUser = JSON.parse(JSON.stringify(extUser)); const existContact = await contactCls.first({ useMasterKey: true });
const contact = { if (existContact) {
UserId: _extUser.UserId, const template_json = JSON.parse(JSON.stringify(tempRes));
Name: _extUser.Name, //update contact in placeholder, signers and update ACl in provide document
Email: email, const docRes = await createDocumentFromTemplate(template_json, existContact, index);
Phone: _extUser?.Phone ? _extUser.Phone : '', if (docRes) {
CreatedBy: _tempRes.CreatedBy, await deductcount(_resSub);
TenantId: _tempRes.ExtUserPtr.TenantId, //condition will execute only if sendInOrder will be false for send email to all signers at a time.
}; if (!template_json?.SendinOrder) {
const template_json = JSON.parse(JSON.stringify(tempRes)); await sendMailToAllSigners(docRes.id);
// if user present on platform create contact on the basis of extended user details }
const contactRes = await saveRoleContact(contact); return { contactId: existContact.id, docId: docRes.id };
const docRes = await createDocumentFromTemplate(template_json, contactRes, index);
if (docRes) {
//condition will execute only if sendInOrder will be false for send email to all signers at a time.
if (!template_json?.SendinOrder) {
await sendMailToAllSigners(docRes.id);
} }
return { contactId: contactRes.id, docId: docRes.id }; } else {
} // Execute the query to check if a user already exists in the 'contracts_Users' class
} else if (name) { const extUserQuery = new Parse.Query('contracts_Users');
try { extUserQuery.equalTo('Email', email);
// Execute the query to check if a user already exists in the '_User' class const extUser = await extUserQuery.first({ useMasterKey: true });
const userQuery = new Parse.Query(Parse.User); if (extUser) {
userQuery.equalTo('email', email); const _extUser = JSON.parse(JSON.stringify(extUser));
const userRes = await userQuery.first({ useMasterKey: true });
if (userRes) {
const contact = { const contact = {
UserId: { __type: 'Pointer', className: '_User', objectId: userRes.id }, UserId: _extUser.UserId,
Name: name, Name: _extUser.Name,
Email: email, Email: email,
Phone: phone, Phone: _extUser?.Phone ? _extUser.Phone : '',
CreatedBy: _tempRes.CreatedBy, CreatedBy: _tempRes.CreatedBy,
TenantId: _tempRes.ExtUserPtr.TenantId, TenantId: _tempRes.ExtUserPtr.TenantId,
}; };
const template_json = JSON.parse(JSON.stringify(tempRes)); const template_json = JSON.parse(JSON.stringify(tempRes));
// Create new contract on the basis provided contact details by user and userId from _User class // if user present on platform create contact on the basis of extended user details
const contactRes = await saveRoleContact(contact); const contactRes = await saveRoleContact(contact);
//update contact in placeholder, signers and update ACl in provide document
const docRes = await createDocumentFromTemplate(template_json, contactRes, index); const docRes = await createDocumentFromTemplate(template_json, contactRes, index);
if (docRes) { if (docRes) {
await deductcount(_resSub);
//condition will execute only if sendInOrder will be false for send email to all signers at a time. //condition will execute only if sendInOrder will be false for send email to all signers at a time.
if (!template_json?.SendinOrder) { if (!template_json?.SendinOrder) {
await sendMailToAllSigners(docRes.id); await sendMailToAllSigners(docRes.id);
} }
return { contactId: contactRes.id, docId: docRes.id }; return { contactId: contactRes.id, docId: docRes.id };
} }
} else if (name) {
try {
// Execute the query to check if a user already exists in the '_User' class
const userQuery = new Parse.Query(Parse.User);
userQuery.equalTo('email', email);
const userRes = await userQuery.first({ useMasterKey: true });
if (userRes) {
const contact = {
UserId: { __type: 'Pointer', className: '_User', objectId: userRes.id },
Name: name,
Email: email,
Phone: phone,
CreatedBy: _tempRes.CreatedBy,
TenantId: _tempRes.ExtUserPtr.TenantId,
};
const template_json = JSON.parse(JSON.stringify(tempRes));
// Create new contract on the basis provided contact details by user and userId from _User class
const contactRes = await saveRoleContact(contact);
//update contact in placeholder, signers and update ACl in provide document
const docRes = await createDocumentFromTemplate(
template_json,
contactRes,
index
);
if (docRes) {
await deductcount(_resSub);
//condition will execute only if sendInOrder will be false for send email to all signers at a time.
if (!template_json?.SendinOrder) {
await sendMailToAllSigners(docRes.id);
}
return { contactId: contactRes.id, docId: docRes.id };
}
} else {
// create new user in _User class on the basis of details provide by user
const _users = Parse.Object.extend('User');
const _user = new _users();
_user.set('name', name);
_user.set('username', email);
_user.set('email', email);
_user.set('password', email);
if (phone) {
_user.set('phone', phone);
}
const newUserRes = await _user.save();
const contact = {
UserId: { __type: 'Pointer', className: '_User', objectId: newUserRes.id },
Name: name,
Email: email,
Phone: phone,
CreatedBy: _tempRes.CreatedBy,
TenantId: _tempRes.ExtUserPtr.TenantId,
};
const template_json = JSON.parse(JSON.stringify(tempRes));
// Create new contract on the basis provided contact details by user and userId from _User class
const contactRes = await saveRoleContact(contact);
//update contact in placeholder, signers and update ACl in provide document
const docRes = await createDocumentFromTemplate(
template_json,
contactRes,
index
);
if (docRes) {
await deductcount(_resSub);
//condition will execute only if sendInOrder will be false for send email to all signers at a time.
if (!template_json?.SendinOrder) {
await sendMailToAllSigners(docRes.id);
}
return { contactId: contactRes.id, docId: docRes.id };
}
}
} catch (err) {
console.log('Err', err);
}
} else { } else {
// create new user in _User class on the basis of details provide by user throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User not found.');
const _users = Parse.Object.extend('User');
const _user = new _users();
_user.set('name', name);
_user.set('username', email);
_user.set('email', email);
_user.set('password', email);
if (phone) {
_user.set('phone', phone);
}
const newUserRes = await _user.save();
const contact = {
UserId: { __type: 'Pointer', className: '_User', objectId: newUserRes.id },
Name: name,
Email: email,
Phone: phone,
CreatedBy: _tempRes.CreatedBy,
TenantId: _tempRes.ExtUserPtr.TenantId,
};
const template_json = JSON.parse(JSON.stringify(tempRes));
// Create new contract on the basis provided contact details by user and userId from _User class
const contactRes = await saveRoleContact(contact);
//update contact in placeholder, signers and update ACl in provide document
const docRes = await createDocumentFromTemplate(template_json, contactRes, index);
if (docRes) {
//condition will execute only if sendInOrder will be false for send email to all signers at a time.
if (!template_json?.SendinOrder) {
await sendMailToAllSigners(docRes.id);
}
return { contactId: contactRes.id, docId: docRes.id };
}
} }
} catch (err) {
console.log('Err', err);
} }
} else { } else {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User not found.'); throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
'Please provide required parameters!'
);
} }
} else {
throw new Parse.Error(Parse.Error.REQUEST_LIMIT_EXCEEDED, 'Insufficient Credit');
} }
} else { } else {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Please provide required parameters!'); throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Plan expired');
} }
} else { } else {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Template not found.'); throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Template not found.');
@@ -68,28 +68,26 @@ const makeEmail = async (to, from, subject, html, url, pdfName) => {
type: 'application/pdf', type: 'application/pdf',
path: './exports/certificate.pdf', path: './exports/certificate.pdf',
}; };
attachments = [file, certificate]; if (fs.existsSync(certificate.path)) {
attachments = [file, certificate];
} else {
attachments = [file];
}
} catch (err) { } catch (err) {
attachments = [file]; attachments = [file];
console.log('Err in read certificate sendmailv3', err); console.log('Err in read certificate sendmailv3', err);
} }
} }
const attachmentParts = attachments.map(attachment => { const attachmentParts = attachments.map(attachment => {
if (fs.existsSync(attachment.path)) { const content = fs.readFileSync(attachment.path);
try { const encodedContent = content.toString('base64');
const content = fs.readFileSync(attachment.path); return [
const encodedContent = content.toString('base64'); `Content-Type: ${attachment.type}\n`,
return [ 'MIME-Version: 1.0\n',
`Content-Type: ${attachment.type}\n`, `Content-Disposition: attachment; filename="${attachment.filename}"\n`,
'MIME-Version: 1.0\n', `Content-Transfer-Encoding: base64\n\n`,
`Content-Disposition: attachment; filename="${attachment.filename}"\n`, `${encodedContent}\n`,
`Content-Transfer-Encoding: base64\n\n`, ].join('');
`${encodedContent}\n`,
].join('');
} catch (err) {
console.log('Err in read attachments sendmailv3', attachment.path);
}
}
}); });
const attachmentBody = attachmentParts.join(`\n--${boundary}\n`); const attachmentBody = attachmentParts.join(`\n--${boundary}\n`);
@@ -149,6 +147,14 @@ export default async function sendMailGmailProvider(_extRes, template) {
}, },
}); });
console.log('gmail provider res: ', response?.status); console.log('gmail provider res: ', response?.status);
const certificatePath = './exports/certificate.pdf';
if (fs.existsSync(certificatePath)) {
try {
fs.unlinkSync(certificatePath);
} catch (err) {
console.log('Err in unlink certificate sendmailgmail provider');
}
}
return { code: 200, message: 'Email sent successfully' }; return { code: 200, message: 'Email sent successfully' };
} catch (error) { } catch (error) {
console.error('Error sending email:', error); console.error('Error sending email:', error);
+184 -696
View File
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -24,24 +24,24 @@
"@signpdf/placeholder-pdf-lib": "^3.2.4", "@signpdf/placeholder-pdf-lib": "^3.2.4",
"@signpdf/signer-p12": "^3.2.4", "@signpdf/signer-p12": "^3.2.4",
"@signpdf/signpdf": "^3.2.4", "@signpdf/signpdf": "^3.2.4",
"aws-sdk": "^2.1687.0", "aws-sdk": "^2.1691.0",
"axios": "^1.7.7", "axios": "^1.7.7",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"express": "^4.21.0", "express": "^4.21.0",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"generate-api-key": "^1.0.2", "generate-api-key": "^1.0.2",
"googleapis": "^140.0.1", "googleapis": "^144.0.0",
"jsonschema": "^1.4.1", "jsonschema": "^1.4.1",
"mailgun.js": "^10.2.3", "mailgun.js": "^10.2.3",
"mongoose": "^8.6.1", "mongoose": "^8.6.3",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"multer-s3": "^3.0.1", "multer-s3": "^3.0.1",
"node-forge": "^1.3.1", "node-forge": "^1.3.1",
"nodemailer": "^6.9.15", "nodemailer": "^6.9.15",
"parse": "^5.3.0", "parse": "^5.3.0",
"parse-dbtool": "^1.2.0", "parse-dbtool": "^1.2.0",
"parse-server": "^7.2.0", "parse-server": "^7.3.0-alpha.8",
"parse-server-api-mail-adapter": "^4.0.0", "parse-server-api-mail-adapter": "^4.0.0",
"pdf-lib": "^1.17.1", "pdf-lib": "^1.17.1",
"posthog-node": "^4.2.0", "posthog-node": "^4.2.0",
@@ -50,11 +50,11 @@
"type": "module", "type": "module",
"devDependencies": { "devDependencies": {
"@babel/eslint-parser": "^7.25.1", "@babel/eslint-parser": "^7.25.1",
"eslint": "^9.9.1", "eslint": "^9.11.1",
"jasmine": "^5.3.0", "jasmine": "^5.3.0",
"mongodb-runner": "^5.6.6", "mongodb-runner": "^5.6.6",
"nodemon": "^3.1.4", "nodemon": "^3.1.7",
"nyc": "^17.0.0", "nyc": "^17.1.0",
"prettier": "^3.3.3" "prettier": "^3.3.3"
}, },
"overrides": { "overrides": {