Compare commits

...
16 Commits
Author SHA1 Message Date
prafull-opensignlabsandGitHub fca45ced38 Merge pull request #1663 from OpenSignLabs/updates-14122971328
v2.15.0
2025-03-28 11:37:55 +05:30
prafull-opensignlabs ac8ab70246 v2.15.0
v2.15.0
2025-03-28 06:02:14 +00:00
prafull-opensignlabsandGitHub 8373679f27 Merge pull request #1661 from OpenSignLabs/do_deploy
feat: update proxy file
2025-03-24 13:47:33 +05:30
prafull-opensignlabs 0a23aabbe4 feat: update proxy file 2025-03-24 13:45:45 +05:30
prafull-opensignlabsandGitHub 4a85599703 Merge pull request #1660 from OpenSignLabs/updates-14030275569
feat: changes to implement one click deployment
2025-03-24 13:42:41 +05:30
prafull-opensignlabs 3e9b84de72 feat: changes to implement one click deployment
feat: changes to implement one click deployment
2025-03-24 08:11:52 +00:00
prafull-opensignlabsandGitHub 4313d8d0e4 Merge pull request #1654 from OpenSignLabs/updates-14016837992
refactor: remove unnecessary code
2025-03-23 13:11:28 +05:30
prafull-opensignlabs 3088fdd163 Merge pull request #403 from OpenSignLabs/staging
refactor: remove unnecessary code
2025-03-23 07:40:01 +00:00
ZathielandGitHub 8c86fe27ec Merge pull request #1616 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSign/i18next-browser-languagedetector-8.0.4
build(deps): bump i18next-browser-languagedetector from 8.0.2 to 8.0.4 in /apps/OpenSign
2025-03-21 21:50:38 +01:00
ZathielandGitHub 01e09998e5 Merge pull request #1650 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSignServer/npm_and_yarn-1c007eb283
build(deps): bump axios from 1.8.3 to 1.8.4 in /apps/OpenSignServer in the npm_and_yarn group across 1 directory
2025-03-21 21:49:55 +01:00
ZathielandGitHub 55fdb52bf3 Merge pull request #1651 from OpenSignLabs/dependabot/npm_and_yarn/apps/OpenSign/npm_and_yarn-1c007eb283
build(deps): bump axios from 1.8.3 to 1.8.4 in /apps/OpenSign in the npm_and_yarn group across 1 directory
2025-03-21 21:49:17 +01:00
dependabot[bot]andGitHub 08f46a393b build(deps): bump axios
Bumps the npm_and_yarn group with 1 update in the /apps/OpenSign directory: [axios](https://github.com/axios/axios).


Updates `axios` from 1.8.3 to 1.8.4
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.8.3...v1.8.4)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-21 14:41:30 +00:00
dependabot[bot]andGitHub 9345da543a build(deps): bump axios
Bumps the npm_and_yarn group with 1 update in the /apps/OpenSignServer directory: [axios](https://github.com/axios/axios).


Updates `axios` from 1.8.3 to 1.8.4
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.8.3...v1.8.4)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-21 14:41:20 +00:00
dependabot[bot]andGitHub 208891e10d build(deps): bump i18next-browser-languagedetector in /apps/OpenSign
Bumps [i18next-browser-languagedetector](https://github.com/i18next/i18next-browser-languageDetector) from 8.0.2 to 8.0.4.
- [Changelog](https://github.com/i18next/i18next-browser-languageDetector/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next-browser-languageDetector/compare/v8.0.2...v8.0.4)

---
updated-dependencies:
- dependency-name: i18next-browser-languagedetector
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-21 14:41:17 +00:00
prafull-opensignlabsandGitHub db0fa61b2b Merge pull request #1648 from OpenSignLabs/updates-13994222227
v2.14.0
2025-03-21 20:09:57 +05:30
prafull-opensignlabs 221f098de6 v2.14.0
v2.14.0
2025-03-21 14:38:32 +00:00
45 changed files with 4214 additions and 4240 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
{$HOST_URL} {
reverse_proxy client:3000
handle_path /app/* {
handle_path /api/* {
reverse_proxy server:8080
rewrite * /app{uri}
rewrite * {uri}
}
}
+407 -516
View File
File diff suppressed because it is too large Load Diff
+24 -23
View File
@@ -4,17 +4,18 @@
"private": true,
"dependencies": {
"@formkit/auto-animate": "^0.8.2",
"@lottiefiles/dotlottie-react": "^0.13.0",
"@lottiefiles/dotlottie-react": "^0.13.2",
"@pdf-lib/fontkit": "^1.1.1",
"@radix-ui/themes": "^3.1.6",
"@react-pdf/renderer": "^4.1.6",
"@react-pdf/renderer": "^4.3.0",
"@reduxjs/toolkit": "^2.5.1",
"axios": "^1.7.9",
"css-minimizer-webpack-plugin": "^7.0.0",
"axios": "^1.8.4",
"css-minimizer-webpack-plugin": "^7.0.2",
"date-fns-tz": "^3.2.0",
"file-saver": "^2.0.5",
"i18next": "^23.16.8",
"i18next-browser-languagedetector": "^8.0.2",
"i18next-http-backend": "^3.0.1",
"i18next-browser-languagedetector": "^8.0.4",
"i18next-http-backend": "^3.0.2",
"jszip": "^3.10.1",
"jwt-decode": "^4.0.0",
"moment": "^2.30.1",
@@ -25,7 +26,7 @@
"radix-ui": "^1.0.1",
"react": "^18.2.0",
"react-bootstrap": "^2.10.9",
"react-confetti": "^6.2.2",
"react-confetti": "^6.4.0",
"react-cookie": "^7.2.2",
"react-datepicker": "^7.6.0",
"react-dnd": "^16.0.1",
@@ -35,16 +36,16 @@
"react-dom": "^18.2.0",
"react-gtm-module": "^2.0.11",
"react-helmet": "^6.1.0",
"react-i18next": "^15.4.0",
"react-i18next": "^15.4.1",
"react-konva": "^18.2.10",
"react-pdf": "^9.2.1",
"react-quill-new": "^3.3.3",
"react-quill-new": "^3.4.6",
"react-redux": "^9.2.0",
"react-rnd": "^10.4.14",
"react-rnd": "^10.5.2",
"react-router": "^7.1.5",
"react-scripts": "^5.0.1",
"react-scrollbars-custom": "^4.1.1",
"react-select": "^5.10.0",
"react-select": "^5.10.1",
"react-signature-canvas": "^1.0.7",
"react-syntax-highlighter": "^15.6.1",
"react-timezone-select": "^3.2.8",
@@ -53,11 +54,11 @@
"reactour": "^1.19.4",
"redux": "^5.0.1",
"redux-thunk": "^3.1.0",
"regex-parser": "^2.3.0",
"regex-parser": "^2.3.1",
"serve": "^14.2.4",
"styled-components": "^5.3.0",
"web-vitals": "^4.2.4",
"ws": "^8.18.0",
"ws": "^8.18.1",
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
},
"scripts": {
@@ -96,26 +97,26 @@
}
},
"devDependencies": {
"@babel/core": "^7.26.9",
"@babel/core": "^7.26.10",
"@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.26.3",
"@babel/runtime-corejs2": "^7.26.9",
"autoprefixer": "^10.4.20",
"babel-loader": "^9.2.1",
"@babel/runtime-corejs2": "^7.27.0",
"autoprefixer": "^10.4.21",
"babel-loader": "^10.0.0",
"commitizen": "^4.3.1",
"concurrently": "^9.1.2",
"css-loader": "^7.1.2",
"daisyui": "^4.12.23",
"dotenv": "^16.4.7",
"dotenv-webpack": "^8.1.0",
"eslint": "^9.20.0",
"eslint-plugin-prettier": "^5.2.3",
"eslint": "^9.23.0",
"eslint-plugin-prettier": "^5.2.5",
"eslint-plugin-react": "^7.37.4",
"lint-staged": "^15.4.3",
"lint-staged": "^15.5.0",
"mini-css-extract-plugin": "^2.9.2",
"postcss": "^8.5.1",
"prettier": "^3.5.0",
"pretty-quick": "^4.0.0",
"postcss": "^8.5.3",
"prettier": "^3.5.3",
"pretty-quick": "^4.1.1",
"tailwindcss": "^3.4.17",
"terser-webpack-plugin": "^5.3.11",
"webpack-cli": "^5.1.4"
@@ -247,7 +247,7 @@
"generate-token-alert": "Sind Sie sicher, dass Sie das Token neu generieren möchten? Das alte Token wird ablaufen.",
"yes": "Ja",
"copied": "Kopiert",
"something-went-wrong-mssg": "Etwas ist schiefgelaufen. Bitte versuchen Sie es später erneut.",
"something-went-wrong-mssg": "Etwas ist schiefgelaufen, Das Aktualisieren dieser Seite kann das Problem lösen.",
"token-generated": "Token erfolgreich generiert.",
"webhook": "Webhook",
"update-webhook": "Webhook aktualisieren",
@@ -458,6 +458,7 @@
"placeholder-alert-3": "Sind Sie sicher, dass Sie dieses Dokument zur Unterzeichnung senden möchten?",
"placeholder-alert-4": "Sie haben erfolgreich E-Mails an alle Empfänger gesendet!",
"placeholder-mail-alert": "Sie haben erfolgreich eine E-Mail an {{name}} gesendet. Die nachfolgenden Unterzeichner erhalten eine E-Mail, sobald {{name}} das Dokument unterzeichnet.",
"placeholder-mail-alert-you": "Nachfolgende Unterzeichner erhalten E-Mails, sobald Sie das Dokument unterschreiben.",
"placeholder-alert-5": "Möchten Sie die Dokumente jetzt unterschreiben?",
"placeholder-alert-6": "Bitte richten Sie den E-Mail-Adapter ein, um E-Mails zu senden!",
"placeholder-alert-7": "Bitte wählen Sie einen Unterzeichner aus, um Platzhalter hinzuzufügen!",
@@ -831,7 +832,7 @@
"initial-type": "Ihre Initialen",
"redirect-url": "Weiterleitungs-URL",
"bulk-send": "Massenversand",
"select-timezone": "Wählen Sie Ihre Zeitzone",
"select-timezone": "Zeitzone",
"current-time": "Aktuelle Uhrzeit",
"email-help": "Aus Sicherheitsgründen dürfen Sie die E-Mail-Adresse nicht ändern. Bitte erstellen Sie ein weiteres kostenloses Konto mit der neuen E-Mail-Adresse.",
"doc-sent": "Dokument erfolgreich gesendet.",
@@ -856,5 +857,11 @@
"enabled-signature-type-help": "Die Einstellung 'Aktivierte Signaturtypen' bestimmt, welche Signaturoptionen in Ihrer Organisation verfügbar sind. Wenn Sie beispielsweise die Option 'Zeichnen' deaktivieren, wird sie den Mitgliedern Ihrer Organisation im Signatur-Widget nicht angezeigt, während die anderen drei Optionen weiterhin zugänglich bleiben.",
"indexing-public-profile": "Erlaube die Indexierung des öffentlichen Profils durch Suchmaschinen",
"user-created-successfully": "Benutzer erfolgreich erstellt.",
"only-15-reminder-allowed": "Sie können bis zu 15 automatische Erinnerungen festlegen. Wenn zum Beispiel 'TimeToComplete' auf 15 Tage und 'RemindOnceInEvery' auf 1 Tag eingestellt ist, erreichen Sie das maximale Limit von 15 Erinnerungen. Passen Sie Ihre Einstellungen entsprechend an."
"only-15-reminder-allowed": "Sie können bis zu 15 automatische Erinnerungen festlegen. Wenn zum Beispiel 'TimeToComplete' auf 15 Tage und 'RemindOnceInEvery' auf 1 Tag eingestellt ist, erreichen Sie das maximale Limit von 15 Erinnerungen. Passen Sie Ihre Einstellungen entsprechend an.",
"rate-your-experience": "👋 Bitte bewerten Sie Ihre Erfahrung mit Opensign",
"thanks-for-feedback": "Danke für Ihr Feedback 🙏",
"share-your-feedback": "Teilen Sie Ihr Feedback",
"share-your-review": "Teilen Sie Ihre Bewertung",
"date-format": "Datumsformat",
"document-deleted": "Das Dokument wurde gelöscht oder Sie haben keinen Zugriff. Bitte kontaktieren Sie den Absender."
}
@@ -247,7 +247,7 @@
"generate-token-alert": "Are you sure you want to regenerate token it will expire old token?",
"yes": "Yes",
"copied": "Copied",
"something-went-wrong-mssg": "Something went wrong, please try again later.",
"something-went-wrong-mssg": "Something went wrong, refreshing this page may solve this issue.",
"token-generated": "Token generated successfully.",
"webhook": "Webhook",
"update-webhook": "Update webhook",
@@ -458,6 +458,7 @@
"placeholder-alert-3": " Are you sure you want to send out this document for signatures?",
"placeholder-alert-4": "You have successfully sent mails to all recipients!",
"placeholder-mail-alert": "You have successfully sent email to {{name}}. Subsequent signers will get email(s) once {{name}} signs the document",
"placeholder-mail-alert-you": "Subsequent signers will get email(s) once you signs the document.",
"placeholder-alert-5": "Do you want to sign the document right now?",
"placeholder-alert-6": "Please setup mail adapter to send mail!",
"placeholder-alert-7": "Please select signer for add placeholder!",
@@ -831,7 +832,7 @@
"initial-type": "Your initials",
"redirect-url": "Redirect url",
"bulk-send": "Bulk send",
"select-timezone": "Select your Timezone",
"select-timezone": "Timezone",
"current-time": "Current time",
"email-help": "You are not allowed to change email address due to security reasons. Please create another free account using the new email address.",
"doc-sent": "Document sent successfully.",
@@ -856,5 +857,11 @@
"enabled-signature-type-help": "The 'Enabled Signature Types' setting determines which signature options are available across your organization. For example, if you disable the 'Draw' option, members of your organization will not see it in the signature widget, while the other three options will remain accessible.",
"indexing-public-profile": "Allow indexing of public profile by search engines",
"user-created-successfully": "user created successfully.",
"only-15-reminder-allowed": "You can set up to 15 automatic reminders. For example, if 'TimeToComplete' is 15 days and 'RemindOnceInEvery' is 1 day, you'll reach the maximum limit of 15 reminders. Adjust your settings accordingly."
"only-15-reminder-allowed": "You can set up to 15 automatic reminders. For example, if 'TimeToComplete' is 15 days and 'RemindOnceInEvery' is 1 day, you'll reach the maximum limit of 15 reminders. Adjust your settings accordingly.",
"rate-your-experience": "👋 Please rate your experience with Opensign",
"thanks-for-feedback": "Thanks for your feedback 🙏",
"share-your-feedback": "Share your feedback",
"share-your-review": "Share your review",
"date-format": "Date format",
"document-deleted": "The document has been deleted or you don't have access. Please contact the sender."
}
@@ -248,7 +248,7 @@
"generate-token-alert": "¿En definitiva quieres regenerar el token? Esto expirará el token antiguo.",
"yes": "Sí",
"copied": "Copiado",
"something-went-wrong-mssg": "Algo salió mal, por favor, intenta de nuevo más tarde.",
"something-went-wrong-mssg": "Un problème est survenu, Actualiser cette page peut résoudre le problème.",
"token-generated": "Token generado exitosamente.",
"webhook": "Webhook",
"update-webhook": "Actualizar webhook",
@@ -458,6 +458,7 @@
"placeholder-alert-3": " ¿En definitiva quieres enviar este documento para ser firmado?",
"placeholder-alert-4": "¡Has enviado exitosamente correos a todos los destinatarios!",
"placeholder-mail-alert": "Has enviado un correo electrónico con éxito a {{name}}. Los siguientes firmantes recibirán un correo electrónico una vez que {{name}} firme el documento.",
"placeholder-mail-alert-you": "Los firmantes posteriores recibirán correos electrónicos una vez que firme el documento.",
"placeholder-alert-5": "¿Quieres firmar documentos ahora mismo?",
"placeholder-alert-6": "¡Por favor, configura el adaptador de correo para enviar correos!",
"placeholder-alert-7": "¡Por favor, selecciona un firmante para agregar un marcador de posición!",
@@ -831,7 +832,7 @@
"initial-type": "Tus iniciales",
"redirect-url": "URL de redireccionamiento",
"bulk-send": "envío masivo",
"select-timezone": "Seleccione su zona horaria",
"select-timezone": "Zona horaria",
"current-time": "Hora actual",
"email-help": "No se permite cambiar la dirección de correo electrónico por razones de seguridad. Por favor, cree otra cuenta gratuita utilizando la nueva dirección de correo electrónico.",
"doc-sent": "Documento enviado con éxito.",
@@ -856,5 +857,11 @@
"enabled-signature-type-help": "La configuración de 'Tipos de firma habilitados' determina qué opciones de firma están disponibles en su organización. Por ejemplo, si desactiva la opción 'Dibujar', los miembros de su organización no la verán en el widget de firma, mientras que las otras tres opciones seguirán siendo accesibles.",
"indexing-public-profile": "Permitir la indexación del perfil público por los motores de búsqueda",
"user-created-successfully": "Usuario creado con éxito.",
"only-15-reminder-allowed": "Puede configurar hasta 15 recordatorios automáticos. Por ejemplo, si 'TimeToComplete' es de 15 días y 'RemindOnceInEvery' es de 1 día, alcanzará el límite máximo de 15 recordatorios. Ajuste su configuración en consecuencia."
"only-15-reminder-allowed": "Puede configurar hasta 15 recordatorios automáticos. Por ejemplo, si 'TimeToComplete' es de 15 días y 'RemindOnceInEvery' es de 1 día, alcanzará el límite máximo de 15 recordatorios. Ajuste su configuración en consecuencia.",
"rate-your-experience": "👋 Por favor, califique su experiencia con Opensign",
"thanks-for-feedback": "Gracias por su comentario 🙏",
"share-your-feedback": "Comparta sus comentarios",
"share-your-review": "Comparta su reseña",
"date-format": "Formato de fecha",
"document-deleted": "El documento ha sido eliminado o no tiene acceso. Por favor, contacte al remitente."
}
@@ -458,6 +458,7 @@
"placeholder-alert-3": "Etes-vous sûr de vouloir envoyer ce document pour signature ? ",
"placeholder-alert-4": "Vous avez envoyé avec succès des mails à tous les",
"placeholder-mail-alert": "Vous avez envoyé un e-mail avec succès à {{name}}. Les signataires suivants recevront un e-mail une fois que {{name}} aura signé le document.",
"placeholder-mail-alert-you": "Les signataires suivants recevront un e-mail dès que vous signez le document.",
"placeholder-alert-5": "Voulez-vous signer des documents maintenant ?",
"placeholder-alert-6": "Veuillez configurer l'adaptateur de messagerie pour envoyer du courrier !",
"placeholder-alert-7": "Veuillez sélectionner le signataire pour ajouter un espace réservé !",
@@ -831,7 +832,7 @@
"initial-type": "Vos initiales",
"redirect-url": "URL de redirection",
"bulk-send": "Envoi groupé",
"select-timezone": "Sélectionnez votre fuseau horaire",
"select-timezone": "Fuseau horaire",
"current-time": "Heure actuelle",
"email-help": "Vous n'êtes pas autorisé à changer d'adresse e-mail pour des raisons de sécurité. Veuillez créer un autre compte gratuit en utilisant la nouvelle adresse e-mail.",
"doc-sent": "Document envoyé avec succès.",
@@ -856,5 +857,11 @@
"enabled-signature-type-help": "Le paramètre 'Types de signature activés' détermine quelles options de signature sont disponibles dans votre organisation. Par exemple, si vous désactivez l'option 'Dessiner', les membres de votre organisation ne la verront pas dans le widget de signature, tandis que les trois autres options resteront accessibles.",
"indexing-public-profile": "Autoriser l'indexation du profil public par les moteurs de recherche",
"user-created-successfully": "Utilisateur créé avec succès.",
"only-15-reminder-allowed": "Vous pouvez définir jusqu'à 15 rappels automatiques. Par exemple, si 'TimeToComplete' est de 15 jours et 'RemindOnceInEvery' est de 1 jour, vous atteindrez la limite maximale de 15 rappels. Ajustez vos paramètres en conséquence."
"only-15-reminder-allowed": "Vous pouvez définir jusqu'à 15 rappels automatiques. Par exemple, si 'TimeToComplete' est de 15 jours et 'RemindOnceInEvery' est de 1 jour, vous atteindrez la limite maximale de 15 rappels. Ajustez vos paramètres en conséquence.",
"rate-your-experience": "👋 Veuillez évaluer votre expérience avec Opensign",
"thanks-for-feedback": "Merci pour votre retour 🙏",
"share-your-feedback": "Partagez votre avis",
"share-your-review": "Partagez votre avis",
"date-format": "Format de date",
"document-deleted": "Le document a été supprimé ou vous n'y avez pas accès. Veuillez contacter l'expéditeur."
}
@@ -247,7 +247,7 @@
"generate-token-alert": "Sei sicuro di voler rigenerare il token? Questo invaliderà il vecchio token.",
"yes": "Sì",
"copied": "Copiato",
"something-went-wrong-mssg": "Qualcosa è andato storto, riprova più tardi.",
"something-went-wrong-mssg": "Si è verificato un errore, L'aggiornamento della pagina potrebbe risolvere il problema.",
"token-generated": "Token generato con successo.",
"webhook": "Webhook",
"update-webhook": "Aggiorna Webhook",
@@ -458,6 +458,7 @@
"placeholder-alert-3": "Sei sicuro di voler inviare questo documento per le firme?",
"placeholder-alert-4": "Hai inviato con successo le mail a tutti i destinatari!",
"placeholder-mail-alert": "Hai inviato con successo un'e-mail a {{name}}. I firmatari successivi riceveranno un'e-mail una volta che {{name}} avrà firmato il documento.",
"placeholder-mail-alert-you": "I firmatari successivi riceveranno un'email non appena firmi il documento.",
"placeholder-alert-5": "Vuoi firmare i documenti ora?",
"placeholder-alert-6": "Configura l'adattatore email per inviare mail!",
"placeholder-alert-7": "Seleziona il firmatario per aggiungere un segnaposto!",
@@ -831,7 +832,7 @@
"initial-type": "Le tue iniziali",
"redirect-url": "URL di reindirizzamento",
"bulk-send": "Invio in blocco",
"select-timezone": "Seleziona il tuo fuso orario",
"select-timezone": "Fuso orario",
"current-time": "Ora corrente",
"email-help": "Non ti è permesso cambiare l'indirizzo email per motivi di sicurezza. Ti preghiamo di creare un altro account gratuito utilizzando il nuovo indirizzo email.",
"doc-sent": "Documento inviato con successo.",
@@ -856,5 +857,11 @@
"enabled-signature-type-help": "L'impostazione 'Tipi di firma abilitati' determina quali opzioni di firma sono disponibili nella tua organizzazione. Ad esempio, se disabiliti l'opzione 'Disegna', i membri della tua organizzazione non la vedranno nel widget della firma, mentre le altre tre opzioni resteranno accessibili.",
"indexing-public-profile": "Consenti l'indicizzazione del profilo pubblico dai motori di ricerca",
"user-created-successfully": "Utente creato con successo.",
"only-15-reminder-allowed": "Puoi impostare fino a 15 promemoria automatici. Ad esempio, se 'TimeToComplete' è di 15 giorni e 'RemindOnceInEvery' è di 1 giorno, raggiungerai il limite massimo di 15 promemoria. Regola le tue impostazioni di conseguenza."
"only-15-reminder-allowed": "Puoi impostare fino a 15 promemoria automatici. Ad esempio, se 'TimeToComplete' è di 15 giorni e 'RemindOnceInEvery' è di 1 giorno, raggiungerai il limite massimo di 15 promemoria. Regola le tue impostazioni di conseguenza.",
"rate-your-experience": "👋 Valuta la tua esperienza con Opensign",
"thanks-for-feedback": "Grazie per il tuo feedback 🙏",
"share-your-feedback": "Condividi il tuo feedback",
"share-your-review": "Condividi la tua recensione",
"date-format": "Formato data",
"document-deleted": "Il documento è stato eliminato o non hai accesso. Si prega di contattare il mittente."
}
@@ -30,15 +30,19 @@ function DraftDocument() {
documentData === "Error: Something went wrong!" ||
(documentData.result && documentData.result.error)
) {
setIsLoading({
isLoader: false,
message: "Error: Something went wrong!"
});
if (documentData?.result?.error?.includes("deleted")) {
setIsLoading({
isLoader: false,
message: t("document-deleted")
});
} else {
setIsLoading({
isLoader: false,
message: t("something-went-wrong-mssg")
});
}
} else {
setIsLoading({
isLoader: false,
message: "No data found!"
});
setIsLoading({ isLoader: false, message: t("no-data") });
}
};
@@ -188,7 +188,7 @@ const EditTemplate = ({ template, onSuccess }) => {
<Tooltip id="istourenabled-tooltip" className="z-50">
<div className="max-w-[200px] md:max-w-[450px]">
<p className="font-bold">{t("enable-tour")}</p>
<p className="p-[5px]">
<div className="p-[5px]">
<ol className="list-disc">
<li>
<span className="font-bold">{t("yes")}: </span>
@@ -199,7 +199,7 @@ const EditTemplate = ({ template, onSuccess }) => {
<span>{t("istourenabled-help.p2")}</span>
</li>
</ol>
</p>
</div>
<p>{t("istourenabled-help.p3", { appName: appName })}</p>
</div>
</Tooltip>
@@ -5,6 +5,7 @@ import Loader from "../../primitives/Loader";
import ModalUi from "../../primitives/ModalUi";
import { useTranslation } from "react-i18next";
import Parse from "parse";
function EmailComponent({
isEmail,
setIsEmail,
@@ -20,6 +21,7 @@ function EmailComponent({
const [emailErr, setEmailErr] = useState(false);
const [isDownloading, setIsDownloading] = useState("");
const isAndroid = /Android/i.test(navigator.userAgent);
//function for send email
const sendEmail = async () => {
setIsLoading(true);
@@ -105,7 +107,7 @@ function EmailComponent({
</div>
)}
<div className="flex justify-between items-center py-[10px] px-[20px] border-b-[1px] border-base-content">
<span className="text-base-content font-semibold">
<span className="text-base-content font-bold text-sm md:text-lg">
{t("successfully-signed")}
</span>
<div className="flex flex-row">
@@ -114,14 +116,14 @@ function EmailComponent({
onClick={(e) =>
handleToPrint(e, setIsDownloading, pdfDetails)
}
className="op-btn op-btn-neutral op-btn-sm text-[15px]"
className="op-btn op-btn-neutral op-btn-sm text-xs md:text-[15px]"
>
<i className="fa-light fa-print" aria-hidden="true"></i>
{t("print")}
</button>
)}
<button
className="op-btn op-btn-primary op-btn-sm text-[15px] ml-2"
className="op-btn op-btn-primary op-btn-sm text-xs md:text-[15px] ml-2"
onClick={() => {
handleClose();
setIsDownloadModal(true);
@@ -137,12 +139,12 @@ function EmailComponent({
{t("email-mssg")}
</p>
{emailList.length > 0 ? (
<div className="p-0 border-[1.5px] op-border-primary rounded w-full text-[15px]">
<div className="p-0 border-[1px] op-border-primary w-full rounded-md text-[15px] overflow-hidden">
<div className="flex flex-row flex-wrap">
{emailList.map((data, ind) => {
return (
<div
className="flex flex-row items-center op-bg-primary m-[4px] rounded-md py-[5px] px-[10px]"
className="flex flex-row items-center op-bg-primary mx-[2px] mt-[2px] rounded-md py-[5px] px-[10px]"
key={ind}
>
<span className="text-base-100 text-[13px]">
@@ -162,7 +164,7 @@ function EmailComponent({
<input
type="email"
value={emailValue}
className="p-[10px] pb-[20px] rounded w-full text-[15px] bg-transparent outline-none"
className="p-[10px] rounded-md w-full text-[15px] bg-transparent outline-none"
onChange={handleEmailValue}
onKeyDown={handleEnterPress}
onBlur={() => emailValue && handleEnterPress("add")}
@@ -179,7 +181,7 @@ function EmailComponent({
<input
type="email"
value={emailValue}
className="p-[10px] pb-[20px] rounded w-full text-[15px] outline-none bg-transparent border-[1.5px] op-border-primary"
className="p-[10px] pb-[20px] rounded-md w-full text-[15px] outline-none bg-transparent border-[1px] op-border-primary"
onChange={handleEmailValue}
onKeyDown={handleEnterPress}
placeholder={t("enter-email-plaholder")}
@@ -197,7 +199,7 @@ function EmailComponent({
{t("email-error-1")}
</p>
)}
<button
{/* <button
className={`${
emailValue ? "cursor-pointer" : "cursor-default"
} op-btn op-btn-primary op-btn-sm m-2 shadow-md`}
@@ -205,26 +207,27 @@ function EmailComponent({
>
<i className="fa-light fa-plus" aria-hidden="true"></i>
</button>
<div className="bg-[#e3e2e1] mt-[10px] p-[5px] rounded">
<span className="font-bold">{t("report-heading.Note")}: </span>
<span className="text-[15px]">{t("email-error-2")}</span>
</div>
<hr className="w-full my-[15px] bg-base-content" />
<button
type="button"
className="op-btn op-btn-secondary"
onClick={() => emailList.length > 0 && sendEmail()}
>
{t("send")}
</button>
<button
type="button"
className="op-btn op-btn-ghost ml-2"
onClick={() => handleClose()}
>
{t("close")}
</button>
<hr className="w-full my-[15px] bg-base-content" /> */}
<div className="mt-2">
<button
type="button"
className="op-btn op-btn-secondary"
onClick={() => emailList.length > 0 && sendEmail()}
>
{t("send")}
</button>
<button
type="button"
className="op-btn op-btn-ghost ml-2"
onClick={() => handleClose()}
>
{t("close")}
</button>
</div>
</div>
</ModalUi>
)}
@@ -1,305 +0,0 @@
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";
import { useNavigate } from "react-router";
function EmbedTab(props) {
const { t } = useTranslation();
const navigate = useNavigate();
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 default function App() {
return (
<div className="app">
<Opensign
onLoad={() => console.log("success")}
onLoadError={(error) => console.log(error)}
templateId= "${props.templateId ? props.templateId : "#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 ? props.templateId : "#templateId"}"
(onLoad)="handleLoad()"
(onLoadError)="handleError($event)"
></opensign>\`,
})
export class AppComponent {
handleLoad() {
console.log("success");
}
handleError(error: string) {
console.log(error);
}
}
`
}
];
const jsCodeString = `
<script
src= "${window.location.origin}/static/js/public-template.bundle.js"
id="opensign-script"
templateId=${props.templateId ? props.templateId : "#templateId"}
></script>
`;
const handleCopy = (code, ind) => {
copytoData(code);
setIsCopied({ ...isCopied, [ind]: true });
setTimeout(() => setIsCopied(false), 3000);
};
return (
<div className={`${props.templateId && "border-t-[1px] mt-4"}`}>
{props.templateId && (
<h3 className="text-base-content font-bold text-lg pt-[15px] pb-[5px]">
{t("embed-template")}
</h3>
)}
<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 pb-10 md:pb-0`}
>
<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>
{ind === 0 && (
<p className="text-[15px] 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>
);
})}
{props.isEmbedPage && (
<p className="text-[15px] my-2">
{t("js-snippet-msg-1")}
<span
className="text-blue-600 cursor-pointer px-1"
onClick={() => navigate("/report/6TeaPr321t")}
>
{t("js-snippet-msg-2")}
</span>
<span>{t("js-snippet-msg-3")}</span>
</p>
)}
<p className="font-medium mt-3 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(`Usage`)}</p>
<p className="text-[15px] my-2">{t("js-snippet-msg")}</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>
{props.isEmbedPage && (
<p className="text-[15px] my-2">
{t("js-snippet-msg-1")}
<span
className="text-blue-600 cursor-pointer px-1"
onClick={() => navigate("/report/6TeaPr321t")}
>
{t("js-snippet-msg-2")}
</span>
<span>{t("js-snippet-msg-3")}</span>
</p>
)}
</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>
{ind === 0 && (
<p className="text-[15px] 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>
);
})}
{props.isEmbedPage && (
<p className="text-[15px] my-2">
{t("js-snippet-msg-1")}
<span
className="text-blue-600 cursor-pointer px-1"
onClick={() => navigate("/report/6TeaPr321t")}
>
{t("js-snippet-msg-2")}
</span>
<span>{t("js-snippet-msg-3")}</span>
</p>
)}
<p className="font-medium mt-3 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;
@@ -25,6 +25,8 @@ const selectFormat = (data) => {
switch (data) {
case "L":
return "MM/dd/yyyy";
case "MM/DD/YYYY":
return "MM/dd/yyyy";
case "DD-MM-YYYY":
return "dd-MM-yyyy";
case "DD/MM/YYYY":
@@ -41,6 +43,8 @@ const selectFormat = (data) => {
return "MM.dd.yyyy";
case "MMM DD, YYYY":
return "MMM dd, yyyy";
case "MMMM DD, YYYY":
return "MMMM dd, yyyy";
case "DD MMMM, YYYY":
return "dd MMMM, yyyy";
default:
@@ -24,7 +24,7 @@ const widgetCls =
function PlaceholderType(props) {
const { t } = useTranslation();
const type = props?.pos?.type;
const widgetTypeTraslation = t(`widgets-name.${props?.pos?.type}`);
const widgetTypeTranslation = t(`widgets-name.${props?.pos?.type}`);
const [selectOption, setSelectOption] = useState("");
const [validatePlaceholder, setValidatePlaceholder] = useState("");
const inputRef = useRef(null);
@@ -342,8 +342,8 @@ function PlaceholderType(props) {
className="font-medium"
>
{props.isNeedSign
? props.pos?.options?.hint || widgetTypeTraslation
: widgetTypeTraslation}
? props.pos?.options?.hint || widgetTypeTranslation
: widgetTypeTranslation}
</div>
)}
</div>
@@ -368,8 +368,8 @@ function PlaceholderType(props) {
className="font-medium"
>
{props.isNeedSign
? props.pos?.options?.hint || widgetTypeTraslation
: widgetTypeTraslation}
? props.pos?.options?.hint || widgetTypeTranslation
: widgetTypeTranslation}
</div>
)}
</div>
@@ -475,7 +475,7 @@ function PlaceholderType(props) {
/>
) : (
<div style={textWidgetStyle} className="select-none-cls">
<span>{textValue || widgetTypeTraslation}</span>
<span>{textValue || widgetTypeTranslation}</span>
</div>
);
case "dropdown":
@@ -538,7 +538,7 @@ function PlaceholderType(props) {
>
{props.pos?.options?.name
? props.pos.options.name
: widgetTypeTraslation}
: widgetTypeTranslation}
<i className="fa-light fa-circle-chevron-down mr-1 "></i>
</div>
);
@@ -562,8 +562,8 @@ function PlaceholderType(props) {
className="font-medium text-center"
>
{props.isNeedSign
? props.pos?.options?.hint || widgetTypeTraslation
: widgetTypeTraslation}
? props.pos?.options?.hint || widgetTypeTranslation
: widgetTypeTranslation}
</div>
)}
</div>
@@ -574,7 +574,7 @@ function PlaceholderType(props) {
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
<textarea
ref={inputRef}
placeholder={hint}
placeholder={hint || widgetTypeTranslation}
rows={1}
onKeyDown={handleEnterPress}
value={textValue}
@@ -597,7 +597,7 @@ function PlaceholderType(props) {
/>
) : (
<div className="flex h-full select-none-cls" style={textWidgetStyle}>
<span>{widgetTypeTraslation}</span>
<span>{widgetTypeTranslation}</span>
</div>
);
case "company":
@@ -606,7 +606,7 @@ function PlaceholderType(props) {
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
<textarea
ref={inputRef}
placeholder={hint}
placeholder={hint || widgetTypeTranslation}
rows={1}
onKeyDown={handleEnterPress}
value={textValue}
@@ -628,7 +628,7 @@ function PlaceholderType(props) {
/>
) : (
<div style={textWidgetStyle} className="select-none-cls">
<span>{widgetTypeTraslation}</span>
<span>{widgetTypeTranslation}</span>
</div>
);
case "job title":
@@ -637,7 +637,7 @@ function PlaceholderType(props) {
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
<textarea
ref={inputRef}
placeholder={hint}
placeholder={hint || widgetTypeTranslation}
rows={1}
onKeyDown={handleEnterPress}
value={textValue}
@@ -659,7 +659,7 @@ function PlaceholderType(props) {
/>
) : (
<div style={textWidgetStyle} className="select-none-cls">
<span>{widgetTypeTraslation}</span>
<span>{widgetTypeTranslation}</span>
</div>
);
case "date":
@@ -748,8 +748,8 @@ function PlaceholderType(props) {
className="font-medium text-center"
>
{props.isNeedSign
? props.pos?.options?.hint || widgetTypeTraslation
: widgetTypeTraslation}
? props.pos?.options?.hint || widgetTypeTranslation
: widgetTypeTranslation}
</div>
)}
</div>
@@ -760,7 +760,7 @@ function PlaceholderType(props) {
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
<textarea
ref={inputRef}
placeholder={hint}
placeholder={hint || widgetTypeTranslation}
rows={1}
onKeyDown={(e) => {
// Prevent new line on Enter key press
@@ -792,7 +792,7 @@ function PlaceholderType(props) {
/>
) : (
<div style={textWidgetStyle} className="select-none-cls">
<span>{widgetTypeTraslation}</span>
<span>{widgetTypeTranslation}</span>
</div>
);
case radioButtonWidget:
@@ -891,8 +891,8 @@ function PlaceholderType(props) {
className="font-medium"
>
{props.isNeedSign
? props.pos?.options?.hint || widgetTypeTraslation
: widgetTypeTraslation}
? props.pos?.options?.hint || widgetTypeTranslation
: widgetTypeTranslation}
</div>
)}
</div>
@@ -0,0 +1,79 @@
import React, { useState } from "react";
import { formatDateTime } from "../../../constant/Utils";
import { useTranslation } from "react-i18next";
const DateFormatSelector = (props) => {
const { t } = useTranslation();
const date = new Date();
const [selectedFormat, setSelectedFormat] = useState(props.dateFormat);
const [is12Hour, setIs12Hour] = useState(props?.is12HourTime);
const dateFormats = [
"MM/DD/YYYY",
"MMMM DD, YYYY",
"DD MMMM, YYYY",
"DD-MM-YYYY",
"DD MMM, YYYY",
"YYYY-MM-DD",
"MM-DD-YYYY",
"MM.DD.YYYY",
"MMM DD, YYYY"
];
// Handle format change
const handleFormatChange = (event) => {
setSelectedFormat(event.target.value);
props.setDateFormat && props.setDateFormat(event.target.value);
};
const handleHrInput = () => {
setIs12Hour(!is12Hour);
props.setIs12HourTime && props.setIs12HourTime(!is12Hour);
};
return (
<div className="max-w-[400px] pr-[20px]">
<label className="text-[14px] mb-[0.7rem] font-medium">
{t("date-format")}
</label>
<select
className="op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content w-full h-full text-[11px]"
value={selectedFormat}
onChange={handleFormatChange}
>
{dateFormats.map((format) => (
<option key={format} value={format}>
{format}
</option>
))}
</select>
<div className="flex flex-col md:flex-row md:gap-4 mt-[0.75rem] text-[12px]">
<div className="flex items-center gap-2 ml-2">
<input
type="radio"
value={true}
className="op-radio op-radio-xs"
checked={is12Hour}
onChange={handleHrInput}
/>
<div className="text-center">12 hr</div>
</div>
<div className="flex items-center gap-2 ml-2">
<input
type="radio"
value={false}
className="op-radio op-radio-xs"
checked={!is12Hour}
onChange={handleHrInput}
/>
<div className="text-center">24 hr</div>
</div>
</div>
<p className="mt-[12px] ml-[10px] text-[13px] font-medium">
<strong>
{formatDateTime(date, selectedFormat, props?.timezone, is12Hour)}
</strong>
</p>
</div>
);
};
export default DateFormatSelector;
@@ -1,10 +1,10 @@
import React, { useState, useEffect } from "react";
import AsyncSelect from "react-select/async";
import AddSigner from "../../AddSigner";
import Parse from "parse";
import AddContact from "../../../primitives/AddContact";
import Tooltip from "../../../primitives/Tooltip";
import { createPortal } from "react-dom";
import { useTranslation } from "react-i18next";
import { findContact } from "../../../constant/Utils";
function arrayMove(array, from, to) {
array = array.slice();
array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]);
@@ -103,17 +103,21 @@ const SignersInput = (props) => {
// `handleNewDetails` is used to set just save from quick form to selected option in dropdown
const handleNewDetails = (data) => {
setState([...state, data]);
const user = {
value: data["objectId"],
label: data["Name"],
email: data?.Email
};
setState([...state, user]);
if (selected.length > 0) {
setSelected([...selected, data]);
setSelected([...selected, user]);
} else {
setSelected([data]);
setSelected([user]);
}
};
const loadOptions = async (inputValue) => {
try {
const params = { search: inputValue };
const contactRes = await Parse.Cloud.run("getsigners", params);
const contactRes = await findContact(inputValue);
if (contactRes) {
const res = JSON.parse(JSON.stringify(contactRes));
//compareArrays is a function where compare between two array (total signersList and dcument signers list)
@@ -148,7 +152,9 @@ const SignersInput = (props) => {
{props.label ? props.label : t("signers")}
{props.required && <span className="text-red-500 text-[13px]">*</span>}
<span
className={`z-[${props?.helptextZindex ? props.helptextZindex : 30}] absolute ml-1 text-xs`}
className={`z-[${
props?.helptextZindex ? props.helptextZindex : 30
}] absolute ml-1 text-xs`}
>
<Tooltip
id={`${props.label ? props.label : "signers"}-tooltip`}
@@ -209,9 +215,8 @@ const SignersInput = (props) => {
</button>
{isModal && (
<AddSigner
valueKey={"objectId"}
displayKey={"Name"}
<AddContact
isDisableTitle
details={handleNewDetails}
closePopup={handleModalCloseClick}
/>
@@ -7,27 +7,10 @@ const TimezoneSelector = (props) => {
// Intl.DateTimeFormat().resolvedOptions().timeZone // Default to the user's local timezone
const onChangeTimezone = (timezone) => {
setSelectedTimezone(timezone);
setSelectedTimezone(timezone?.value);
props.setTimezone && props.setTimezone(timezone?.value);
};
// Format date and time for the selected timezone
const formatDate = (date, timezone) => {
return timezone
? new Intl.DateTimeFormat("en-US", {
weekday: "short",
year: "numeric",
month: "short",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
timeZone: timezone,
hour12: false
}).format(date)
: new Date(date).toUTCString();
};
return (
<>
<div className="max-w-[400px] pr-[20px]">
@@ -54,11 +37,6 @@ const TimezoneSelector = (props) => {
}}
/>
</div>
<div className="mt-[12px] ml-[10px] text-[13px]">
<strong>
{formatDate(new Date(), selectedTimezone?.value || selectedTimezone)}
</strong>{" "}
</div>
</>
);
};
+5 -4
View File
@@ -3,8 +3,7 @@ import { useTranslation } from "react-i18next";
import { NavLink } from "react-router";
const Menu = ({ item, isOpen, closeSidebar }) => {
const appName =
"OpenSign™";
const appName = "OpenSign™";
const drivename = appName === "OpenSign™" ? "OpenSign™" : "";
const { t } = useTranslation();
return (
@@ -18,13 +17,15 @@ const Menu = ({ item, isOpen, closeSidebar }) => {
className={({ isActive }) =>
`${
isActive ? " bg-base-300 text-base-content" : ""
} flex items-center text-left p-3 lg:p-4 text-base-content hover:text-base-content focus:bg-base-300 hover:bg-base-300 hover:no-underline focus:outline-none`
} flex items-center justify-start text-left p-3 lg:p-4 text-base-content hover:text-base-content focus:bg-base-300 hover:bg-base-300 hover:no-underline focus:outline-none`
}
onClick={closeSidebar}
tabIndex={isOpen ? 0 : -1}
role="menuitem"
>
<i className={`${item.icon} text-[18px]`} aria-hidden="true"></i>
<span className="w-[20px] h-[20px] flex justify-center">
<i className={`${item.icon} text-[18px]`} aria-hidden="true"></i>
</span>
<span className="ml-3 lg:ml-4">
{t(`sidebar.${item.title}`, { appName: drivename })}
</span>
+13 -10
View File
@@ -3,8 +3,7 @@ import { useTranslation } from "react-i18next";
import { NavLink } from "react-router";
const Submenu = ({ item, closeSidebar, toggleSubmenu, submenuOpen }) => {
const appName =
"OpenSign™";
const appName = "OpenSign™";
const drivename = appName === "OpenSign™" ? "OpenSign™" : "";
const { t } = useTranslation();
const { title, icon, children } = item;
@@ -12,14 +11,16 @@ const Submenu = ({ item, closeSidebar, toggleSubmenu, submenuOpen }) => {
<li role="none" className="my-0.5">
<button
onClick={() => toggleSubmenu(item.title)}
className="flex items-center text-left p-3 lg:p-4 text-base-content hover:text-base-content focus:bg-base-300 hover:bg-base-300 hover:no-underline focus:outline-none "
className="flex items-center justify-start text-left p-3 lg:p-4 text-base-content hover:text-base-content focus:bg-base-300 hover:bg-base-300 hover:no-underline focus:outline-none "
aria-expanded={submenuOpen}
aria-haspopup="true"
aria-controls={`submenu-${title}`}
>
<i className={`${icon} text-[18px]`}></i>
<span className="w-[20px] h-[20px] flex justify-center">
<i className={`${icon} text-[18px]`}></i>
</span>
<div className="flex justify-between items-center w-full">
<span className="ml-3 lg:ml-4">
<span className="ml-3 lg:ml-4 text-start">
{t(`sidebar.${item.title}`, { appName })}
</span>
<i
@@ -45,16 +46,18 @@ const Submenu = ({ item, closeSidebar, toggleSubmenu, submenuOpen }) => {
className={({ isActive }) =>
`${
isActive ? "bg-base-300 text-base-content" : ""
} flex items-center text-left pl-6 md:pl-8 py-2 text-sm cursor-pointer text-base-content hover:text-base-content focus:bg-base-300 hover:bg-base-300 hover:no-underline focus:outline-none`
} flex items-center justify-start text-left pl-6 md:pl-8 py-2 text-sm cursor-pointer text-base-content hover:text-base-content focus:bg-base-300 hover:bg-base-300 hover:no-underline focus:outline-none`
}
onClick={closeSidebar}
role="menuitem"
tabIndex={submenuOpen ? 0 : -1}
>
<i
className={`${childItem.icon} text-[18px]`}
aria-hidden="true"
></i>
<span className="w-[15px] h-[15px] flex justify-center">
<i
className={`${childItem.icon} text-[18px]`}
aria-hidden="true"
></i>
</span>
<span className="ml-3 lg:ml-4">
{t(`sidebar.${item.title}-Children.${childItem.title}`, {
appName: drivename
+77 -48
View File
@@ -8,6 +8,7 @@ import { saveAs } from "file-saver";
import printModule from "print-js";
import fontkit from "@pdf-lib/fontkit";
import { themeColor } from "./const";
import { format, toZonedTime } from "date-fns-tz";
export const fontsizeArr = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28];
export const fontColorArr = ["red", "black", "blue", "yellow"];
@@ -232,17 +233,47 @@ export const widgets = [
{ type: "email", icon: "fa-light fa-envelope", iconSize: "20px" }
];
export const getDate = () => {
export const getDate = (dateformat) => {
const format = dateformat || "MM/DD/YYYY";
const date = new Date();
const milliseconds = date.getTime();
const newDate = moment(milliseconds).format("MM/DD/YYYY");
const newDate = moment(milliseconds).format(format);
return newDate;
};
export const addWidgetOptions = (type) => {
const defaultOpt = {
name: type,
status: "required"
};
export const selectFormat = (data) => {
switch (data) {
case "L":
return "MM/dd/yyyy";
case "MM/DD/YYYY":
return "MM/dd/yyyy";
case "DD-MM-YYYY":
return "dd-MM-yyyy";
case "DD/MM/YYYY":
return "dd/MM/yyyy";
case "LL":
return "MMMM dd, yyyy";
case "DD MMM, YYYY":
return "dd MMM, yyyy";
case "YYYY-MM-DD":
return "yyyy-MM-dd";
case "MM-DD-YYYY":
return "MM-dd-yyyy";
case "MM.DD.YYYY":
return "MM.dd.yyyy";
case "MMM DD, YYYY":
return "MMM dd, yyyy";
case "MMMM DD, YYYY":
return "MMMM dd, yyyy";
case "DD MMMM, YYYY":
return "dd MMMM, yyyy";
default:
return "MM/dd/yyyy";
}
};
export const addWidgetOptions = (type, signer) => {
const defaultOpt = { name: type, status: "required" };
switch (type) {
case "signature":
return defaultOpt;
@@ -263,12 +294,16 @@ export const addWidgetOptions = (type) => {
return { ...defaultOpt };
case "job title":
return { ...defaultOpt };
case "date":
case "date": {
const dateFormat = signer?.DateFormat
? selectFormat(signer?.DateFormat)
: "MM/dd/yyyy";
return {
...defaultOpt,
response: getDate(),
validation: { format: "MM/dd/yyyy", type: "date-format" }
response: getDate(signer?.DateFormat),
validation: { format: dateFormat, type: "date-format" }
};
}
case "image":
return defaultOpt;
case "email":
@@ -289,7 +324,7 @@ export const addWidgetOptions = (type) => {
}
};
export const addWidgetSelfsignOptions = (type, getWidgetValue) => {
export const addWidgetSelfsignOptions = (type, getWidgetValue, owner) => {
switch (type) {
case "signature":
return { name: "signature" };
@@ -319,12 +354,16 @@ export const addWidgetSelfsignOptions = (type, getWidgetValue) => {
defaultValue: getWidgetValue(type),
validation: { type: "text", pattern: "" }
};
case "date":
case "date": {
const dateFormat = owner?.DateFormat
? selectFormat(owner?.DateFormat)
: "MM/dd/yyyy";
return {
name: "date",
response: getDate(),
validation: { format: "MM/dd/yyyy", type: "date-format" }
response: getDate(owner?.DateFormat),
validation: { format: dateFormat, type: "date-format" }
};
}
case "image":
return { name: "image" };
case "email":
@@ -932,10 +971,7 @@ export const calculateInitialWidthHeight = (widgetData) => {
const height = span.offsetHeight;
document.body.removeChild(span);
return {
getWidth: width,
getHeight: height
};
return { getWidth: width, getHeight: height };
};
export const addInitialData = (signerPos, setXyPosition, value, userId) => {
function widgetDataValue(type) {
@@ -966,9 +1002,7 @@ export const addInitialData = (signerPos, setXyPosition, value, userId) => {
)
};
} else {
return {
...item
};
return item;
}
} else if (item.pos && item.pos.length > 0) {
// If there is no nested array, add the new field
@@ -986,17 +1020,9 @@ export const addInitialData = (signerPos, setXyPosition, value, userId) => {
...item.options,
defaultValue: item?.options?.defaultValue || widgetData
}
// Width:
// calculateInitialWidthHeight(item.type, widgetData).getWidth ||
// item?.Width,
// Height:
// calculateInitialWidthHeight(item.type, widgetData).getHeight ||
// item?.Height
};
} else {
return {
...item
};
return item;
}
}
});
@@ -2167,13 +2193,13 @@ export const fetchUrl = async (url, pdfName) => {
try {
const response = await fetch(url);
if (!response.ok) {
alert("something went wrong, please try again later.");
alert("something went wrong, refreshing this page may solve this issue.");
throw new Error("Network response was not ok");
}
const blob = await response.blob();
saveAs(blob, `${sanitizeFileName(pdfName)}_signed_by_${appName}.pdf`);
} catch (error) {
alert("something went wrong, please try again later.");
alert("something went wrong, refreshing this page may solve this issue.");
console.error("Error downloading the file:", error);
}
};
@@ -2244,7 +2270,7 @@ export const handleDownloadPdf = async (
} catch (err) {
console.log("err in getsignedurl", err);
setIsDownloading("");
alert("something went wrong, please try again later.");
alert("something went wrong, refreshing this page may solve this issue.");
}
}
};
@@ -2302,7 +2328,7 @@ export const handleToPrint = async (event, setIsDownloading, pdfDetails) => {
} catch (err) {
setIsDownloading("");
console.log("err in getsignedurl", err);
alert("something went wrong, please try again later.");
alert("something went wrong, refreshing this page may solve this issue.");
}
};
@@ -2388,7 +2414,7 @@ export const handleDownloadCertificate = async (
} catch (err) {
setIsDownloading("certificate_err");
console.log("err in download in certificate", err);
alert("something went wrong, please try again later.");
alert("something went wrong, refreshing this page may solve this issue.");
}
}
};
@@ -2845,20 +2871,11 @@ export function generatePdfName(length) {
// Format date and time for the selected timezone
export const formatTimeInTimezone = (date, timezone) => {
return timezone
? new Intl.DateTimeFormat("en-US", {
weekday: "short",
year: "numeric",
month: "short",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
timeZone: timezone,
timeZoneName: "short",
hour12: false
}).format(date)
const nyDate = timezone && toZonedTime(date, timezone);
const generatedDate = timezone
? format(nyDate, "EEE, dd MMM yyyy HH:mm:ss zzz", { timeZone: timezone })
: new Date(date).toUTCString();
return generatedDate;
};
// `usertimezone` is used to get timezone of current user
@@ -2957,3 +2974,15 @@ export const mailTemplate = (param) => {
return { subject, body };
};
export function formatDateTime(date, dateFormat, timeZone, is12Hour) {
const zonedDate = toZonedTime(date, timeZone); // Convert date to the given timezone
const timeFormat = is12Hour ? "hh:mm:ss a" : "HH:mm:ss";
return dateFormat
? format(
zonedDate,
`${selectFormat(dateFormat)}, ${timeFormat} 'GMT' XXX`,
{ timeZone }
)
: formatTimeInTimezone(date, timeZone);
}
+3 -5
View File
@@ -1,11 +1,9 @@
import logo from "../assets/images/logo.png";
export function serverUrl_fn() {
let baseUrl;
baseUrl = process.env.REACT_APP_SERVERURL
? process.env.REACT_APP_SERVERURL
: window.location.origin + "/app";
let baseUrl = process.env.REACT_APP_SERVERURL
? process.env.REACT_APP_SERVERURL
: window.location.origin + "/api/app";
return baseUrl;
}
export const appInfo = {
-8
View File
@@ -14,7 +14,6 @@ import {
Preview
} from "react-dnd-multi-backend";
import DragElement from "./components/pdf/DragElement";
import TagManager from "react-gtm-module";
import Parse from "parse";
import "./polyfills";
import { serverUrl_fn } from "./constant/appinfo";
@@ -56,13 +55,6 @@ const generatePreview = (props) => {
);
};
if (process.env.REACT_APP_GTM) {
const tagManagerArgs = {
gtmId: process.env.REACT_APP_GTM
};
TagManager.initialize(tagManagerArgs);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<CookiesProvider defaultSetOptions={{ path: "/" }}>
+6 -13
View File
@@ -187,13 +187,6 @@ const Forms = (props) => {
}
} catch (err) {
if (err?.message?.includes("is encrypted")) {
try {
await Parse.Cloud.run("encryptedpdf", {
email: Parse.User.current().getEmail()
});
} catch (err) {
console.log("err in sending posthog encryptedpdf", err);
}
try {
setIsDecrypting(true);
const size = files?.[0].size;
@@ -859,7 +852,7 @@ const Forms = (props) => {
<div className="max-w-[200px] md:max-w-[450px]">
<p className="font-bold">{t("send-in-order")}</p>
<p>{t("send-in-order-help.p1")}</p>
<p className="p-[5px]">
<div className="p-[5px]">
<ol className="list-disc">
<li>
<span className="font-bold">
@@ -874,7 +867,7 @@ const Forms = (props) => {
<span>{t("send-in-order-help.p3")}</span>
</li>
</ol>
</p>
</div>
<p>{t("send-in-order-help.p4")}</p>
</div>
</Tooltip>
@@ -956,7 +949,7 @@ const Forms = (props) => {
{t("send-in-order")}
</p>
<p>{t("send-in-order-help.p1")}</p>
<p className="p-[5px]">
<div className="p-[5px]">
<ol className="list-disc">
<li>
<span className="font-bold">
@@ -975,7 +968,7 @@ const Forms = (props) => {
</span>
</li>
</ol>
</p>
</div>
<p>{t("send-in-order-help.p4")}</p>
</div>
</Tooltip>
@@ -1093,7 +1086,7 @@ const Forms = (props) => {
<Tooltip id="istourenabled-tooltip" className="z-[999]">
<div className="max-w-[200px] md:max-w-[450px]">
<p className="font-bold">{t("enable-tour")}</p>
<p className="p-[5px]">
<div className="p-[5px]">
<ol className="list-disc">
<li>
<span className="font-bold">
@@ -1106,7 +1099,7 @@ const Forms = (props) => {
<span>{t("istourenabled-help.p2")}</span>
</li>
</ol>
</p>
</div>
<p>
{t("istourenabled-help.p3", { appName: appName })}
</p>
+49 -59
View File
@@ -7,9 +7,7 @@ import { NavLink, useNavigate, useLocation } from "react-router";
import login_img from "../assets/images/login_img.svg";
import { useWindowSize } from "../hook/useWindowSize";
import ModalUi from "../primitives/ModalUi";
import {
emailRegex,
} from "../constant/const";
import { emailRegex } from "../constant/const";
import Alert from "../primitives/Alert";
import { appInfo } from "../constant/appinfo";
import { fetchAppInfo } from "../redux/reducers/infoReducer";
@@ -24,8 +22,7 @@ import { useTranslation } from "react-i18next";
import SelectLanguage from "../components/pdf/SelectLanguage";
function Login() {
const appName =
"OpenSign™";
const appName = "OpenSign™";
const { t, i18n } = useTranslation();
const navigate = useNavigate();
const location = useLocation();
@@ -43,7 +40,7 @@ function Login() {
baseUrl: localStorage.getItem("baseUrl"),
parseAppId: localStorage.getItem("parseAppId"),
loading: false,
thirdpartyLoader: false,
thirdpartyLoader: false
});
const [userDetails, setUserDetails] = useState({
Company: "",
@@ -61,9 +58,7 @@ function Login() {
const app = await getAppLogo();
if (app?.error === "invalid_json") {
setErrMsg(t("server-down", { appName: appName }));
} else if (
app?.user === "not_exist"
) {
} else if (app?.user === "not_exist") {
navigate("/addadmin");
}
if (app?.logo) {
@@ -153,9 +148,9 @@ function Login() {
localStorage.setItem("PageLanding", menu.pageId);
localStorage.setItem("defaultmenuid", menu.menuId);
localStorage.setItem("pageType", menu.pageType);
setState({ ...state, loading: false });
// Redirect to the appropriate URL after successful login
navigate(redirectUrl);
setState({ ...state, loading: false });
// Redirect to the appropriate URL after successful login
navigate(redirectUrl);
} else {
setState({ ...state, loading: false });
setIsModal(true);
@@ -171,14 +166,14 @@ function Login() {
logOutUser();
}
} else {
setState({ ...state, loading: false });
setState({
...state,
loading: false,
alertType: "danger",
alertMsg: "User not found."
});
logOutUser();
setState({ ...state, loading: false });
setState({
...state,
loading: false,
alertType: "danger",
alertMsg: "User not found."
});
logOutUser();
}
})
.catch((error) => {
@@ -186,7 +181,7 @@ function Login() {
...state,
loading: false,
alertType: "danger",
alertMsg: `Something went wrong.`
alertMsg: t("something-went-wrong-mssg")
});
setTimeout(() => setState({ ...state, alertMsg: "" }), 2000);
console.error("Error while fetching Follow", error);
@@ -282,7 +277,7 @@ function Login() {
localStorage.setItem("PageLanding", menu.pageId);
localStorage.setItem("defaultmenuid", menu.menuId);
localStorage.setItem("pageType", menu.pageType);
navigate(redirectUrl);
navigate(redirectUrl);
} else {
setState({
...state,
@@ -380,8 +375,8 @@ function Login() {
localStorage.setItem("PageLanding", menu.pageId);
localStorage.setItem("defaultmenuid", menu.menuId);
localStorage.setItem("pageType", menu.pageType);
// Redirect to the appropriate URL after successful login
navigate(redirectUrl);
// Redirect to the appropriate URL after successful login
navigate(redirectUrl);
} else {
setState({ ...state, loading: false });
logOutUser();
@@ -408,7 +403,7 @@ function Login() {
setState({
...state,
alertType: "danger",
alertMsg: "Something went wrong, please try again later."
alertMsg: t("something-went-wrong-mssg")
});
console.log("err", error);
} finally {
@@ -501,7 +496,6 @@ function Login() {
localStorage.setItem("parseAppId", appid);
};
return errMsg ? (
<div className="h-screen flex justify-center text-center items-center p-4 text-gray-500 text-base">
{errMsg}
@@ -561,39 +555,35 @@ function Login() {
onInput={(e) => e.target.setCustomValidity("")}
/>
<hr className="my-1 border-none" />
<label className="block text-xs" htmlFor="password">
{t("password")}
</label>
<div className="relative">
<input
id="password"
type={
state.passwordVisible ? "text" : "password"
}
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
name="password"
value={state.password}
autoComplete="current-password"
onChange={handleChange}
onInvalid={(e) =>
e.target.setCustomValidity(
t("input-required")
)
}
onInput={(e) => e.target.setCustomValidity("")}
required
/>
<span
className="absolute cursor-pointer top-[50%] right-[10px] -translate-y-[50%] text-base-content"
onClick={togglePasswordVisibility}
>
{state.passwordVisible ? (
<i className="fa-light fa-eye-slash text-xs pb-1" /> // Close eye icon
) : (
<i className="fa-light fa-eye text-xs pb-1 " /> // Open eye icon
)}
</span>
</div>
<label className="block text-xs" htmlFor="password">
{t("password")}
</label>
<div className="relative">
<input
id="password"
type={state.passwordVisible ? "text" : "password"}
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
name="password"
value={state.password}
autoComplete="current-password"
onChange={handleChange}
onInvalid={(e) =>
e.target.setCustomValidity(t("input-required"))
}
onInput={(e) => e.target.setCustomValidity("")}
required
/>
<span
className="absolute cursor-pointer top-[50%] right-[10px] -translate-y-[50%] text-base-content"
onClick={togglePasswordVisibility}
>
{state.passwordVisible ? (
<i className="fa-light fa-eye-slash text-xs pb-1" /> // Close eye icon
) : (
<i className="fa-light fa-eye text-xs pb-1 " /> // Open eye icon
)}
</span>
</div>
<div className="relative mt-1">
<NavLink
+11 -12
View File
@@ -1,11 +1,7 @@
import React, { useEffect, useState, useRef } from "react";
import "../styles/opensigndrive.css";
import {
iconColor,
} from "../constant/const";
import {
getDrive
} from "../constant/Utils";
import { iconColor } from "../constant/const";
import { getDrive } from "../constant/Utils";
import { useNavigate } from "react-router";
import Title from "../components/Title";
import Parse from "parse";
@@ -29,8 +25,7 @@ const AppLoader = () => {
);
};
function Opensigndrive() {
const appName =
"OpenSign™";
const appName = "OpenSign™";
const drivename = appName === "OpenSign™" ? "OpenSign™" : "";
const { t } = useTranslation();
const navigate = useNavigate();
@@ -130,7 +125,7 @@ function Opensigndrive() {
}
];
const getDetails = async () => {
getPdfDocumentList();
getPdfDocumentList();
};
//function for get all pdf document list
const getPdfDocumentList = async (disbaleLoading) => {
@@ -144,7 +139,7 @@ function Opensigndrive() {
try {
const driveDetails = await getDrive(docId, skip, limit);
if (driveDetails && driveDetails === "Error: Something went wrong!") {
setHandleError("Error: Something went wrong!");
setHandleError(t("something-went-wrong-mssg"));
} else if (driveDetails && driveDetails.length > 0) {
const addMoreTour = [
{
@@ -635,7 +630,9 @@ function Opensigndrive() {
<div className="flex flex-row items-center">
<div
id="folder-menu"
className={`${isOptions ? "dropdown show dropDownStyle" : "dropdown"} hidden md:block`}
className={`${
isOptions ? "dropdown show dropDownStyle" : "dropdown"
} hidden md:block`}
onClick={() => setIsOptions(!isOptions)}
>
<div className="sort" data-tut="reactourSecond">
@@ -773,7 +770,9 @@ function Opensigndrive() {
</div>
<div
id="folder-menu"
className={`${isOptions ? "dropdown show dropDownStyle" : "dropdown"} md:hidden`}
className={`${
isOptions ? "dropdown show dropDownStyle" : "dropdown"
} md:hidden`}
onClick={() => setIsOptions(!isOptions)}
>
<div
File diff suppressed because it is too large Load Diff
+15 -10
View File
@@ -150,7 +150,6 @@ function PlaceHolderSign() {
status: false,
message: ""
});
const [extUserId, setExtUserId] = useState("");
const [isCustomize, setIsCustomize] = useState(false);
const [zoomPercent, setZoomPercent] = useState(0);
const [scale, setScale] = useState(1);
@@ -164,13 +163,13 @@ function PlaceHolderSign() {
const [userList, setUserList] = useState([]);
const [isAttchSignerModal, setIsAttchSignerModal] = useState(false);
const [isNewContact, setIsNewContact] = useState({ status: false, id: "" });
const [owner, setOwner] = useState({});
const isMobile = window.innerWidth < 767;
const [, drop] = useDrop({
accept: "BOX",
drop: (item, monitor) => addPositionOfSignature(item, monitor),
collect: (monitor) => ({ isOver: !!monitor.isOver() })
});
const documentId = docId;
useEffect(() => {
if (documentId) {
@@ -286,7 +285,7 @@ function PlaceHolderSign() {
setPdfArrayBuffer(arrayBuffer);
setPdfBase64Url(base64Pdf);
}
setExtUserId(documentData[0]?.ExtUserPtr?.objectId);
setOwner(documentData?.[0]?.ExtUserPtr);
const alreadyPlaceholder = documentData[0]?.SignedUrl;
// Check if document is sent for signing
if (alreadyPlaceholder) {
@@ -457,7 +456,11 @@ function PlaceHolderSign() {
documentData === "Error: Something went wrong!" ||
(documentData.result && documentData.result.error)
) {
setHandleError(t("something-went-wrong-mssg"));
if (documentData?.result?.error?.includes("deleted")) {
setHandleError(t("document-deleted"));
} else {
setHandleError(t("something-went-wrong-mssg"));
}
setIsLoading({ isLoad: false });
} else {
setHandleError(t("no-data-avaliable"));
@@ -525,7 +528,7 @@ function PlaceHolderSign() {
scale: containerScale,
zIndex: posZIndex,
type: dragTypeValue,
options: addWidgetOptions(dragTypeValue),
options: addWidgetOptions(dragTypeValue, owner),
Width: widgetWidth / (containerScale * scale),
Height: widgetHeight / (containerScale * scale)
};
@@ -556,7 +559,7 @@ function PlaceHolderSign() {
scale: containerScale,
zIndex: posZIndex,
type: dragTypeValue,
options: addWidgetOptions(dragTypeValue),
options: addWidgetOptions(dragTypeValue, owner),
Width: widgetWidth / (containerScale * scale),
Height: widgetHeight / (containerScale * scale)
};
@@ -1225,7 +1228,7 @@ function PlaceHolderSign() {
sigingUrl: signPdf
};
let params = {
extUserId: extUserId,
extUserId: owner?.objectId,
recipient: signerMail[i].Email,
subject: replaceVar?.subject
? replaceVar?.subject
@@ -2093,9 +2096,11 @@ function PlaceHolderSign() {
<LottieWithLoader />
{pdfDetails[0].SendinOrder ? (
<p>
{t("placeholder-mail-alert", {
name: signersdata[0]?.Name
})}
{isCurrUser
? t("placeholder-mail-alert-you")
: t("placeholder-mail-alert", {
name: signersdata[0]?.Name
})}
</p>
) : (
<p>{t("placeholder-alert-4")}</p>
+37 -13
View File
@@ -20,6 +20,7 @@ import EditorToolbar, {
module2,
formats
} from "../components/pdf/EditorToolbar";
import DateFormatSelector from "../components/shared/fields/DateFormatSelector";
const Preferences = () => {
const appName = "OpenSign™";
@@ -47,6 +48,8 @@ const Preferences = () => {
const [tab, setTab] = useState([generaltab]);
const [sendinOrder, setSendinOrder] = useState(true);
const [isTourEnabled, setIsTourEnabled] = useState(false);
const [dateFormat, setDateFormat] = useState("MM/DD/YYYY");
const [is12HourTime, setIs12HourTime] = useState(false);
useEffect(() => {
fetchSignType();
@@ -99,10 +102,18 @@ const Preferences = () => {
? _getUser?.IsTourEnabled
: true;
setIsTourEnabled(istourenabled);
const DateFormat =
_getUser?.DateFormat !== undefined
? _getUser?.DateFormat
: "MM/DD/YYYY";
setDateFormat(DateFormat);
const is12Hr =
_getUser?.Is12HourTime !== undefined ? _getUser?.Is12HourTime : false;
setIs12HourTime(is12Hr);
}
} catch (err) {
console.log("err while getting user details", err);
setErrMsg("Something went wrong");
setErrMsg(t("something-went-wrong-mssg"));
} finally {
setIsTopLoader(false);
}
@@ -154,11 +165,13 @@ const Preferences = () => {
params = {
...params,
SendinOrder: sendinOrder,
IsTourEnabled: isTourEnabled
IsTourEnabled: isTourEnabled,
DateFormat: dateFormat,
Is12HourTime: is12HourTime
};
const updateRes = await Parse.Cloud.run("updatepreferences", params);
if (updateRes) {
setIsAlert({ type: "success", msg: "Saved successfully." });
setIsAlert({ type: "success", msg: t("saved-successfully") });
let extUser =
localStorage.getItem("Extand_Class") &&
JSON.parse(localStorage.getItem("Extand_Class"))?.[0];
@@ -166,6 +179,8 @@ const Preferences = () => {
extUser.NotifyOnSignatures = isNotifyOnSignatures;
extUser.SendinOrder = sendinOrder;
extUser.IsTourEnabled = isTourEnabled;
extUser.DateFormat = dateFormat;
extUser.Is12HourTime = is12HourTime;
const _extUser = JSON.parse(JSON.stringify(extUser));
localStorage.setItem("Extand_Class", JSON.stringify([_extUser]));
}
@@ -238,12 +253,12 @@ const Preferences = () => {
const updateRes = JSON.parse(JSON.stringify(res));
SetCompletionBody(updateRes?.CompletionBody);
setCompletionSubject(updateRes?.CompletionSubject);
setIsAlert({ type: "success", msg: "Saved successfully." });
setIsAlert({ type: "success", msg: t("saved-successfully") });
setTimeout(() => setIsAlert({ type: "", msg: "" }), 1500);
}
} catch (err) {
console.log("Err", err);
setIsAlert({ type: "danger", msg: "Something went wrong." });
setIsAlert({ type: "danger", msg: t("something-went-wrong-mssg") });
setTimeout(() => setIsAlert({ type: "", msg: "" }), 1500);
} finally {
setIsLoader(false);
@@ -265,12 +280,12 @@ const Preferences = () => {
const updateRes = JSON.parse(JSON.stringify(res));
setRequestBody(updateRes?.RequestBody);
setRequestSubject(updateRes?.RequestSubject);
setIsAlert({ type: "success", msg: "Saved successfully." });
setIsAlert({ type: "success", msg: t("saved-successfully") });
setTimeout(() => setIsAlert({ type: "", msg: "" }), 1500);
}
} catch (err) {
console.log("Err", err);
setIsAlert({ type: "danger", msg: "Something went wrong." });
setIsAlert({ type: "danger", msg: t("something-went-wrong-mssg") });
setTimeout(() => setIsAlert({ type: "", msg: "" }), 1500);
} finally {
setIsLoader(false);
@@ -376,7 +391,7 @@ const Preferences = () => {
{t("allowed-signature-types")}
</p>
<p>{t("allowed-signature-types-help.p1")}</p>
<p className="p-[5px] ml-2">
<div className="p-[5px] ml-2">
<ol className="list-disc">
<li>
<span className="font-bold">Draw: </span>
@@ -403,7 +418,7 @@ const Preferences = () => {
</span>
</li>
</ol>
</p>
</div>
</div>
</ReactTooltip>
</label>
@@ -481,6 +496,15 @@ const Preferences = () => {
setTimezone={setTimezone}
/>
</div>
<div className="mb-[0.75rem]">
<DateFormatSelector
timezone={timezone}
dateFormat={dateFormat}
is12HourTime={is12HourTime}
setIs12HourTime={setIs12HourTime}
setDateFormat={setDateFormat}
/>
</div>
<div className="mb-[0.75rem] text-[12px]">
<label className="block mb-[0.7rem]">
<span className="text-[14px] font-medium">
@@ -501,7 +525,7 @@ const Preferences = () => {
<div className="max-w-[200px] md:max-w-[450px]">
<p className="font-bold">{t("send-in-order")}</p>
<p>{t("send-in-order-help.p1")}</p>
<p className="p-[5px]">
<div className="p-[5px]">
<ol className="list-disc">
<li>
<span className="font-bold">
@@ -514,7 +538,7 @@ const Preferences = () => {
<span>{t("send-in-order-help.p3")}</span>
</li>
</ol>
</p>
</div>
<p>{t("send-in-order-help.p4")}</p>
</div>
</ReactTooltip>
@@ -563,7 +587,7 @@ const Preferences = () => {
>
<div className="max-w-[200px] md:max-w-[450px]">
<p className="font-bold">{t("enable-tour")}</p>
<p className="p-[5px]">
<div className="p-[5px]">
<ol className="list-disc">
<li>
<span className="font-bold">
@@ -576,7 +600,7 @@ const Preferences = () => {
<span>{t("istourenabled-help.p2")}</span>
</li>
</ol>
</p>
</div>
<p>
{t("istourenabled-help.p3", {
appName: appName
+13 -54
View File
@@ -40,7 +40,8 @@ import {
convertBase64ToFile,
generatePdfName,
handleRemoveWidgets,
compressedFileSize
compressedFileSize,
addWidgetSelfsignOptions
} from "../constant/Utils";
import { useParams } from "react-router";
import Tour from "reactour";
@@ -144,6 +145,7 @@ function SignYourSelf() {
isVisible: false,
signId: ""
});
const [owner, setOwner] = useState({});
const [, drop] = useDrop({
accept: "BOX",
drop: (item, monitor) => addPositionOfSignature(item, monitor),
@@ -204,6 +206,7 @@ function SignYourSelf() {
const documentData = await contractDocument(documentId);
if (documentData && documentData.length > 0) {
setOwner(documentData?.[0]?.ExtUserPtr);
setPdfDetails(documentData);
const placeholders =
documentData[0]?.Placeholders?.length > 0
@@ -249,7 +252,11 @@ function SignYourSelf() {
documentData === "Error: Something went wrong!" ||
(documentData.result && documentData.result.error)
) {
setHandleError(t("something-went-wrong-mssg"));
if (documentData?.result?.error?.includes("deleted")) {
setHandleError(t("document-deleted"));
} else {
setHandleError(t("something-went-wrong-mssg"));
}
setIsLoading({ isLoad: false });
} else {
setHandleError(t("no-data-avaliable"));
@@ -321,7 +328,7 @@ function SignYourSelf() {
}
} catch (err) {
console.log("Error: error in getDocumentDetails", err);
setHandleError("Error: Something went wrong!");
setHandleError(t("something-went-wrong-mssg"));
setIsLoading({ isLoad: false });
}
};
@@ -344,54 +351,6 @@ function SignYourSelf() {
}
};
const addWidgetOptions = (type) => {
switch (type) {
case "signature":
return { name: "signature" };
case "stamp":
return { name: "stamp" };
case "checkbox":
return { name: "checkbox" };
case textWidget:
return { name: "text" };
case "initials":
return { name: "initials" };
case "name":
return {
name: "name",
defaultValue: getWidgetValue(type),
validation: { type: "text", pattern: "" }
};
case "company":
return {
name: "company",
defaultValue: getWidgetValue(type),
validation: { type: "text", pattern: "" }
};
case "job title":
return {
name: "job title",
defaultValue: getWidgetValue(type),
validation: { type: "text", pattern: "" }
};
case "date":
return {
name: "date",
response: getDate(),
validation: { format: "MM/dd/yyyy", type: "date-format" }
};
case "image":
return { name: "image" };
case "email":
return {
name: "email",
defaultValue: getWidgetValue(type),
validation: { type: "email", pattern: "" }
};
default:
return {};
}
};
//function for setting position after drop signature button over pdf
const addPositionOfSignature = (item, monitor) => {
setCurrWidgetsDetails({});
@@ -416,7 +375,7 @@ function SignYourSelf() {
// `getBoundingClientRect()` is used to get accurate measurement height of the div
const divHeight = divRef.current.getBoundingClientRect().height;
const getWidth = widgetTypeExist
? calculateInitialWidthHeight(dragTypeValue, widgetValue).getWidth
? calculateInitialWidthHeight(widgetValue).getWidth
: defaultWidthHeight(dragTypeValue).width;
const getHeight = defaultWidthHeight(dragTypeValue).height;
@@ -430,7 +389,7 @@ function SignYourSelf() {
scale: containerScale,
Width: getWidth,
Height: getHeight,
options: addWidgetOptions(dragTypeValue)
options: addWidgetSelfsignOptions(dragTypeValue, getWidgetValue, owner)
};
dropData.push(dropObj);
} else {
@@ -459,7 +418,7 @@ function SignYourSelf() {
type: dragTypeValue,
Width: getWidth / (containerScale * scale),
Height: getHeight / (containerScale * scale),
options: addWidgetOptions(dragTypeValue),
options: addWidgetSelfsignOptions(dragTypeValue, getWidgetValue, owner),
scale: containerScale
};
dropData.push(dropObj);
@@ -139,6 +139,7 @@ const TemplatePlaceholder = () => {
const [updatedPdfUrl, setUpdatedPdfUrl] = useState("");
const [tempSignerId, setTempSignerId] = useState("");
const [unSignedWidgetId, setUnSignedWidgetId] = useState("");
const [owner, setOwner] = useState({});
useEffect(() => {
fetchTemplate();
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -214,6 +215,7 @@ const TemplatePlaceholder = () => {
: [];
if (documentData && documentData.length > 0) {
setOwner(documentData?.[0]?.ExtUserPtr);
const url = documentData[0] && documentData[0]?.URL;
if (url) {
const arrayBuffer = await convertPdfArrayBuffer(url);
@@ -391,7 +393,7 @@ const TemplatePlaceholder = () => {
scale: containerScale,
zIndex: posZIndex,
type: dragTypeValue,
options: addWidgetOptions(dragTypeValue),
options: addWidgetOptions(dragTypeValue, owner),
Width: widgetWidth / (containerScale * scale),
Height: widgetHeight / (containerScale * scale)
};
@@ -421,7 +423,7 @@ const TemplatePlaceholder = () => {
// isMobile: isMobile,
zIndex: posZIndex,
type: item.text,
options: addWidgetOptions(dragTypeValue),
options: addWidgetOptions(dragTypeValue, owner),
Width: widgetWidth / (containerScale * scale),
Height: widgetHeight / (containerScale * scale)
};
@@ -7,8 +7,7 @@ import Title from "../components/Title";
import { useTranslation } from "react-i18next";
import { emailRegex } from "../constant/const";
const UpdateExistUserAdmin = () => {
const appName =
"OpenSign™";
const appName = "OpenSign™";
const { t } = useTranslation();
const navigate = useNavigate();
const [formdata, setFormdata] = useState({ email: "", masterkey: "" });
@@ -30,7 +29,7 @@ const UpdateExistUserAdmin = () => {
}
} catch (err) {
console.log("Err in checkadminexist", err);
setErrMsg("Something went wrong.");
setErrMsg(t("something-went-wrong-mssg"));
} finally {
setLoader(false);
}
+10 -10
View File
@@ -33,8 +33,9 @@ const AddContact = (props) => {
try {
const baseURL = localStorage.getItem("baseUrl");
const url = `${baseURL}functions/isuserincontactbook`;
const token =
{ "X-Parse-Session-Token": localStorage.getItem("accesstoken") };
const token = {
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
};
const headers = {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
@@ -63,18 +64,15 @@ const AddContact = (props) => {
)
);
const userId = user?.objectId || "";
const tenantDetails = await getTenantDetails(
userId,
);
const tenantDetails = await getTenantDetails(userId);
const tenantId = tenantDetails?.objectId || "";
if (tenantId) {
try {
const baseURL = localStorage.getItem("baseUrl");
const url = `${baseURL}functions/savecontact`;
const token =
{
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
};
const token = {
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
};
const data = { name, email, phone, tenantId };
const headers = {
"Content-Type": "application/json",
@@ -137,7 +135,9 @@ const AddContact = (props) => {
</div>
)}
<div className="w-full mx-auto p-[8px]">
<div className="text-[14px] font-[700]">{t("add-contact")}</div>
{!props?.isDisableTitle && (
<div className="text-[14px] font-[700]">{t("add-contact")}</div>
)}
{isUserExist && (
<div className="mb-[0.75rem] flex items-center mt-1">
<input
@@ -14,7 +14,7 @@ import {
copytoData,
fetchUrl,
formatDate,
formatTimeInTimezone,
formatDateTime,
getSignedUrl,
getTenantDetails,
handleSignatureType,
@@ -1012,11 +1012,23 @@ const ReportTable = (props) => {
);
if (matchSigner) {
const timezone = extClass?.[0]?.Timezone || "";
const DateFormat = extClass?.[0]?.DateFormat || "MM/DD/YYYY";
const Is12Hr = extClass?.[0]?.Is12HourTime || false;
const signedon = matchSigner?.SignedOn
? formatTimeInTimezone(new Date(matchSigner?.SignedOn), timezone)
? formatDateTime(
new Date(matchSigner?.SignedOn),
DateFormat,
timezone,
Is12Hr
)
: "-";
const viewedon = matchSigner?.ViewedOn
? formatTimeInTimezone(new Date(matchSigner?.ViewedOn), timezone)
? formatDateTime(
new Date(matchSigner?.ViewedOn),
DateFormat,
timezone,
Is12Hr
)
: "-";
return {
id: i,
+39 -4
View File
@@ -6,10 +6,6 @@ dotenv.config();
export const cloudServerUrl = 'http://localhost:8080/app';
export const appName = 'OpenSign™';
export function customAPIurl() {
const url = new URL(cloudServerUrl);
return url.pathname === '/api/app' ? url.origin + '/api' : url.origin;
}
export const color = [
'#93a3db',
@@ -256,3 +252,42 @@ export const mailTemplate = param => {
return { subject, body };
};
export const selectFormat = data => {
switch (data) {
case 'L':
return 'MM/dd/yyyy';
case 'MM/DD/YYYY':
return 'MM/dd/yyyy';
case 'DD-MM-YYYY':
return 'dd-MM-yyyy';
case 'DD/MM/YYYY':
return 'dd/MM/yyyy';
case 'LL':
return 'MMMM dd, yyyy';
case 'DD MMM, YYYY':
return 'dd MMM, yyyy';
case 'YYYY-MM-DD':
return 'yyyy-MM-dd';
case 'MM-DD-YYYY':
return 'MM-dd-yyyy';
case 'MM.DD.YYYY':
return 'MM.dd.yyyy';
case 'MMM DD, YYYY':
return 'MMM dd, yyyy';
case 'MMMM DD, YYYY':
return 'MMMM dd, yyyy';
case 'DD MMMM, YYYY':
return 'dd MMMM, yyyy';
default:
return 'MM/dd/yyyy';
}
};
export function formatDateTime(date, dateFormat, timeZone, is12Hour) {
const zonedDate = toZonedTime(date, timeZone); // Convert date to the given timezone
const timeFormat = is12Hour ? 'hh:mm:ss a' : 'HH:mm:ss';
return dateFormat
? format(zonedDate, `${selectFormat(dateFormat)}, ${timeFormat} 'GMT' XXX`, { timeZone })
: formatTimeInTimezone(date, timeZone);
}
-2
View File
@@ -21,7 +21,6 @@ import UserAfterFind from './parsefunction/UserAfterFInd.js';
import SignatureAfterFind from './parsefunction/SignatureAfterFind.js';
import TenantAterFind from './parsefunction/TenantAfterFind.js';
import VerifyEmail from './parsefunction/VerifyEmail.js';
import encryptedpdf from './parsefunction/encryptedPdf.js';
import { getSignedUrl } from './parsefunction/getSignedUrl.js';
import createBatchDocs from './parsefunction/createBatchDocs.js';
import linkContactToDoc from './parsefunction/linkContactToDoc.js';
@@ -83,7 +82,6 @@ Parse.Cloud.define('getReport', getReport);
Parse.Cloud.define('getTemplate', GetTemplate);
Parse.Cloud.define('callwebhook', callWebhook);
Parse.Cloud.define('verifyemail', VerifyEmail);
Parse.Cloud.define('encryptedpdf', encryptedpdf);
Parse.Cloud.define('getsignedurl', getSignedUrl);
Parse.Cloud.define('batchdocuments', createBatchDocs);
Parse.Cloud.define('linkcontacttodoc', linkContactToDoc);
@@ -1,14 +0,0 @@
import { PostHog } from 'posthog-node';
const ph_project_api_key = process.env.PH_PROJECT_API_KEY;
const client = ph_project_api_key ? new PostHog(ph_project_api_key) : '';
export default async function encryptedpdf(request) {
const email = request.params.email;
if (client) {
client?.capture({
distinctId: email,
event: 'encrypted_pdf_error',
properties: { response_code: 200 },
});
}
return { message: 'success' };
}
@@ -1,7 +1,5 @@
import axios from 'axios';
import {
cloudServerUrl,
} from '../../Utils.js';
import { cloudServerUrl } from '../../Utils.js';
export default async function getDocument(request) {
const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const docId = request.params.docId;
@@ -47,13 +45,12 @@ export default async function getDocument(request) {
console.log('err user in not authenticated', err);
return { error: "You don't have access of this document!" };
}
}
else {
} else {
return { error: "You don't have access of this document!" };
}
}
} else {
return { error: "You don't have access of this document!" };
return { error: "document deleted or you don't have access." };
}
} catch (err) {
console.log('err', err);
@@ -1,12 +1,12 @@
import { PDFDocument, rgb } from 'pdf-lib';
import fs from 'node:fs';
import fontkit from '@pdf-lib/fontkit';
import {
formatTimeInTimezone,
} from '../../../Utils.js';
import { formatDateTime } from '../../../Utils.js';
export default async function GenerateCertificate(docDetails) {
const timezone = docDetails?.ExtUserPtr?.Timezone || '';
const Is12Hr = docDetails?.ExtUserPtr?.Is12HourTime || false;
const DateFormat = docDetails?.ExtUserPtr?.DateFormat || 'MM/DD/YYYY';
const pdfDoc = await PDFDocument.create();
// `fontBytes` is used to embed custom font in pdf
const fontBytes = fs.readFileSync('./font/times.ttf'); //
@@ -22,23 +22,27 @@ export default async function GenerateCertificate(docDetails) {
const titleColor = rgb(0, 0.2, 0.4); //rgb(0, 0.53, 0.71);
const titleUnderline = rgb(0, 0.2, 0.4); // rgb(0.12, 0.12, 0.12);
const title = 25;
const subtitle = 20;
const text = 14;
const subtitle = 16;
const text = 13;
const signertext = 13;
const timeText = 11;
const textKeyColor = rgb(0.12, 0.12, 0.12);
const textValueColor = rgb(0.3, 0.3, 0.3);
const completedAt = docDetails?.completedAt ? new Date(docDetails?.completedAt) : new Date();
const completedAtperTimezone = formatTimeInTimezone(completedAt, timezone);
const completedAtperTimezone = formatDateTime(completedAt, DateFormat, timezone, Is12Hr);
const completedUTCtime = completedAtperTimezone;
const signersCount = docDetails?.Signers?.length || 1;
const generateAt = docDetails?.completedAt ? new Date(docDetails?.completedAt) : new Date();
const generatedAtperTimezone = formatTimeInTimezone(generateAt, timezone);
const generatedAtperTimezone = formatDateTime(generateAt, DateFormat, timezone, Is12Hr);
const generatedUTCTime = generatedAtperTimezone;
const generatedOn = 'Generated On ' + generatedUTCTime;
const textWidth = timesRomanFont.widthOfTextAtSize(generatedOn, 12);
const margin = 30;
const maxX = width - margin - textWidth; // Ensures text stays inside the border with 30px margin
const OriginIp = docDetails?.OriginIp || '';
const company = docDetails?.ExtUserPtr?.Company || '';
const createdAt = docDetails?.DocSentAt?.iso || docDetails.createdAt;
const createdAtperTimezone = formatTimeInTimezone(createdAt, timezone);
const createdAtperTimezone = formatDateTime(createdAt, DateFormat, timezone, Is12Hr);
const IsEnableOTP = docDetails?.IsEnableOTP || false;
const filteredaudit = docDetails?.AuditTrail?.filter(x => x?.UserPtr?.objectId);
const auditTrail =
@@ -75,15 +79,15 @@ export default async function GenerateCertificate(docDetails) {
borderColor: borderColor,
borderWidth: 1,
});
page.drawImage(pngImage, {
x: 30,
y: 790,
width: 100,
height: 25,
});
page.drawImage(pngImage, {
x: 30,
y: 790,
width: 100,
height: 25,
});
page.drawText(generatedOn, {
x: 320,
x: Math.max(startX, maxX), // Adjusts dynamically 320
y: 810,
size: 12,
font: timesRomanFont,
@@ -92,13 +96,13 @@ export default async function GenerateCertificate(docDetails) {
page.drawText('Certificate of Completion', {
x: 160,
y: 750,
y: 755,
size: title,
font: timesRomanFont,
color: titleColor,
});
const underlineY = 740;
const underlineY = 745;
page.drawLine({
start: { x: 30, y: underlineY },
end: { x: width - 30, y: underlineY },
@@ -108,7 +112,7 @@ export default async function GenerateCertificate(docDetails) {
page.drawText('Summary', {
x: 30,
y: 710,
y: 727,
size: subtitle,
font: timesRomanFont,
color: titleColor,
@@ -116,15 +120,15 @@ export default async function GenerateCertificate(docDetails) {
page.drawText('Document Id :', {
x: 30,
y: 685,
y: 710,
size: text,
font: timesRomanFont,
color: textKeyColor,
});
page.drawText(docDetails.objectId, {
x: 115,
y: 685,
x: 110,
y: 710,
size: text,
font: timesRomanFont,
color: textValueColor,
@@ -132,15 +136,15 @@ export default async function GenerateCertificate(docDetails) {
page.drawText('Document Name :', {
x: 30,
y: 665,
y: 690,
size: text,
font: timesRomanFont,
color: textKeyColor,
});
page.drawText(docDetails?.Name, {
x: 140,
y: 665,
x: 130,
y: 690,
size: docDetails?.Name?.length >= 78 ? 12 : text,
font: timesRomanFont,
color: textValueColor,
@@ -148,52 +152,52 @@ export default async function GenerateCertificate(docDetails) {
page.drawText('Organization :', {
x: 30,
y: 645,
y: 670,
size: text,
font: timesRomanFont,
color: textKeyColor,
});
page.drawText(company, {
x: 115,
y: 645,
x: 110,
y: 670,
size: text,
font: timesRomanFont,
color: textValueColor,
});
page.drawText('Created on :', {
x: 30,
y: 625,
y: 650,
size: text,
font: timesRomanFont,
color: textKeyColor,
});
page.drawText(`${createdAtperTimezone}`, {
x: 105,
y: 625,
x: 97,
y: 650,
size: text,
font: timesRomanFont,
color: textValueColor,
});
page.drawText('Completed on :', {
x: 30,
y: 605,
y: 630,
size: text,
font: timesRomanFont,
color: textKeyColor,
});
page.drawText(`${completedUTCtime}`, {
x: 125,
y: 605,
x: 115,
y: 630,
size: text,
font: timesRomanFont,
color: textValueColor,
});
page.drawText('Signers :', {
x: 30,
y: 585,
y: 610,
size: text,
font: timesRomanFont,
color: textKeyColor,
@@ -201,73 +205,76 @@ export default async function GenerateCertificate(docDetails) {
page.drawText(`${signersCount}`, {
x: 80,
y: 585,
y: 610,
size: text,
font: timesRomanFont,
color: textValueColor,
});
page.drawText('Document originator', {
x: 30,
y: 565,
y: 590,
size: 17,
font: timesRomanFont,
color: titleColor,
});
page.drawText('Name :', {
x: 60,
y: 545,
y: 573,
size: text,
font: timesRomanFont,
color: textKeyColor,
});
page.drawText(ownerName, {
x: 105,
y: 545,
y: 573,
size: text,
font: timesRomanFont,
color: textValueColor,
});
page.drawText('Email :', {
x: 60,
y: 525,
y: 553,
size: text,
font: timesRomanFont,
color: textKeyColor,
});
page.drawText(ownerEmail, {
x: 105,
y: 525,
y: 553,
size: text,
font: timesRomanFont,
color: textValueColor,
});
page.drawText('IP address :', {
x: 60,
y: 505,
y: 533,
size: text,
font: timesRomanFont,
color: textKeyColor,
});
page.drawText(`${OriginIp}`, {
x: 130,
y: 505,
x: 125,
y: 533,
size: text,
font: timesRomanFont,
color: textValueColor,
});
page.drawLine({
start: { x: 30, y: 495 },
end: { x: width - 30, y: 495 },
start: { x: 30, y: 527 },
end: { x: width - 30, y: 527 },
color: rgb(0.12, 0.12, 0.12),
thickness: 0.5,
});
let yPosition1 = 475;
let yPosition2 = 455;
let yPosition3 = 435;
let yPosition4 = 415;
let yPosition5 = 395;
let yPosition6 = 360;
let yPosition1 = 512;
let yPosition2 = 498;
let yPosition3 = 478;
let yPosition4 = 458;
let yPosition5 = 438;
let yPosition6 = 418;
let yPosition7 = 398;
let yPosition8 = 363;
auditTrail.slice(0, 3).forEach(async (x, i) => {
const embedPng = x.Signature ? await pdfDoc.embedPng(x.Signature) : '';
page.drawText(`Signer ${i + 1}`, {
@@ -280,7 +287,7 @@ export default async function GenerateCertificate(docDetails) {
page.drawText('Name :', {
x: 30,
y: yPosition2,
size: text,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
@@ -288,32 +295,32 @@ export default async function GenerateCertificate(docDetails) {
page.drawText(x?.Name, {
x: 75,
y: yPosition2,
size: text,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
page.drawText('Viewed on :', {
x: half + 45,
y: yPosition2,
size: timeText,
font: timesRomanFont,
color: textKeyColor,
});
//new Date(x.ViewedOn).toUTCString()
page.drawText(`${formatTimeInTimezone(x.ViewedOn, timezone)}`, {
x: half + 102,
y: yPosition2,
size: timeText,
font: timesRomanFont,
color: textValueColor,
});
if (IsEnableOTP) {
page.drawText('Security level :', {
x: half + 120,
y: yPosition2,
size: timeText,
font: timesRomanFont,
color: textKeyColor,
});
page.drawText('Email, OTP Auth', {
x: half + 190,
y: yPosition2,
size: timeText,
font: timesRomanFont,
color: textValueColor,
});
}
page.drawText('Email :', {
x: 30,
y: yPosition3,
size: text,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
@@ -321,70 +328,70 @@ export default async function GenerateCertificate(docDetails) {
page.drawText(x?.Email, {
x: 75,
y: yPosition3,
size: text,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
page.drawText('Viewed on :', {
x: 30,
y: yPosition4,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
page.drawText(`${formatDateTime(x.ViewedOn, DateFormat, timezone, Is12Hr)}`, {
x: 97,
y: yPosition4,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
page.drawText('Signed on :', {
x: half + 45,
y: yPosition3 + 5,
size: timeText,
x: 30,
y: yPosition5,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
// new Date(x.SignedOn).toUTCString()
page.drawText(`${formatTimeInTimezone(x.SignedOn, timezone)}`, {
x: half + 98,
y: yPosition3 + 5,
size: timeText,
page.drawText(`${formatDateTime(x.SignedOn, DateFormat, timezone, Is12Hr)}`, {
x: 95,
y: yPosition5,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
page.drawText('IP address :', {
x: 30,
y: yPosition4,
size: text,
y: yPosition6,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
page.drawText(x?.ipAddress, {
x: 100,
y: yPosition4,
size: 13,
x: 95,
y: yPosition6,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
if (IsEnableOTP) {
page.drawText('Security level :', {
x: half + 45,
y: yPosition4 + 10,
size: timeText,
font: timesRomanFont,
color: textKeyColor,
});
page.drawText('Email, OTP Auth', {
x: half + 115,
y: yPosition4 + 10,
size: timeText,
font: timesRomanFont,
color: textValueColor,
});
}
page.drawText('Signature :', {
x: 30,
y: yPosition5,
size: text,
y: yPosition7,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
page.drawRectangle({
x: 98,
y: yPosition5 - 30,
y: yPosition7 - 30,
width: 104,
height: 44,
borderColor: rgb(0.22, 0.18, 0.47),
@@ -393,24 +400,26 @@ export default async function GenerateCertificate(docDetails) {
if (embedPng) {
page.drawImage(embedPng, {
x: 100,
y: yPosition5 - 27,
y: yPosition7 - 27,
width: 100,
height: 40,
});
}
page.drawLine({
start: { x: 30, y: yPosition6 },
end: { x: width - 30, y: yPosition6 },
start: { x: 30, y: yPosition8 },
end: { x: width - 30, y: yPosition8 },
color: rgb(0.12, 0.12, 0.12),
thickness: 0.5,
});
yPosition1 = yPosition6 - 20;
yPosition1 = yPosition8 - 20;
yPosition2 = yPosition1 - 20;
yPosition3 = yPosition2 - 20;
yPosition4 = yPosition3 - 20;
yPosition5 = yPosition4 - 20;
yPosition6 = yPosition6 - 140;
yPosition6 = yPosition5 - 20;
yPosition7 = yPosition6 - 20;
yPosition8 = yPosition8 - 174;
});
if (auditTrail.length > 3) {
@@ -420,7 +429,7 @@ export default async function GenerateCertificate(docDetails) {
const embedPng = x.Signature ? await pdfDoc.embedPng(x.Signature) : '';
// Calculate remaining space on current page
const remainingSpace = yPosition6;
const remainingSpace = yPosition8;
// If there's not enough space for the next entry, create a new page
if (remainingSpace < 90) {
@@ -440,7 +449,10 @@ export default async function GenerateCertificate(docDetails) {
yPosition3 = yPosition2 - 20;
yPosition4 = yPosition3 - 20;
yPosition5 = yPosition4 - 20;
yPosition6 = currentPage.getHeight() - 160;
yPosition5 = yPosition4 - 20;
yPosition6 = yPosition5 - 20;
yPosition7 = yPosition6 - 20;
yPosition8 = currentPage.getHeight() - 190;
}
currentPage.drawText(`Signer ${4 + i}`, {
@@ -453,7 +465,7 @@ export default async function GenerateCertificate(docDetails) {
currentPage.drawText('Name :', {
x: 30,
y: yPosition2,
size: text,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
@@ -461,32 +473,32 @@ export default async function GenerateCertificate(docDetails) {
currentPage.drawText(x?.Name, {
x: 75,
y: yPosition2,
size: text,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
currentPage.drawText('Viewed on :', {
x: half + 45,
y: yPosition2,
size: timeText,
font: timesRomanFont,
color: textKeyColor,
});
// new Date(x.ViewedOn).toUTCString()
currentPage.drawText(`${formatTimeInTimezone(x.ViewedOn, timezone)}`, {
x: half + 102,
y: yPosition2,
size: timeText,
font: timesRomanFont,
color: textValueColor,
});
if (IsEnableOTP) {
currentPage.drawText('Security level :', {
x: half + 120,
y: yPosition2,
size: timeText,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText(`Email, OTP Auth`, {
x: half + 190,
y: yPosition2,
size: timeText,
font: timesRomanFont,
color: textValueColor,
});
}
currentPage.drawText('Email :', {
x: 30,
y: yPosition3,
size: text,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
@@ -494,70 +506,68 @@ export default async function GenerateCertificate(docDetails) {
currentPage.drawText(x?.Email, {
x: 75,
y: yPosition3,
size: text,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
currentPage.drawText('Signed on :', {
x: half + 45,
y: yPosition3 + 5,
size: timeText,
currentPage.drawText('Viewed on :', {
x: 30,
y: yPosition4,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
// new Date(x.SignedOn).toUTCString()
currentPage.drawText(`${formatTimeInTimezone(x.SignedOn, timezone)}`, {
x: half + 98,
y: yPosition3 + 5,
size: timeText,
currentPage.drawText(`${formatDateTime(x.ViewedOn, DateFormat, timezone, Is12Hr)}`, {
x: 97,
y: yPosition4,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
currentPage.drawText('Signed on :', {
x: 30,
y: yPosition5,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText(`${formatDateTime(x.SignedOn, DateFormat, timezone, Is12Hr)}`, {
x: 95,
y: yPosition5,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
currentPage.drawText('IP address :', {
x: 30,
y: yPosition4,
size: text,
y: yPosition6,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText(x?.ipAddress, {
x: 100,
y: yPosition4,
size: text,
y: yPosition6,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
if (IsEnableOTP) {
currentPage.drawText('Security level :', {
x: half + 45,
y: yPosition4 + 10,
size: timeText,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText(`Email, OTP Auth`, {
x: half + 115,
y: yPosition4 + 10,
size: timeText,
font: timesRomanFont,
color: textValueColor,
});
}
currentPage.drawText('Signature :', {
x: 30,
y: yPosition5,
size: text,
y: yPosition7,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawRectangle({
x: 98,
y: yPosition5 - 27,
y: yPosition7 - 27,
width: 104,
height: 44,
borderColor: rgb(0.22, 0.18, 0.47),
@@ -566,26 +576,28 @@ export default async function GenerateCertificate(docDetails) {
if (embedPng) {
currentPage.drawImage(embedPng, {
x: 100,
y: yPosition5 - 25,
y: yPosition7 - 25,
width: 100,
height: 40,
});
}
currentPage.drawLine({
start: { x: 30, y: yPosition6 },
end: { x: width - 30, y: yPosition6 },
start: { x: 30, y: yPosition8 },
end: { x: width - 30, y: yPosition8 },
color: rgb(0.12, 0.12, 0.12),
thickness: 0.5,
});
// Update y positions for the next entry
yPosition1 = yPosition6 - 20;
yPosition1 = yPosition8 - 20;
yPosition2 = yPosition1 - 20;
yPosition3 = yPosition2 - 20;
yPosition4 = yPosition3 - 20;
yPosition5 = yPosition4 - 20;
yPosition6 = yPosition6 - 140;
yPosition6 = yPosition5 - 20;
yPosition7 = yPosition6 - 20;
yPosition8 = yPosition8 - 174;
});
}
@@ -209,7 +209,8 @@ async function sendCompletedMail(obj) {
subject = replaceVar.subject;
body = replaceVar.body;
}
const Bcc = doc?.Bcc?.length > 0 ? doc.Bcc.map(x => x.Email) : '';
const Bcc = doc?.Bcc?.length > 0 ? doc.Bcc.map(x => x.Email) : [];
const updatedBcc = doc?.SenderMail ? [...Bcc, doc?.SenderMail] : Bcc;
const params = {
extUserId: sender.objectId,
url: url,
@@ -220,7 +221,7 @@ async function sendCompletedMail(obj) {
pdfName: pdfName,
html: body,
mailProvider: obj.mailProvider,
bcc: Bcc,
bcc: updatedBcc?.length > 0 ? updatedBcc : '',
certificatePath: `./exports/signed_certificate_${doc.objectId}.pdf`,
filename: obj?.filename,
};
@@ -31,120 +31,97 @@ async function sendMailProvider(req, plan, monthchange) {
if (req.params.url) {
const randomNumber = Math.floor(Math.random() * 5000);
const testPdf = `test_${randomNumber}.pdf`;
let Pdf = fs.createWriteStream(testPdf);
const writeToLocalDisk = () => {
return new Promise((resolve, reject) => {
const isSecure =
new URL(req.params.url)?.protocol === 'https:' &&
new URL(req.params.url)?.hostname !== 'localhost';
if (isSecure) {
https
.get(req.params.url, async function (response) {
response.pipe(Pdf);
response.on('end', () => resolve('success'));
})
.on('error', e => {
console.error(`error: ${e.message}`);
resolve('error');
});
} else {
const httpsAgent = new https.Agent({ rejectUnauthorized: false }); // Disable SSL validation
axios
.get(req.params.url, { responseType: 'stream', httpsAgent })
.then(response => {
response.data.pipe(Pdf);
Pdf.on('finish', () => resolve('success'));
Pdf.on('error', () => resolve('error'));
})
.catch(e => {
console.log('error', e.message);
resolve('error');
});
}
});
};
// `writeToLocalDisk` is used to create pdf file from doc url
const ress = await writeToLocalDisk();
if (ress) {
function readTolocal() {
try {
let Pdf = fs.createWriteStream(testPdf);
const writeToLocalDisk = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
let PdfBuffer = fs.readFileSync(Pdf.path);
resolve(PdfBuffer);
}, 100);
const isSecure =
new URL(req.params.url)?.protocol === 'https:' &&
new URL(req.params.url)?.hostname !== 'localhost';
if (isSecure) {
https
.get(req.params.url, async function (response) {
response.pipe(Pdf);
response.on('end', () => resolve('success'));
})
.on('error', e => {
console.error(`error: ${e.message}`);
resolve('error');
});
} else {
const httpsAgent = new https.Agent({ rejectUnauthorized: false }); // Disable SSL validation
axios
.get(req.params.url, { responseType: 'stream', httpsAgent })
.then(response => {
response.data.pipe(Pdf);
Pdf.on('finish', () => resolve('success'));
Pdf.on('error', () => resolve('error'));
})
.catch(e => {
console.log('error', e.message);
resolve('error');
});
}
});
}
// `PdfBuffer` used to create buffer from pdf file
let PdfBuffer = await readTolocal();
const pdfName = req.params.pdfName && `${req.params.pdfName}.pdf`;
const filename = req.params.filename;
const file = {
filename: filename || pdfName || 'exported.pdf',
content: smtpenable ? PdfBuffer : undefined,
data: smtpenable ? undefined : PdfBuffer,
};
// `writeToLocalDisk` is used to create pdf file from doc url
const ress = await writeToLocalDisk();
if (ress) {
function readTolocal() {
return new Promise((resolve, reject) => {
setTimeout(() => {
let PdfBuffer = fs.readFileSync(Pdf.path);
resolve(PdfBuffer);
}, 100);
});
}
// `PdfBuffer` used to create buffer from pdf file
let PdfBuffer = await readTolocal();
const pdfName = req.params.pdfName && `${req.params.pdfName}.pdf`;
const filename = req.params.filename;
const file = {
filename: filename || pdfName || 'exported.pdf',
content: smtpenable ? PdfBuffer : undefined,
data: smtpenable ? undefined : PdfBuffer,
};
let attachment;
const certificatePath = req.params.certificatePath || `./exports/certificate.pdf`;
if (fs.existsSync(certificatePath)) {
try {
// `certificateBuffer` used to create buffer from pdf file
const certificateBuffer = fs.readFileSync(certificatePath);
const certificate = {
filename: 'certificate.pdf',
content: smtpenable ? certificateBuffer : undefined, //fs.readFileSync('./exports/exported_file_1223.pdf'),
data: smtpenable ? undefined : certificateBuffer,
};
attachment = [file, certificate];
} catch (err) {
let attachment;
const certificatePath = req.params.certificatePath || `./exports/certificate.pdf`;
if (fs.existsSync(certificatePath)) {
try {
// `certificateBuffer` used to create buffer from pdf file
const certificateBuffer = fs.readFileSync(certificatePath);
const certificate = {
filename: 'certificate.pdf',
content: smtpenable ? certificateBuffer : undefined, //fs.readFileSync('./exports/exported_file_1223.pdf'),
data: smtpenable ? undefined : certificateBuffer,
};
attachment = [file, certificate];
} catch (err) {
attachment = [file];
console.log('Err in read certificate sendmailv3', err);
}
} else {
attachment = [file];
console.log('Err in read certificate sendmailv3', err);
}
} else {
attachment = [file];
}
const from = req.params.from || '';
const mailsender = smtpenable ? process.env.SMTP_USER_EMAIL : process.env.MAILGUN_SENDER;
const replyto = req.params?.replyto || '';
const messageParams = {
from: from + ' <' + mailsender + '>',
to: req.params.recipient,
subject: req.params.subject,
text: req.params.text || 'mail',
html: req.params.html || '',
attachments: smtpenable ? attachment : undefined,
attachment: smtpenable ? undefined : attachment,
bcc: req.params.bcc ? req.params.bcc : undefined,
replyTo: replyto ? replyto : undefined,
};
if (transporterSMTP) {
const res = await transporterSMTP.sendMail(messageParams);
console.log('smtp transporter res: ', res?.response);
if (!res.err) {
if (req.params?.extUserId) {
await updateMailCount(req.params.extUserId, plan, monthchange);
}
if (fs.existsSync(certificatePath)) {
try {
fs.unlinkSync(certificatePath);
} catch (err) {
console.log('Err in unlink certificate sendmailv3');
}
}
if (fs.existsSync(testPdf)) {
try {
fs.unlinkSync(testPdf);
} catch (err) {
console.log('Err in unlink pdf sendmailv3');
}
}
return { status: 'success' };
}
} else {
if (mailgunApiKey) {
const res = await mailgunClient.messages.create(mailgunDomain, messageParams);
console.log('mailgun res: ', res?.status);
if (res.status === 200) {
const from = req.params.from || '';
const mailsender = smtpenable ? process.env.SMTP_USER_EMAIL : process.env.MAILGUN_SENDER;
const replyto = req.params?.replyto || '';
const messageParams = {
from: from + ' <' + mailsender + '>',
to: req.params.recipient,
subject: req.params.subject,
text: req.params.text || 'mail',
html: req.params.html || '',
attachments: smtpenable ? attachment : undefined,
attachment: smtpenable ? undefined : attachment,
bcc: req.params.bcc ? req.params.bcc : undefined,
replyTo: replyto ? replyto : undefined,
};
if (transporterSMTP) {
const res = await transporterSMTP.sendMail(messageParams);
console.log('smtp transporter res: ', res?.response);
if (!res.err) {
if (req.params?.extUserId) {
await updateMailCount(req.params.extUserId, plan, monthchange);
}
@@ -165,23 +142,60 @@ async function sendMailProvider(req, plan, monthchange) {
return { status: 'success' };
}
} else {
if (fs.existsSync(certificatePath)) {
try {
fs.unlinkSync(certificatePath);
} catch (err) {
console.log('Err in unlink certificate sendmailv3');
if (mailgunApiKey) {
const res = await mailgunClient.messages.create(mailgunDomain, messageParams);
console.log('mailgun res: ', res?.status);
if (res.status === 200) {
if (req.params?.extUserId) {
await updateMailCount(req.params.extUserId, plan, monthchange);
}
if (fs.existsSync(certificatePath)) {
try {
fs.unlinkSync(certificatePath);
} catch (err) {
console.log('Err in unlink certificate sendmailv3');
}
}
if (fs.existsSync(testPdf)) {
try {
fs.unlinkSync(testPdf);
} catch (err) {
console.log('Err in unlink pdf sendmailv3');
}
}
return { status: 'success' };
}
}
if (fs.existsSync(testPdf)) {
try {
fs.unlinkSync(testPdf);
} catch (err) {
console.log('Err in unlink pdf sendmailv3');
} else {
if (fs.existsSync(certificatePath)) {
try {
fs.unlinkSync(certificatePath);
} catch (err) {
console.log('Err in unlink certificate sendmailv3');
}
}
if (fs.existsSync(testPdf)) {
try {
fs.unlinkSync(testPdf);
} catch (err) {
console.log('Err in unlink pdf sendmailv3');
}
}
return { status: 'error' };
}
return { status: 'error' };
}
}
} catch (err) {
console.log('err in sendmailv3', err);
if (fs.existsSync(testPdf)) {
try {
fs.unlinkSync(testPdf);
} catch (err) {
console.log('Err in unlink pdf sendmailv3');
}
}
if (err) {
return { status: 'error' };
}
}
} else {
const from = req.params.from || '';
@@ -230,8 +244,8 @@ async function sendMailProvider(req, plan, monthchange) {
}
async function sendmailv3(req) {
const nonCustomMail = await sendMailProvider(req);
return nonCustomMail;
const nonCustomMail = await sendMailProvider(req);
return nonCustomMail;
}
export default sendmailv3;
@@ -48,6 +48,12 @@ export default async function updatePreferences(request) {
if (request.params.IsTourEnabled !== undefined) {
newOrg.set('IsTourEnabled', request.params.IsTourEnabled);
}
if (request.params.DateFormat) {
newOrg.set('DateFormat', request.params.DateFormat);
}
if (request.params.Is12HourTime !== undefined) {
newOrg.set('Is12HourTime', request.params.Is12HourTime);
}
const updateUserRes = await newOrg.save(null, { useMasterKey: true });
if (updateUserRes) {
const _updateUserRes = JSON.parse(JSON.stringify(updateUserRes));
-12
View File
@@ -15,7 +15,6 @@ import AWS from 'aws-sdk';
import { app as customRoute } from './cloud/customRoute/customApp.js';
import { exec } from 'child_process';
import { createTransport } from 'nodemailer';
import { PostHog } from 'posthog-node';
import { appName, cloudServerUrl, smtpenable, smtpsecure, useLocal } from './Utils.js';
import { SSOAuth } from './auth/authadapter.js';
import createContactIndex from './migrationdb/createContactIndex.js';
@@ -175,16 +174,6 @@ function getUserIP(request) {
return request.socket.remoteAddress;
}
}
app.use(function (req, res, next) {
const ph_project_api_key = process.env.PH_PROJECT_API_KEY;
try {
req.posthog = new PostHog(ph_project_api_key);
} catch (err) {
// console.log('Err', err);
req.posthog = '';
}
next();
});
app.use(async function (req, res, next) {
const isFilePath = req.path.includes('files') || false;
@@ -225,7 +214,6 @@ if (!process.env.TESTING) {
// Mount your custom express app
app.use('/', customRoute);
// Parse Server plays nicely with the rest of your web routes
app.get('/', function (req, res) {
res.status(200).send('opensign-server is running !!!');
+2352 -2099
View File
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -18,26 +18,26 @@
"watch": "nodemon index.js"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.741.0",
"@aws-sdk/s3-request-presigner": "^3.741.0",
"@aws-sdk/client-s3": "^3.775.0",
"@aws-sdk/s3-request-presigner": "^3.775.0",
"@parse/fs-files-adapter": "^3.0.0",
"@parse/s3-files-adapter": "^4.1.0",
"@pdf-lib/fontkit": "^1.1.1",
"@signpdf/placeholder-pdf-lib": "^3.2.4",
"@signpdf/signer-p12": "^3.2.4",
"@signpdf/signpdf": "^3.2.4",
"@signpdf/signpdf": "^3.2.5",
"aws-sdk": "^2.1692.0",
"axios": "^1.7.9",
"axios": "^1.8.4",
"cors": "^2.8.5",
"date-fns-tz": "^3.2.0",
"dotenv": "^16.4.7",
"express": "^4.21.1",
"form-data": "^4.0.1",
"form-data": "^4.0.2",
"generate-api-key": "^1.0.2",
"googleapis": "^144.0.0",
"googleapis": "^148.0.0",
"mailgun.js": "^11.1.0",
"mongodb": "^6.13.0",
"multer": "^1.4.5-lts.1",
"mongodb": "^6.15.0",
"multer": "^1.4.5-lts.2",
"multer-s3": "^3.0.1",
"node-forge": "^1.3.1",
"nodemailer": "^6.10.0",
@@ -46,18 +46,18 @@
"parse-server": "^7.4.0",
"parse-server-api-mail-adapter": "^4.1.0",
"pdf-lib": "^1.17.1",
"posthog-node": "^4.5.0",
"ws": "^8.18.0"
"posthog-node": "^4.10.2",
"ws": "^8.18.1"
},
"type": "module",
"devDependencies": {
"@babel/eslint-parser": "^7.26.5",
"eslint": "^9.20.0",
"@babel/eslint-parser": "^7.27.0",
"eslint": "^9.23.0",
"jasmine": "^5.6.0",
"mongodb-runner": "^5.7.1",
"mongodb-runner": "^5.8.0",
"nodemon": "^3.1.9",
"nyc": "^17.1.0",
"prettier": "^3.5.0"
"prettier": "^3.5.3"
},
"overrides": {
"ws": "$ws",
+2 -1
View File
@@ -11,7 +11,8 @@ services:
env_file: .env.prod
environment:
- NODE_ENV=production
- SERVER_URL=${HOST_URL:-https://localhost:3001}/app
- SERVER_URL=${HOST_URL:-https://localhost:3001}/api/app
- PUBLIC_URL=${HOST_URL:-https://localhost:3001}
networks:
- app-network
mongo: