mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-17 21:25:54 +02:00
Merge pull request #2576 from nxglabs/sync-to-public_repo-27677371306
Merge pull request #2575 from nxglabs/staging
This commit is contained in:
Generated
+525
-454
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,7 @@
|
||||
"@usewaypoint/block-text": "^0.0.7",
|
||||
"@usewaypoint/document-core": "^0.0.6",
|
||||
"@usewaypoint/email-builder": "^0.0.9",
|
||||
"axios": "^1.15.2",
|
||||
"axios": "^1.16.0",
|
||||
"date-fns-tz": "^3.2.0",
|
||||
"dompurify": "^3.4.1",
|
||||
"file-saver": "^2.0.5",
|
||||
@@ -128,7 +128,7 @@
|
||||
"autoprefixer": "^10.5.0",
|
||||
"babel-loader": "^9.2.1",
|
||||
"commitizen": "^4.3.1",
|
||||
"concurrently": "^9.2.1",
|
||||
"concurrently": "^10.0.3",
|
||||
"css-loader": "^7.1.4",
|
||||
"daisyui": "^4.12.24",
|
||||
"eslint": "^9.39.4",
|
||||
@@ -140,8 +140,8 @@
|
||||
"pretty-quick": "^4.2.2",
|
||||
"rollup-plugin-node-polyfills": "^0.2.1",
|
||||
"tailwindcss": "^3.4.19",
|
||||
"tmp": "^0.2.5",
|
||||
"vite": "^8.0.10",
|
||||
"tmp": "^0.2.7",
|
||||
"vite": ">=8.0.16",
|
||||
"vite-plugin-svgr": "^5.2.0",
|
||||
"vite-tsconfig-paths": "^6.1.1",
|
||||
"vitest": "^4.1.5"
|
||||
@@ -149,7 +149,8 @@
|
||||
"overrides": {
|
||||
"tmp": "$tmp",
|
||||
"react": "$react",
|
||||
"react-dom": "$react-dom"
|
||||
"react-dom": "$react-dom",
|
||||
"form-data": ">=4.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20 || 22"
|
||||
|
||||
@@ -284,6 +284,8 @@
|
||||
"yes": "Ja",
|
||||
"copied": "Kopiert",
|
||||
"something-went-wrong-mssg": "Etwas ist schiefgelaufen, Das Aktualisieren dieser Seite kann das Problem lösen.",
|
||||
"attachments-docx-upload-failed": "Derzeit liegt ein Problem vor. Bitte versuchen Sie es erneut.",
|
||||
"attachments-docx-upload-limit": "Das Upload-Limit für große DOCX-Dateien ist erreicht. Bitte warten Sie 4 Minuten und versuchen Sie es erneut.",
|
||||
"token-generated": "Token erfolgreich generiert.",
|
||||
"webhook": "Webhook",
|
||||
"update-webhook": "Webhook aktualisieren",
|
||||
@@ -421,7 +423,10 @@
|
||||
"image": "Bild",
|
||||
"email": "E-Mail",
|
||||
"number": "Zahl",
|
||||
"draw": "Zeichnen"
|
||||
"draw": "Zeichnen",
|
||||
"attachments": "Anhänge",
|
||||
"attachments-add": "Klicken, um Anhänge hochzuladen",
|
||||
"attachments-count": "{{count}} Anhang/Anhänge"
|
||||
},
|
||||
"fields": "Felder",
|
||||
"recipients": "Empfänger",
|
||||
@@ -1359,7 +1364,7 @@
|
||||
"export-all-formdata-error": "Sie können die Formulardaten nicht exportieren, da die Vorlage doppelte Widget-Namen enthält. Bitte erstellen Sie eine neue Vorlage, um Formulardaten exportieren zu können.",
|
||||
"export-formdata-error": "Sie können die Formulardaten nicht exportieren, da das Dokument doppelte Widget-Namen enthält. Bitte erstellen Sie ein neues Dokument ohne doppelte Widget-Namen, um Formulardaten exportieren zu können.",
|
||||
"duplicate-widget-name-error": "Dieser Widget-Name ist bereits einem anderen Unterzeichner zugewiesen. Bitte wählen Sie einen anderen Namen.",
|
||||
"duplicate-template-widget-error": "Sie können diese Vorlage nicht duplizieren, da sie doppelte Widget-Namen enthält.",
|
||||
"duplicate-template-widget-error": "Die Vorlage kann nicht dupliziert werden, weil einige Widget-Namen in verschiedenen Rollen doppelt vorkommen. Benennen Sie die doppelten Widgets um und versuchen Sie es erneut.",
|
||||
"credit-alert": "Kreditwarnung",
|
||||
"document-form-data": "Dokumenten-Formulardaten",
|
||||
"view-formdata-paid-title-error": "Die Funktion 'Formulardaten anzeigen' ermöglicht es Ihnen, die von Unterzeichnern ausgefüllten Widget-Daten auszudrucken und herunterzuladen.",
|
||||
@@ -1558,5 +1563,12 @@
|
||||
"attach-all-role-to-signer": "Bitte weisen Sie dem Unterzeichner alle Rollen zu.",
|
||||
"upgrade-to-edit": "Zum Bearbeiten upgraden",
|
||||
"hide-live-chat-for-signers": "Live-Chat für Unterzeichner ausblenden",
|
||||
"hide-live-chat-for-signers-help": "Wenn aktiviert, werden Live-Chat-Widgets für Unterzeichner auf Signierseiten ausgeblendet."
|
||||
"hide-live-chat-for-signers-help": "Wenn aktiviert, werden Live-Chat-Widgets für Unterzeichner auf Signierseiten ausgeblendet.",
|
||||
"attachments-creator-hint": "Unterzeichner können Dateien hochladen, die am Ende des Dokuments angehängt werden.",
|
||||
"attachments-drop-hint": "Dateien hier ablegen oder klicken, um auszuwählen",
|
||||
"attachments-limits": "PDF, DOCX, PNG, JPG. Max. {{maxFiles}} Dateien, je {{maxSizeMB}} MB.",
|
||||
"attachments-invalid-type": "Dateityp wird nicht unterstützt: {{name}}",
|
||||
"attachments-max-files": "Maximal {{maxFiles}} Anhänge erlaubt.",
|
||||
"attachments-remove-confirm": "Das Entfernen löscht nur die Metadaten. Bereits angehängte Seiten bleiben im Dokument. Fortfahren?",
|
||||
"attachments-docx-not-supported": "Derzeit tritt ein Problem beim Hochladen von DOCX-Dateien auf. Bitte versuchen Sie, das Dokument in einem anderen unterstützten Format hochzuladen, oder versuchen Sie es später erneut."
|
||||
}
|
||||
|
||||
@@ -421,7 +421,10 @@
|
||||
"image": "image",
|
||||
"email": "email",
|
||||
"number": "number",
|
||||
"draw": "draw"
|
||||
"draw": "draw",
|
||||
"attachments": "attachments",
|
||||
"attachments-add": "Click to add attachments",
|
||||
"attachments-count": "{{count}} attachment(s)"
|
||||
},
|
||||
"fields": "Fields",
|
||||
"recipients": "Recipients",
|
||||
@@ -606,6 +609,8 @@
|
||||
"pdf-download": "PDF download",
|
||||
"generate-certificate-alert": " Your completion certificate is being generated. Please wait momentarily. If the download doesn't start shortly, click the button again.",
|
||||
"generate-certificate-err": "We are currently experiencing an issue with certificate generation. Please try again later.",
|
||||
"attachments-docx-upload-failed": "We are currently facing a problem. Please try again.",
|
||||
"attachments-docx-size-limit": "Upload limit reached for large files. Please wait until {{time}} before retrying.",
|
||||
"folder-already-exist": "Folder already exists!",
|
||||
"folder-created-successfully": "Folder created successfully!",
|
||||
"fill-folder-name": "Please fill folder name",
|
||||
@@ -1361,7 +1366,7 @@
|
||||
"export-all-formdata-error": "You can/t export form data because the template contains duplicate widget names. Please create a fresh template to be able to export form data.",
|
||||
"export-formdata-error": "You can't export form data because the document contains duplicate widget names. Please create a fresh document without duplicate widget names to be able to export form data.",
|
||||
"duplicate-widget-name-error": "This widget name is already assigned to another signer. Please choose a different name.",
|
||||
"duplicate-template-widget-error": "You can't duplicate this template because it contains duplicate widget names.",
|
||||
"duplicate-template-widget-error": "Unable to duplicate the template because some widget names are duplicated across different roles. Rename the duplicate widgets and try again.",
|
||||
"credit-alert": "Credit Alert",
|
||||
"document-form-data": "Document Form Data",
|
||||
"view-formdata-paid-title-error": "The View Form Data feature lets you print and download the widget data filled in by signers while signing.",
|
||||
@@ -1558,5 +1563,13 @@
|
||||
"benefit-bulksend-api-team-year-help": "This plan comes with 500 premium credits per year that let you send documents via API, share public signing links, run bulk signature requests, use Kiosk mode for in-person signing, or collect signatures from documents embedded directly on your website. Each time you initiate or send a document, one credit is used — and that single document can include up to 10 signers.",
|
||||
"failed-pdf-for-prefill-processing": "Failed to load PDF for prefill processing.",
|
||||
"attach-all-role-to-signer": "Please attach all roles to the signer.",
|
||||
"upgrade-to-edit": "Upgrade to edit"
|
||||
}
|
||||
"upgrade-to-edit": "Upgrade to edit",
|
||||
"attachments-creator-hint": "Signers can upload files that will be appended to the end of the document.",
|
||||
"attachments-drop-hint": "Drop files here or click to choose",
|
||||
"attachments-limits": "PDF, DOCX, PNG, JPG. Up to {{maxFiles}} files, {{maxSizeMB}} MB each.",
|
||||
"attachments-invalid-type": "Unsupported file type: {{name}}",
|
||||
"attachments-max-files": "A maximum of {{maxFiles}} attachments are allowed.",
|
||||
"attachments-remove-confirm": "Removing only deletes the metadata. Pages already appended will remain in the document. Continue?",
|
||||
"attachement-note":"Note: This widget allows signers to upload a file during the signing process. The uploaded file will be appended as additional pages at the end of the existing PDF",
|
||||
"attachments-docx-not-supported":"We are currently experiencing an issue with DOCX file uploads. Please try uploading the document in a different supported format, or try again later."
|
||||
}
|
||||
|
||||
@@ -284,6 +284,8 @@
|
||||
"yes": "Sí",
|
||||
"copied": "Copiado",
|
||||
"something-went-wrong-mssg": "Un problème est survenu, Actualiser cette page peut résoudre le problème.",
|
||||
"attachments-docx-upload-failed": "Actualmente tenemos un problema. Inténtalo de nuevo.",
|
||||
"attachments-docx-upload-limit": "Se alcanzó el límite de carga para archivos DOCX grandes. Espera 4 minutos antes de intentarlo de nuevo.",
|
||||
"token-generated": "Token generado exitosamente.",
|
||||
"webhook": "Webhook",
|
||||
"update-webhook": "Actualizar webhook",
|
||||
@@ -421,7 +423,10 @@
|
||||
"image": "imagen",
|
||||
"email": "correo",
|
||||
"number": "número",
|
||||
"draw": "Dibujar"
|
||||
"draw": "Dibujar",
|
||||
"attachments": "adjuntos",
|
||||
"attachments-add": "Clic para subir archivos adjuntos",
|
||||
"attachments-count": "{{count}} adjunto(s)"
|
||||
},
|
||||
"fields": "Campos",
|
||||
"recipients": "Destinatarios",
|
||||
@@ -1359,7 +1364,7 @@
|
||||
"export-all-formdata-error": "No puede exportar los datos del formulario porque la plantilla contiene nombres de widgets duplicados. Cree una nueva plantilla para poder exportar los datos.",
|
||||
"export-formdata-error": "No puede exportar los datos del formulario porque el documento contiene nombres de widgets duplicados. Cree un documento nuevo sin nombres duplicados para poder exportar los datos.",
|
||||
"duplicate-widget-name-error": "Este nombre de widget ya está asignado a otro firmante. Por favor elija un nombre diferente.",
|
||||
"duplicate-template-widget-error": "No puede duplicar esta plantilla porque contiene nombres de widgets duplicados.",
|
||||
"duplicate-template-widget-error": "No se puede duplicar la plantilla porque algunos nombres de widgets están duplicados en diferentes roles. Cambie el nombre de los widgets duplicados e inténtelo de nuevo.",
|
||||
"credit-alert": "Alerta de crédito",
|
||||
"document-form-data": "Datos del formulario del documento",
|
||||
"view-formdata-paid-title-error": "La función 'Ver datos del formulario' le permite imprimir y descargar los datos de los widgets completados por los firmantes durante la firma.",
|
||||
@@ -1558,5 +1563,13 @@
|
||||
"attach-all-role-to-signer": "Por favor, asigna todos los roles al firmante.",
|
||||
"upgrade-to-edit": "Actualiza para editar",
|
||||
"hide-live-chat-for-signers": "Ocultar chat en vivo para firmantes",
|
||||
"hide-live-chat-for-signers-help": "Cuando está activado, los widgets de chat en vivo se ocultarán para los firmantes en las páginas de firma."
|
||||
"hide-live-chat-for-signers-help": "Cuando está activado, los widgets de chat en vivo se ocultarán para los firmantes en las páginas de firma.",
|
||||
"attachments-creator-hint": "Los firmantes pueden subir archivos que se añadirán al final del documento.",
|
||||
"attachments-drop-hint": "Arrastra archivos aquí o haz clic para seleccionar",
|
||||
"attachments-limits": "PDF, DOCX, PNG, JPG. Hasta {{maxFiles}} archivos, {{maxSizeMB}} MB cada uno.",
|
||||
"attachments-invalid-type": "Tipo de archivo no admitido: {{name}}",
|
||||
"attachments-max-files": "Se permiten hasta {{maxFiles}} adjuntos.",
|
||||
"attachments-remove-confirm": "Eliminar solo borra los metadatos. Las páginas ya añadidas permanecerán en el documento. ¿Continuar?",
|
||||
"attachement-note": "Nota: Este widget permite a los firmantes cargar un archivo durante el proceso de firma. El archivo cargado se añadirá como páginas adicionales al final del PDF existente.",
|
||||
"attachments-docx-not-supported": "Actualmente estamos experimentando un problema con las cargas de archivos DOCX. Intente cargar el documento en otro formato compatible o vuelva a intentarlo más tarde."
|
||||
}
|
||||
|
||||
@@ -421,7 +421,10 @@
|
||||
"image": "image",
|
||||
"email": "e-mail",
|
||||
"number": "nombre",
|
||||
"draw": "Dessiner"
|
||||
"draw": "Dessiner",
|
||||
"attachments": "pièces jointes",
|
||||
"attachments-add": "Cliquer pour ajouter des pièces jointes",
|
||||
"attachments-count": "{{count}} pièce(s) jointe(s)"
|
||||
},
|
||||
"fields": "Des champs",
|
||||
"recipients": "Destinataires",
|
||||
@@ -1359,7 +1362,7 @@
|
||||
"export-all-formdata-error": "Vous ne pouvez pas exporter les données du formulaire car le modèle contient des noms de widgets en double. Veuillez créer un nouveau modèle pour pouvoir exporter les données.",
|
||||
"export-formdata-error": "Vous ne pouvez pas exporter les données du formulaire car le document contient des noms de widgets en double. Veuillez créer un nouveau document sans doublons pour pouvoir exporter les données.",
|
||||
"duplicate-widget-name-error": "Ce nom de widget est déjà attribué à un autre signataire. Veuillez choisir un autre nom.",
|
||||
"duplicate-template-widget-error": "Vous ne pouvez pas dupliquer ce modèle car il contient des noms de widgets en double.",
|
||||
"duplicate-template-widget-error": "Impossible de dupliquer le modèle, car certains noms de widgets sont dupliqués dans différents rôles. Renommez les widgets en double, puis réessayez.",
|
||||
"credit-alert": "Alerte de crédit",
|
||||
"document-form-data": "Données du formulaire du document",
|
||||
"view-formdata-paid-title-error": "La fonction 'Afficher les données du formulaire' vous permet d'imprimer et de télécharger les données des widgets remplies par les signataires lors de la signature.",
|
||||
@@ -1556,8 +1559,18 @@
|
||||
"benefit-bulksend-api-team-month-help": "Ce forfait inclut 100 crédits premium par mois qui vous permettent d'envoyer des documents via l'API, de partager des liens publics de signature, de lancer des demandes de signature en masse, d'utiliser le mode Kiosque pour les signatures en personne ou de collecter des signatures à partir de documents intégrés directement à votre site web. À chaque fois que vous initiez ou envoyez un document, un crédit est utilisé — et ce document peut inclure jusqu'à 10 signataires.",
|
||||
"benefit-bulksend-api-team-year-help": "Ce forfait inclut 500 crédits premium par an qui vous permettent d'envoyer des documents via l'API, de partager des liens publics de signature, de lancer des demandes de signature en masse, d'utiliser le mode Kiosque pour les signatures en personne ou de collecter des signatures à partir de documents intégrés directement à votre site web. À chaque fois que vous initiez ou envoyez un document, un crédit est utilisé — et ce document peut inclure jusqu'à 10 signataires.",
|
||||
"failed-pdf-for-prefill-processing": "Impossible de charger le PDF pour le traitement du préremplissage.",
|
||||
"attachments-docx-upload-failed": "Nous rencontrons actuellement un problème. Veuillez réessayer.",
|
||||
"attachments-docx-upload-limit": "La limite de téléchargement pour les fichiers DOCX volumineux a été atteinte. Veuillez attendre 4 minutes avant de réessayer.",
|
||||
"attach-all-role-to-signer": "Veuillez attribuer tous les rôles au signataire.",
|
||||
"upgrade-to-edit": "Mettre à niveau pour modifier",
|
||||
"hide-live-chat-for-signers": "Masquer le chat en direct pour les signataires",
|
||||
"hide-live-chat-for-signers-help": "Lorsqu'activé, les widgets de chat en direct seront masqués pour les signataires sur les pages de signature."
|
||||
"hide-live-chat-for-signers-help": "Lorsqu'activé, les widgets de chat en direct seront masqués pour les signataires sur les pages de signature.",
|
||||
"attachments-creator-hint": "Les signataires peuvent téléverser des fichiers qui seront ajoutés à la fin du document.",
|
||||
"attachments-drop-hint": "Déposez les fichiers ici ou cliquez pour choisir",
|
||||
"attachments-limits": "PDF, DOCX, PNG, JPG. Jusqu'à {{maxFiles}} fichiers, {{maxSizeMB}} Mo chacun.",
|
||||
"attachments-invalid-type": "Type de fichier non pris en charge : {{name}}",
|
||||
"attachments-max-files": "Maximum {{maxFiles}} pièces jointes autorisées.",
|
||||
"attachments-remove-confirm": "La suppression efface uniquement les métadonnées. Les pages déjà ajoutées resteront dans le document. Continuer ?",
|
||||
"attachement-note": "Remarque : Ce widget permet aux signataires de télécharger un fichier pendant le processus de signature. Le fichier téléchargé sera ajouté en tant que pages supplémentaires à la fin du PDF existant.",
|
||||
"attachments-docx-not-supported": "Nous rencontrons actuellement un problème avec le téléchargement des fichiers DOCX. Veuillez essayer de télécharger le document dans un autre format pris en charge ou réessayer plus tard."
|
||||
}
|
||||
|
||||
@@ -284,6 +284,8 @@
|
||||
"yes": "हाँ",
|
||||
"copied": "कॉपी किया गया",
|
||||
"something-went-wrong-mssg": "कुछ गलत हो गया, इस पृष्ठ को रीफ्रेश करने से यह समस्या हल हो सकती है।",
|
||||
"attachments-docx-upload-failed": "फिलहाल एक समस्या आ रही है। कृपया पुनः प्रयास करें।",
|
||||
"attachments-docx-upload-limit": "बड़ी DOCX फ़ाइलों के लिए अपलोड सीमा को पार कर लिया गया है। कृपया 4 मिनट तक प्रतीक्षा करें और फिर प्रयास करें।",
|
||||
"token-generated": "टोकन सफलतापूर्वक उत्पन्न हुआ।",
|
||||
"webhook": "वेबहूक",
|
||||
"update-webhook": "वेबहूक अपडेट करें",
|
||||
@@ -421,7 +423,10 @@
|
||||
"image": "छवि",
|
||||
"email": "ईमेल",
|
||||
"number": "संख्या",
|
||||
"draw": "आरेखित करें"
|
||||
"draw": "आरेखित करें",
|
||||
"attachments": "संलग्नक",
|
||||
"attachments-add": "संलग्नक अपलोड करने के लिए क्लिक करें",
|
||||
"attachments-count": "{{count}} संलग्नक"
|
||||
},
|
||||
"fields": "क्षेत्र",
|
||||
"recipients": "प्राप्तकर्ता",
|
||||
@@ -1359,7 +1364,7 @@
|
||||
"export-all-formdata-error": "आप फ़ॉर्म डेटा निर्यात नहीं कर सकते क्योंकि टेम्पलेट में डुप्लिकेट विजेट नाम हैं। कृपया नया टेम्पलेट बनाएं ताकि आप फ़ॉर्म डेटा निर्यात कर सकें।",
|
||||
"export-formdata-error": "आप फ़ॉर्म डेटा निर्यात नहीं कर सकते क्योंकि दस्तावेज़ में डुप्लिकेट विजेट नाम हैं। कृपया नया दस्तावेज़ बनाएं जिसमें डुप्लिकेट विजेट नाम न हों।",
|
||||
"duplicate-widget-name-error": "यह विजेट नाम पहले से ही किसी अन्य साइनर को सौंपा गया है। कृपया कोई दूसरा नाम चुनें।",
|
||||
"duplicate-template-widget-error": "आप इस टेम्पलेट को डुप्लिकेट नहीं कर सकते क्योंकि इसमें डुप्लिकेट विजेट नाम हैं।",
|
||||
"duplicate-template-widget-error": "टेम्पलेट को डुप्लिकेट नहीं किया जा सकता क्योंकि कुछ विजेट नाम अलग-अलग भूमिकाओं में डुप्लिकेट हैं। डुप्लिकेट विजेट्स का नाम बदलें और फिर से प्रयास करें।",
|
||||
"credit-alert": "क्रेडिट अलर्ट",
|
||||
"document-form-data": "दस्तावेज़ फ़ॉर्म डेटा",
|
||||
"view-formdata-paid-title-error": "'फ़ॉर्म डेटा देखें' सुविधा आपको हस्ताक्षर करते समय साइनरों द्वारा भरे गए विजेट डेटा को प्रिंट और डाउनलोड करने की सुविधा देती है.",
|
||||
@@ -1558,5 +1563,13 @@
|
||||
"attach-all-role-to-signer": "कृपया सभी भूमिकाएँ साइनर से जोड़ें।",
|
||||
"upgrade-to-edit": "एडिट करने के लिए अपग्रेड करें",
|
||||
"hide-live-chat-for-signers": "साइनर के लिए लाइव चैट छुपाएं",
|
||||
"hide-live-chat-for-signers-help": "सक्षम होने पर, साइनिंग पेजों पर साइनर के लिए लाइव चैट विजेट छुपाए जाएंगे।"
|
||||
"hide-live-chat-for-signers-help": "सक्षम होने पर, साइनिंग पेजों पर साइनर के लिए लाइव चैट विजेट छुपाए जाएंगे।",
|
||||
"attachments-creator-hint": "हस्ताक्षरकर्ता ऐसी फ़ाइलें अपलोड कर सकते हैं जो दस्तावेज़ के अंत में जोड़ी जाएँगी।",
|
||||
"attachments-drop-hint": "फ़ाइलें यहाँ छोड़ें या चुनने के लिए क्लिक करें",
|
||||
"attachments-limits": "PDF, DOCX, PNG, JPG. अधिकतम {{maxFiles}} फ़ाइलें, प्रत्येक {{maxSizeMB}} MB।",
|
||||
"attachments-invalid-type": "असमर्थित फ़ाइल प्रकार: {{name}}",
|
||||
"attachments-max-files": "अधिकतम {{maxFiles}} संलग्नक अनुमत हैं।",
|
||||
"attachments-remove-confirm": "हटाने से केवल मेटाडेटा हटेगा। पहले से जोड़े गए पृष्ठ दस्तावेज़ में बने रहेंगे। जारी रखें?",
|
||||
"attachement-note": "नोट: यह विजेट हस्ताक्षरकर्ताओं को साइनिंग प्रक्रिया के दौरान फ़ाइल अपलोड करने की अनुमति देता है। अपलोड की गई फ़ाइल मौजूदा PDF के अंत में अतिरिक्त पेज के रूप में जोड़ दी जाएगी।",
|
||||
"attachments-docx-not-supported": "हम वर्तमान में DOCX फ़ाइल अपलोड में एक समस्या का सामना कर रहे हैं। कृपया दस्तावेज़ को किसी अन्य समर्थित प्रारूप में अपलोड करने का प्रयास करें, या बाद में पुनः प्रयास करें।"
|
||||
}
|
||||
|
||||
@@ -284,6 +284,8 @@
|
||||
"yes": "Sì",
|
||||
"copied": "Copiato",
|
||||
"something-went-wrong-mssg": "Si è verificato un errore, L'aggiornamento della pagina potrebbe risolvere il problema.",
|
||||
"attachments-docx-upload-failed": "Al momento si è verificato un problema. Riprova.",
|
||||
"attachments-docx-upload-limit": "È stato raggiunto il limite di caricamento per file DOCX grandi. Attendi 4 minuti prima di riprovare.",
|
||||
"token-generated": "Token generato con successo.",
|
||||
"webhook": "Webhook",
|
||||
"update-webhook": "Aggiorna Webhook",
|
||||
@@ -421,7 +423,10 @@
|
||||
"image": "immagine",
|
||||
"email": "email",
|
||||
"number": "numero",
|
||||
"draw": "Disegno"
|
||||
"draw": "Disegno",
|
||||
"attachments": "allegati",
|
||||
"attachments-add": "Clicca per caricare allegati",
|
||||
"attachments-count": "{{count}} allegato/i"
|
||||
},
|
||||
"fields": "Campi",
|
||||
"recipients": "Destinatari",
|
||||
@@ -1359,7 +1364,7 @@
|
||||
"export-all-formdata-error": "Non è possibile esportare i dati del modulo perché il modello contiene nomi di widget duplicati. Creare un nuovo modello per poter esportare i dati.",
|
||||
"export-formdata-error": "Non è possibile esportare i dati del modulo perché il documento contiene nomi di widget duplicati. Creare un nuovo documento senza nomi duplicati per poter esportare i dati.",
|
||||
"duplicate-widget-name-error": "Questo nome di widget è già assegnato a un altro firmatario. Scegli un nome diverso.",
|
||||
"duplicate-template-widget-error": "Non è possibile duplicare questo modello perché contiene nomi di widget duplicati.",
|
||||
"duplicate-template-widget-error": "Impossibile duplicare il modello perché alcuni nomi di widget sono duplicati in ruoli diversi. Rinomina i widget duplicati e riprova.",
|
||||
"credit-alert": "Avviso di credito",
|
||||
"document-form-data": "Dati del modulo del documento",
|
||||
"view-formdata-paid-title-error": "La funzione 'Visualizza dati del modulo' consente di stampare e scaricare i dati dei widget compilati dai firmatari durante la firma.",
|
||||
@@ -1558,5 +1563,13 @@
|
||||
"attach-all-role-to-signer": "Per favore, assegna tutti i ruoli al firmatario.",
|
||||
"upgrade-to-edit": "Esegui l'upgrade per modificare",
|
||||
"hide-live-chat-for-signers": "Nascondi chat dal vivo per i firmatari",
|
||||
"hide-live-chat-for-signers-help": "Se attivato, i widget di chat dal vivo saranno nascosti per i firmatari nelle pagine di firma."
|
||||
"hide-live-chat-for-signers-help": "Se attivato, i widget di chat dal vivo saranno nascosti per i firmatari nelle pagine di firma.",
|
||||
"attachments-creator-hint": "I firmatari possono caricare file che verranno aggiunti alla fine del documento.",
|
||||
"attachments-drop-hint": "Trascina i file qui o clicca per selezionare",
|
||||
"attachments-limits": "PDF, DOCX, PNG, JPG. Fino a {{maxFiles}} file, {{maxSizeMB}} MB ciascuno.",
|
||||
"attachments-invalid-type": "Tipo di file non supportato: {{name}}",
|
||||
"attachments-max-files": "Massimo {{maxFiles}} allegati consentiti.",
|
||||
"attachments-remove-confirm": "La rimozione cancella solo i metadati. Le pagine già aggiunte resteranno nel documento. Continuare?",
|
||||
"attachement-note": "Nota: Questo widget consente ai firmatari di caricare un file durante il processo di firma. Il file caricato verrà aggiunto come pagine aggiuntive alla fine del PDF esistente.",
|
||||
"attachments-docx-not-supported": "Al momento stiamo riscontrando un problema con il caricamento dei file DOCX. Prova a caricare il documento in un altro formato supportato oppure riprova più tardi."
|
||||
}
|
||||
|
||||
@@ -284,6 +284,8 @@
|
||||
"yes": "네",
|
||||
"copied": "복사됨",
|
||||
"something-went-wrong-mssg": "문제가 발생했습니다. 새로고침 시 문제가 해결될 수 있습니다.",
|
||||
"attachments-docx-upload-failed": "현재 문제가 발생했습니다. 다시 시도해 주세요.",
|
||||
"attachments-docx-upload-limit": "큰 DOCX 파일에 대한 업로드 제한에 도달했습니다. 4분 후에 다시 시도해 주세요.",
|
||||
"token-generated": "토큰이 성공적으로 생성되었습니다.",
|
||||
"webhook": "웹훅",
|
||||
"update-webhook": "웹훅 업데이트",
|
||||
@@ -421,7 +423,10 @@
|
||||
"image": "이미지",
|
||||
"email": "이메일",
|
||||
"number": "숫자",
|
||||
"draw": "그리기"
|
||||
"draw": "그리기",
|
||||
"attachments": "첨부파일",
|
||||
"attachments-add": "클릭하여 첨부파일 업로드",
|
||||
"attachments-count": "{{count}}개 첨부파일"
|
||||
},
|
||||
"fields": "필드",
|
||||
"recipients": "수신자",
|
||||
@@ -1359,7 +1364,7 @@
|
||||
"export-all-formdata-error": "템플릿에 중복된 위젯 이름이 포함되어 있어 양식 데이터를 내보낼 수 없습니다. 양식 데이터를 내보내려면 새 템플릿을 만드십시오.",
|
||||
"export-formdata-error": "문서에 중복된 위젯 이름이 포함되어 있어 양식 데이터를 내보낼 수 없습니다. 양식 데이터를 내보내려면 중복된 위젯 이름이 없는 새 문서를 만드십시오.",
|
||||
"duplicate-widget-name-error": "이 위젯 이름은 이미 다른 서명자에게 할당되었습니다. 다른 이름을 선택하십시오.",
|
||||
"duplicate-template-widget-error": "이 템플릿에는 중복된 위젯 이름이 포함되어 있어 복제할 수 없습니다.",
|
||||
"duplicate-template-widget-error": "일부 위젯 이름이 다른 역할에서 중복되어 템플릿을 복제할 수 없습니다. 중복된 위젯의 이름을 변경한 후 다시 시도하세요.",
|
||||
"credit-alert": "크레딧 알림",
|
||||
"document-form-data": "문서 양식 데이터",
|
||||
"view-formdata-paid-title-error": "양식 데이터 보기 기능을 사용하면 서명자가 서명하는 동안 채운 위젯 데이터를 인쇄하고 다운로드할 수 있습니다.",
|
||||
@@ -1558,5 +1563,13 @@
|
||||
"attach-all-role-to-signer": "서명자에게 모든 역할을 연결해 주세요.",
|
||||
"upgrade-to-edit": "편집하려면 업그레이드하세요",
|
||||
"hide-live-chat-for-signers": "서명자에게 라이브 채팅 숨기기",
|
||||
"hide-live-chat-for-signers-help": "활성화하면 서명 페이지에서 서명자에게 라이브 채팅 위젯이 숨겨집니다."
|
||||
"hide-live-chat-for-signers-help": "활성화하면 서명 페이지에서 서명자에게 라이브 채팅 위젯이 숨겨집니다.",
|
||||
"attachments-creator-hint": "서명자는 문서 끝에 추가될 파일을 업로드할 수 있습니다.",
|
||||
"attachments-drop-hint": "파일을 여기에 놓거나 클릭하여 선택하세요",
|
||||
"attachments-limits": "PDF, DOCX, PNG, JPG. 최대 {{maxFiles}}개 파일, 각 {{maxSizeMB}} MB.",
|
||||
"attachments-invalid-type": "지원되지 않는 파일 형식: {{name}}",
|
||||
"attachments-max-files": "최대 {{maxFiles}}개의 첨부파일이 허용됩니다.",
|
||||
"attachments-remove-confirm": "제거하면 메타데이터만 삭제됩니다. 이미 추가된 페이지는 문서에 남아 있습니다. 계속하시겠습니까?",
|
||||
"attachement-note": "참고: 이 위젯을 사용하면 서명자가 서명 과정 중에 파일을 업로드할 수 있습니다. 업로드된 파일은 기존 PDF의 마지막에 추가 페이지로 첨부됩니다.",
|
||||
"attachments-docx-not-supported": "현재 DOCX 파일 업로드에 문제가 발생하고 있습니다. 다른 지원되는 형식으로 문서를 업로드하시거나 잠시 후 다시 시도해 주세요."
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ const EXCLUDED_WIDGET_TYPES = new Set([
|
||||
"image",
|
||||
"signature",
|
||||
"stamp",
|
||||
"initials"
|
||||
"initials",
|
||||
]);
|
||||
const ALL_EXCLUDED_TYPES = new Set([
|
||||
...EXCLUDED_PREFILL_TYPES,
|
||||
@@ -80,7 +80,14 @@ const BulkSendUi = (props) => {
|
||||
const initializeWidgetsWithValues = async () => {
|
||||
if (props?.Placeholders?.length > 0) {
|
||||
const roles = props?.Placeholders?.filter((p) => !p.signerObjId) || [];
|
||||
const emails = [];
|
||||
const reservedEmails = (
|
||||
props?.Placeholders?.filter((p) => !!p?.signerObjId) || []
|
||||
)
|
||||
.map(
|
||||
(role) =>
|
||||
normalizeKey(role?.email) || normalizeKey(role?.signerPtr?.Email)
|
||||
)
|
||||
.filter(Boolean);
|
||||
|
||||
const users = await Promise.all(
|
||||
roles?.map(async (role) => {
|
||||
@@ -146,10 +153,6 @@ const BulkSendUi = (props) => {
|
||||
})
|
||||
)
|
||||
);
|
||||
const signerEmail =
|
||||
normalizeKey(role?.email) || role?.signerPtr?.Email;
|
||||
if (signerEmail) emails.push(signerEmail);
|
||||
|
||||
return {
|
||||
fieldId: role.Id,
|
||||
email: "",
|
||||
@@ -171,7 +174,7 @@ const BulkSendUi = (props) => {
|
||||
setStepKey("recipients");
|
||||
setStep(0);
|
||||
}
|
||||
setEmails(emails);
|
||||
setEmails(reservedEmails);
|
||||
|
||||
// Build headers with required ordering:
|
||||
// 1) all role emails first
|
||||
@@ -290,24 +293,28 @@ const BulkSendUi = (props) => {
|
||||
|
||||
function validateEmails(data) {
|
||||
for (const [rowIndex, item] of data.entries()) {
|
||||
let email = "";
|
||||
const rowEmails = new Set();
|
||||
const rowNumber = rowIndex + 1;
|
||||
const filterFields = item?.fields || [];
|
||||
for (const field of filterFields) {
|
||||
// skip prefill
|
||||
if (field?.label === "prefill") continue;
|
||||
const normalizedEmail = normalizeKey(field?.email);
|
||||
const params = { email: field.email, row: rowNumber };
|
||||
if (!field.email) {
|
||||
if (!normalizedEmail) {
|
||||
alert(t("email-not-found-in-row", { ...params }));
|
||||
return false;
|
||||
} else if (!emailRegex.test(field.email)) {
|
||||
} else if (!emailRegex.test(normalizedEmail)) {
|
||||
alert(t("invalid-email-found-in-row", { ...params }));
|
||||
return false;
|
||||
} else if (email === field.email || emails?.includes(field.email)) {
|
||||
} else if (
|
||||
rowEmails.has(normalizedEmail) ||
|
||||
emails?.includes(normalizedEmail)
|
||||
) {
|
||||
alert(t("duplicate-email-found-in-row", { ...params }));
|
||||
return false;
|
||||
} else {
|
||||
email = field.email;
|
||||
rowEmails.add(normalizedEmail);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,16 +37,17 @@ const PrefillWidgets = ({ prefills = [], setPrefills, onNext }) => {
|
||||
a.pageNumber !== b.pageNumber
|
||||
? a.pageNumber - b.pageNumber
|
||||
: (a.yPosition ?? 0) - (b.yPosition ?? 0)
|
||||
).map((widget, index) => (
|
||||
<RenderWidgets
|
||||
key={widget.key}
|
||||
showLabel
|
||||
widget={widget}
|
||||
handleWidgetDetails={(value) =>
|
||||
handleWidgetDetails(value, index)
|
||||
}
|
||||
/>
|
||||
))}
|
||||
)
|
||||
.map((widget, index) => (
|
||||
<RenderWidgets
|
||||
key={widget.key}
|
||||
showLabel
|
||||
widget={widget}
|
||||
handleWidgetDetails={(value) =>
|
||||
handleWidgetDetails(value, index)
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import React, { memo, useState, useEffect, useRef } from "react";
|
||||
import "../../styles/opensigndrive.css";
|
||||
import axios from "axios";
|
||||
import { ContextMenu } from "radix-ui";
|
||||
@@ -676,4 +676,4 @@ function DriveBody(props) {
|
||||
);
|
||||
}
|
||||
|
||||
export default DriveBody;
|
||||
export default memo(DriveBody);
|
||||
|
||||
@@ -36,7 +36,7 @@ function WidgetComponent(props) {
|
||||
{ id: 14, text: "dropdown" },
|
||||
{ id: 15, text: radioButtonWidget },
|
||||
{ id: 16, text: "image" },
|
||||
{ id: 17, text: drawWidget }
|
||||
{ id: 17, text: drawWidget },
|
||||
];
|
||||
|
||||
// Create all drag refs in one go
|
||||
@@ -90,9 +90,12 @@ function WidgetComponent(props) {
|
||||
);
|
||||
const selfSignWidgets = widgetList.filter(
|
||||
(data) =>
|
||||
!["dropdown", radioButtonWidget, textInputWidget, drawWidget].includes(
|
||||
data.type
|
||||
)
|
||||
![
|
||||
"dropdown",
|
||||
radioButtonWidget,
|
||||
textInputWidget,
|
||||
drawWidget,
|
||||
].includes(data.type)
|
||||
);
|
||||
//if user select prefill role then allow only date,image,text,checkbox,radio,dropdownAdd commentMore actions
|
||||
//dropdown widget should only be show in template flow
|
||||
|
||||
@@ -386,9 +386,7 @@ const WidgetNameModal = (props) => {
|
||||
)}
|
||||
{isSignOrInitials && (
|
||||
<div className="mb-[0.75rem]">
|
||||
<label className="text-[14px] mb-[0.7rem]">
|
||||
{t("rotation")}
|
||||
</label>
|
||||
<label className="text-[14px] mb-[0.7rem]">{t("rotation")}</label>
|
||||
<div className="ml-[7px] flex items-center gap-[10px]">
|
||||
<select
|
||||
className="op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs w-[120px]"
|
||||
@@ -418,6 +416,7 @@ const WidgetNameModal = (props) => {
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showFontControls && (
|
||||
<div className="flex flex-col md:flex-row md:items-center gap-3 mb-3">
|
||||
<div className="flex items-center gap-2 ">
|
||||
|
||||
@@ -1036,6 +1036,11 @@ function WidgetsValueModal(props) {
|
||||
? e.target?.value?.trim()
|
||||
: e.target.value;
|
||||
setWidgetValue(value);
|
||||
props.setCurrWidgetsDetails?.((prev) =>
|
||||
prev && prev.key === currWidgetsDetails?.key
|
||||
? { ...prev, options: { ...prev.options, response: value } }
|
||||
: prev
|
||||
);
|
||||
onChangeInput(
|
||||
value,
|
||||
currWidgetsDetails,
|
||||
@@ -1588,24 +1593,24 @@ function WidgetsValueModal(props) {
|
||||
? String(data.name)
|
||||
: "";
|
||||
return (
|
||||
<div key={ind} className="text-base-content select-none-cls">
|
||||
<label
|
||||
// htmlFor={`radio-${currWidgetsDetails?.key + ind}`}
|
||||
className="cursor-pointer flex items-center text-sm gap-1"
|
||||
>
|
||||
<input
|
||||
id={`radio-${currWidgetsDetails?.key + ind}`}
|
||||
className={`op-radio op-radio-xs mt-1`}
|
||||
type="radio"
|
||||
value={label}
|
||||
checked={handleRadioCheck(label?.trim())}
|
||||
onChange={(e) => {
|
||||
handleCheckRadio(e.target.value?.trim());
|
||||
}}
|
||||
/>
|
||||
<span>{label}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div key={ind} className="text-base-content select-none-cls">
|
||||
<label
|
||||
// htmlFor={`radio-${currWidgetsDetails?.key + ind}`}
|
||||
className="cursor-pointer flex items-center text-sm gap-1"
|
||||
>
|
||||
<input
|
||||
id={`radio-${currWidgetsDetails?.key + ind}`}
|
||||
className={`op-radio op-radio-xs mt-1`}
|
||||
type="radio"
|
||||
value={label}
|
||||
checked={handleRadioCheck(label?.trim())}
|
||||
onChange={(e) => {
|
||||
handleCheckRadio(e.target.value?.trim());
|
||||
}}
|
||||
/>
|
||||
<span>{label}</span>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -34,6 +34,86 @@ export const drawWidget = "draw";
|
||||
export const textWidget = "text";
|
||||
export const radioButtonWidget = "radio button";
|
||||
export const cellsWidget = "cells";
|
||||
const duplicateAutoApplyWidgetTypes = [
|
||||
"name",
|
||||
"company",
|
||||
"job title",
|
||||
"email",
|
||||
textInputWidget
|
||||
];
|
||||
const normalizeDuplicateWidgetType = (type) => {
|
||||
if (typeof type !== "string") {
|
||||
return type;
|
||||
}
|
||||
const normalizedType = type.trim().toLowerCase();
|
||||
// Backward compatibility for legacy payloads.
|
||||
if (normalizedType === "textbox") {
|
||||
return textInputWidget;
|
||||
}
|
||||
return normalizedType;
|
||||
};
|
||||
const normalizeDuplicateWidgetName = (name) =>
|
||||
typeof name === "string" ? name.trim().toLowerCase() : "";
|
||||
const isDuplicateAutoApplyWidget = (widget) =>
|
||||
duplicateAutoApplyWidgetTypes.includes(
|
||||
normalizeDuplicateWidgetType(widget?.type)
|
||||
);
|
||||
const getDuplicateAutoApplyName = (widget) => {
|
||||
if (!isDuplicateAutoApplyWidget(widget)) {
|
||||
return "";
|
||||
}
|
||||
return normalizeDuplicateWidgetName(widget?.options?.name);
|
||||
};
|
||||
const getWidgetResponseValue = (widget) =>
|
||||
widget?.options?.response ?? widget?.options?.defaultValue;
|
||||
const getDuplicateResponseMap = (widgets = []) => {
|
||||
const responseByName = new Map();
|
||||
widgets.forEach((widget) => {
|
||||
const widgetName = getDuplicateAutoApplyName(widget);
|
||||
const response = getWidgetResponseValue(widget);
|
||||
if (
|
||||
widgetName &&
|
||||
response !== undefined &&
|
||||
response !== "" &&
|
||||
!responseByName.has(widgetName)
|
||||
) {
|
||||
responseByName.set(widgetName, response);
|
||||
}
|
||||
});
|
||||
return responseByName;
|
||||
};
|
||||
const applyDuplicateResponsesToWidgets = (
|
||||
widgets = [],
|
||||
responseByName = getDuplicateResponseMap(widgets)
|
||||
) => {
|
||||
if (responseByName.size === 0) {
|
||||
return widgets;
|
||||
}
|
||||
|
||||
return widgets.map((widget) => {
|
||||
const widgetName = getDuplicateAutoApplyName(widget);
|
||||
if (!widgetName || !responseByName.has(widgetName)) {
|
||||
return widget;
|
||||
}
|
||||
return {
|
||||
...widget,
|
||||
options: {
|
||||
...widget.options,
|
||||
response: responseByName.get(widgetName),
|
||||
defaultValue: ""
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
const applyDuplicateResponsesToPages = (pages = []) => {
|
||||
const responseByName = getDuplicateResponseMap(
|
||||
pages.flatMap((page) => page?.pos || [])
|
||||
);
|
||||
return pages.map((page) => ({
|
||||
...page,
|
||||
pos: applyDuplicateResponsesToWidgets(page?.pos || [], responseByName)
|
||||
}));
|
||||
};
|
||||
export function getEnv() {
|
||||
return window?.RUNTIME_ENV || {};
|
||||
}
|
||||
@@ -1120,6 +1200,28 @@ export const onChangeInput = (
|
||||
dateDetails,
|
||||
textWidgetHeight
|
||||
) => {
|
||||
const isDuplicateValueUpdate = !dateFormat && !textWidgetHeight;
|
||||
const shouldAutoApplyDuplicateWidget = (position) => {
|
||||
const currentName = getDuplicateAutoApplyName(currentPosition);
|
||||
const positionName = getDuplicateAutoApplyName(position);
|
||||
return currentName && positionName && currentName === positionName;
|
||||
};
|
||||
const applyDuplicateWidgetValue = (position) => {
|
||||
if (
|
||||
position?.options?.response === value &&
|
||||
position?.options?.defaultValue === ""
|
||||
) {
|
||||
return position;
|
||||
}
|
||||
return {
|
||||
...position,
|
||||
options: {
|
||||
...position.options,
|
||||
response: value,
|
||||
defaultValue: ""
|
||||
}
|
||||
};
|
||||
};
|
||||
const isSigners = xyPosition.some(
|
||||
(data) => data.signerPtr || data.Role === "prefill"
|
||||
);
|
||||
@@ -1137,8 +1239,7 @@ export const onChangeInput = (
|
||||
(data) => data.pageNumber === index
|
||||
);
|
||||
if (getPageNumer.length > 0) {
|
||||
const getXYdata = getPageNumer[0].pos;
|
||||
const addSignPos = getXYdata.map((position) => {
|
||||
const updatePositionValue = (position) => {
|
||||
if (position.key === currentPosition.key) {
|
||||
if (dateFormat) {
|
||||
return {
|
||||
@@ -1177,40 +1278,39 @@ export const onChangeInput = (
|
||||
) {
|
||||
return { ...position, Height: textWidgetHeight };
|
||||
} else {
|
||||
return {
|
||||
...position,
|
||||
options: {
|
||||
...position.options,
|
||||
response: value,
|
||||
defaultValue: ""
|
||||
}
|
||||
};
|
||||
return applyDuplicateWidgetValue(position);
|
||||
}
|
||||
}
|
||||
if (
|
||||
isDuplicateValueUpdate &&
|
||||
shouldAutoApplyDuplicateWidget(position)
|
||||
) {
|
||||
return applyDuplicateWidgetValue(position);
|
||||
}
|
||||
return position;
|
||||
};
|
||||
setXyPosition((prevPosition) => {
|
||||
const sourcePosition = Array.isArray(prevPosition)
|
||||
? prevPosition
|
||||
: xyPosition;
|
||||
return sourcePosition.map((obj) => {
|
||||
if (obj.Id !== userId) {
|
||||
return obj;
|
||||
}
|
||||
const updatedPlaceHolder = (obj.placeHolder || []).map((page) => ({
|
||||
...page,
|
||||
pos: page.pos.map(updatePositionValue)
|
||||
}));
|
||||
return {
|
||||
...obj,
|
||||
placeHolder: applyNumberFormulasToPages(updatedPlaceHolder)
|
||||
};
|
||||
});
|
||||
});
|
||||
const newUpdateSignPos = getPlaceHolder.map((obj) => {
|
||||
if (obj.pageNumber === index) {
|
||||
return { ...obj, pos: addSignPos };
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
|
||||
const recalculatedPages = applyNumberFormulasToPages(newUpdateSignPos);
|
||||
|
||||
const newUpdateSigner = xyPosition.map((obj) => {
|
||||
if (obj.Id === userId) {
|
||||
return { ...obj, placeHolder: recalculatedPages };
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
|
||||
setXyPosition(newUpdateSigner);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let getXYdata = xyPosition[index].pos;
|
||||
const updatePosition = getXYdata.map((positionData) => {
|
||||
const updatePositionValue = (positionData) => {
|
||||
if (positionData.key === currentPosition.key) {
|
||||
if (dateFormat) {
|
||||
return {
|
||||
@@ -1233,26 +1333,28 @@ export const onChangeInput = (
|
||||
) {
|
||||
return { ...positionData, Height: textWidgetHeight };
|
||||
} else {
|
||||
return {
|
||||
...positionData,
|
||||
options: {
|
||||
...positionData.options,
|
||||
response: value,
|
||||
defaultValue: ""
|
||||
}
|
||||
};
|
||||
return applyDuplicateWidgetValue(positionData);
|
||||
}
|
||||
}
|
||||
return positionData;
|
||||
});
|
||||
|
||||
const updatePlaceholder = xyPosition.map((obj, ind) => {
|
||||
if (ind === index) {
|
||||
return { ...obj, pos: updatePosition };
|
||||
if (
|
||||
isDuplicateValueUpdate &&
|
||||
shouldAutoApplyDuplicateWidget(positionData)
|
||||
) {
|
||||
return applyDuplicateWidgetValue(positionData);
|
||||
}
|
||||
return obj;
|
||||
return positionData;
|
||||
};
|
||||
|
||||
setXyPosition((prevPosition) => {
|
||||
const sourcePosition = Array.isArray(prevPosition)
|
||||
? prevPosition
|
||||
: xyPosition;
|
||||
const updatePlaceholder = sourcePosition.map((obj) => ({
|
||||
...obj,
|
||||
pos: obj.pos.map(updatePositionValue)
|
||||
}));
|
||||
return applyNumberFormulasToPages(updatePlaceholder);
|
||||
});
|
||||
setXyPosition(applyNumberFormulasToPages(updatePlaceholder));
|
||||
}
|
||||
};
|
||||
//function to increase height of text area on press enter
|
||||
@@ -4184,10 +4286,8 @@ export const updateDateWidgetsRes = (
|
||||
: [];
|
||||
const sortedPlaceHolder = placeHolder
|
||||
.sort((a, b) => a.pageNumber - b.pageNumber)
|
||||
.map((ph) => ({
|
||||
...ph,
|
||||
// Sort positions within each page
|
||||
pos: [...ph.pos]
|
||||
.map((ph) => {
|
||||
const sortedWidgets = [...ph.pos]
|
||||
.sort((a, b) => {
|
||||
// Sort widgets by Y position (top to bottom) and X position (left to right)
|
||||
// Treat widgets within 5px Y difference as belonging to the same row
|
||||
@@ -4219,9 +4319,14 @@ export const updateDateWidgetsRes = (
|
||||
};
|
||||
}
|
||||
return widget;
|
||||
})
|
||||
}));
|
||||
return { ...item, placeHolder: sortedPlaceHolder };
|
||||
});
|
||||
let widgetsWithResponses = sortedWidgets;
|
||||
return { ...ph, pos: widgetsWithResponses };
|
||||
});
|
||||
return {
|
||||
...item,
|
||||
placeHolder: applyDuplicateResponsesToPages(sortedPlaceHolder)
|
||||
};
|
||||
}
|
||||
|
||||
return item;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState, useRef, useEffect } from "react";
|
||||
import { useState, useRef, useEffect, useCallback } from "react";
|
||||
import { PDFDocument } from "pdf-lib";
|
||||
import "../styles/signature.css";
|
||||
import Parse from "parse";
|
||||
@@ -409,7 +409,7 @@ function PdfRequestFiles(
|
||||
documentData?.[0]?.AuditTrail?.some(
|
||||
(data) =>
|
||||
data?.UserPtr?.objectId === currUserId &&
|
||||
(data.Activity === "Signed"
|
||||
(data.Activity === "Signed"
|
||||
)
|
||||
) || false;
|
||||
if (checkAlreadySign) {
|
||||
@@ -462,7 +462,7 @@ function PdfRequestFiles(
|
||||
(data) => data.objectId === placeholder?.signerObjId
|
||||
);
|
||||
placeholdersOrSigners.push({
|
||||
...getSignerData
|
||||
...getSignerData,
|
||||
});
|
||||
} else {
|
||||
placeholdersOrSigners.push(placeholder);
|
||||
@@ -1137,11 +1137,11 @@ function PdfRequestFiles(
|
||||
}
|
||||
];
|
||||
//function for get pdf page details
|
||||
const pageDetails = async (pdf) => {
|
||||
const pdfWHObj = await getOriginalWH(pdf);
|
||||
setPdfOriginalWH(pdfWHObj);
|
||||
setPdfLoad(true);
|
||||
};
|
||||
const pageDetails = async (pdf) => {
|
||||
const pdfWHObj = await getOriginalWH(pdf);
|
||||
setPdfOriginalWH(pdfWHObj);
|
||||
setPdfLoad(true);
|
||||
};
|
||||
//function for change page
|
||||
function changePage(offset) {
|
||||
setPageNumber((prevPageNumber) => prevPageNumber + offset);
|
||||
@@ -1817,7 +1817,7 @@ function PdfRequestFiles(
|
||||
!alreadySign &&
|
||||
!isCompleted?.isCertificate &&
|
||||
!isDecline?.isDeclined &&
|
||||
(
|
||||
(
|
||||
<AgreementSign
|
||||
setIsAgree={setIsAgree}
|
||||
showFirstWidget={showFirstWidget}
|
||||
@@ -2239,7 +2239,7 @@ function PdfRequestFiles(
|
||||
{pdfDetails[0]?.AllowModifications &&
|
||||
currentSigner &&
|
||||
!alreadySign &&
|
||||
(
|
||||
(
|
||||
<div data-tut="reactourFourth">
|
||||
<WidgetComponent
|
||||
pdfUrl={pdfUrl}
|
||||
|
||||
@@ -7,6 +7,59 @@ export default async function addUser(request) {
|
||||
const currentUser = { __type: 'Pointer', className: '_User', objectId: request.user.id };
|
||||
if (name && email && password && organization && team && role && tenantId) {
|
||||
try {
|
||||
// Derive the caller's tenant/organization/role from the server-side
|
||||
// record rather than trusting client-supplied identifiers. This
|
||||
// prevents an authenticated low-privileged user from creating an admin
|
||||
// or assigning the new user to an arbitrary tenant/organization/team.
|
||||
const callerQuery = new Parse.Query('contracts_Users');
|
||||
callerQuery.equalTo('UserId', currentUser);
|
||||
callerQuery.notEqualTo('IsDisabled', true);
|
||||
const callerExtUser = await callerQuery.first({ useMasterKey: true });
|
||||
if (!callerExtUser) {
|
||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User not found.');
|
||||
}
|
||||
const callerRole = callerExtUser.get('UserRole');
|
||||
const isAdmin = callerRole === 'contracts_Admin';
|
||||
const isOrgAdmin = callerRole === 'contracts_OrgAdmin';
|
||||
if (!isAdmin && !isOrgAdmin) {
|
||||
throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Unauthorized.');
|
||||
}
|
||||
const callerTenantId = callerExtUser.get('TenantId')?.id;
|
||||
const callerOrgId = callerExtUser.get('OrganizationId')?.id;
|
||||
// Enforce tenant-bound writes for all admins and require org scope for OrgAdmin callers.
|
||||
if (!callerTenantId || tenantId !== callerTenantId || (isOrgAdmin && !callerOrgId)) {
|
||||
throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Unauthorized.');
|
||||
}
|
||||
|
||||
// Only allow creating non-admin roles; never allow elevating to a
|
||||
// tenant Admin through this endpoint.
|
||||
const allowedRoles = ['OrgAdmin', 'Editor', 'User'];
|
||||
if (!allowedRoles.includes(role)) {
|
||||
throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Invalid role.');
|
||||
}
|
||||
|
||||
// Resolve and authorize the target organization within the caller's tenant.
|
||||
const targetOrgId = organization.objectId;
|
||||
if (!targetOrgId) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Please provide all required fields.');
|
||||
}
|
||||
const orgQuery = new Parse.Query('contracts_Organizations');
|
||||
const targetOrg = await orgQuery.get(targetOrgId, { useMasterKey: true });
|
||||
if (targetOrg.get('TenantId')?.id !== callerTenantId) {
|
||||
throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Unauthorized.');
|
||||
}
|
||||
// An OrgAdmin may only add users to their own organization.
|
||||
if (isOrgAdmin && targetOrgId !== callerOrgId) {
|
||||
throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Unauthorized.');
|
||||
}
|
||||
|
||||
// Authorize the target team belongs to the target organization.
|
||||
const teamQuery = new Parse.Query('contracts_Teams');
|
||||
const targetTeam = await teamQuery.get(team, { useMasterKey: true });
|
||||
if (targetTeam.get('OrganizationId')?.id !== targetOrgId) {
|
||||
throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Unauthorized.');
|
||||
}
|
||||
|
||||
const extUser = new Parse.Object('contracts_Users');
|
||||
extUser.set('Name', name);
|
||||
if (phone) {
|
||||
@@ -14,33 +67,27 @@ export default async function addUser(request) {
|
||||
}
|
||||
extUser.set('Email', email);
|
||||
extUser.set('UserRole', `contracts_${role}`);
|
||||
if (team) {
|
||||
extUser.set('TeamIds', [
|
||||
{
|
||||
__type: 'Pointer',
|
||||
className: 'contracts_Teams',
|
||||
objectId: team,
|
||||
},
|
||||
]);
|
||||
}
|
||||
if (organization.objectId) {
|
||||
extUser.set('OrganizationId', {
|
||||
extUser.set('TeamIds', [
|
||||
{
|
||||
__type: 'Pointer',
|
||||
className: 'contracts_Organizations',
|
||||
objectId: organization.objectId,
|
||||
});
|
||||
}
|
||||
className: 'contracts_Teams',
|
||||
objectId: team,
|
||||
},
|
||||
]);
|
||||
extUser.set('OrganizationId', {
|
||||
__type: 'Pointer',
|
||||
className: 'contracts_Organizations',
|
||||
objectId: targetOrgId,
|
||||
});
|
||||
if (organization.company) {
|
||||
extUser.set('Company', organization.company);
|
||||
}
|
||||
|
||||
if (tenantId) {
|
||||
extUser.set('TenantId', {
|
||||
__type: 'Pointer',
|
||||
className: 'partners_Tenant',
|
||||
objectId: tenantId,
|
||||
});
|
||||
}
|
||||
extUser.set('TenantId', {
|
||||
__type: 'Pointer',
|
||||
className: 'partners_Tenant',
|
||||
objectId: callerTenantId,
|
||||
});
|
||||
if (timezone) {
|
||||
extUser.set('Timezone', timezone);
|
||||
}
|
||||
@@ -61,10 +108,10 @@ export default async function addUser(request) {
|
||||
|
||||
extUser.set('UserId', user);
|
||||
const acl = new Parse.ACL();
|
||||
acl.setPublicReadAccess(true);
|
||||
acl.setPublicWriteAccess(true);
|
||||
acl.setReadAccess(request.user.id, true);
|
||||
acl.setWriteAccess(request.user.id, true);
|
||||
acl.setReadAccess(user.id, true);
|
||||
acl.setWriteAccess(user.id, true);
|
||||
extUser.setACL(acl);
|
||||
const extUserRes = await extUser.save();
|
||||
|
||||
@@ -82,10 +129,10 @@ export default async function addUser(request) {
|
||||
extUser.set('CreatedBy', currentUser);
|
||||
extUser.set('UserId', { __type: 'Pointer', className: '_User', objectId: userRes.id });
|
||||
const acl = new Parse.ACL();
|
||||
acl.setPublicReadAccess(true);
|
||||
acl.setPublicWriteAccess(true);
|
||||
acl.setReadAccess(request.user.id, true);
|
||||
acl.setWriteAccess(request.user.id, true);
|
||||
acl.setReadAccess(userRes.id, true);
|
||||
acl.setWriteAccess(userRes.id, true);
|
||||
|
||||
extUser.setACL(acl);
|
||||
const res = await extUser.save();
|
||||
|
||||
@@ -116,13 +116,24 @@ async function sendMail(document, publicUrl) {
|
||||
: senderEmail;
|
||||
|
||||
if (document.SendinOrder) {
|
||||
signerMail = signerMail.slice();
|
||||
signerMail.splice(1);
|
||||
const getRole = signer => signer?.SignerRole || signer?.signer_role || signer?.role || 'signer';
|
||||
const firstSignerIndex = signerMail.findIndex(signer => getRole(signer) === 'signer');
|
||||
signerMail = signerMail.filter((signer, idx) => {
|
||||
const role = getRole(signer);
|
||||
return role === 'viewer' || idx === firstSignerIndex;
|
||||
});
|
||||
if (signerMail.length === 0 && document?.Placeholders?.length > 0) {
|
||||
signerMail = document.Placeholders.filter(x => x?.Role !== 'prefill').slice(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < signerMail.length; i++) {
|
||||
try {
|
||||
let url = `${serverUrl}/functions/sendmailv3`;
|
||||
const headers = { 'Content-Type': 'application/json', 'X-Parse-Application-Id': appId };
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Parse-Application-Id': appId,
|
||||
};
|
||||
const objectId = signerMail[i]?.signerObjId;
|
||||
const hostUrl = baseUrl.origin;
|
||||
let encodeBase64;
|
||||
|
||||
@@ -43,6 +43,8 @@ async function fetchDocumentsByName(
|
||||
query.notEqualTo('IsArchive', true);
|
||||
query.descending('updatedAt');
|
||||
query.exclude('AuditTrail');
|
||||
query.exclude('OriginalDocument');
|
||||
query.exclude('SignedDocument');
|
||||
query.notEqualTo('Type', 'Folder');
|
||||
try {
|
||||
return await query.find({ useMasterKey: true });
|
||||
|
||||
@@ -36,6 +36,8 @@ export default async function getDrive(request) {
|
||||
query.skip(skip);
|
||||
query.limit(limit);
|
||||
query.exclude('AuditTrail');
|
||||
query.exclude('OriginalDocument');
|
||||
query.exclude('SignedDocument');
|
||||
const res = await query.find({ useMasterKey: true });
|
||||
return res;
|
||||
} catch (err) {
|
||||
|
||||
@@ -9,6 +9,39 @@ export default async function getUserListByOrg(req) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.');
|
||||
} else {
|
||||
try {
|
||||
if (!OrganizationId) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Please provide organizationId.');
|
||||
}
|
||||
// Authorize the requested organization against the caller's server-side
|
||||
// tenant/organization. This prevents an authenticated user from
|
||||
// enumerating users in an arbitrary organization or tenant.
|
||||
const callerQuery = new Parse.Query('contracts_Users');
|
||||
callerQuery.equalTo('UserId', {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: req.user.id,
|
||||
});
|
||||
callerQuery.notEqualTo('IsDisabled', true);
|
||||
const callerExtUser = await callerQuery.first({ useMasterKey: true });
|
||||
if (!callerExtUser) {
|
||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User not found.');
|
||||
}
|
||||
const callerTenantId = callerExtUser.get('TenantId')?.id;
|
||||
const callerOrgId = callerExtUser.get('OrganizationId')?.id;
|
||||
const callerRole = callerExtUser.get('UserRole');
|
||||
const isAdmin = callerRole === 'contracts_Admin' || callerRole === 'contracts_OrgAdmin';
|
||||
|
||||
const orgQuery = new Parse.Query('contracts_Organizations');
|
||||
const targetOrg = await orgQuery.get(OrganizationId, { useMasterKey: true });
|
||||
// Must belong to the caller's tenant.
|
||||
if (!callerTenantId || targetOrg.get('TenantId')?.id !== callerTenantId) {
|
||||
throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Unauthorized.');
|
||||
}
|
||||
// Non-admins may only list their own organization.
|
||||
if (!isAdmin && OrganizationId !== callerOrgId) {
|
||||
throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Unauthorized.');
|
||||
}
|
||||
|
||||
const extUser = new Parse.Query('contracts_Users');
|
||||
extUser.equalTo('OrganizationId', orgPtr);
|
||||
extUser.include('TeamIds');
|
||||
|
||||
@@ -8,6 +8,30 @@ export default async function updateTenant(request) {
|
||||
if (!request.user) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'unauthorized');
|
||||
}
|
||||
|
||||
// Derive the caller's tenant and role server-side. Never trust the
|
||||
// client-supplied tenantId: an authenticated user may only update their own
|
||||
// tenant and must hold an admin role to do so.
|
||||
const callerQuery = new Parse.Query('contracts_Users');
|
||||
callerQuery.equalTo('UserId', {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: request.user.id,
|
||||
});
|
||||
callerQuery.notEqualTo('IsDisabled', true);
|
||||
const callerExtUser = await callerQuery.first({ useMasterKey: true });
|
||||
if (!callerExtUser) {
|
||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User not found.');
|
||||
}
|
||||
const callerRole = callerExtUser.get('UserRole');
|
||||
if (callerRole !== 'contracts_Admin' && callerRole !== 'contracts_OrgAdmin') {
|
||||
throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Unauthorized.');
|
||||
}
|
||||
const callerTenantId = callerExtUser.get('TenantId')?.id;
|
||||
if (!callerTenantId || callerTenantId !== tenantId) {
|
||||
throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Unauthorized.');
|
||||
}
|
||||
|
||||
const validKeys = ['CompletionBody', 'CompletionSubject', 'RequestBody', 'RequestSubject'];
|
||||
try {
|
||||
const tenant = new Parse.Object('partners_Tenant');
|
||||
|
||||
Generated
+49
-45
@@ -18,13 +18,13 @@
|
||||
"@signpdf/placeholder-pdf-lib": "^3.3.0",
|
||||
"@signpdf/signer-p12": "^3.3.0",
|
||||
"@signpdf/signpdf": "^3.3.0",
|
||||
"axios": "^1.15.2",
|
||||
"axios": "^1.16.0",
|
||||
"coherentpdf": "^2.5.5",
|
||||
"cors": "^2.8.6",
|
||||
"date-fns-tz": "^3.2.0",
|
||||
"dotenv": "^17.4.2",
|
||||
"express": "^5.2.1",
|
||||
"form-data": "^4.0.5",
|
||||
"form-data": "^4.0.6",
|
||||
"generate-api-key": "^1.0.2",
|
||||
"googleapis": "^171.4.0",
|
||||
"libreoffice-convert": "^1.8.1",
|
||||
@@ -38,7 +38,7 @@
|
||||
"p-limit": "^7.3.0",
|
||||
"parse": "^8.1.0",
|
||||
"parse-dbtool": "^1.2.0",
|
||||
"parse-server": "^8.6.76",
|
||||
"parse-server": "^8.6.77",
|
||||
"parse-server-api-mail-adapter": "^5.0.5",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"posthog-node": "^5.21.2",
|
||||
@@ -46,7 +46,7 @@
|
||||
"rate-limiter-flexible": "^9.1.1",
|
||||
"sharp": "^0.34.5",
|
||||
"speakeasy": "^2.0.0",
|
||||
"ws": "^8.20.0"
|
||||
"ws": ">=8.21.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^7.28.6",
|
||||
@@ -5729,12 +5729,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz",
|
||||
"integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==",
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz",
|
||||
"integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.11",
|
||||
"follow-redirects": "^1.16.0",
|
||||
"form-data": "^4.0.5",
|
||||
"proxy-from-env": "^2.1.0"
|
||||
}
|
||||
@@ -7420,9 +7420,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-xml-builder": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.5.tgz",
|
||||
"integrity": "sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz",
|
||||
"integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -7431,7 +7431,8 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-expression-matcher": "^1.1.3"
|
||||
"path-expression-matcher": "^1.5.0",
|
||||
"xml-naming": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-xml-parser": {
|
||||
@@ -7735,16 +7736,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
|
||||
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz",
|
||||
"integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
"hasown": "^2.0.4",
|
||||
"mime-types": "^2.1.35"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
@@ -8797,9 +8798,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
|
||||
"integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
@@ -11082,9 +11083,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/parse-server": {
|
||||
"version": "8.6.76",
|
||||
"resolved": "https://registry.npmjs.org/parse-server/-/parse-server-8.6.76.tgz",
|
||||
"integrity": "sha512-PVdrGBLitd3WcKWss7ZI4yoWKQIAwzPSdBx9c8kngL1eqFNGelRKAwQ2+xy52V/pV2b+5M2/UpTlx0pxOphqbw==",
|
||||
"version": "8.6.77",
|
||||
"resolved": "https://registry.npmjs.org/parse-server/-/parse-server-8.6.77.tgz",
|
||||
"integrity": "sha512-eQBdaiSN0eUDDv8tQiTClS9EpaBv61XS8xtrgI/CfFEWXh1WDVCyJnVeM2Z8P8V2mmtC7GgLLqp2Yvptc8Hkrg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@@ -11923,25 +11924,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/protobufjs": {
|
||||
"version": "7.5.5",
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.5.tgz",
|
||||
"integrity": "sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg==",
|
||||
"hasInstallScript": true,
|
||||
"version": "8.6.3",
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.6.3.tgz",
|
||||
"integrity": "sha512-alQyzT0j401LGBtwsqu6uprjR6pfNH1UJf9N6GBFMjIcd+HzTe0/HrjAbFCqun+zvnfLarrxAtMM2xvZ+kFZ5A==",
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.2",
|
||||
"@protobufjs/base64": "^1.1.2",
|
||||
"@protobufjs/codegen": "^2.0.4",
|
||||
"@protobufjs/eventemitter": "^1.1.0",
|
||||
"@protobufjs/fetch": "^1.1.0",
|
||||
"@protobufjs/float": "^1.0.2",
|
||||
"@protobufjs/inquire": "^1.1.0",
|
||||
"@protobufjs/path": "^1.1.2",
|
||||
"@protobufjs/pool": "^1.1.0",
|
||||
"@protobufjs/utf8": "^1.1.0",
|
||||
"@types/node": ">=13.7.0",
|
||||
"long": "^5.0.0"
|
||||
"long": "^5.3.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
@@ -13272,9 +13261,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tmp": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
|
||||
"integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
|
||||
"version": "0.2.7",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz",
|
||||
"integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.14"
|
||||
@@ -13906,9 +13895,9 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.20.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz",
|
||||
"integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==",
|
||||
"version": "8.21.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
|
||||
"integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
@@ -13926,6 +13915,21 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/xml-naming": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz",
|
||||
"integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
|
||||
@@ -27,13 +27,13 @@
|
||||
"@signpdf/placeholder-pdf-lib": "^3.3.0",
|
||||
"@signpdf/signer-p12": "^3.3.0",
|
||||
"@signpdf/signpdf": "^3.3.0",
|
||||
"axios": "^1.15.2",
|
||||
"axios": "^1.16.0",
|
||||
"coherentpdf": "^2.5.5",
|
||||
"cors": "^2.8.6",
|
||||
"date-fns-tz": "^3.2.0",
|
||||
"dotenv": "^17.4.2",
|
||||
"express": "^5.2.1",
|
||||
"form-data": "^4.0.5",
|
||||
"form-data": "^4.0.6",
|
||||
"generate-api-key": "^1.0.2",
|
||||
"googleapis": "^171.4.0",
|
||||
"libreoffice-convert": "^1.8.1",
|
||||
@@ -47,7 +47,7 @@
|
||||
"p-limit": "^7.3.0",
|
||||
"parse": "^8.1.0",
|
||||
"parse-dbtool": "^1.2.0",
|
||||
"parse-server": "^8.6.76",
|
||||
"parse-server": "^8.6.77",
|
||||
"parse-server-api-mail-adapter": "^5.0.5",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"posthog-node": "^5.21.2",
|
||||
@@ -55,7 +55,7 @@
|
||||
"rate-limiter-flexible": "^9.1.1",
|
||||
"sharp": "^0.34.5",
|
||||
"speakeasy": "^2.0.0",
|
||||
"ws": "^8.20.0"
|
||||
"ws": ">=8.21.0"
|
||||
},
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
@@ -71,7 +71,10 @@
|
||||
"ws": "$ws",
|
||||
"parse": "$parse",
|
||||
"form-data": "$form-data",
|
||||
"@parse/push-adapter": "$@parse/push-adapter"
|
||||
"@parse/push-adapter": "$@parse/push-adapter",
|
||||
"fast-xml-builder": "1.2.0",
|
||||
"protobufjs": ">=7.6.3",
|
||||
"tmp": ">=0.2.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20 || 22"
|
||||
|
||||
Reference in New Issue
Block a user